Skip to content

Commit

Permalink
refactor piv algorithm extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
dangfan committed Dec 24, 2023
1 parent 4db715b commit 0d8d72e
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 49 deletions.
5 changes: 0 additions & 5 deletions applets/admin/admin.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ uint8_t cfg_is_webusb_landing_enable(void) { return current_config.webusb_landin

uint8_t cfg_is_kbd_with_return_enable(void) { return current_config.kbd_with_return_en; }

uint8_t cfg_is_piv_algo_extension_enable(void) { return current_config.piv_algo_ext_en; }

void admin_poweroff(void) { pin.is_validated = 0; }

int admin_install(const uint8_t reset) {
Expand Down Expand Up @@ -131,9 +129,6 @@ static int admin_config(const CAPDU *capdu, RAPDU *rapdu) {
case ADMIN_P1_CFG_KBD_WITH_RETURN:
current_config.kbd_with_return_en = P2 & 1;
break;
case ADMIN_P1_CFG_PIV_ALGO_EXT:
current_config.piv_algo_ext_en = P2 & 1;
break;
default:
EXCEPT(SW_WRONG_P1P2);
}
Expand Down
100 changes: 60 additions & 40 deletions applets/piv/piv.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@
#define CARD_ADMIN_KEY_PATH "piv-admk" // 9B

// alg
#define ALGORITHM_EXT_CONFIG_PATH "piv-alg"
#define ALG_DEFAULT 0x00
#define ALG_TDEA_3KEY 0x03
#define ALG_RSA_2048 0x07
#define ALG_ECC_256 0x11
#define ALG_ECC_384 0x14
#define ALG_ED25519 0x22 // Not defined in NIST SP 800-78-4, defined in https://github.com/go-piv/piv-go/pull/69
#define ALG_RSA_3072 0x50 // Not defined in NIST SP 800-78-4
#define ALG_RSA_4096 0x51 // Not defined in NIST SP 800-78-4
#define ALG_X25519 0x52 // Not defined in NIST SP 800-78-4
#define ALG_SECP256K1 0x53 // Not defined in NIST SP 800-78-4
#define ALG_SM2 0x54 // Not defined in NIST SP 800-78-4
#define ALG_ED25519_DEFAULT 0x22 // defined in https://github.com/go-piv/piv-go/pull/69
#define ALG_RSA_3072_DEFAULT 0x50
#define ALG_RSA_4096_DEFAULT 0x51
#define ALG_X25519_DEFAULT 0x52
#define ALG_SECP256K1_DEFAULT 0x53
#define ALG_SM2_DEFAULT 0x54

#define TDEA_BLOCK_SIZE 8

Expand Down Expand Up @@ -97,6 +98,7 @@ static char piv_do_path[MAX_DO_PATH_LEN]; // data object file path during chaini
static int piv_do_write; // -1: not in chaining write, otherwise: count of remaining bytes
static int piv_do_read; // -1: not in chaining read mode, otherwise: data object offset
static uint32_t last_touch = UINT32_MAX;
static piv_algorithm_extension_config_t alg_ext_cfg;

static pin_t pin = {.min_length = 8, .max_length = 8, .is_validated = 0, .path = "piv-pin"};
static pin_t puk = {.min_length = 8, .max_length = 8, .is_validated = 0, .path = "piv-puk"};
Expand Down Expand Up @@ -126,45 +128,50 @@ static key_type_t algo_id_to_key_type(const uint8_t id) {
return SECP384R1;
case ALG_RSA_2048:
return RSA2048;
case ALG_ED25519:
return ED25519;
case ALG_DEFAULT:
case ALG_TDEA_3KEY:
return TDEA;
default:

if (!cfg_is_piv_algo_extension_enable()) return KEY_TYPE_PKC_END;

switch (id) {
case ALG_X25519:
return X25519;
case ALG_SECP256K1:
return SECP256K1;
case ALG_SM2:
return SM2;
case ALG_RSA_3072:
return RSA3072;
case ALG_RSA_4096:
return RSA4096;
default:
return KEY_TYPE_PKC_END;
}
break;
}

if (alg_ext_cfg.enabled == 0) return KEY_TYPE_PKC_END;
if (id == alg_ext_cfg.ed25519) return ED25519;
if (id == alg_ext_cfg.rsa3072) return RSA3072;
if (id == alg_ext_cfg.rsa4096) return RSA4096;
if (id == alg_ext_cfg.x25519) return X25519;
if (id == alg_ext_cfg.secp256k1) return SECP256K1;
if (id == alg_ext_cfg.sm2) return SM2;
return KEY_TYPE_PKC_END;
}

static uint8_t key_type_to_algo_id[] = {
[SECP256R1] = ALG_ECC_256,
[SECP384R1] = ALG_ECC_384,
[RSA2048] = ALG_RSA_2048,
[ED25519] = ALG_ED25519,
[X25519] = ALG_X25519,
[SECP256K1] = ALG_SECP256K1,
[SM2] = ALG_SM2,
[RSA3072] = ALG_RSA_3072,
[RSA4096] = ALG_RSA_4096,
[TDEA] = ALG_TDEA_3KEY,
[KEY_TYPE_PKC_END] = ALG_DEFAULT,
};
static uint8_t key_type_to_algo_id(const key_type_t type) {
switch (type) {
case SECP256R1:
return ALG_ECC_256;
case SECP384R1:
return ALG_ECC_384;
case RSA2048:
return ALG_RSA_2048;
case ED25519:
return alg_ext_cfg.ed25519;
case X25519:
return alg_ext_cfg.x25519;
case SECP256K1:
return alg_ext_cfg.secp256k1;
case SM2:
return alg_ext_cfg.sm2;
case RSA3072:
return alg_ext_cfg.rsa3072;
case RSA4096:
return alg_ext_cfg.rsa4096;
case TDEA:
return ALG_TDEA_3KEY;
case KEY_TYPE_PKC_END:
default:
return ALG_DEFAULT;
}
}

int piv_security_status_check(uint8_t id __attribute__((unused)), const key_meta_t *meta) {
switch (meta->pin_policy) {
Expand Down Expand Up @@ -194,7 +201,10 @@ void piv_poweroff(void) {

int piv_install(const uint8_t reset) {
piv_poweroff();
if (!reset && get_file_size(PIV_AUTH_CERT_PATH) >= 0) return 0;
if (!reset && get_file_size(ALGORITHM_EXT_CONFIG_PATH) >= 0) {
if (read_file(ALGORITHM_EXT_CONFIG_PATH, &alg_ext_cfg, 0, sizeof(alg_ext_cfg)) < 0) return -1;
return 0;
}

// objects
if (write_file(PIV_AUTH_CERT_PATH, NULL, 0, 0, 1) < 0) return -1;
Expand Down Expand Up @@ -244,6 +254,16 @@ int piv_install(const uint8_t reset) {
if (pin_create(&puk, DEFAULT_PUK, 8, 3) < 0) return -1;
if (write_attr(puk.path, TAG_PIN_KEY_DEFAULT, &tmp, sizeof(tmp)) < 0) return -1;

// Algorithm extensions
alg_ext_cfg.enabled = 0;
alg_ext_cfg.ed25519 = ALG_ED25519_DEFAULT;
alg_ext_cfg.rsa3072 = ALG_RSA_3072_DEFAULT;
alg_ext_cfg.rsa4096 = ALG_RSA_4096_DEFAULT;
alg_ext_cfg.x25519 = ALG_X25519_DEFAULT;
alg_ext_cfg.secp256k1 = ALG_SECP256K1_DEFAULT;
alg_ext_cfg.sm2 = ALG_SM2_DEFAULT;
if (write_file(ALGORITHM_EXT_CONFIG_PATH, &alg_ext_cfg, 0, sizeof(alg_ext_cfg), 1) < 0) return -1;

return 0;
}

Expand Down Expand Up @@ -1048,7 +1068,7 @@ static int piv_get_metadata(const CAPDU *capdu, RAPDU *rapdu) {

RDATA[pos++] = 0x01; // Algorithm
RDATA[pos++] = 0x01;
RDATA[pos++] = key_type_to_algo_id[key.meta.type];
RDATA[pos++] = key_type_to_algo_id(key.meta.type);
RDATA[pos++] = 0x02; // Policy
RDATA[pos++] = 0x02;
RDATA[pos++] = key.meta.pin_policy;
Expand Down
3 changes: 0 additions & 3 deletions include/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#define ADMIN_P1_CFG_NDEF 0x04
#define ADMIN_P1_CFG_WEBUSB_LANDING 0x05
#define ADMIN_P1_CFG_KBD_WITH_RETURN 0x06
#define ADMIN_P1_CFG_PIV_ALGO_EXT 0x07

typedef struct {
uint32_t reserved;
Expand All @@ -38,7 +37,6 @@ typedef struct {
uint32_t ndef_en : 1;
uint32_t webusb_landing_en : 1;
uint32_t kbd_with_return_en : 1;
uint32_t piv_algo_ext_en : 1;
} __packed admin_device_config_t;

void admin_poweroff(void);
Expand All @@ -54,6 +52,5 @@ uint8_t cfg_is_kbd_interface_enable(void);
uint8_t cfg_is_ndef_enable(void);
uint8_t cfg_is_webusb_landing_enable(void);
uint8_t cfg_is_kbd_with_return_enable(void);
uint8_t cfg_is_piv_algo_extension_enable(void);

#endif // CANOKEY_CORE_ADMIN_ADMIN_H_
10 changes: 10 additions & 0 deletions include/piv.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@
#define PIV_INS_IMPORT_ASYMMETRIC_KEY 0xFE
#define PIV_INS_SET_MANAGEMENT_KEY 0xFF

typedef struct {
uint8_t enabled;
uint8_t ed25519;
uint8_t rsa3072;
uint8_t rsa4096;
uint8_t x25519;
uint8_t secp256k1;
uint8_t sm2;
} __packed piv_algorithm_extension_config_t;

int piv_install(uint8_t reset);
void piv_poweroff(void);
int piv_process_apdu(const CAPDU *capdu, RAPDU *rapdu);
Expand Down
3 changes: 2 additions & 1 deletion src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ int read_file(const char *path, void *buf, lfs_soff_t off, lfs_size_t len) {
err = lfs_file_close(&lfs, &f);
if (err < 0) return err;
return read_length;
err_close:

err_close:
lfs_file_close(&lfs, &f);
return err;
}
Expand Down

0 comments on commit 0d8d72e

Please sign in to comment.