From 0d8d72e2862fdd1aaf9672d1f05636413e0aa781 Mon Sep 17 00:00:00 2001 From: Fan DANG Date: Sun, 24 Dec 2023 16:08:47 +0800 Subject: [PATCH] refactor piv algorithm extensions --- applets/admin/admin.c | 5 --- applets/piv/piv.c | 100 +++++++++++++++++++++++++----------------- include/admin.h | 3 -- include/piv.h | 10 +++++ src/fs.c | 3 +- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/applets/admin/admin.c b/applets/admin/admin.c index a14e8c92..1f05fd4a 100644 --- a/applets/admin/admin.c +++ b/applets/admin/admin.c @@ -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) { @@ -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); } diff --git a/applets/piv/piv.c b/applets/piv/piv.c index 82c448ed..1fca0ed9 100644 --- a/applets/piv/piv.c +++ b/applets/piv/piv.c @@ -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 @@ -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"}; @@ -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) { @@ -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; @@ -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; } @@ -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; diff --git a/include/admin.h b/include/admin.h index d54b740c..3a0a21a4 100644 --- a/include/admin.h +++ b/include/admin.h @@ -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; @@ -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); @@ -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_ diff --git a/include/piv.h b/include/piv.h index 6f30d2ee..427a023c 100644 --- a/include/piv.h +++ b/include/piv.h @@ -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); diff --git a/src/fs.c b/src/fs.c index 75c89407..1bed45bf 100644 --- a/src/fs.c +++ b/src/fs.c @@ -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; }