From 5eb6822bf5578fd5637d2e971a13414b3880599e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 4 Mar 2023 14:08:47 +0100 Subject: [PATCH] Update code style. Signed-off-by: Pol Henarejos --- pico-hsm-sdk | 2 +- src/openpgp/files.c | 301 +++++++++---- src/openpgp/files.h | 16 +- src/openpgp/openpgp.c | 986 +++++++++++++++++++++++++----------------- src/openpgp/openpgp.h | 1 - 5 files changed, 815 insertions(+), 491 deletions(-) diff --git a/pico-hsm-sdk b/pico-hsm-sdk index 31e6600..3b268a3 160000 --- a/pico-hsm-sdk +++ b/pico-hsm-sdk @@ -1 +1 @@ -Subproject commit 31e66007d3742eaabe43ddfbae2b23a142d939a1 +Subproject commit 3b268a33eb22309c51cc621dd751ef8909114672 diff --git a/src/openpgp/files.c b/src/openpgp/files.c index f2648d9..6fd335b 100644 --- a/src/openpgp/files.c +++ b/src/openpgp/files.c @@ -20,12 +20,12 @@ extern const uint8_t openpgp_aid[]; extern const uint8_t openpgp_aid_full[]; -#define ACL_NONE {0xff,0xff,0xff,0xff,0xff,0xff,0xff} -#define ACL_ALL {0} -#define ACL_RO {0xff,0xff,0xff,0xff,0xff,0xff,0x00} -#define ACL_RW {0xff,0xff,0xff,0xff,0x00,0x00,0x00} -#define ACL_R_WP {0xff,0xff,0xff,0xff,0x90,0x90,0x00} -#define ACL_WP {0xff,0xff,0xff,0xff,0x90,0x90,0xff} +#define ACL_NONE { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } +#define ACL_ALL { 0 } +#define ACL_RO { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 } +#define ACL_RW { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define ACL_R_WP { 0xff, 0xff, 0xff, 0xff, 0x90, 0x90, 0x00 } +#define ACL_WP { 0xff, 0xff, 0xff, 0xff, 0x90, 0x90, 0xff } extern int parse_ch_data(const file_t *f, int mode); extern int parse_sec_tpl(const file_t *f, int mode); @@ -41,110 +41,221 @@ extern int parse_discrete_do(const file_t *f, int mode); extern int parse_pw_status(const file_t *f, int mode); uint8_t historical_bytes[] = { - 10, 0, - 0x00, - 0x31, 0x84, /* Full DF name, GET DATA, MF */ - 0x73, - 0x80, 0x01, 0xC0, /* Full DF name */ - /* 1-byte */ - /* Command chaining, No extended Lc and Le */ - 0x05, - 0x90, 0x00 /* Status info */ + 10, 0, + 0x00, + 0x31, 0x84, /* Full DF name, GET DATA, MF */ + 0x73, + 0x80, 0x01, 0xC0, /* Full DF name */ + /* 1-byte */ + /* Command chaining, No extended Lc and Le */ + 0x05, + 0x90, 0x00 /* Status info */ }; uint8_t extended_capabilities[] = { - 10, 0, - 0x77, /* - * No Secure Messaging supported - * GET CHALLENGE supported - * Key import supported - * PW status byte can be put - * No private_use_DO - * Algorithm attrs are changable - * ENC/DEC with AES - * KDF-DO available - */ - 0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */ - 0x00, 128, /* Max size of GET CHALLENGE */ - 0x08, 0x00, /* max. length of cardholder certificate (2KiB) */ - 0x00, 0xff, - 0x00, 0x1 + 10, 0, + 0x77, /* + * No Secure Messaging supported + * GET CHALLENGE supported + * Key import supported + * PW status byte can be put + * No private_use_DO + * Algorithm attrs are changable + * ENC/DEC with AES + * KDF-DO available + */ + 0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */ + 0x00, 128, /* Max size of GET CHALLENGE */ + 0x08, 0x00, /* max. length of cardholder certificate (2KiB) */ + 0x00, 0xff, + 0x00, 0x1 }; uint8_t feature_mngmnt[] = { - 3, 0, - 0x81, 0x01, 0x20, + 3, 0, + 0x81, 0x01, 0x20, }; uint8_t exlen_info[] = { - 8,0, + 8, 0, 0x2, 0x2, 0x07, 0xff, 0x2, 0x2, 0x08, 0x00, }; file_t file_entries[] = { - /* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = ACL_NONE }, // MF - /* 1 */ { .fid = EF_FULL_AID, .parent = 0, .name = openpgp_aid_full, .type = FILE_TYPE_WORKING_EF, .data = (uint8_t *)openpgp_aid_full, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 2 */ { .fid = EF_CH_NAME, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 3 */ { .fid = EF_LOGIN_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 4 */ { .fid = EF_LANG_PREF, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 5 */ { .fid = EF_SEX, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 6 */ { .fid = EF_URI_URL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 7 */ { .fid = EF_HIST_BYTES, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = historical_bytes, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 8 */ { .fid = EF_CH_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ch_data, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 9 */ { .fid = EF_SEC_TPL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_sec_tpl, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 10 */ { .fid = EF_CH_CERT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ch_cert, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 11 */ { .fid = EF_EXLEN_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = exlen_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 12 */ { .fid = EF_GFM, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = feature_mngmnt, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 13 */ { .fid = EF_SIG_COUNT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 14 */ { .fid = EF_EXT_CAP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = extended_capabilities, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 15 */ { .fid = EF_ALGO_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_algoinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 16 */ { .fid = EF_ALGO_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_algoinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 17 */ { .fid = EF_ALGO_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_algoinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 18 */ { .fid = EF_PW_STATUS, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_pw_status, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 19 */ { .fid = EF_FP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_fp, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 20 */ { .fid = EF_FP_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 21 */ { .fid = EF_FP_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 22 */ { .fid = EF_FP_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 23 */ { .fid = EF_CA_FP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_cafp, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 24 */ { .fid = EF_FP_CA1, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 25 */ { .fid = EF_FP_CA2, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 26 */ { .fid = EF_FP_CA3, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 27 */ { .fid = EF_TS_ALL, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_ts, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 28 */ { .fid = EF_TS_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 29 */ { .fid = EF_TS_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 30 */ { .fid = EF_TS_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 31 */ { .fid = EF_RESET_CODE, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 32 */ { .fid = EF_UIF_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 33 */ { .fid = EF_UIF_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 34 */ { .fid = EF_UIF_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 35 */ { .fid = EF_KEY_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_keyinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 36 */ { .fid = EF_ALGO_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_algoinfo, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 37 */ { .fid = EF_APP_DATA, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_app_data, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 38 */ { .fid = EF_DISCRETE_DO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *)parse_discrete_do, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 39 */ { .fid = EF_PW1, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 40 */ { .fid = EF_RC, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 41 */ { .fid = EF_PW3, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 42 */ { .fid = EF_ALGO_PRIV1, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 43 */ { .fid = EF_ALGO_PRIV2, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 44 */ { .fid = EF_ALGO_PRIV3, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 45 */ { .fid = EF_PK_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 46 */ { .fid = EF_PK_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 47 */ { .fid = EF_PK_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, - /* 48 */ { .fid = EF_PB_SIG, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 49 */ { .fid = EF_PB_DEC, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 50 */ { .fid = EF_PB_AUT, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 51 */ { .fid = EF_PW_PRIV, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 52 */ { .fid = EF_DEK, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, - /* 53 */ { .fid = EF_KDF, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, - /* 54 */ { .fid = EF_CH_1, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, - /* 55 */ { .fid = EF_CH_2, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, - /* 56 */ { .fid = EF_CH_3, .parent = 0, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, + /* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, + .ef_structure = 0, .acl = ACL_NONE }, // MF + /* 1 */ { .fid = EF_FULL_AID, .parent = 0, .name = openpgp_aid_full, + .type = FILE_TYPE_WORKING_EF, .data = (uint8_t *) openpgp_aid_full, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 2 */ { .fid = EF_CH_NAME, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 3 */ { .fid = EF_LOGIN_DATA, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 4 */ { .fid = EF_LANG_PREF, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 5 */ { .fid = EF_SEX, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 6 */ { .fid = EF_URI_URL, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 7 */ { .fid = EF_HIST_BYTES, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = historical_bytes, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 8 */ { .fid = EF_CH_DATA, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_ch_data, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 9 */ { .fid = EF_SEC_TPL, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_sec_tpl, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 10 */ { .fid = EF_CH_CERT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_ch_cert, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 11 */ { .fid = EF_EXLEN_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = exlen_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 12 */ { .fid = EF_GFM, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = feature_mngmnt, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 13 */ { .fid = EF_SIG_COUNT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 14 */ { .fid = EF_EXT_CAP, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = extended_capabilities, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 15 */ { .fid = EF_ALGO_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_algoinfo, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 16 */ { .fid = EF_ALGO_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_algoinfo, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 17 */ { .fid = EF_ALGO_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_algoinfo, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 18 */ { .fid = EF_PW_STATUS, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_pw_status, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 19 */ { .fid = EF_FP, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_fp, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 20 */ { .fid = EF_FP_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 21 */ { .fid = EF_FP_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 22 */ { .fid = EF_FP_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 23 */ { .fid = EF_CA_FP, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_cafp, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 24 */ { .fid = EF_FP_CA1, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 25 */ { .fid = EF_FP_CA2, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 26 */ { .fid = EF_FP_CA3, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 27 */ { .fid = EF_TS_ALL, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_ts, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 28 */ { .fid = EF_TS_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 29 */ { .fid = EF_TS_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 30 */ { .fid = EF_TS_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 31 */ { .fid = EF_RESET_CODE, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 32 */ { .fid = EF_UIF_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 33 */ { .fid = EF_UIF_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 34 */ { .fid = EF_UIF_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 35 */ { .fid = EF_KEY_INFO, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_keyinfo, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 36 */ { .fid = EF_ALGO_INFO, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_algoinfo, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 37 */ { .fid = EF_APP_DATA, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_app_data, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 38 */ { .fid = EF_DISCRETE_DO, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_discrete_do, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 39 */ { .fid = EF_PW1, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 40 */ { .fid = EF_RC, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 41 */ { .fid = EF_PW3, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 42 */ { .fid = EF_ALGO_PRIV1, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 43 */ { .fid = EF_ALGO_PRIV2, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 44 */ { .fid = EF_ALGO_PRIV3, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 45 */ { .fid = EF_PK_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 46 */ { .fid = EF_PK_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 47 */ { .fid = EF_PK_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP }, + /* 48 */ { .fid = EF_PB_SIG, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 49 */ { .fid = EF_PB_DEC, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 50 */ { .fid = EF_PB_AUT, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 51 */ { .fid = EF_PW_PRIV, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 52 */ { .fid = EF_DEK, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, + /* 53 */ { .fid = EF_KDF, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP }, + /* 54 */ { .fid = EF_CH_1, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, + /* 55 */ { .fid = EF_CH_2, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, + /* 56 */ { .fid = EF_CH_3, .parent = 0, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_NONE }, - /* 57 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, - /* 58 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = ACL_NONE } //end + /* 57 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO }, + /* 58 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, + .ef_structure = 0, .acl = ACL_NONE } //end }; const file_t *MF = &file_entries[0]; -const file_t *file_openpgp = &file_entries[sizeof(file_entries)/sizeof(file_t)-2]; -const file_t *file_last = &file_entries[sizeof(file_entries)/sizeof(file_t)-1]; \ No newline at end of file +const file_t *file_openpgp = &file_entries[sizeof(file_entries) / sizeof(file_t) - 2]; +const file_t *file_last = &file_entries[sizeof(file_entries) / sizeof(file_t) - 1]; diff --git a/src/openpgp/files.h b/src/openpgp/files.h index c7b4b04..1918927 100644 --- a/src/openpgp/files.h +++ b/src/openpgp/files.h @@ -1,17 +1,17 @@ -/* +/* * This file is part of the Pico OpenPGP distribution (https://github.com/polhenarejos/pico-openpgp). * Copyright (c) 2022 Pol Henarejos. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 549696a..ca07197 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -37,23 +37,25 @@ bool has_rc = false; uint8_t session_pw1[32]; uint8_t session_rc[32]; uint8_t session_pw3[32]; -static uint8_t dek[IV_SIZE+32]; -static uint16_t algo_dec = EF_ALGO_PRIV2, algo_aut = EF_ALGO_PRIV3, pk_dec = EF_PK_DEC, pk_aut = EF_PK_AUT; +static uint8_t dek[IV_SIZE + 32]; +static uint16_t algo_dec = EF_ALGO_PRIV2, algo_aut = EF_ALGO_PRIV3, pk_dec = EF_PK_DEC, + pk_aut = EF_PK_AUT; uint8_t openpgp_aid[] = { 6, - 0xD2,0x76,0x00,0x01,0x24,0x01, + 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, }; uint8_t openpgp_aid_full[] = { - 16,00, - 0xD2,0x76,0x00,0x01,0x24,0x01, - OPGP_VERSION_MAJOR,OPGP_VERSION_MINOR,0xff,0xfe,0xff,0xff,0xff,0xff,0x00,0x00 + 16, 00, + 0xD2, 0x76, 0x00, 0x01, 0x24, 0x01, + OPGP_VERSION_MAJOR, OPGP_VERSION_MINOR, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }; char atr_openpgp[] = { 21, - 0x3b,0xda,0x18,0xff,0x81,0xb1,0xfe,0x75,0x1f,0x03,0x00,0x31,0xf5,0x73,0xc0,0x01,0x60,0x00,0x90,0x00,0x1c + 0x3b, 0xda, 0x18, 0xff, 0x81, 0xb1, 0xfe, 0x75, 0x1f, 0x03, 0x00, 0x31, 0xf5, 0x73, 0xc0, 0x01, + 0x60, 0x00, 0x90, 0x00, 0x1c }; int openpgp_process_apdu(); @@ -69,17 +71,15 @@ static bool wait_button_pressed(uint16_t fid) { queue_try_add(&card_to_usb_q, &val); do { queue_remove_blocking(&usb_to_card_q, &val); - } - while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT); + }while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT); } #endif return val == EV_BUTTON_TIMEOUT; } void select_file(file_t *pe) { - if (!pe) - { - currentDF = (file_t *)MF; + if (!pe) { + currentDF = (file_t *) MF; currentEF = NULL; } else if (pe->type & FILE_TYPE_INTERNAL_EF) { @@ -101,14 +101,15 @@ static int cmd_select() { file_t *pe = NULL; uint16_t fid = 0x0; - if (apdu.nc >= 2) + if (apdu.nc >= 2) { fid = get_uint16_t(apdu.data, 0); + } if (!pe) { if (p1 == 0x0) { //Select MF, DF or EF - File identifier or absent if (apdu.nc == 0) { - pe = (file_t *)MF; - //ac_fini(); + pe = (file_t *) MF; + //ac_fini(); } else if (apdu.nc == 2) { if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) { @@ -127,15 +128,16 @@ static int cmd_select() { } } else if (p1 == 0x03) { //Select parent DF of the current DF - Absent - if (apdu.nc != 0) + if (apdu.nc != 0) { return SW_REFERENCE_NOT_FOUND(); + } } else if (p1 == 0x04) { //Select by DF name - e.g., [truncated] application identifier if (!(pe = search_by_name(apdu.data, apdu.nc))) { return SW_REFERENCE_NOT_FOUND(); } if (card_terminated) { - return set_res_sw (0x62, 0x85); + return set_res_sw(0x62, 0x85); } } else if (p1 == 0x08) { //Select from the MF - Path without the MF identifier @@ -150,13 +152,15 @@ static int cmd_select() { } } if ((p2 & 0xfc) == 0x00 || (p2 & 0xfc) == 0x04) { - if ((p2 & 0xfc) == 0x04) - process_fci(pe,0); + if ((p2 & 0xfc) == 0x04) { + process_fci(pe, 0); + } } - else + else { return SW_INCORRECT_P1P2(); + } select_file(pe); - return SW_OK (); + return SW_OK(); } void scan_files() { @@ -165,18 +169,18 @@ void scan_files() { if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) { ef->data = openpgp_aid_full; #ifndef ENABLE_EMULATION - pico_get_unique_board_id_string((char *)ef->data+12, 4); + pico_get_unique_board_id_string((char *) ef->data + 12, 4); #else - memset((char *)ef->data + 12, 0, 4); + memset((char *) ef->data + 12, 0, 4); #endif } if ((ef = search_by_fid(EF_PW1, NULL, SPECIFY_ANY))) { if (!ef->data) { printf("PW1 is empty. Initializing with default password\r\n"); - const uint8_t def[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 }; + const uint8_t def[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }; uint8_t dhash[33]; dhash[0] = sizeof(def); - double_hash_pin(def, sizeof(def), dhash+1); + double_hash_pin(def, sizeof(def), dhash + 1); flash_write_data_to_file(ef, dhash, sizeof(dhash)); } } @@ -184,10 +188,10 @@ void scan_files() { if (!ef->data) { printf("RC is empty. Initializing with default password\r\n"); - const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 }; + const uint8_t def[8] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 }; uint8_t dhash[33]; dhash[0] = sizeof(def); - double_hash_pin(def, sizeof(def), dhash+1); + double_hash_pin(def, sizeof(def), dhash + 1); flash_write_data_to_file(ef, dhash, sizeof(dhash)); } } @@ -195,10 +199,10 @@ void scan_files() { if (!ef->data) { printf("PW3 is empty. Initializing with default password\r\n"); - const uint8_t def[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 }; + const uint8_t def[8] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 }; uint8_t dhash[33]; dhash[0] = sizeof(def); - double_hash_pin(def, sizeof(def), dhash+1); + double_hash_pin(def, sizeof(def), dhash + 1); flash_write_data_to_file(ef, dhash, sizeof(dhash)); } } @@ -219,20 +223,20 @@ void scan_files() { if ((ef = search_by_fid(EF_DEK, NULL, SPECIFY_ANY))) { if (!ef->data) { printf("DEK is empty\r\n"); - const uint8_t def1[6] = { 0x31,0x32,0x33,0x34,0x35,0x36 }; - const uint8_t def3[8] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38 }; + const uint8_t def1[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }; + const uint8_t def3[8] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 }; - uint8_t def[IV_SIZE+32+32+32]; - const uint8_t *dek = random_bytes_get(IV_SIZE+32); - memcpy(def, dek, IV_SIZE+32); - memcpy(def+IV_SIZE+32, dek+IV_SIZE, 32); + uint8_t def[IV_SIZE + 32 + 32 + 32]; + const uint8_t *dek = random_bytes_get(IV_SIZE + 32); + memcpy(def, dek, IV_SIZE + 32); + memcpy(def + IV_SIZE + 32, dek + IV_SIZE, 32); hash_multi(def1, sizeof(def1), session_pw1); - aes_encrypt_cfb_256(session_pw1, def, def+IV_SIZE, 32); + aes_encrypt_cfb_256(session_pw1, def, def + IV_SIZE, 32); memset(session_pw1, 0, sizeof(session_pw1)); hash_multi(def3, sizeof(def3), session_pw3); - aes_encrypt_cfb_256(session_pw3, def, def+IV_SIZE+32, 32); - aes_encrypt_cfb_256(session_pw3, def, def+IV_SIZE+32+32, 32); + aes_encrypt_cfb_256(session_pw3, def, def + IV_SIZE + 32, 32); + aes_encrypt_cfb_256(session_pw3, def, def + IV_SIZE + 32 + 32, 32); memset(session_pw3, 0, sizeof(session_pw3)); flash_write_data_to_file(ef, def, sizeof(def)); } @@ -277,23 +281,26 @@ void scan_files() { } int load_dek() { - if (!has_pw1 && !has_pw2 && !has_pw3) + if (!has_pw1 && !has_pw2 && !has_pw3) { return CCID_NO_LOGIN; + } file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF); - if (!tf) + if (!tf) { return CCID_ERR_FILE_NOT_FOUND; + } int r = CCID_OK; if (has_pw1 || has_pw2) { - memcpy(dek, file_get_data(tf), IV_SIZE+32); - r = aes_decrypt_cfb_256(session_pw1, dek, dek+IV_SIZE, 32); + memcpy(dek, file_get_data(tf), IV_SIZE + 32); + r = aes_decrypt_cfb_256(session_pw1, dek, dek + IV_SIZE, 32); } else if (has_pw3) { memcpy(dek, file_get_data(tf), IV_SIZE); - memcpy(dek+IV_SIZE, file_get_data(tf)+IV_SIZE+32+32, 32); - r = aes_decrypt_cfb_256(session_pw3, dek, dek+IV_SIZE, 32); + memcpy(dek + IV_SIZE, file_get_data(tf) + IV_SIZE + 32 + 32, 32); + r = aes_decrypt_cfb_256(session_pw3, dek, dek + IV_SIZE, 32); } - if (r != 0) + if (r != 0) { return CCID_EXEC_ERROR; + } return CCID_OK; } @@ -303,18 +310,20 @@ void release_dek() { int dek_encrypt(uint8_t *data, size_t len) { int r; - if ((r = load_dek()) != CCID_OK) + if ((r = load_dek()) != CCID_OK) { return r; - r = aes_encrypt_cfb_256(dek+IV_SIZE, dek, data, len); + } + r = aes_encrypt_cfb_256(dek + IV_SIZE, dek, data, len); release_dek(); return r; } int dek_decrypt(uint8_t *data, size_t len) { int r; - if ((r = load_dek()) != CCID_OK) + if ((r = load_dek()) != CCID_OK) { return r; - r = aes_decrypt_cfb_256(dek+IV_SIZE, dek, data, len); + } + r = aes_decrypt_cfb_256(dek + IV_SIZE, dek, data, len); release_dek(); return r; } @@ -347,19 +356,19 @@ int heapLeft() { int left = &__StackLimit - p; free(p); #else - int left = 1024*1024; + int left = 1024 * 1024; #endif return left; } app_t *openpgp_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, openpgp_aid+1, MIN(aid_len,openpgp_aid[0]))) { + if (!memcmp(aid, openpgp_aid + 1, MIN(aid_len, openpgp_aid[0]))) { a->aid = openpgp_aid; a->process_apdu = openpgp_process_apdu; a->unload = openpgp_unload; init_openpgp(); - process_fci(file_openpgp,1); - memcpy(res_APDU+res_APDU_size,"\x64\x06\x53\x04", 4); + process_fci(file_openpgp, 1); + memcpy(res_APDU + res_APDU_size, "\x64\x06\x53\x04", 4); res_APDU_size += 4; int heap_left = heapLeft(); res_APDU[res_APDU_size++] = ((heap_left >> 24) & 0xff); @@ -373,8 +382,8 @@ app_t *openpgp_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) { return NULL; } -void __attribute__ ((constructor)) openpgp_ctor() { - ccid_atr = (uint8_t *)atr_openpgp; +void __attribute__((constructor)) openpgp_ctor() { + ccid_atr = (uint8_t *) atr_openpgp; register_app(openpgp_select_aid); } @@ -382,29 +391,32 @@ int parse_do(uint16_t *fids, int mode) { int len = 0; file_t *ef; for (int i = 0; i < fids[0]; i++) { - if ((ef = search_by_fid(fids[i+1], NULL, SPECIFY_EF))) { + if ((ef = search_by_fid(fids[i + 1], NULL, SPECIFY_EF))) { uint16_t data_len; if ((ef->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) { - data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *)ef, mode); + data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, mode); } else { - if (ef->data) + if (ef->data) { data_len = file_get_size(ef); - else + } + else { data_len = 0; + } if (mode == 1) { if (fids[0] > 1 && res_APDU_size > 0) { - if (fids[i+1] < 0x0100) { - res_APDU[res_APDU_size++] = fids[i+1] & 0xff; + if (fids[i + 1] < 0x0100) { + res_APDU[res_APDU_size++] = fids[i + 1] & 0xff; } else { - res_APDU[res_APDU_size++] = fids[i+1] >> 8; - res_APDU[res_APDU_size++] = fids[i+1] & 0xff; + res_APDU[res_APDU_size++] = fids[i + 1] >> 8; + res_APDU[res_APDU_size++] = fids[i + 1] & 0xff; } - res_APDU_size += format_tlv_len(data_len, res_APDU+res_APDU_size); + res_APDU_size += format_tlv_len(data_len, res_APDU + res_APDU_size); + } + if (ef->data) { + memcpy(res_APDU + res_APDU_size, file_get_data(ef), data_len); } - if (ef->data) - memcpy(res_APDU+res_APDU_size, file_get_data(ef), data_len); res_APDU_size += data_len; } } @@ -417,17 +429,17 @@ int parse_do(uint16_t *fids, int mode) { int parse_trium(uint16_t fid, uint8_t num, size_t size) { for (uint8_t i = 0; i < num; i++) { file_t *ef; - if ((ef = search_by_fid(fid+i, NULL, SPECIFY_EF)) && ef->data) { + if ((ef = search_by_fid(fid + i, NULL, SPECIFY_EF)) && ef->data) { uint16_t data_len = file_get_size(ef); - memcpy(res_APDU+res_APDU_size, file_get_data(ef), data_len); + memcpy(res_APDU + res_APDU_size, file_get_data(ef), data_len); res_APDU_size += data_len; } else { - memset(res_APDU+res_APDU_size, 0, size); + memset(res_APDU + res_APDU_size, 0, size); res_APDU_size += size; } } - return num*size; + return num * size; } int parse_ch_data(const file_t *f, int mode) { @@ -437,43 +449,49 @@ int parse_ch_data(const file_t *f, int mode) { }; res_APDU[res_APDU_size++] = EF_CH_DATA & 0xff; res_APDU[res_APDU_size++] = 0x82; - uint8_t *lp = res_APDU+res_APDU_size; + uint8_t *lp = res_APDU + res_APDU_size; res_APDU_size += 2; parse_do(fids, mode); - uint16_t lpdif = res_APDU+res_APDU_size-lp-2; + uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; *lp++ = lpdif >> 8; *lp++ = lpdif & 0xff; - return lpdif+4; + return lpdif + 4; } int inc_sig_count() { file_t *pw_status; - if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)) || !pw_status->data) + if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)) || !pw_status->data) { return SW_REFERENCE_NOT_FOUND(); - if (file_get_data(pw_status)[0] == 1) + } + if (file_get_data(pw_status)[0] == 1) { has_pw1 = false; + } file_t *ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY); - if (!ef || !ef->data) + if (!ef || !ef->data) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t *p = file_get_data(ef); uint32_t counter = (p[0] << 16) | (p[1] << 8) | p[2]; counter++; - uint8_t q[3] = { (counter>>16) & 0xff, (counter>>8) & 0xff, counter&0xff }; + uint8_t q[3] = { (counter >> 16) & 0xff, (counter >> 8) & 0xff, counter & 0xff }; int r = flash_write_data_to_file(ef, q, sizeof(q)); - if (r != CCID_OK) + if (r != CCID_OK) { return CCID_EXEC_ERROR; + } low_flash_available(); return CCID_OK; } int reset_sig_count() { file_t *ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY); - if (!ef || !ef->data) + if (!ef || !ef->data) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t q[3] = { 0 }; int r = flash_write_data_to_file(ef, q, sizeof(q)); - if (r != CCID_OK) + if (r != CCID_OK) { return CCID_EXEC_ERROR; + } low_flash_available(); return CCID_OK; } @@ -485,10 +503,10 @@ int parse_sec_tpl(const file_t *f, int mode) { if (ef && ef->data) { res_APDU[res_APDU_size++] = EF_SIG_COUNT & 0xff; res_APDU[res_APDU_size++] = 3; - memcpy(res_APDU+res_APDU_size, file_get_data(ef), 3); + memcpy(res_APDU + res_APDU_size, file_get_data(ef), 3); res_APDU_size += 3; } - return 5+2; + return 5 + 2; } int parse_ch_cert(const file_t *f, int mode) { @@ -521,25 +539,31 @@ int parse_keyinfo(const file_t *f, int mode) { } file_t *ef = search_by_fid(EF_PK_SIG, NULL, SPECIFY_ANY); res_APDU[res_APDU_size++] = 0x00; - if (ef && ef->data) + if (ef && ef->data) { res_APDU[res_APDU_size++] = 0x01; - else + } + else { res_APDU[res_APDU_size++] = 0x00; + } ef = search_by_fid(EF_PK_DEC, NULL, SPECIFY_ANY); res_APDU[res_APDU_size++] = 0x01; - if (ef && ef->data) + if (ef && ef->data) { res_APDU[res_APDU_size++] = 0x01; - else + } + else { res_APDU[res_APDU_size++] = 0x00; + } ef = search_by_fid(EF_PK_AUT, NULL, SPECIFY_ANY); res_APDU[res_APDU_size++] = 0x02; - if (ef && ef->data) + if (ef && ef->data) { res_APDU[res_APDU_size++] = 0x01; - else + } + else { res_APDU[res_APDU_size++] = 0x00; - return res_APDU_size-init_len; + } + return res_APDU_size - init_len; } int parse_pw_status(const file_t *f, int mode) { @@ -551,10 +575,10 @@ int parse_pw_status(const file_t *f, int mode) { } ef = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_ANY); if (ef && ef->data) { - memcpy(res_APDU+res_APDU_size, file_get_data(ef), 7); + memcpy(res_APDU + res_APDU_size, file_get_data(ef), 7); res_APDU_size += 7; } - return res_APDU_size-init_len; + return res_APDU_size - init_len; } #define ALGO_RSA 0x01 @@ -580,97 +604,97 @@ int parse_pw_status(const file_t *f, int mode) { #define ALGO_CV22519 12 static const uint8_t algorithm_attr_x448[] = { - 4, - ALGO_ECDH, - /* OID of X448 */ - 0x2b, 0x65, 0x6f + 4, + ALGO_ECDH, + /* OID of X448 */ + 0x2b, 0x65, 0x6f }; static const uint8_t algorithm_attr_rsa1k[] = { - 6, - ALGO_RSA, - 0x04, 0x00, /* Length modulus (in bit): 1024 */ - 0x00, 0x20, /* Length exponent (in bit): 32 */ - 0x00 /* 0: Acceptable format is: P and Q */ + 6, + ALGO_RSA, + 0x04, 0x00, /* Length modulus (in bit): 1024 */ + 0x00, 0x20, /* Length exponent (in bit): 32 */ + 0x00 /* 0: Acceptable format is: P and Q */ }; static const uint8_t algorithm_attr_rsa2k[] = { - 6, - ALGO_RSA, - 0x08, 0x00, /* Length modulus (in bit): 2048 */ - 0x00, 0x20, /* Length exponent (in bit): 32 */ - 0x00 /* 0: Acceptable format is: P and Q */ + 6, + ALGO_RSA, + 0x08, 0x00, /* Length modulus (in bit): 2048 */ + 0x00, 0x20, /* Length exponent (in bit): 32 */ + 0x00 /* 0: Acceptable format is: P and Q */ }; static const uint8_t algorithm_attr_rsa3k[] = { - 6, - ALGO_RSA, - 0x0C, 0x00, /* Length modulus (in bit): 3072 */ - 0x00, 0x20, /* Length exponent (in bit): 32 */ - 0x00 /* 0: Acceptable format is: P and Q */ + 6, + ALGO_RSA, + 0x0C, 0x00, /* Length modulus (in bit): 3072 */ + 0x00, 0x20, /* Length exponent (in bit): 32 */ + 0x00 /* 0: Acceptable format is: P and Q */ }; static const uint8_t algorithm_attr_rsa4k[] = { - 6, - ALGO_RSA, - 0x10, 0x00, /* Length modulus (in bit): 4096 */ - 0x00, 0x20, /* Length exponent (in bit): 32 */ - 0x00 /* 0: Acceptable format is: P and Q */ + 6, + ALGO_RSA, + 0x10, 0x00, /* Length modulus (in bit): 4096 */ + 0x00, 0x20, /* Length exponent (in bit): 32 */ + 0x00 /* 0: Acceptable format is: P and Q */ }; static const uint8_t algorithm_attr_p256k1[] = { - 6, - ALGO_ECDSA, - 0x2b, 0x81, 0x04, 0x00, 0x0a + 6, + ALGO_ECDSA, + 0x2b, 0x81, 0x04, 0x00, 0x0a }; static const uint8_t algorithm_attr_p256r1[] = { - 9, - ALGO_ECDSA, - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07 + 9, + ALGO_ECDSA, + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }; static const uint8_t algorithm_attr_p384r1[] = { - 6, - ALGO_ECDSA, - 0x2B,0x81,0x04,0x00,0x22 + 6, + ALGO_ECDSA, + 0x2B, 0x81, 0x04, 0x00, 0x22 }; static const uint8_t algorithm_attr_p521r1[] = { - 6, - ALGO_ECDSA, - 0x2B,0x81,0x04,0x00,0x23 + 6, + ALGO_ECDSA, + 0x2B, 0x81, 0x04, 0x00, 0x23 }; static const uint8_t algorithm_attr_bp256r1[] = { - 10, - ALGO_ECDSA, - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07 + 10, + ALGO_ECDSA, + 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07 }; static const uint8_t algorithm_attr_bp384r1[] = { - 10, - ALGO_ECDSA, - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B + 10, + ALGO_ECDSA, + 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B }; static const uint8_t algorithm_attr_bp512r1[] = { - 10, - ALGO_ECDSA, - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D + 10, + ALGO_ECDSA, + 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D }; static const uint8_t algorithm_attr_cv25519[] = { - 11, - ALGO_ECDH, - 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 + 11, + ALGO_ECDH, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 }; int parse_algo(const uint8_t *algo, uint16_t tag) { res_APDU[res_APDU_size++] = tag & 0xff; - memcpy(res_APDU+res_APDU_size, algo, algo[0]+1); - res_APDU_size += algo[0]+1; - return algo[0]+2; + memcpy(res_APDU + res_APDU_size, algo, algo[0] + 1); + res_APDU_size += algo[0] + 1; + return algo[0] + 2; } int parse_algoinfo(const file_t *f, int mode) { @@ -717,16 +741,17 @@ int parse_algoinfo(const file_t *f, int mode) { datalen += parse_algo(algorithm_attr_bp256r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp384r1, EF_ALGO_AUT); datalen += parse_algo(algorithm_attr_bp512r1, EF_ALGO_AUT); - uint16_t lpdif = res_APDU+res_APDU_size-lp-2; + uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; *lp++ = lpdif >> 8; *lp++ = lpdif & 0xff; - datalen = lpdif+4; + datalen = lpdif + 4; } else if (f->fid == EF_ALGO_SIG || f->fid == EF_ALGO_DEC || f->fid == EF_ALGO_AUT) { uint16_t fid = 0x1000 | f->fid; file_t *ef; - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)) || !ef->data) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF)) || !ef->data) { datalen += parse_algo(algorithm_attr_rsa2k, f->fid); + } else { uint16_t len = file_get_size(ef); if (res_APDU_size > 0) { @@ -734,7 +759,7 @@ int parse_algoinfo(const file_t *f, int mode) { res_APDU[res_APDU_size++] = len & 0xff; datalen += 2; } - memcpy(res_APDU+res_APDU_size, file_get_data(ef), len); + memcpy(res_APDU + res_APDU_size, file_get_data(ef), len); res_APDU_size += len; datalen += len; } @@ -749,58 +774,64 @@ int parse_app_data(const file_t *f, int mode) { }; res_APDU[res_APDU_size++] = EF_APP_DATA & 0xff; res_APDU[res_APDU_size++] = 0x82; - uint8_t *lp = res_APDU+res_APDU_size; + uint8_t *lp = res_APDU + res_APDU_size; res_APDU_size += 2; parse_do(fids, mode); - uint16_t lpdif = res_APDU+res_APDU_size-lp-2; + uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; *lp++ = lpdif >> 8; *lp++ = lpdif & 0xff; - return lpdif+4; + return lpdif + 4; } int parse_discrete_do(const file_t *f, int mode) { uint16_t fids[] = { 11, - EF_EXT_CAP, EF_ALGO_SIG, EF_ALGO_DEC, EF_ALGO_AUT, EF_PW_STATUS, EF_FP, EF_CA_FP, EF_TS_ALL, EF_UIF_SIG, EF_UIF_DEC, EF_UIF_AUT + EF_EXT_CAP, EF_ALGO_SIG, EF_ALGO_DEC, EF_ALGO_AUT, EF_PW_STATUS, EF_FP, EF_CA_FP, EF_TS_ALL, + EF_UIF_SIG, EF_UIF_DEC, EF_UIF_AUT }; res_APDU[res_APDU_size++] = EF_DISCRETE_DO & 0xff; res_APDU[res_APDU_size++] = 0x82; - uint8_t *lp = res_APDU+res_APDU_size; + uint8_t *lp = res_APDU + res_APDU_size; res_APDU_size += 2; parse_do(fids, mode); - uint16_t lpdif = res_APDU+res_APDU_size-lp-2; + uint16_t lpdif = res_APDU + res_APDU_size - lp - 2; *lp++ = lpdif >> 8; *lp++ = lpdif & 0xff; - return lpdif+4; + return lpdif + 4; } static int cmd_get_data() { - if (apdu.nc > 0) + if (apdu.nc > 0) { return SW_WRONG_LENGTH(); + } uint16_t fid = (P1(apdu) << 8) | P2(apdu); file_t *ef; - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (!authenticate_action(ef, ACL_OP_READ_SEARCH)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } if (currentEF && (currentEF->fid & 0x1FF0) == (fid & 0x1FF0)) { //previously selected ef = currentEF; } - else + else { select_file(ef); + } if (ef->data) { - uint16_t fids[] = {1,fid}; + uint16_t fids[] = { 1, fid }; uint16_t data_len = parse_do(fids, 1); uint8_t *p = NULL; uint16_t tg = 0; size_t tg_len = 0; if (walk_tlv(res_APDU, data_len, &p, &tg, &tg_len, NULL)) { uint8_t dec = 2; - if ((tg & 0x1f) == 0x1f) + if ((tg & 0x1f) == 0x1f) { dec++; - if ((res_APDU[dec-1] & 0xF0) == 0x80) + } + if ((res_APDU[dec - 1] & 0xF0) == 0x80) { dec += (res_APDU[dec - 1] & 0x0F); + } if (tg_len + dec == data_len) { memmove(res_APDU, res_APDU + dec, data_len - dec); data_len -= dec; @@ -814,46 +845,54 @@ static int cmd_get_data() { } int pin_reset_retries(const file_t *pin, bool force) { - if (!pin) + if (!pin) { return CCID_ERR_NULL_PARAM; + } file_t *pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF); - if (!pw_status) + if (!pw_status) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t p[7]; memcpy(p, file_get_data(pw_status), 7); - uint8_t retries = p[3+(pin->fid&0x3)]; - if (retries == 0 && force == false) //blocked + uint8_t retries = p[3 + (pin->fid & 0x3)]; + if (retries == 0 && force == false) { //blocked return CCID_ERR_BLOCKED; - p[3+(pin->fid&0x3)] = 3; + } + p[3 + (pin->fid & 0x3)] = 3; int r = flash_write_data_to_file(pw_status, p, file_get_size(pw_status)); low_flash_available(); return r; } int pin_wrong_retry(const file_t *pin) { - if (!pin) + if (!pin) { return CCID_ERR_NULL_PARAM; + } file_t *pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF); - if (!pw_status) + if (!pw_status) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t p[7]; memcpy(p, file_get_data(pw_status), 7); - if (p[3+(pin->fid&0x3)] > 0) { - p[3+(pin->fid&0x3)] -= 1; + if (p[3 + (pin->fid & 0x3)] > 0) { + p[3 + (pin->fid & 0x3)] -= 1; int r = flash_write_data_to_file(pw_status, p, file_get_size(pw_status)); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } low_flash_available(); - if (p[3+(pin->fid&0x3)] == 0) + if (p[3 + (pin->fid & 0x3)] == 0) { return CCID_ERR_BLOCKED; - return p[3+(pin->fid&0x3)]; + } + return p[3 + (pin->fid & 0x3)]; } return CCID_ERR_BLOCKED; } int check_pin(const file_t *pin, const uint8_t *data, size_t len) { - if (!pin) + if (!pin) { return SW_REFERENCE_NOT_FOUND(); + } if (!pin->data) { return SW_REFERENCE_NOT_FOUND(); } @@ -862,26 +901,32 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) { uint8_t dhash[32]; double_hash_pin(data, len, dhash); - if (sizeof(dhash) != file_get_size(pin)-1) //1 byte for pin len + if (sizeof(dhash) != file_get_size(pin) - 1) { //1 byte for pin len return SW_CONDITIONS_NOT_SATISFIED(); - if (memcmp(file_get_data(pin)+1, dhash, sizeof(dhash)) != 0) { + } + if (memcmp(file_get_data(pin) + 1, dhash, sizeof(dhash)) != 0) { int retries; - if ((retries = pin_wrong_retry(pin)) < CCID_OK) + if ((retries = pin_wrong_retry(pin)) < CCID_OK) { return SW_PIN_BLOCKED(); + } return set_res_sw(0x63, 0xc0 | retries); } int r = pin_reset_retries(pin, false); - if (r == CCID_ERR_BLOCKED) + if (r == CCID_ERR_BLOCKED) { return SW_PIN_BLOCKED(); - if (r != CCID_OK) + } + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); + } isUserAuthenticated = true; if (pin->fid == EF_PW1) { - if (P2(apdu) == 0x81) + if (P2(apdu) == 0x81) { has_pw1 = true; - else + } + else { has_pw2 = true; + } hash_multi(data, len, session_pw1); } else if (pin->fid == EF_PW3) { @@ -896,48 +941,62 @@ static int cmd_verify() { uint8_t p2 = P2(apdu); if (p1 == 0xFF) { - if (apdu.nc != 0) + if (apdu.nc != 0) { return SW_WRONG_DATA(); - if (p2 == 0x81) + } + if (p2 == 0x81) { has_pw1 = false; - else if (p2 == 0x82) + } + else if (p2 == 0x82) { has_pw2 = false; - else if (p2 == 0x83) + } + else if (p2 == 0x83) { has_pw3 = false; + } return SW_OK(); } - else if (p1 != 0x0 || (p2 & 0x60) != 0x0) + else if (p1 != 0x0 || (p2 & 0x60) != 0x0) { return SW_WRONG_P1P2(); + } uint16_t fid = 0x1000 | p2; - if (fid == EF_RC && apdu.nc > 0) + if (fid == EF_RC && apdu.nc > 0) { fid = EF_PW1; + } file_t *pw, *pw_status; - if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); - if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) + } + if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); - if (file_get_data(pw)[0] == 0) //not initialized + } + if (file_get_data(pw)[0] == 0) { //not initialized return SW_REFERENCE_NOT_FOUND(); + } if (apdu.nc > 0) { return check_pin(pw, apdu.data, apdu.nc); } - uint8_t retries = *(file_get_data(pw_status)+3+(fid&0x3)); - if (retries == 0) + uint8_t retries = *(file_get_data(pw_status) + 3 + (fid & 0x3)); + if (retries == 0) { return SW_PIN_BLOCKED(); - if ((p2 == 0x81 && has_pw1) || (p2 == 0x82 && has_pw2) || (p2 == 0x83 && has_pw3)) + } + if ((p2 == 0x81 && has_pw1) || (p2 == 0x82 && has_pw2) || (p2 == 0x83 && has_pw3)) { return SW_OK(); + } return set_res_sw(0x63, 0xc0 | retries); } static int cmd_put_data() { uint16_t fid = (P1(apdu) << 8) | P2(apdu); file_t *ef; - if (fid == EF_RESET_CODE) + if (fid == EF_RESET_CODE) { fid = EF_RC; - else if (fid == EF_ALGO_SIG || fid == EF_ALGO_DEC || fid == EF_ALGO_AUT) + } + else if (fid == EF_ALGO_SIG || fid == EF_ALGO_DEC || fid == EF_ALGO_AUT) { fid |= 0x1000; - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + } + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } @@ -952,65 +1011,74 @@ static int cmd_put_data() { int r = 0; if (fid == EF_RC) { has_rc = false; - if ((r = load_dek()) != CCID_OK) + if ((r = load_dek()) != CCID_OK) { return SW_EXEC_ERROR(); + } uint8_t dhash[33]; dhash[0] = apdu.nc; - double_hash_pin(apdu.data, apdu.nc, dhash+1); + double_hash_pin(apdu.data, apdu.nc, dhash + 1); r = flash_write_data_to_file(ef, dhash, sizeof(dhash)); file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF); - if (!tf) + if (!tf) { return SW_REFERENCE_NOT_FOUND(); - uint8_t def[IV_SIZE+32+32+32]; + } + uint8_t def[IV_SIZE + 32 + 32 + 32]; memcpy(def, file_get_data(tf), file_get_size(tf)); hash_multi(apdu.data, apdu.nc, session_rc); memcpy(def + IV_SIZE + 32, dek + IV_SIZE, 32); aes_encrypt_cfb_256(session_rc, def, def + IV_SIZE + 32, 32); r = flash_write_data_to_file(tf, def, sizeof(def)); } - else + else { r = flash_write_data_to_file(ef, apdu.data, apdu.nc); - if (r != CCID_OK) + } + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); + } low_flash_available(); } return SW_OK(); } static int cmd_change_pin() { - if (P1(apdu) != 0x0) + if (P1(apdu) != 0x0) { return SW_WRONG_P1P2(); + } uint16_t fid = 0x1000 | P2(apdu); file_t *pw; - if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(pw = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } uint8_t pin_len = file_get_data(pw)[0]; uint16_t r = 0; - if ((r = load_dek()) != CCID_OK) + if ((r = load_dek()) != CCID_OK) { return SW_EXEC_ERROR(); + } r = check_pin(pw, apdu.data, pin_len); - if (r != 0x9000) + if (r != 0x9000) { return r; + } uint8_t dhash[33]; - dhash[0] = apdu.nc-pin_len; - double_hash_pin(apdu.data+pin_len, apdu.nc-pin_len, dhash+1); + dhash[0] = apdu.nc - pin_len; + double_hash_pin(apdu.data + pin_len, apdu.nc - pin_len, dhash + 1); flash_write_data_to_file(pw, dhash, sizeof(dhash)); file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF); - if (!tf) + if (!tf) { return SW_REFERENCE_NOT_FOUND(); - uint8_t def[IV_SIZE+32+32+32]; + } + uint8_t def[IV_SIZE + 32 + 32 + 32]; memcpy(def, file_get_data(tf), file_get_size(tf)); if (P2(apdu) == 0x81) { - hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_pw1); + hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_pw1); memcpy(def + IV_SIZE, dek + IV_SIZE, 32); aes_encrypt_cfb_256(session_pw1, def, def + IV_SIZE, 32); } else if (P2(apdu) == 0x83) { - hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_pw3); + hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_pw3); memcpy(def + IV_SIZE + 32 + 32, dek + IV_SIZE, 32); - aes_encrypt_cfb_256(session_pw3, def, def+IV_SIZE+32+32, 32); + aes_encrypt_cfb_256(session_pw3, def, def + IV_SIZE + 32 + 32, 32); } flash_write_data_to_file(tf, def, sizeof(def)); low_flash_available(); @@ -1018,52 +1086,61 @@ static int cmd_change_pin() { } static int cmd_reset_retry() { - if (P2(apdu) != 0x81) + if (P2(apdu) != 0x81) { return SW_REFERENCE_NOT_FOUND(); + } if (P1(apdu) == 0x0 || P1(apdu) == 0x2) { int newpin_len = 0; file_t *pw = NULL; has_pw1 = false; - if (!(pw = search_by_fid(EF_PW1, NULL, SPECIFY_EF))) + if (!(pw = search_by_fid(EF_PW1, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (P1(apdu) == 0x0) { file_t *rc; - if (!(rc = search_by_fid(EF_RC, NULL, SPECIFY_EF))) + if (!(rc = search_by_fid(EF_RC, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } uint8_t pin_len = file_get_data(rc)[0]; - if (apdu.nc <= pin_len) + if (apdu.nc <= pin_len) { return SW_WRONG_LENGTH(); + } uint16_t r = check_pin(rc, apdu.data, pin_len); - if (r != 0x9000) + if (r != 0x9000) { return r; - newpin_len = apdu.nc-pin_len; + } + newpin_len = apdu.nc - pin_len; has_rc = true; hash_multi(apdu.data, pin_len, session_rc); } else if (P1(apdu) == 0x2) { - if (!has_pw3) + if (!has_pw3) { return SW_CONDITIONS_NOT_SATISFIED(); + } newpin_len = apdu.nc; } int r = 0; - if ((r = load_dek()) != CCID_OK) + if ((r = load_dek()) != CCID_OK) { return SW_EXEC_ERROR(); + } file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF); - if (!tf) + if (!tf) { return SW_REFERENCE_NOT_FOUND(); - uint8_t def[IV_SIZE+32+32+32]; + } + uint8_t def[IV_SIZE + 32 + 32 + 32]; memcpy(def, file_get_data(tf), file_get_size(tf)); - hash_multi(apdu.data+(apdu.nc-newpin_len), newpin_len, session_pw1); + hash_multi(apdu.data + (apdu.nc - newpin_len), newpin_len, session_pw1); memcpy(def + IV_SIZE, dek + IV_SIZE, 32); aes_encrypt_cfb_256(session_pw1, def, def + IV_SIZE, 32); r = flash_write_data_to_file(tf, def, sizeof(def)); uint8_t dhash[33]; dhash[0] = newpin_len; - double_hash_pin(apdu.data+(apdu.nc-newpin_len), newpin_len, dhash+1); + double_hash_pin(apdu.data + (apdu.nc - newpin_len), newpin_len, dhash + 1); flash_write_data_to_file(pw, dhash, sizeof(dhash)); - if (pin_reset_retries(pw, true) != CCID_OK) + if (pin_reset_retries(pw, true) != CCID_OK) { return SW_MEMORY_FAILURE(); + } low_flash_available(); return SW_OK(); } @@ -1072,7 +1149,7 @@ static int cmd_reset_retry() { int store_keys(void *key_ctx, int type, uint16_t key_id) { int r, key_size = 0; - uint8_t kdata[4096/8]; //worst + uint8_t kdata[4096 / 8]; //worst //if (!has_pw3) // return CCID_NO_LOGIN; @@ -1080,28 +1157,32 @@ int store_keys(void *key_ctx, int type, uint16_t key_id) { //if (!pw3) // return CCID_ERR_FILE_NOT_FOUND; file_t *ef = search_by_fid(key_id, NULL, SPECIFY_EF); - if (!ef) + if (!ef) { return CCID_ERR_FILE_NOT_FOUND; + } if (type == ALGO_RSA) { - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx; - key_size = mbedtls_mpi_size(&rsa->P)+mbedtls_mpi_size(&rsa->Q); - mbedtls_mpi_write_binary(&rsa->P, kdata, key_size/2); - mbedtls_mpi_write_binary(&rsa->Q, kdata+key_size/2, key_size/2); + mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; + key_size = mbedtls_mpi_size(&rsa->P) + mbedtls_mpi_size(&rsa->Q); + mbedtls_mpi_write_binary(&rsa->P, kdata, key_size / 2); + mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2); } else if (type == ALGO_ECDSA || type == ALGO_ECDH) { - mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx; + mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; key_size = mbedtls_mpi_size(&ecdsa->d); kdata[0] = ecdsa->grp.id & 0xff; - mbedtls_mpi_write_binary(&ecdsa->d, kdata+1, key_size); + mbedtls_mpi_write_binary(&ecdsa->d, kdata + 1, key_size); key_size++; } else if (type & ALGO_AES) { - if (type == ALGO_AES_128) + if (type == ALGO_AES_128) { key_size = 16; - else if (type == ALGO_AES_192) + } + else if (type == ALGO_AES_192) { key_size = 24; - else if (type == ALGO_AES_256) + } + else if (type == ALGO_AES_256) { key_size = 32; + } memcpy(kdata, key_ctx, key_size); } r = dek_encrypt(kdata, key_size); @@ -1112,24 +1193,25 @@ int store_keys(void *key_ctx, int type, uint16_t key_id) { //if (r != CCID_OK) // return r; r = flash_write_data_to_file(ef, kdata, key_size); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } low_flash_available(); return CCID_OK; } int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) { int key_size = file_get_size(fkey); - uint8_t kdata[4096/8]; + uint8_t kdata[4096 / 8]; memcpy(kdata, file_get_data(fkey), key_size); if (dek_decrypt(kdata, key_size) != 0) { return CCID_EXEC_ERROR; } - if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size/2) != 0) { + if (mbedtls_mpi_read_binary(&ctx->P, kdata, key_size / 2) != 0) { mbedtls_rsa_free(ctx); return CCID_WRONG_DATA; } - if (mbedtls_mpi_read_binary(&ctx->Q, kdata+key_size/2, key_size/2) != 0) { + if (mbedtls_mpi_read_binary(&ctx->Q, kdata + key_size / 2, key_size / 2) != 0) { mbedtls_rsa_free(ctx); return CCID_WRONG_DATA; } @@ -1160,7 +1242,7 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) { return CCID_EXEC_ERROR; } mbedtls_ecp_group_id gid = kdata[0]; - int r = mbedtls_ecp_read_key(gid, ctx, kdata+1, key_size-1); + int r = mbedtls_ecp_read_key(gid, ctx, kdata + 1, key_size - 1); if (r != 0) { mbedtls_ecdsa_free(ctx); return CCID_EXEC_ERROR; @@ -1178,24 +1260,33 @@ int load_aes_key(uint8_t *aes_key, file_t *fkey) { } mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_len) { - if (memcmp(algorithm_attr_p256k1+2, algo, algo_len) == 0) + if (memcmp(algorithm_attr_p256k1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_SECP256K1; - else if (memcmp(algorithm_attr_p256r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_p256r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_SECP256R1; - else if (memcmp(algorithm_attr_p384r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_p384r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_SECP384R1; - else if (memcmp(algorithm_attr_p521r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_p521r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_SECP521R1; - else if (memcmp(algorithm_attr_bp256r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_bp256r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_BP256R1; - else if (memcmp(algorithm_attr_bp384r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_bp384r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_BP384R1; - else if (memcmp(algorithm_attr_bp512r1+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_bp512r1 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_BP512R1; - else if (memcmp(algorithm_attr_cv25519+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_cv25519 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_CURVE25519; - else if (memcmp(algorithm_attr_x448+2, algo, algo_len) == 0) + } + else if (memcmp(algorithm_attr_x448 + 2, algo, algo_len) == 0) { return MBEDTLS_ECP_DP_CURVE448; + } return MBEDTLS_ECP_DP_NONE; } @@ -1204,54 +1295,71 @@ void make_rsa_response(mbedtls_rsa_context *rsa) { res_APDU_size = 5; res_APDU[res_APDU_size++] = 0x81; res_APDU[res_APDU_size++] = 0x82; - put_uint16_t(mbedtls_mpi_size(&rsa->N), res_APDU+res_APDU_size); res_APDU_size += 2; - mbedtls_mpi_write_binary(&rsa->N, res_APDU+res_APDU_size, mbedtls_mpi_size(&rsa->N)); res_APDU_size += mbedtls_mpi_size(&rsa->N); + put_uint16_t(mbedtls_mpi_size(&rsa->N), res_APDU + res_APDU_size); res_APDU_size += 2; + mbedtls_mpi_write_binary(&rsa->N, res_APDU + res_APDU_size, mbedtls_mpi_size(&rsa->N)); + res_APDU_size += mbedtls_mpi_size(&rsa->N); res_APDU[res_APDU_size++] = 0x82; res_APDU[res_APDU_size++] = mbedtls_mpi_size(&rsa->E) & 0xff; - mbedtls_mpi_write_binary(&rsa->E, res_APDU+res_APDU_size, mbedtls_mpi_size(&rsa->E)); res_APDU_size += mbedtls_mpi_size(&rsa->E); - put_uint16_t(res_APDU_size-5, res_APDU+3); + mbedtls_mpi_write_binary(&rsa->E, res_APDU + res_APDU_size, mbedtls_mpi_size(&rsa->E)); + res_APDU_size += mbedtls_mpi_size(&rsa->E); + put_uint16_t(res_APDU_size - 5, res_APDU + 3); } void make_ecdsa_response(mbedtls_ecdsa_context *ecdsa) { uint8_t pt[MBEDTLS_ECP_MAX_PT_LEN]; size_t plen = 0; - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &plen, pt, sizeof(pt)); + mbedtls_ecp_point_write_binary(&ecdsa->grp, + &ecdsa->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &plen, + pt, + sizeof(pt)); res_APDU[res_APDU_size++] = 0x7f; res_APDU[res_APDU_size++] = 0x49; - if (plen >= 128) + if (plen >= 128) { res_APDU[res_APDU_size++] = 0x81; + } res_APDU[res_APDU_size++] = plen + (plen >= 128 ? 3 : 2); res_APDU[res_APDU_size++] = 0x86; - if (plen >= 128) + if (plen >= 128) { res_APDU[res_APDU_size++] = 0x81; + } res_APDU[res_APDU_size++] = plen; memcpy(res_APDU + res_APDU_size, pt, plen); res_APDU_size += plen; } static int cmd_keypair_gen() { - if (P2(apdu) != 0x0) + if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); - if (apdu.nc != 2 && apdu.nc != 5) + } + if (apdu.nc != 2 && apdu.nc != 5) { return SW_WRONG_LENGTH(); - if (!has_pw3 && P1(apdu) == 0x80) + } + if (!has_pw3 && P1(apdu) == 0x80) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } uint16_t fid = 0x0; int r = CCID_OK; - if (apdu.data[0] == 0xB6) + if (apdu.data[0] == 0xB6) { fid = EF_PK_SIG; - else if (apdu.data[0] == 0xB8) + } + else if (apdu.data[0] == 0xB8) { fid = EF_PK_DEC; - else if (apdu.data[0] == 0xA4) + } + else if (apdu.data[0] == 0xA4) { fid = EF_PK_AUT; - else + } + else { return SW_WRONG_DATA(); + } - file_t *algo_ef = search_by_fid(fid-0x0010, NULL, SPECIFY_EF); - if (!algo_ef) + file_t *algo_ef = search_by_fid(fid - 0x0010, NULL, SPECIFY_EF); + if (!algo_ef) { return SW_REFERENCE_NOT_FOUND(); - const uint8_t *algo = algorithm_attr_rsa2k+1; + } + const uint8_t *algo = algorithm_attr_rsa2k + 1; uint16_t algo_len = algorithm_attr_rsa2k[0]; if (algo_ef && algo_ef->data) { algo = file_get_data(algo_ef); @@ -1260,7 +1368,7 @@ static int cmd_keypair_gen() { if (P1(apdu) == 0x80) { //generate if (algo[0] == ALGO_RSA) { int exponent = 65537, nlen = (algo[1] << 8) | algo[2]; - printf("KEYPAIR RSA %d\r\n",nlen); + printf("KEYPAIR RSA %d\r\n", nlen); //if (nlen != 2048 && nlen != 4096) // return SW_FUNC_NOT_SUPPORTED(); mbedtls_rsa_context rsa; @@ -1274,14 +1382,16 @@ static int cmd_keypair_gen() { r = store_keys(&rsa, ALGO_RSA, fid); make_rsa_response(&rsa); mbedtls_rsa_free(&rsa); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } } else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) { printf("KEYPAIR ECDSA\r\n"); - mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo+1, algo_len-1); - if (gid == MBEDTLS_ECP_DP_NONE) + mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1); + if (gid == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); + } mbedtls_ecdsa_context ecdsa; mbedtls_ecdsa_init(&ecdsa); uint8_t index = 0; @@ -1293,19 +1403,24 @@ static int cmd_keypair_gen() { r = store_keys(&ecdsa, algo[0], fid); make_ecdsa_response(&ecdsa); mbedtls_ecdsa_free(&ecdsa); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } } - else + else { return SW_FUNC_NOT_SUPPORTED(); - file_t *pbef = search_by_fid(fid+3, NULL, SPECIFY_EF); - if (!pbef) + } + file_t *pbef = search_by_fid(fid + 3, NULL, SPECIFY_EF); + if (!pbef) { return SW_REFERENCE_NOT_FOUND(); + } r = flash_write_data_to_file(pbef, res_APDU, res_APDU_size); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); - if (fid == EF_PK_SIG) + } + if (fid == EF_PK_SIG) { reset_sig_count(); + } else if (fid == EF_PK_DEC) { // OpenPGP does not allow generating AES keys. So, we generate a new one when gen for DEC is called. // It is a 256 AES key by default. @@ -1321,9 +1436,10 @@ static int cmd_keypair_gen() { return SW_OK(); } else if (P1(apdu) == 0x81) { //read - file_t *ef = search_by_fid(fid+3, NULL, SPECIFY_EF); - if (!ef || !ef->data) + file_t *ef = search_by_fid(fid + 3, NULL, SPECIFY_EF); + if (!ef || !ef->data) { return SW_REFERENCE_NOT_FOUND(); + } res_APDU_size = file_get_size(ef); memcpy(res_APDU, file_get_data(ef), res_APDU_size); return SW_OK(); @@ -1331,51 +1447,67 @@ static int cmd_keypair_gen() { return SW_INCORRECT_P1P2(); } -int rsa_sign(mbedtls_rsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) { - uint8_t *d = (uint8_t *)data, *end = d+data_len, *hsh = NULL; +int rsa_sign(mbedtls_rsa_context *ctx, + const uint8_t *data, + size_t data_len, + uint8_t *out, + size_t *out_len) { + uint8_t *d = (uint8_t *) data, *end = d + data_len, *hsh = NULL; size_t seq_len = 0, hash_len = 0; int key_size = ctx->len, r = 0; mbedtls_md_type_t md = MBEDTLS_MD_SHA256; - if (mbedtls_asn1_get_tag(&d, end, &seq_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0) { + if (mbedtls_asn1_get_tag(&d, end, &seq_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0) { mbedtls_asn1_buf mdb; r = mbedtls_asn1_get_alg_null(&d, end, &mdb); if (r == 0) { if (mbedtls_asn1_get_tag(&d, end, &hash_len, MBEDTLS_ASN1_OCTET_STRING) == 0) { - if (memcmp(mdb.p, "\x2B\x0E\x03\x02\x1A", 5) == 0) + if (memcmp(mdb.p, "\x2B\x0E\x03\x02\x1A", 5) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9) == 0) + } + else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x04", 9) == 0) { md = MBEDTLS_MD_SHA224; - else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9) == 0) + } + else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x01", 9) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9) == 0) + } + else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x02", 9) == 0) { md = MBEDTLS_MD_SHA384; - else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9) == 0) + } + else if (memcmp(mdb.p, "\x60\x86\x48\x01\x65\x03\x04\x02\x03", 9) == 0) { md = MBEDTLS_MD_SHA512; + } hsh = d; } } } if (md == MBEDTLS_MD_NONE) { - if (data_len == 32) + if (data_len == 32) { md = MBEDTLS_MD_SHA256; - else if (data_len == 20) + } + else if (data_len == 20) { md = MBEDTLS_MD_SHA1; - else if (data_len == 28) + } + else if (data_len == 28) { md = MBEDTLS_MD_SHA224; - else if (data_len == 48) + } + else if (data_len == 48) { md = MBEDTLS_MD_SHA384; - else if (data_len == 64) + } + else if (data_len == 64) { md = MBEDTLS_MD_SHA512; + } hash_len = data_len; - hsh = (uint8_t *)data; + hsh = (uint8_t *) data; } if (md == MBEDTLS_MD_NONE) { - if (data_len < key_size) //needs padding - memset((uint8_t *)data+data_len, 0, key_size-data_len); + if (data_len < key_size) { //needs padding + memset((uint8_t *) data + data_len, 0, key_size - data_len); + } r = mbedtls_rsa_private(ctx, random_gen, NULL, data, out); } else { - uint8_t *signature = (uint8_t *)calloc(key_size, sizeof(uint8_t)); + uint8_t *signature = (uint8_t *) calloc(key_size, sizeof(uint8_t)); r = mbedtls_rsa_pkcs1_sign(ctx, random_gen, NULL, md, hash_len, hsh, signature); memcpy(out, signature, key_size); free(signature); @@ -1384,7 +1516,11 @@ int rsa_sign(mbedtls_rsa_context *ctx, const uint8_t *data, size_t data_len, uin return r; } -int ecdsa_sign(mbedtls_ecdsa_context *ctx, const uint8_t *data, size_t data_len, uint8_t *out, size_t *out_len) { +int ecdsa_sign(mbedtls_ecdsa_context *ctx, + const uint8_t *data, + size_t data_len, + uint8_t *out, + size_t *out_len) { mbedtls_mpi ri, si; mbedtls_mpi_init(&ri); mbedtls_mpi_init(&si); @@ -1393,7 +1529,7 @@ int ecdsa_sign(mbedtls_ecdsa_context *ctx, const uint8_t *data, size_t data_len, size_t plen = (ctx->grp.nbits + 7) / 8; mbedtls_mpi_write_binary(&ri, out, plen); mbedtls_mpi_write_binary(&si, out + plen, plen); - *out_len = 2*plen; + *out_len = 2 * plen; } mbedtls_mpi_free(&ri); mbedtls_mpi_free(&si); @@ -1404,37 +1540,44 @@ static int cmd_pso() { uint16_t algo_fid = 0x0, pk_fid = 0x0; bool is_aes = false; if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) { - if (!has_pw3 && !has_pw1) + if (!has_pw3 && !has_pw1) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } algo_fid = EF_ALGO_PRIV1; pk_fid = EF_PK_SIG; } else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { - if (!has_pw3 && !has_pw2) + if (!has_pw3 && !has_pw2) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } algo_fid = algo_dec; pk_fid = pk_dec; } - else + else { return SW_INCORRECT_P1P2(); + } file_t *algo_ef = search_by_fid(algo_fid, NULL, SPECIFY_EF); - if (!algo_ef) + if (!algo_ef) { return SW_REFERENCE_NOT_FOUND(); - const uint8_t *algo = algorithm_attr_rsa2k+1; + } + const uint8_t *algo = algorithm_attr_rsa2k + 1; if (algo_ef && algo_ef->data) { algo = file_get_data(algo_ef); } if (apdu.data[0] == 0x2) { //AES PSO? - if (((apdu.nc - 1)%16 == 0 && P1(apdu) == 0x80 && P2(apdu) == 0x86) || (apdu.nc%16 == 0 && P1(apdu) == 0x86 && P2(apdu) == 0x80)) { + if (((apdu.nc - 1) % 16 == 0 && P1(apdu) == 0x80 && P2(apdu) == 0x86) || + (apdu.nc % 16 == 0 && P1(apdu) == 0x86 && P2(apdu) == 0x80)) { pk_fid = EF_AES_KEY; is_aes = true; } } file_t *ef = search_by_fid(pk_fid, NULL, SPECIFY_EF); - if (!ef) + if (!ef) { return SW_REFERENCE_NOT_FOUND(); - if (wait_button_pressed(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true) + } + if (wait_button_pressed(pk_fid == EF_PK_SIG ? EF_UIF_SIG : EF_UIF_DEC) == true) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } int r = CCID_OK; int key_size = file_get_size(ef); if (is_aes) { @@ -1445,21 +1588,23 @@ static int cmd_pso() { return SW_EXEC_ERROR(); } if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { //decipher - r = aes_decrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.data+1, apdu.nc-1); + r = aes_decrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.data + 1, apdu.nc - 1); memset(aes_key, 0, sizeof(aes_key)); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); - memcpy(res_APDU, apdu.data+1, apdu.nc-1); - res_APDU_size = apdu.nc-1; + } + memcpy(res_APDU, apdu.data + 1, apdu.nc - 1); + res_APDU_size = apdu.nc - 1; } else if (P1(apdu) == 0x86 && P2(apdu) == 0x80) { //encipher r = aes_encrypt(aes_key, NULL, key_size, HSM_AES_MODE_CBC, apdu.data, apdu.nc); memset(aes_key, 0, sizeof(aes_key)); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } res_APDU[0] = 0x2; - memcpy(res_APDU+1, apdu.data, apdu.nc); - res_APDU_size = apdu.nc+1; + memcpy(res_APDU + 1, apdu.data, apdu.nc); + res_APDU_size = apdu.nc + 1; } return SW_OK(); } @@ -1475,17 +1620,25 @@ static int cmd_pso() { size_t olen = 0; r = rsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); mbedtls_rsa_free(&ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = olen; //apdu.ne = key_size; inc_sig_count(); } else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { - if (apdu.nc < key_size) //needs padding - memset(apdu.data+apdu.nc, 0, key_size-apdu.nc); + if (apdu.nc < key_size) { //needs padding + memset(apdu.data + apdu.nc, 0, key_size - apdu.nc); + } size_t olen = 0; - r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data+1, res_APDU, key_size); + r = mbedtls_rsa_pkcs1_decrypt(&ctx, + random_gen, + NULL, + &olen, + apdu.data + 1, + res_APDU, + key_size); mbedtls_rsa_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); @@ -1505,22 +1658,28 @@ static int cmd_pso() { size_t olen = 0; r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); mbedtls_ecdsa_free(&ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = olen; inc_sig_count(); } else if (P1(apdu) == 0x80 && P2(apdu) == 0x86) { mbedtls_ecdh_context ctx; uint8_t kdata[67]; - uint8_t *data = apdu.data, *end = data+apdu.nc; + uint8_t *data = apdu.data, *end = data + apdu.nc; size_t len = 0; - if (mbedtls_asn1_get_tag(&data, end, &len, 0xA6) != 0) + if (mbedtls_asn1_get_tag(&data, end, &len, 0xA6) != 0) { return SW_WRONG_DATA(); - if (*data++ != 0x7f) + } + if (*data++ != 0x7f) { return SW_WRONG_DATA(); - if (mbedtls_asn1_get_tag(&data, end, &len, 0x49) != 0 || mbedtls_asn1_get_tag(&data, end, &len, 0x86) != 0) + } + if (mbedtls_asn1_get_tag(&data, end, &len, + 0x49) != 0 || + mbedtls_asn1_get_tag(&data, end, &len, 0x86) != 0) { return SW_WRONG_DATA(); + } //if (len != 2*key_size-1) // return SW_WRONG_LENGTH(); memcpy(kdata, file_get_data(ef), key_size); @@ -1534,18 +1693,23 @@ static int cmd_pso() { mbedtls_ecdh_free(&ctx); return SW_DATA_INVALID(); } - r = mbedtls_mpi_read_binary(&ctx.ctx.mbed_ecdh.d, kdata+1, key_size-1); + r = mbedtls_mpi_read_binary(&ctx.ctx.mbed_ecdh.d, kdata + 1, key_size - 1); if (r != 0) { mbedtls_ecdh_free(&ctx); return SW_DATA_INVALID(); } - r = mbedtls_ecdh_read_public(&ctx, data-1, len+1); + r = mbedtls_ecdh_read_public(&ctx, data - 1, len + 1); if (r != 0) { mbedtls_ecdh_free(&ctx); return SW_DATA_INVALID(); } size_t olen = 0; - r = mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); + r = mbedtls_ecdh_calc_secret(&ctx, + &olen, + res_APDU, + MBEDTLS_ECP_MAX_BYTES, + random_gen, + NULL); if (r != 0) { mbedtls_ecdh_free(&ctx); return SW_EXEC_ERROR(); @@ -1558,15 +1722,19 @@ static int cmd_pso() { } static int cmd_terminate_df() { - if (P1(apdu) != 0x0 || P2(apdu) != 0x0) + if (P1(apdu) != 0x0 || P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); + } file_t *retries; - if (!(retries = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) + if (!(retries = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); - if (!has_pw3 && *(file_get_data(retries)+6) > 0) + } + if (!has_pw3 && *(file_get_data(retries) + 6) > 0) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (apdu.nc != 0) + } + if (apdu.nc != 0) { return SW_WRONG_LENGTH(); + } initialize_flash(true); scan_files(); return SW_OK(); @@ -1577,31 +1745,37 @@ static int cmd_activate_file() { } static int cmd_challenge() { - uint8_t *rb = (uint8_t *)random_bytes_get(apdu.ne); - if (!rb) + uint8_t *rb = (uint8_t *) random_bytes_get(apdu.ne); + if (!rb) { return SW_WRONG_LENGTH(); + } memcpy(res_APDU, rb, apdu.ne); res_APDU_size = apdu.ne; return SW_OK(); } static int cmd_internal_aut() { - if (P1(apdu) != 0x00 || P2(apdu) != 0x00) + if (P1(apdu) != 0x00 || P2(apdu) != 0x00) { return SW_WRONG_P1P2(); - if (!has_pw3 && !has_pw2) + } + if (!has_pw3 && !has_pw2) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } file_t *algo_ef = search_by_fid(algo_aut, NULL, SPECIFY_EF); - if (!algo_ef) + if (!algo_ef) { return SW_REFERENCE_NOT_FOUND(); - const uint8_t *algo = algorithm_attr_rsa2k+1; + } + const uint8_t *algo = algorithm_attr_rsa2k + 1; if (algo_ef && algo_ef->data) { algo = file_get_data(algo_ef); } file_t *ef = search_by_fid(pk_aut, NULL, SPECIFY_EF); - if (!ef) + if (!ef) { return SW_REFERENCE_NOT_FOUND(); - if (wait_button_pressed(EF_UIF_AUT) == true) + } + if (wait_button_pressed(EF_UIF_AUT) == true) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } int r = CCID_OK; if (algo[0] == ALGO_RSA) { mbedtls_rsa_context ctx; @@ -1614,8 +1788,9 @@ static int cmd_internal_aut() { size_t olen = 0; r = rsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); mbedtls_rsa_free(&ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = olen; } else if (algo[0] == ALGO_ECDH || algo[0] == ALGO_ECDSA) { @@ -1629,18 +1804,22 @@ static int cmd_internal_aut() { size_t olen = 0; r = ecdsa_sign(&ctx, apdu.data, apdu.nc, res_APDU, &olen); mbedtls_ecdsa_free(&ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = olen; } return SW_OK(); } static int cmd_mse() { - if (P1(apdu) != 0x41 || (P2(apdu) != 0xA4 && P2(apdu) != 0xB8)) + if (P1(apdu) != 0x41 || (P2(apdu) != 0xA4 && P2(apdu) != 0xB8)) { return SW_WRONG_P1P2(); - if (apdu.data[0] != 0x83 || apdu.data[1] != 0x1 || (apdu.data[2] != 0x2 && apdu.data[2] != 0x3)) + } + if (apdu.data[0] != 0x83 || apdu.data[1] != 0x1 || + (apdu.data[2] != 0x2 && apdu.data[2] != 0x3)) { return SW_WRONG_DATA(); + } if (P2(apdu) == 0xA4) { if (apdu.data[2] == 0x2) { algo_dec = EF_ALGO_PRIV2; @@ -1679,47 +1858,59 @@ size_t tag_len(uint8_t **data) { static int cmd_import_data() { file_t *ef = NULL; uint16_t fid = 0x0; - if (P1(apdu) != 0x3F || P2(apdu) != 0xFF) + if (P1(apdu) != 0x3F || P2(apdu) != 0xFF) { return SW_WRONG_P1P2(); - if (apdu.nc < 5) + } + if (apdu.nc < 5) { return SW_WRONG_LENGTH(); + } uint8_t *start = apdu.data; - if (*start++ != 0x4D) + if (*start++ != 0x4D) { return SW_WRONG_DATA(); + } size_t tgl = tag_len(&start); - if (*start != 0xB6 && *start != 0xB8 && *start != 0xA4) + if (*start != 0xB6 && *start != 0xB8 && *start != 0xA4) { return SW_WRONG_DATA(); - if (*start == 0xB6) + } + if (*start == 0xB6) { fid = EF_PK_SIG; - else if (*start == 0xB8) + } + else if (*start == 0xB8) { fid = EF_PK_DEC; - else if (*start == 0xA4) + } + else if (*start == 0xA4) { fid = EF_PK_AUT; - else + } + else { return SW_WRONG_DATA(); + } start++; - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } start += (*start + 1); - if (*start++ != 0x7F || *start++ != 0x48) + if (*start++ != 0x7F || *start++ != 0x48) { return SW_WRONG_DATA(); + } tgl = tag_len(&start); - uint8_t *end = start + tgl, len[9] = {0}, *p[9] = {0}; + uint8_t *end = start + tgl, len[9] = { 0 }, *p[9] = { 0 }; while (start < end) { uint8_t tag = *start++; if ((tag >= 0x91 && tag <= 0x97) || tag == 0x99) { - len[tag-0x91] = tag_len(&start); + len[tag - 0x91] = tag_len(&start); } - else + else { return SW_WRONG_DATA(); + } } - if (*start++ != 0x5F || *start++ != 0x48) + if (*start++ != 0x5F || *start++ != 0x48) { return SW_WRONG_DATA(); + } tgl = tag_len(&start); - end = start+tgl; + end = start + tgl; for (int t = 0; start < end && t < 9; t++) { if (len[t] > 0) { p[t] = start; @@ -1727,10 +1918,11 @@ static int cmd_import_data() { } } - file_t *algo_ef = search_by_fid(fid-0x0010, NULL, SPECIFY_EF); - if (!algo_ef) + file_t *algo_ef = search_by_fid(fid - 0x0010, NULL, SPECIFY_EF); + if (!algo_ef) { return SW_REFERENCE_NOT_FOUND(); - const uint8_t *algo = algorithm_attr_rsa2k+1; + } + const uint8_t *algo = algorithm_attr_rsa2k + 1; uint16_t algo_len = algorithm_attr_rsa2k[0]; if (algo_ef && algo_ef->data) { algo = file_get_data(algo_ef); @@ -1739,8 +1931,10 @@ static int cmd_import_data() { int r = 0; if (algo[0] == ALGO_RSA) { mbedtls_rsa_context rsa; - if (p[0] == NULL || len[0] == 0 || p[1] == NULL || len[1] == 0 || p[2] == NULL || len[2] == 0) + if (p[0] == NULL || len[0] == 0 || p[1] == NULL || len[1] == 0 || p[2] == NULL || + len[2] == 0) { return SW_WRONG_DATA(); + } mbedtls_rsa_init(&rsa); r = mbedtls_mpi_read_binary(&rsa.E, p[0], len[0]); if (r != 0) { @@ -1775,16 +1969,19 @@ static int cmd_import_data() { r = store_keys(&rsa, ALGO_RSA, fid); make_rsa_response(&rsa); mbedtls_rsa_free(&rsa); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } } else if (algo[0] == ALGO_ECDSA || algo[0] == ALGO_ECDH) { - mbedtls_ecdsa_context ecdsa; - if (p[1] == NULL || len[1] == 0) + mbedtls_ecdsa_context ecdsa; + if (p[1] == NULL || len[1] == 0) { return SW_WRONG_DATA(); - mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo+1, algo_len-1); - if (gid == MBEDTLS_ECP_DP_NONE) + } + mbedtls_ecp_group_id gid = get_ec_group_id_from_attr(algo + 1, algo_len - 1); + if (gid == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); + } mbedtls_ecdsa_init(&ecdsa); r = mbedtls_ecp_read_key(gid, &ecdsa, p[1], len[1]); if (r != 0) { @@ -1799,17 +1996,21 @@ static int cmd_import_data() { r = store_keys(&ecdsa, ALGO_ECDSA, fid); make_ecdsa_response(&ecdsa); mbedtls_ecdsa_free(&ecdsa); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } } - if (fid == EF_PK_SIG) + if (fid == EF_PK_SIG) { reset_sig_count(); - file_t *pbef = search_by_fid(fid+3, NULL, SPECIFY_EF); - if (!pbef) + } + file_t *pbef = search_by_fid(fid + 3, NULL, SPECIFY_EF); + if (!pbef) { return SW_REFERENCE_NOT_FOUND(); + } r = flash_write_data_to_file(pbef, res_APDU, res_APDU_size); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } res_APDU_size = 0; //make_*_response sets a response. we need to overwrite return SW_OK(); } @@ -1824,48 +2025,61 @@ static int cmd_version() { static int cmd_select_data() { file_t *ef = NULL; uint16_t fid = 0x0; - if (P2(apdu) != 0x4) + if (P2(apdu) != 0x4) { return SW_WRONG_P1P2(); - if (apdu.data[0] != 0x60) + } + if (apdu.data[0] != 0x60) { return SW_WRONG_DATA(); - if (apdu.nc != apdu.data[1]+2 || apdu.nc < 5) + } + if (apdu.nc != apdu.data[1] + 2 || apdu.nc < 5) { return SW_WRONG_LENGTH(); - if (apdu.data[2] != 0x5C) + } + if (apdu.data[2] != 0x5C) { return SW_WRONG_DATA(); - if (apdu.data[3] == 2) + } + if (apdu.data[3] == 2) { fid = (apdu.data[4] << 8) | apdu.data[5]; - else + } + else { fid = apdu.data[4]; - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + } + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } fid &= ~0x6000; //Now get private DO fid += P1(apdu); - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); - select_file(ef); - return SW_OK(); + } + select_file(ef); + return SW_OK(); } static int cmd_get_next_data() { file_t *ef = NULL; - if (apdu.nc > 0) + if (apdu.nc > 0) { return SW_WRONG_LENGTH(); - if (!currentEF) + } + if (!currentEF) { return SW_RECORD_NOT_FOUND(); + } uint16_t fid = (P1(apdu) << 8) | P2(apdu); - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if ((currentEF->fid & 0x1FF0) != (fid & 0x1FF0)) + if ((currentEF->fid & 0x1FF0) != (fid & 0x1FF0)) { return SW_WRONG_P1P2(); + } fid = currentEF->fid + 1; //curentEF contains private DO. so, we select the next one - if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); + } select_file(ef); return cmd_get_data(); } @@ -1906,7 +2120,7 @@ static const cmd_t cmds[] = { { INS_VERSION, cmd_version }, { INS_SELECT_DATA, cmd_select_data }, { INS_GET_NEXT_DATA, cmd_get_next_data }, - { 0x00, 0x0} + { 0x00, 0x0 } }; int openpgp_process_apdu() { @@ -1919,4 +2133,4 @@ int openpgp_process_apdu() { } } return SW_INS_NOT_SUPPORTED(); -} \ No newline at end of file +} diff --git a/src/openpgp/openpgp.h b/src/openpgp/openpgp.h index 4d5e7cf..5714094 100644 --- a/src/openpgp/openpgp.h +++ b/src/openpgp/openpgp.h @@ -30,4 +30,3 @@ extern bool has_pw1; extern bool has_pw3; #endif -