diff --git a/CMakeLists.txt b/CMakeLists.txt index 055db74..168b4f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,13 +89,23 @@ if(NOT ESP_PLATFORM) target_sources(pico_openpgp PUBLIC ${SOURCES}) target_include_directories(pico_openpgp PUBLIC ${INCLUDES}) - target_compile_options(pico_openpgp PUBLIC + set(COMMON_COMPILE_OPTIONS -Wall ) + target_compile_options(pico_openpgp PRIVATE ${COMMON_COMPILE_OPTIONS}) + + pico_keys_apply_strict_flags( + SOURCES ${SOURCES} + FILTER_REGEX "/src/openpgp/|/pico-keys-sdk/src/|/pico-keys-sdk/config/" + ) + if(NOT MSVC) - target_compile_options(pico_openpgp PUBLIC - -Werror - ) + string(FIND ${CMAKE_C_COMPILER} ":" COMPILER_COLON) + if(${COMPILER_COLON} GREATER_EQUAL 0) + target_compile_options(pico_openpgp PRIVATE + -Wno-error=use-after-free + ) + endif() endif() if(ENABLE_EMULATION) diff --git a/pico-keys-sdk b/pico-keys-sdk index 3463382..8aad7bd 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 34633828d7351cf979bbb7aa75fede3db047251a +Subproject commit 8aad7bdef9103f0c2abb4ececffa29928d489403 diff --git a/src/openpgp/cmd_activate_file.c b/src/openpgp/cmd_activate_file.c index 964c862..31fa95f 100644 --- a/src/openpgp/cmd_activate_file.c +++ b/src/openpgp/cmd_activate_file.c @@ -17,6 +17,6 @@ #include "openpgp.h" -int cmd_activate_file() { +int cmd_activate_file(void) { return SW_OK(); } \ No newline at end of file diff --git a/src/openpgp/cmd_challenge.c b/src/openpgp/cmd_challenge.c index 6cf8df8..0094fbb 100644 --- a/src/openpgp/cmd_challenge.c +++ b/src/openpgp/cmd_challenge.c @@ -18,7 +18,7 @@ #include "openpgp.h" #include "random.h" -int cmd_challenge() { +int cmd_challenge(void) { uint8_t *rb = (uint8_t *) random_bytes_get(apdu.ne); if (!rb) { return SW_WRONG_LENGTH(); diff --git a/src/openpgp/cmd_change_pin.c b/src/openpgp/cmd_change_pin.c index 56a0736..c29bf68 100644 --- a/src/openpgp/cmd_change_pin.c +++ b/src/openpgp/cmd_change_pin.c @@ -18,7 +18,7 @@ #include "openpgp.h" #include "otp.h" -int cmd_change_pin() { +int cmd_change_pin(void) { if (P1(apdu) != 0x0) { return SW_WRONG_P1P2(); } diff --git a/src/openpgp/cmd_get_data.c b/src/openpgp/cmd_get_data.c index 938e99c..dc054b2 100644 --- a/src/openpgp/cmd_get_data.c +++ b/src/openpgp/cmd_get_data.c @@ -20,7 +20,7 @@ extern bool is_gpg; -int cmd_get_data() { +int cmd_get_data(void) { if (apdu.nc > 0) { return SW_WRONG_LENGTH(); } @@ -115,7 +115,7 @@ int cmd_get_data() { return SW_OK(); } -int cmd_get_next_data() { +int cmd_get_next_data(void) { file_t *ef = NULL; if (apdu.nc > 0) { return SW_WRONG_LENGTH(); @@ -141,7 +141,7 @@ int cmd_get_next_data() { return cmd_get_data(); } -int cmd_get_bulk_data() { +int cmd_get_bulk_data(void) { if (apdu.nc < 3) { return SW_WRONG_LENGTH(); } diff --git a/src/openpgp/cmd_import_data.c b/src/openpgp/cmd_import_data.c index 2be1363..7c3e445 100644 --- a/src/openpgp/cmd_import_data.c +++ b/src/openpgp/cmd_import_data.c @@ -25,7 +25,7 @@ #include "random.h" #include "do.h" -uint16_t tag_len(uint8_t **data) { +static uint16_t tag_len(uint8_t **data) { size_t len = *(*data)++; if (len == 0x82) { len = *(*data)++ << 8; @@ -37,7 +37,7 @@ uint16_t tag_len(uint8_t **data) { return len; } -int cmd_import_data() { +int cmd_import_data(void) { file_t *ef = NULL; uint16_t fid = 0x0; if (P1(apdu) != 0x3F || P2(apdu) != 0xFF) { diff --git a/src/openpgp/cmd_internal_aut.c b/src/openpgp/cmd_internal_aut.c index 3fcaf56..9d4ee65 100644 --- a/src/openpgp/cmd_internal_aut.c +++ b/src/openpgp/cmd_internal_aut.c @@ -18,7 +18,7 @@ #include "openpgp.h" #include "do.h" -int cmd_internal_aut() { +int cmd_internal_aut(void) { if (P1(apdu) != 0x00 || P2(apdu) != 0x00) { return SW_WRONG_P1P2(); } diff --git a/src/openpgp/cmd_keypair_gen.c b/src/openpgp/cmd_keypair_gen.c index c41e66d..a334aca 100644 --- a/src/openpgp/cmd_keypair_gen.c +++ b/src/openpgp/cmd_keypair_gen.c @@ -19,7 +19,7 @@ #include "do.h" #include "random.h" -int cmd_keypair_gen() { +int cmd_keypair_gen(void) { if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); } diff --git a/src/openpgp/cmd_mse.c b/src/openpgp/cmd_mse.c index 50e7ace..6db31bb 100644 --- a/src/openpgp/cmd_mse.c +++ b/src/openpgp/cmd_mse.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_mse() { +int cmd_mse(void) { if (P1(apdu) != 0x41 || (P2(apdu) != 0xA4 && P2(apdu) != 0xB8)) { return SW_WRONG_P1P2(); } diff --git a/src/openpgp/cmd_pso.c b/src/openpgp/cmd_pso.c index 3c93db2..42bb662 100644 --- a/src/openpgp/cmd_pso.c +++ b/src/openpgp/cmd_pso.c @@ -27,7 +27,7 @@ #include "mbedtls/ecdh.h" #include "mbedtls/asn1.h" -int cmd_pso() { +int cmd_pso(void) { uint16_t algo_fid = 0x0, pk_fid = 0x0; bool is_aes = false; if (P1(apdu) == 0x9E && P2(apdu) == 0x9A) { @@ -70,7 +70,7 @@ int cmd_pso() { return SW_SECURE_MESSAGE_EXEC_ERROR(); } int r = PICOKEY_OK; - int key_size = file_get_size(ef); + size_t key_size = file_get_size(ef); if (is_aes) { uint8_t aes_key[32]; r = load_aes_key(aes_key, ef); diff --git a/src/openpgp/cmd_put_data.c b/src/openpgp/cmd_put_data.c index e364071..3767766 100644 --- a/src/openpgp/cmd_put_data.c +++ b/src/openpgp/cmd_put_data.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_put_data() { +int cmd_put_data(void) { uint16_t fid = (P1(apdu) << 8) | P2(apdu); file_t *ef; if (fid == EF_RESET_CODE) { diff --git a/src/openpgp/cmd_reset_retry.c b/src/openpgp/cmd_reset_retry.c index 5525363..4f4b2f9 100644 --- a/src/openpgp/cmd_reset_retry.c +++ b/src/openpgp/cmd_reset_retry.c @@ -18,7 +18,7 @@ #include "openpgp.h" #include "otp.h" -int cmd_reset_retry() { +int cmd_reset_retry(void) { if (P2(apdu) != 0x81) { return SW_REFERENCE_NOT_FOUND(); } diff --git a/src/openpgp/cmd_select.c b/src/openpgp/cmd_select.c index d97f9b6..32d1e4b 100644 --- a/src/openpgp/cmd_select.c +++ b/src/openpgp/cmd_select.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_select() { +int cmd_select(void) { uint8_t p1 = P1(apdu); uint8_t p2 = P2(apdu); file_t *pe = NULL; diff --git a/src/openpgp/cmd_select_data.c b/src/openpgp/cmd_select_data.c index b529e04..65dc96f 100644 --- a/src/openpgp/cmd_select_data.c +++ b/src/openpgp/cmd_select_data.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_select_data() { +int cmd_select_data(void) { file_t *ef = NULL; uint16_t fid = 0x0; if (P2(apdu) != 0x4) { @@ -26,7 +26,7 @@ int cmd_select_data() { if (apdu.data[0] != 0x60) { return SW_WRONG_DATA(); } - if (apdu.nc != apdu.data[1] + 2 || apdu.nc < 5) { + if (apdu.nc != (uint32_t) apdu.data[1] + 2u || apdu.nc < 5u) { return SW_WRONG_LENGTH(); } if (apdu.data[2] != 0x5C) { diff --git a/src/openpgp/cmd_terminate_df.c b/src/openpgp/cmd_terminate_df.c index dfc1e77..7f8145d 100644 --- a/src/openpgp/cmd_terminate_df.c +++ b/src/openpgp/cmd_terminate_df.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_terminate_df() { +int cmd_terminate_df(void) { if (P1(apdu) != 0x0 || P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); } diff --git a/src/openpgp/cmd_verify.c b/src/openpgp/cmd_verify.c index 6cd12d4..590e0be 100644 --- a/src/openpgp/cmd_verify.c +++ b/src/openpgp/cmd_verify.c @@ -17,7 +17,7 @@ #include "openpgp.h" -int cmd_verify() { +int cmd_verify(void) { uint8_t p1 = P1(apdu); uint8_t p2 = P2(apdu); diff --git a/src/openpgp/cmd_version.c b/src/openpgp/cmd_version.c index f1cd8a2..f6d82be 100644 --- a/src/openpgp/cmd_version.c +++ b/src/openpgp/cmd_version.c @@ -18,7 +18,7 @@ #include "openpgp.h" #include "version.h" -int cmd_version_openpgp() { +int cmd_version_openpgp(void) { res_APDU[res_APDU_size++] = PIPGP_VERSION_MAJOR; res_APDU[res_APDU_size++] = PIPGP_VERSION_MINOR; res_APDU[res_APDU_size++] = 0x0; diff --git a/src/openpgp/do.c b/src/openpgp/do.c index fba8580..fe11f39 100644 --- a/src/openpgp/do.c +++ b/src/openpgp/do.c @@ -18,6 +18,20 @@ #include "openpgp.h" #include "asn1.h" +int parse_trium(uint16_t fid, uint8_t num, size_t size); +int parse_ch_data(const file_t *f, int mode); +int parse_sec_tpl(const file_t *f, int mode); +int parse_ch_cert(const file_t *f, int mode); +int parse_fp(const file_t *f, int mode); +int parse_cafp(const file_t *f, int mode); +int parse_ts(const file_t *f, int mode); +int parse_keyinfo(const file_t *f, int mode); +int parse_pw_status(const file_t *f, int mode); +int parse_algo(const uint8_t *algo, uint16_t tag); +int parse_algoinfo(const file_t *f, int mode); +int parse_app_data(const file_t *f, int mode); +int parse_discrete_do(const file_t *f, int mode); + int parse_do(uint16_t *fids, int mode) { int len = 0; file_t *ef; @@ -25,7 +39,9 @@ int parse_do(uint16_t *fids, int mode) { 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); + int (*file_data_func)(const file_t *, int) = NULL; + memcpy(&file_data_func, &ef->data, sizeof(file_data_func)); + data_len = file_data_func(ef, mode); } else { data_len = file_get_size(ef); @@ -69,6 +85,7 @@ int parse_trium(uint16_t fid, uint8_t num, size_t size) { } int parse_ch_data(const file_t *f, int mode) { + (void) f; uint16_t fids[] = { 3, EF_CH_NAME, EF_LANG_PREF, EF_SEX, @@ -85,6 +102,8 @@ int parse_ch_data(const file_t *f, int mode) { } int parse_sec_tpl(const file_t *f, int mode) { + (void) f; + (void) mode; res_APDU[res_APDU_size++] = EF_SEC_TPL & 0xff; res_APDU[res_APDU_size++] = 5; file_t *ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY); @@ -98,28 +117,38 @@ int parse_sec_tpl(const file_t *f, int mode) { } int parse_ch_cert(const file_t *f, int mode) { + (void) f; + (void) mode; return 0; } int parse_fp(const file_t *f, int mode) { + (void) f; + (void) mode; res_APDU[res_APDU_size++] = EF_FP & 0xff; res_APDU[res_APDU_size++] = 60; return parse_trium(EF_FP_SIG, 3, 20) + 2; } int parse_cafp(const file_t *f, int mode) { + (void) f; + (void) mode; res_APDU[res_APDU_size++] = EF_CA_FP & 0xff; res_APDU[res_APDU_size++] = 60; return parse_trium(EF_FP_CA1, 3, 20) + 2; } int parse_ts(const file_t *f, int mode) { + (void) f; + (void) mode; res_APDU[res_APDU_size++] = EF_TS_ALL & 0xff; res_APDU[res_APDU_size++] = 12; return parse_trium(EF_TS_SIG, 3, 4) + 2; } int parse_keyinfo(const file_t *f, int mode) { + (void) f; + (void) mode; int init_len = res_APDU_size; if (res_APDU_size > 0) { res_APDU[res_APDU_size++] = EF_KEY_INFO & 0xff; @@ -155,6 +184,8 @@ int parse_keyinfo(const file_t *f, int mode) { } int parse_pw_status(const file_t *f, int mode) { + (void) f; + (void) mode; file_t *ef; int init_len = res_APDU_size; if (res_APDU_size > 0) { @@ -278,6 +309,7 @@ int parse_algo(const uint8_t *algo, uint16_t tag) { } int parse_algoinfo(const file_t *f, int mode) { + (void) mode; int datalen = 0; if (f->fid == EF_ALGO_INFO) { res_APDU[res_APDU_size++] = EF_ALGO_INFO & 0xff; @@ -356,6 +388,7 @@ int parse_algoinfo(const file_t *f, int mode) { } int parse_app_data(const file_t *f, int mode) { + (void) f; uint16_t fids[] = { 6, EF_FULL_AID, EF_HIST_BYTES, EF_EXLEN_INFO, EF_GFM, EF_DISCRETE_DO, EF_KEY_INFO @@ -372,6 +405,7 @@ int parse_app_data(const file_t *f, int mode) { } int parse_discrete_do(const file_t *f, int mode) { + (void) f; 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, diff --git a/src/openpgp/management.c b/src/openpgp/management.c index cc4498d..cf0fe80 100644 --- a/src/openpgp/management.c +++ b/src/openpgp/management.c @@ -24,16 +24,16 @@ bool is_gpg = true; -int man_process_apdu(); -int man_unload(); +static int man_process_apdu(void); +static int man_unload(void); const uint8_t man_aid[] = { 8, 0xa0, 0x00, 0x00, 0x05, 0x27, 0x47, 0x11, 0x17 }; -extern void init_piv(); -int man_select(app_t *a, uint8_t force) { +extern void init_piv(void); +static int man_select(app_t *a, uint8_t force) { (void) force; a->process_apdu = man_process_apdu; a->unload = man_unload; @@ -49,7 +49,7 @@ INITIALIZER( man_ctor ) { register_app(man_select, man_aid); } -int man_unload() { +static int man_unload(void) { return PICOKEY_OK; } @@ -74,7 +74,7 @@ bool cap_supported(uint16_t cap) { return true; } -int man_get_config() { +int man_get_config(void) { file_t *ef = search_dynamic_file(EF_DEV_CONF); res_APDU_size = 0; res_APDU[res_APDU_size++] = 0; // Overall length. Filled later @@ -118,12 +118,12 @@ int man_get_config() { return 0; } -int cmd_read_config() { +static int cmd_read_config(void) { man_get_config(); return SW_OK(); } -int cmd_write_config() { +static int cmd_write_config(void) { if (apdu.data[0] != apdu.nc - 1) { return SW_WRONG_DATA(); } @@ -142,7 +142,7 @@ static const cmd_t cmds[] = { { 0x00, 0x0 } }; -int man_process_apdu() { +static int man_process_apdu(void) { if (CLA(apdu) != 0x00) { return SW_CLA_NOT_SUPPORTED(); } diff --git a/src/openpgp/management.h b/src/openpgp/management.h index 7ff5bd4..5d6eb17 100644 --- a/src/openpgp/management.h +++ b/src/openpgp/management.h @@ -50,6 +50,6 @@ #define FLAG_EJECT 0x80 extern bool cap_supported(uint16_t cap); -extern int man_get_config(); +extern int man_get_config(void); #endif //_MANAGEMENT_H diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index 2765604..2b36c02 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -61,7 +61,7 @@ char atr_openpgp[] = { 0x60, 0x00, 0x90, 0x00, 0x1c }; -int openpgp_process_apdu(); +int openpgp_process_apdu(void); extern uint32_t board_button_read(void); @@ -75,6 +75,8 @@ bool wait_button_pressed_fid(uint16_t fid) { queue_remove_blocking(&usb_to_card_q, &val); }while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT); } +#else + (void) fid; #endif return val == EV_BUTTON_TIMEOUT; } @@ -97,7 +99,7 @@ void select_file(file_t *pe) { } } -void scan_files_openpgp() { +void scan_files_openpgp(void) { scan_flash(); file_t *ef; if ((ef = search_by_fid(EF_FULL_AID, NULL, SPECIFY_ANY))) { @@ -112,10 +114,10 @@ void scan_files_openpgp() { 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); - memcpy(def + IV_SIZE + 32 + 32, dek + IV_SIZE, 32); + const uint8_t *random_dek = random_bytes_get(IV_SIZE + 32); + memcpy(def, random_dek, IV_SIZE + 32); + memcpy(def + IV_SIZE + 32, random_dek + IV_SIZE, 32); + memcpy(def + IV_SIZE + 32 + 32, random_dek + IV_SIZE, 32); hash_multi(def1, sizeof(def1), session_pw1); aes_encrypt_cfb_256(session_pw1, def, def + IV_SIZE, 32); memset(session_pw1, 0, sizeof(session_pw1)); @@ -219,13 +221,13 @@ void scan_files_openpgp() { low_flash_available(); } -void release_dek() { +static void release_dek(void) { memset(dek, 0, sizeof(dek)); } extern bool has_pwpiv; extern uint8_t session_pwpiv[32]; -int load_dek() { +int load_dek(void) { if (!has_pw1 && !has_pw2 && !has_pw3 && !has_pwpiv) { return PICOKEY_NO_LOGIN; } @@ -280,7 +282,7 @@ int dek_decrypt(uint8_t *data, size_t len) { return r; } -void init_openpgp() { +static void init_openpgp(void) { isUserAuthenticated = false; has_pw1 = has_pw2 = has_pw3 = false; algo_dec = EF_ALGO_PRIV2; @@ -291,7 +293,7 @@ void init_openpgp() { //cmd_select(); } -int openpgp_unload() { +static int openpgp_unload(void) { isUserAuthenticated = false; has_pw1 = has_pw2 = has_pw3 = false; algo_dec = EF_ALGO_PRIV2; @@ -302,7 +304,7 @@ int openpgp_unload() { } extern char __StackLimit; -int heapLeft() { +static int heapLeft(void) { #if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) char *p = malloc(256); // try to avoid undue fragmentation int left = &__StackLimit - p; @@ -313,7 +315,7 @@ int heapLeft() { return left; } -int openpgp_select_aid(app_t *a, uint8_t force) { +static int openpgp_select_aid(app_t *a, uint8_t force) { (void) force; a->process_apdu = openpgp_process_apdu; a->unload = openpgp_unload; @@ -361,7 +363,7 @@ int pin_reset_retries(const file_t *pin, bool force) { return r; } -int pin_wrong_retry(const file_t *pin) { +static int pin_wrong_retry(const file_t *pin) { if (!pin) { return PICOKEY_ERR_NULL_PARAM; } @@ -433,7 +435,7 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) { return SW_OK(); } -int inc_sig_count() { +int inc_sig_count(void) { file_t *pw_status; if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF)) || !pw_status->data) { return SW_REFERENCE_NOT_FOUND(); @@ -457,7 +459,7 @@ int inc_sig_count() { return PICOKEY_OK; } -int reset_sig_count() { +int reset_sig_count(void) { file_t *ef = search_by_fid(EF_SIG_COUNT, NULL, SPECIFY_ANY); if (!ef || !ef->data) { return PICOKEY_ERR_FILE_NOT_FOUND; @@ -684,7 +686,8 @@ int rsa_sign(mbedtls_rsa_context *ctx, 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; + size_t key_size = ctx->len; + int r = 0; mbedtls_md_type_t md = MBEDTLS_MD_NONE; if (mbedtls_asn1_get_tag(&d, end, &seq_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0) { @@ -776,25 +779,6 @@ int ecdsa_sign(mbedtls_ecp_keypair *ctx, return r; } -extern int cmd_select(); -extern int cmd_get_data(); -extern int cmd_get_next_data(); -extern int cmd_put_data(); -extern int cmd_verify(); -extern int cmd_select_data(); -extern int cmd_version_openpgp(); -extern int cmd_import_data(); -extern int cmd_change_pin(); -extern int cmd_mse(); -extern int cmd_internal_aut(); -extern int cmd_challenge(); -extern int cmd_activate_file(); -extern int cmd_terminate_df(); -extern int cmd_pso(); -extern int cmd_keypair_gen(); -extern int cmd_reset_retry(); -extern int cmd_get_bulk_data(); - #define INS_VERIFY 0x20 #define INS_MSE 0x22 #define INS_CHANGE_PIN 0x24 @@ -836,7 +820,7 @@ static const cmd_t cmds[] = { { 0x00, NULL } }; -int openpgp_process_apdu() { +int openpgp_process_apdu(void) { sm_unwrap(); for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) { if (cmd->ins == INS(apdu)) { diff --git a/src/openpgp/openpgp.h b/src/openpgp/openpgp.h index 9ff9dd9..79e39b3 100644 --- a/src/openpgp/openpgp.h +++ b/src/openpgp/openpgp.h @@ -67,16 +67,35 @@ extern int pin_reset_retries(const file_t *pin, bool force); extern void select_file(file_t *pe); extern int parse_do(uint16_t *fids, int mode); -extern int load_dek(); +extern int load_dek(void); extern int check_pin(const file_t *pin, const uint8_t *data, size_t len); extern mbedtls_ecp_group_id get_ec_group_id_from_attr(const uint8_t *algo, size_t algo_len); -extern int reset_sig_count(); +extern int reset_sig_count(void); extern uint16_t algo_dec, algo_aut, pk_dec, pk_aut; extern bool wait_button_pressed_fid(uint16_t fid); -extern void scan_files_openpgp(); +extern void scan_files_openpgp(void); extern int load_aes_key(uint8_t *aes_key, file_t *fkey); -extern int inc_sig_count(); +extern int inc_sig_count(void); extern int dek_encrypt(uint8_t *data, size_t len); extern int dek_decrypt(uint8_t *data, size_t len); +int cmd_select(void); +int cmd_get_data(void); +int cmd_get_next_data(void); +int cmd_put_data(void); +int cmd_verify(void); +int cmd_select_data(void); +int cmd_version_openpgp(void); +int cmd_import_data(void); +int cmd_change_pin(void); +int cmd_mse(void); +int cmd_internal_aut(void); +int cmd_challenge(void); +int cmd_activate_file(void); +int cmd_terminate_df(void); +int cmd_pso(void); +int cmd_keypair_gen(void); +int cmd_reset_retry(void); +int cmd_get_bulk_data(void); + #endif diff --git a/src/openpgp/piv.c b/src/openpgp/piv.c index ccbc66b..2004067 100644 --- a/src/openpgp/piv.c +++ b/src/openpgp/piv.c @@ -76,9 +76,11 @@ uint8_t yk_aid[] = { bool has_pwpiv = false; uint8_t session_pwpiv[32]; -int piv_process_apdu(); +int piv_process_apdu(void); +void init_piv(void); +int piv_parse_discovery(const file_t *ef); -static int get_serial() { +static int get_serial(void) { uint32_t serial = (pico_serial.id[0] & 0x7F) << 24 | pico_serial.id[1] << 16 | pico_serial.id[2] << 8 | pico_serial.id[3]; return serial; } @@ -116,8 +118,8 @@ static int x509_create_cert(void *pk_ctx, uint8_t algo, uint8_t slot, bool attes mbedtls_x509write_crt_set_issuer_key(&ctx, &ikey); uint8_t ver[] = {PIV_VERSION_MAJOR, PIV_VERSION_MINOR, 0}; mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x03", 10, 0, ver, sizeof(ver)); - uint32_t serial = get_serial(); - mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x07", 10, 0, (const uint8_t *)&serial, sizeof(serial)); + uint32_t device_serial = get_serial(); + mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x07", 10, 0, (const uint8_t *)&device_serial, sizeof(device_serial)); int meta_len = 0; uint8_t *meta; if ((meta_len = meta_find(slot, &meta)) >= 0) { @@ -163,7 +165,7 @@ static int x509_create_cert(void *pk_ctx, uint8_t algo, uint8_t slot, bool attes return ret; } -static void scan_files_piv() { +static void scan_files_piv(void) { scan_flash(); file_t *ef = search_by_fid(EF_PIV_KEY_CARDMGM, NULL, SPECIFY_EF); if ((ef = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_ANY))) { @@ -199,23 +201,23 @@ static void scan_files_piv() { if (file_get_size(ef) == 0 || file_get_size(ef) == IV_SIZE+32*3) { printf("DEK is empty or older\r\n"); const uint8_t defpin[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 }; - const uint8_t *dek = random_bytes_get(IV_SIZE + 32); + const uint8_t *random_dek = random_bytes_get(IV_SIZE + 32); uint8_t def[IV_SIZE + 32 + 32 + 32 + 32]; if (file_get_size(ef) > 0) { memcpy(def, file_get_data(ef), file_get_size(ef)); } else { - memcpy(def, dek, IV_SIZE); + memcpy(def, random_dek, IV_SIZE); } - memcpy(def + IV_SIZE + 32*3, dek + IV_SIZE, 32); + memcpy(def + IV_SIZE + 32*3, random_dek + IV_SIZE, 32); hash_multi(defpin, sizeof(defpin), session_pwpiv); aes_encrypt_cfb_256(session_pwpiv, def, def + IV_SIZE + 32*3, 32); file_put_data(ef, def, sizeof(def)); has_pwpiv = true; uint8_t *key = (uint8_t *)"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"; - file_t *ef = search_by_fid(EF_PIV_KEY_CARDMGM, NULL, SPECIFY_ANY); - file_put_data(ef, key, 24); + file_t *ef_cardmgm = search_by_fid(EF_PIV_KEY_CARDMGM, NULL, SPECIFY_ANY); + file_put_data(ef_cardmgm, key, 24); uint8_t meta[] = { PIV_ALGO_AES192, PINPOLICY_ALWAYS, TOUCHPOLICY_ALWAYS }; meta_add(EF_PIV_KEY_CARDMGM, meta, sizeof(meta)); has_pwpiv = false; @@ -261,17 +263,17 @@ static void scan_files_piv() { low_flash_available(); } -void init_piv() { +void init_piv(void) { scan_files_piv(); has_pwpiv = false; // cmd_select(); } -int piv_unload() { +static int piv_unload(void) { return PICOKEY_OK; } -void select_piv_aid() { +static void select_piv_aid(void) { res_APDU[res_APDU_size++] = 0x61; res_APDU[res_APDU_size++] = 0; //filled later res_APDU[res_APDU_size++] = 0x4F; @@ -298,7 +300,7 @@ void select_piv_aid() { res_APDU[res_APDU_size++] = 0x00; } -int piv_select_aid(app_t *a, uint8_t force) { +static int piv_select_aid(app_t *a, uint8_t force) { (void) force; a->process_apdu = piv_process_apdu; a->unload = piv_unload; @@ -312,14 +314,14 @@ INITIALIZER( piv_ctor ) { register_app(piv_select_aid, yk_aid); } -static int cmd_version() { +static int cmd_version(void) { res_APDU[res_APDU_size++] = PIV_VERSION_MAJOR; res_APDU[res_APDU_size++] = PIV_VERSION_MINOR; res_APDU[res_APDU_size++] = 0x0; return SW_OK(); } -static int cmd_select() { +static int cmd_piv_select(void) { if (P2(apdu) != 0x1) { return SW_WRONG_P1P2(); } @@ -330,12 +332,13 @@ static int cmd_select() { } int piv_parse_discovery(const file_t *ef) { + (void) ef; memcpy(res_APDU, "\x7E\x12\x4F\x0B\xA0\x00\x00\x03\x08\x00\x00\x10\x00\x01\x00\x5F\x2F\x02\x40\x10", 20); res_APDU_size = 20; return res_APDU_size; } -static int cmd_get_serial() { +static int cmd_get_serial(void) { uint32_t serial = get_serial(); res_APDU[res_APDU_size++] = serial >> 24; res_APDU[res_APDU_size++] = serial >> 16; @@ -344,8 +347,7 @@ static int cmd_get_serial() { return SW_OK(); } -extern int check_pin(const file_t *pin, const uint8_t *data, size_t len); -static int cmd_verify() { +static int cmd_piv_verify(void) { uint8_t key_ref = P2(apdu); if (P1(apdu) != 0x00 && P1(apdu) != 0xFF) { return SW_INCORRECT_P1P2(); @@ -382,7 +384,7 @@ static int cmd_verify() { return set_res_sw(0x63, 0xc0 | retries); } -static int cmd_get_data() { +static int cmd_piv_get_data(void) { if (P1(apdu) != 0x3F || P2(apdu) != 0xFF) { return SW_INCORRECT_P1P2(); } @@ -402,7 +404,9 @@ static int cmd_get_data() { uint16_t data_len = 0; res_APDU_size = 2; // Minimum: TAG+LEN if ((ef->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) { - data_len = ((int (*)(const file_t *))(ef->data))((const file_t *) ef); + int (*file_data_func)(const file_t *) = NULL; + memcpy(&file_data_func, &ef->data, sizeof(file_data_func)); + data_len = file_data_func(ef); } else { if (ef->data) { @@ -428,7 +432,7 @@ static int cmd_get_data() { return SW_OK(); } -static int cmd_get_metadata() { +static int cmd_get_metadata(void) { if (P1(apdu) != 0x00) { return SW_INCORRECT_P1P2(); } @@ -561,7 +565,7 @@ static int cmd_get_metadata() { uint8_t challenge[16]; bool has_challenge = false; bool has_mgm = false; -static int cmd_authenticate() { +static int cmd_authenticate(void) { uint8_t algo = P1(apdu), key_ref = P2(apdu); if (apdu.nc == 0) { return SW_WRONG_LENGTH(); @@ -838,7 +842,7 @@ static int cmd_authenticate() { return SW_OK(); } -static int cmd_asym_keygen() { +static int cmd_asym_keygen(void) { uint8_t key_ref = P2(apdu); if (apdu.nc == 0) { return SW_WRONG_LENGTH(); @@ -945,7 +949,7 @@ static int cmd_asym_keygen() { return SW_OK(); } -static int cmd_put_data() { +static int cmd_piv_put_data(void) { if (P1(apdu) != 0x3F || P2(apdu) != 0xFF) { return SW_INCORRECT_P1P2(); } @@ -974,7 +978,7 @@ static int cmd_put_data() { return SW_OK(); } -static int cmd_set_mgmkey() { +static int cmd_set_mgmkey(void) { if (P1(apdu) != 0xFF) { return SW_INCORRECT_P1P2(); } @@ -1010,7 +1014,7 @@ static int cmd_set_mgmkey() { return SW_OK(); } -static int cmd_move_key() { +static int cmd_move_key(void) { if (apdu.nc != 0) { return SW_WRONG_LENGTH(); } @@ -1115,7 +1119,7 @@ static int cmd_move_key() { return SW_OK(); } -static int cmd_change_pin() { +static int cmd_piv_change_pin(void) { uint8_t pin_ref = P2(apdu); if (P1(apdu) != 0x0 || (pin_ref != 0x80 && pin_ref != 0x81)) { return SW_INCORRECT_P1P2(); @@ -1137,7 +1141,7 @@ static int cmd_change_pin() { return SW_OK(); } -static int cmd_reset_retry() { +static int cmd_piv_reset_retry(void) { if (P1(apdu) != 0x0 || P2(apdu) != 0x80) { return SW_INCORRECT_P1P2(); } @@ -1160,7 +1164,7 @@ static int cmd_reset_retry() { return SW_OK(); } -static int cmd_set_retries() { +static int cmd_set_retries(void) { file_t *ef = search_by_fid(EF_PW_RETRIES, NULL, SPECIFY_ANY); if (!ef) { return SW_MEMORY_FAILURE(); @@ -1191,7 +1195,7 @@ static int cmd_set_retries() { return SW_OK(); } -static int cmd_reset() { +static int cmd_reset(void) { if (P1(apdu) != 0x0 || P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); } @@ -1210,7 +1214,7 @@ static int cmd_reset() { return SW_OK(); } -static int cmd_attestation() { +static int cmd_attestation(void) { uint8_t key_ref = P1(apdu); if (P2(apdu) != 0x00) { return SW_INCORRECT_P1P2(); @@ -1265,7 +1269,7 @@ static int cmd_attestation() { return SW_OK(); } -static int cmd_import_asym() { +static int cmd_import_asym(void) { uint8_t algo = P1(apdu), key_ref = P2(apdu); if (key_ref != EF_PIV_KEY_AUTHENTICATION && key_ref != EF_PIV_KEY_SIGNATURE && key_ref != EF_PIV_KEY_KEYMGM && key_ref != EF_PIV_KEY_CARDAUTH && !(key_ref >= EF_PIV_KEY_RETIRED1 && key_ref <= EF_PIV_KEY_RETIRED20)) { return SW_INCORRECT_P1P2(); @@ -1379,18 +1383,18 @@ static int cmd_import_asym() { static const cmd_t cmds[] = { { INS_VERSION, cmd_version }, - { INS_SELECT, cmd_select }, + { INS_SELECT, cmd_piv_select }, { INS_YK_SERIAL, cmd_get_serial }, - { INS_VERIFY, cmd_verify }, - { INS_GET_DATA, cmd_get_data }, + { INS_VERIFY, cmd_piv_verify }, + { INS_GET_DATA, cmd_piv_get_data }, { INS_GET_METADATA, cmd_get_metadata }, { INS_AUTHENTICATE, cmd_authenticate }, { INS_ASYM_KEYGEN, cmd_asym_keygen }, - { INS_PUT_DATA, cmd_put_data }, + { INS_PUT_DATA, cmd_piv_put_data }, { INS_SET_MGMKEY, cmd_set_mgmkey }, { INS_MOVE_KEY, cmd_move_key }, - { INS_CHANGE_PIN, cmd_change_pin }, - { INS_RESET_RETRY, cmd_reset_retry }, + { INS_CHANGE_PIN, cmd_piv_change_pin }, + { INS_RESET_RETRY, cmd_piv_reset_retry }, { INS_SET_RETRIES, cmd_set_retries }, { INS_RESET, cmd_reset }, { INS_ATTESTATION, cmd_attestation }, @@ -1398,7 +1402,7 @@ static const cmd_t cmds[] = { { 0x00, 0x0 } }; -int piv_process_apdu() { +int piv_process_apdu(void) { sm_unwrap(); for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) { if (cmd->ins == INS(apdu)) {