From c3b66773e8f82d3f5667771bb725fe98170df01c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 18:11:28 +0100 Subject: [PATCH] Use new asn1 structs. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 6 +- pico-keys-sdk | 2 +- src/hsm/cmd_bip_slip.c | 5 +- src/hsm/cmd_cipher_sym.c | 241 ++++++++++++++--------------- src/hsm/cmd_decrypt_asym.c | 26 ++-- src/hsm/cmd_general_authenticate.c | 4 +- src/hsm/cmd_initialize.c | 4 +- src/hsm/cmd_keypair_gen.c | 78 ++++------ src/hsm/cmd_mse.c | 4 +- src/hsm/cmd_signature.c | 34 ++-- src/hsm/cmd_update_ef.c | 4 +- src/hsm/cvc.c | 45 +++--- src/hsm/sc_hsm.c | 40 ++--- 13 files changed, 244 insertions(+), 249 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 309bca2..ee5157b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ target_compile_options(pico_hsm PUBLIC -Wall ) if (NOT MSVC) - target_compile_options(pico_hsm PUBLIC + target_compile_options(pico_hsm PUBLIC -Werror ) endif() @@ -106,10 +106,10 @@ target_link_options(pico_hsm PUBLIC -Wl,-dead_strip ) elseif(MSVC) - target_compile_options(pico_hsm PUBLIC + target_compile_options(pico_hsm PUBLIC -WX ) - + target_link_libraries(pico_hsm PUBLIC wsock32 ws2_32 Bcrypt) else() target_link_options(pico_hsm PUBLIC diff --git a/pico-keys-sdk b/pico-keys-sdk index caddf87..e055d4c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit caddf87c236a068f94e5283e10b9411d1cfa39e0 +Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13 diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 13db1f2..41d27d6 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -160,7 +160,10 @@ int node_derive_path(const uint8_t *path, int r = 0; memset(last_node, 0, 4); memset(fingerprint, 0, 4); - for (; walk_tlv(path, path_len, &p, &tag, &tag_len, &tag_data); node++) { + + asn1_ctx_t ctxi; + asn1_ctx_init((uint8_t *)path, path_len, &ctxi); + for (; walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data); node++) { if (tag == 0x02) { if ((node == 0 && tag_len != 1) || (node != 0 && tag_len != 4)) { return CCID_WRONG_DATA; diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index c816c63..6de1409 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -269,20 +269,19 @@ int cmd_cipher_sym() { res_APDU_size = (uint16_t)apdu.nc; } else if (algo == ALGO_EXT_CIPHER_ENCRYPT || algo == ALGO_EXT_CIPHER_DECRYPT) { - uint16_t oid_len = 0, aad_len = 0, iv_len = 0, enc_len = 0; - uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; - if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x6, &oid_len, - &oid) || oid_len == 0 || oid == NULL) { + asn1_ctx_t ctxi, oid = {0}, enc = {0}, iv = {0}, aad = {0}; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (!asn1_find_tag(&ctxi, 0x6, &oid) || asn1_len(&oid) == 0) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x81, &enc_len, &enc); - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x82, &iv_len, &iv); - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x83, &aad_len, &aad); + asn1_find_tag(&ctxi, 0x81, &enc); + asn1_find_tag(&ctxi, 0x82, &iv); + asn1_find_tag(&ctxi, 0x83, &aad); uint8_t tmp_iv[16]; memset(tmp_iv, 0, sizeof(tmp_iv)); - if (memcmp(oid, OID_CHACHA20_POLY1305, oid_len) == 0) { - if (algo == ALGO_EXT_CIPHER_DECRYPT && enc_len < 16) { + if (memcmp(oid.data, OID_CHACHA20_POLY1305, oid.len) == 0) { + if (algo == ALGO_EXT_CIPHER_DECRYPT && enc.len < 16) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } @@ -292,22 +291,22 @@ int cmd_cipher_sym() { mbedtls_chachapoly_setkey(&ctx, kdata); if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_chachapoly_encrypt_and_tag(&ctx, - enc_len, - iv ? iv : tmp_iv, - aad, - aad_len, - enc, + enc.len, + asn1_len(&iv) > 0 ? iv.data : tmp_iv, + aad.data, + aad.len, + enc.data, res_APDU, - res_APDU + enc_len); + res_APDU + enc.len); } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_chachapoly_auth_decrypt(&ctx, - enc_len - 16, - iv ? iv : tmp_iv, - aad, - aad_len, - enc + enc_len - 16, - enc, + enc.len - 16, + asn1_len(&iv) > 0 ? iv.data : tmp_iv, + aad.data, + aad.len, + enc.data + enc.len - 16, + enc.data, res_APDU); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); @@ -319,60 +318,60 @@ int cmd_cipher_sym() { return SW_EXEC_ERROR(); } if (algo == ALGO_EXT_CIPHER_ENCRYPT) { - res_APDU_size = enc_len + 16; + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } } - else if (memcmp(oid, OID_DIGEST, 7) == 0) { + else if (memcmp(oid.data, OID_DIGEST, 7) == 0) { const mbedtls_md_info_t *md_info = NULL; - if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) { + if (memcmp(oid.data, OID_HMAC_SHA1, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); } - else if (memcmp(oid, OID_HMAC_SHA224, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA224, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); } - else if (memcmp(oid, OID_HMAC_SHA256, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA256, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); } - else if (memcmp(oid, OID_HMAC_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA384, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); } - else if (memcmp(oid, OID_HMAC_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA512, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } if (md_info == NULL) { return SW_WRONG_DATA(); } - int r = mbedtls_md_hmac(md_info, kdata, key_size, enc, enc_len, res_APDU); + int r = mbedtls_md_hmac(md_info, kdata, key_size, enc.data, enc.len, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_EXEC_ERROR(); } res_APDU_size = md_info->size; } - else if (memcmp(oid, OID_HKDF_SHA256, - oid_len) == 0 || - memcmp(oid, OID_HKDF_SHA384, - oid_len) == 0 || memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA256, + oid.len) == 0 || + memcmp(oid.data, OID_HKDF_SHA384, + oid.len) == 0 || memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) { const mbedtls_md_info_t *md_info = NULL; - if (memcmp(oid, OID_HKDF_SHA256, oid_len) == 0) { + if (memcmp(oid.data, OID_HKDF_SHA256, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); } - else if (memcmp(oid, OID_HKDF_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA384, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); } - else if (memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } int r = mbedtls_hkdf(md_info, - iv, - iv_len, + iv.data, + iv.len, kdata, key_size, - enc, - enc_len, + enc.data, + enc.len, res_APDU, apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info)); @@ -382,12 +381,12 @@ int cmd_cipher_sym() { } res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : (uint16_t)mbedtls_md_get_size(md_info); } - else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { + else if (memcmp(oid.data, OID_PKCS5_PBKDF2, oid.len) == 0) { int iterations = 0; uint16_t keylen = 0; mbedtls_asn1_buf salt, params = - { .p = enc, .len = enc_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; + { .p = enc.data, .len = enc.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; int r = pkcs5_parse_pbkdf2_params(¶ms, &salt, &iterations, &keylen, &md_type); @@ -411,16 +410,16 @@ int cmd_cipher_sym() { } res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32); } - else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { + else if (memcmp(oid.data, OID_PKCS5_PBES2, oid.len) == 0) { size_t olen = 0; mbedtls_asn1_buf params = - {.p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; + {.p = aad.data, .len = aad.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; int r = mbedtls_pkcs5_pbes2_ext(¶ms, algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, kdata, key_size, - enc, - enc_len, + enc.data, + enc.len, res_APDU, 4096, &olen); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { @@ -428,28 +427,28 @@ int cmd_cipher_sym() { } res_APDU_size = (uint16_t)olen; } - else if (memcmp(oid, OID_KDF_X963, oid_len) == 0) { + else if (memcmp(oid.data, OID_KDF_X963, oid.len) == 0) { mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; - if (memcmp(enc, OID_HMAC_SHA1, enc_len) == 0) { + if (memcmp(enc.data, OID_HMAC_SHA1, enc.len) == 0) { md_type = MBEDTLS_MD_SHA1; } - else if (memcmp(enc, OID_HMAC_SHA224, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA224, enc.len) == 0) { md_type = MBEDTLS_MD_SHA224; } - else if (memcmp(enc, OID_HMAC_SHA256, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA256, enc.len) == 0) { md_type = MBEDTLS_MD_SHA256; } - else if (memcmp(enc, OID_HMAC_SHA384, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA384, enc.len) == 0) { md_type = MBEDTLS_MD_SHA384; } - else if (memcmp(enc, OID_HMAC_SHA512, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA512, enc.len) == 0) { md_type = MBEDTLS_MD_SHA512; } int r = mbedtls_ansi_x963_kdf(md_type, key_size, kdata, - aad_len, - aad, + aad.len, + aad.data, apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); @@ -458,11 +457,11 @@ int cmd_cipher_sym() { } res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32; } - else if (memcmp(oid, OID_NIST_AES, 8) == 0) { - if (oid_len != 9) { + else if (memcmp(oid.data, OID_NIST_AES, 8) == 0) { + if (oid.len != 9) { return SW_WRONG_DATA(); } - uint8_t aes_algo = oid[8], + uint8_t aes_algo = oid.data[8], mode = (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); if ((aes_algo >= 0x01 && aes_algo <= 0x09 && key_size != 16) || @@ -473,9 +472,9 @@ int cmd_cipher_sym() { mbedtls_aes_context ctx; int r = 0; mbedtls_aes_init(&ctx); - if (iv == NULL || iv_len == 0) { - iv = tmp_iv; - iv_len = sizeof(tmp_iv); + if (asn1_len(&iv) == 0) { + iv.data = tmp_iv; + iv.len = sizeof(tmp_iv); } if (aes_algo == 0x01 || aes_algo == 0x15 || aes_algo == 0x29) { /* ECB */ if (algo == ALGO_EXT_CIPHER_ENCRYPT) { @@ -485,12 +484,12 @@ int cmd_cipher_sym() { r = mbedtls_aes_setkey_dec(&ctx, kdata, key_size * 8); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ecb(&ctx, mode, enc, res_APDU); + r = mbedtls_aes_crypt_ecb(&ctx, mode, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = MIN(enc_len, 16); // ECB operates with 16-byte blocks + res_APDU_size = MIN(enc.len, 16); // ECB operates with 16-byte blocks } else if (aes_algo == 0x02 || aes_algo == 0x16 || aes_algo == 0x2A) { /* CBC */ if (algo == ALGO_EXT_CIPHER_ENCRYPT) { @@ -503,34 +502,34 @@ int cmd_cipher_sym() { return SW_EXEC_ERROR(); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_cbc(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cbc(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x03 || aes_algo == 0x17 || aes_algo == 0x2B) { /* OFB */ size_t iv_off = 0; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ofb(&ctx, enc_len, &iv_off, iv, enc, res_APDU); + r = mbedtls_aes_crypt_ofb(&ctx, enc.len, &iv_off, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x04 || aes_algo == 0x18 || aes_algo == 0x2C) { /* CFB */ size_t iv_off = 0; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_cfb128(&ctx, mode, enc_len, &iv_off, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cfb128(&ctx, mode, enc.len, &iv_off, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x06 || aes_algo == 0x1A || aes_algo == 0x2E) { /* GCM */ mbedtls_aes_free(&ctx); // No AES ctx used @@ -541,29 +540,29 @@ int cmd_cipher_sym() { if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_gcm_crypt_and_tag(&gctx, MBEDTLS_GCM_ENCRYPT, - enc_len, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, 16, - res_APDU + enc_len); - res_APDU_size = enc_len + 16; + res_APDU + enc.len); + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_gcm_auth_decrypt(&gctx, - enc_len - 16, - iv, - iv_len, - aad, - aad_len, - enc + enc_len - 16, + enc.len - 16, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data + enc.len - 16, 16, - enc, + enc.data, res_APDU); - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } mbedtls_gcm_free(&gctx); if (r != 0) { @@ -575,12 +574,12 @@ int cmd_cipher_sym() { uint8_t stream_block[16]; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ctr(&ctx, enc_len, &iv_off, iv, stream_block, enc, res_APDU); + r = mbedtls_aes_crypt_ctr(&ctx, enc.len, &iv_off, iv.data, stream_block, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x07 || aes_algo == 0x1B || aes_algo == 0x2F) { /* CCM */ mbedtls_aes_free(&ctx); // No AES ctx used @@ -590,35 +589,35 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - if (iv_len == 16) { - iv_len = 12; + if (iv.len == 16) { + iv.len = 12; } mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_ccm_encrypt_and_tag(&gctx, - enc_len, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, - res_APDU + enc_len, + res_APDU + enc.len, 16); - res_APDU_size = enc_len + 16; + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_ccm_auth_decrypt(&gctx, - enc_len - 16, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len - 16, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, - enc + enc_len - 16, + enc.data + enc.len - 16, 16); - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } mbedtls_ccm_free(&gctx); if (r != 0) { @@ -626,18 +625,18 @@ int cmd_cipher_sym() { } } } - else if (memcmp(oid, OID_IEEE_ALG, 8) == 0) { - if (oid_len != 9) { + else if (memcmp(oid.data, OID_IEEE_ALG, 8) == 0) { + if (oid.len != 9) { return SW_WRONG_DATA(); } - uint8_t aes_algo = oid[8], + uint8_t aes_algo = oid.data[8], mode = (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); int r = 0; memset(tmp_iv, 0, sizeof(tmp_iv)); - if (iv == NULL || iv_len == 0) { - iv = tmp_iv; - iv_len = sizeof(tmp_iv); + if (asn1_len(&iv) == 0) { + iv.data = tmp_iv; + iv.len = sizeof(tmp_iv); } if ((aes_algo == 0x01 && key_size != 32) || (aes_algo == 0x02 && key_size != 64)) { return SW_WRONG_DATA(); @@ -651,14 +650,14 @@ int cmd_cipher_sym() { r = mbedtls_aes_xts_setkey_dec(&ctx, kdata, key_size * 8); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_xts(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_xts(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_xts_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } - else if (memcmp(oid, OID_HD, 11) == 0) { + else if (memcmp(oid.data, OID_HD, 11) == 0) { mbedtls_aes_context ctx; int r = 0; uint8_t mode = @@ -673,16 +672,16 @@ int cmd_cipher_sym() { r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), kdata, key_size, - aad, - aad_len, + aad.data, + aad.len, secret); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_EXEC_ERROR(); } - if (iv == tmp_iv || iv_len == 0) { - iv = secret + 32; - iv_len = 16; + if (iv.data == tmp_iv || iv.len == 0) { + iv.data = secret + 32; + iv.len = 16; } if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_aes_setkey_enc(&ctx, secret, key_size * 8); @@ -693,12 +692,12 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - r = mbedtls_aes_crypt_cbc(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cbc(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; mbedtls_ecdsa_free(&hd_context); hd_keytype = 0; } diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 55880a2..e68853e 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -152,34 +152,32 @@ int cmd_decrypt_asym() { if ((ext = cvc_get_ext(apdu.data, (uint16_t)apdu.nc, &ext_len)) == NULL) { return SW_WRONG_DATA(); } - uint8_t *p = NULL, *tag_data = NULL, *kdom_uid = NULL; + uint8_t *p = NULL; uint16_t tag = 0; - uint16_t tag_len = 0, kdom_uid_len = 0; - while (walk_tlv(ext, ext_len, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi, ctxo = { 0 }, kdom_uid = { 0 }; + asn1_ctx_init((uint8_t *)ext, ext_len, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &ctxo.len, &ctxo.data)) { if (tag == 0x73) { - uint16_t oid_len = 0; - uint8_t *oid_data = NULL; - if (asn1_find_tag(tag_data, tag_len, 0x6, &oid_len, - &oid_data) == true && - oid_len == strlen(OID_ID_KEY_DOMAIN_UID) && - memcmp(oid_data, OID_ID_KEY_DOMAIN_UID, + asn1_ctx_t oid = {0}; + if (asn1_find_tag(&ctxo, 0x6, &oid) == true && + oid.len == strlen(OID_ID_KEY_DOMAIN_UID) && + memcmp(oid.data, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)) == 0) { - if (asn1_find_tag(tag_data, tag_len, 0x80, &kdom_uid_len, - &kdom_uid) == false) { + if (asn1_find_tag(&ctxo, 0x80, &kdom_uid) == false) { return SW_WRONG_DATA(); } break; } } } - if (kdom_uid_len == 0 || kdom_uid == NULL) { + if (asn1_len(&kdom_uid) == 0) { return SW_WRONG_DATA(); } for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) { file_t *tf = search_dynamic_file(EF_XKEK + n); if (tf) { - if (file_get_size(tf) == kdom_uid_len && - memcmp(file_get_data(tf), kdom_uid, kdom_uid_len) == 0) { + if (file_get_size(tf) == kdom_uid.len && + memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) { file_new(EF_DKEK + n); if (store_dkek_key(n, res_APDU + 1) != CCID_OK) { return SW_EXEC_ERROR(); diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index c27e2c9..64c5860 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -33,7 +33,9 @@ int cmd_general_authenticate() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data + 2, (uint16_t)(apdu.nc - 2), &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data + 2, (uint16_t)(apdu.nc - 2), &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before pubkey_len = tag_len + 1; diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index 33c3b81..cf19cb3 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -49,7 +49,9 @@ int cmd_initialize() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { //options file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); flash_write_data_to_file(tf, tag_data, tag_len); diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 7b3b1a3..6a88b85 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -31,31 +31,21 @@ int cmd_keypair_gen() { } int ret = 0; - uint16_t tout = 0; //sc_asn1_print_tags(apdu.data, apdu.nc); - uint8_t *p = NULL; //DEBUG_DATA(apdu.data,apdu.nc); - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { - uint16_t oid_len = 0; - uint8_t *oid = NULL; - if (asn1_find_tag(p, tout, 0x6, &oid_len, &oid) && oid_len > 0 && oid != NULL) { - if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { //RSA - uint16_t ex_len = 3, ks_len = 2; - uint8_t *ex = NULL, *ks = NULL; + asn1_ctx_t ctxi, ctxo = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x7f49, &ctxo) && asn1_len(&ctxo) > 0) { + asn1_ctx_t oid = { 0 }; + if (asn1_find_tag(&ctxo, 0x6, &oid) && asn1_len(&oid) > 0) { + if (memcmp(oid.data, OID_ID_TA_RSA_V1_5_SHA_256, oid.len) == 0) { //RSA + asn1_ctx_t ex = { 0 }, ks = { 0 }; uint32_t exponent = 65537, key_size = 2048; - if (asn1_find_tag(p, tout, 0x82, &ex_len, &ex) && ex_len > 0 && ex != NULL) { - uint8_t *dt = ex; - exponent = 0; - for (uint16_t i = 0; i < ex_len; i++) { - exponent = (exponent << 8) | *dt++; - } + if (asn1_find_tag(&ctxo, 0x82, &ex) && asn1_len(&ex) > 0) { + exponent = asn1_get_uint(&ex); } - if (asn1_find_tag(p, tout, 0x2, &ks_len, &ks) && ks_len > 0 && ks != NULL) { - uint8_t *dt = ks; - key_size = 0; - for (uint16_t i = 0; i < ks_len; i++) { - key_size = (key_size << 8) | *dt++; - } + if (asn1_find_tag(&ctxo, 0x2, &ks) && asn1_len(&ks) > 0) { + key_size = asn1_get_uint(&ks); } printf("KEYPAIR RSA %lu (%lx)\r\n", (unsigned long) key_size, @@ -79,13 +69,12 @@ int cmd_keypair_gen() { } mbedtls_rsa_free(&rsa); } - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC - uint16_t prime_len; - uint8_t *prime = NULL; - if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) { + else if (memcmp(oid.data, OID_ID_TA_ECDSA_SHA_256, MIN(oid.len, 10)) == 0) { //ECC + asn1_ctx_t prime = { 0 }; + if (asn1_find_tag(&ctxo, 0x81, &prime) != true) { return SW_WRONG_DATA(); } - mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime, prime_len); + mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime.data, prime.len); printf("KEYPAIR ECC %d\r\n", ec_id); if (ec_id == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); @@ -98,30 +87,27 @@ int cmd_keypair_gen() { mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - uint16_t l91 = 0, ext_len = 0; - uint8_t *p91 = NULL, *ext = NULL; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x91, &l91, &p91) && p91 != NULL && l91 > 0) { - for (size_t n = 0; n < l91; n++) { - if (p91[n] == ALGO_EC_DH_XKEK) { - uint16_t l92 = 0; - uint8_t *p92 = NULL; - if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x92, &l92, - &p92) || p92 == NULL || l92 == 0) { + asn1_ctx_t a91 = { 0 }, ext = { 0 }; + if (asn1_find_tag(&ctxi, 0x91, &a91) && asn1_len(&a91) > 0) { + for (size_t n = 0; n < a91.len; n++) { + if (a91.data[n] == ALGO_EC_DH_XKEK) { + asn1_ctx_t a92 = {0}; + if (!asn1_find_tag(&ctxi, 0x92, &a92) || asn1_len(&a92) == 0) { return SW_WRONG_DATA(); } - if (p92[0] > MAX_KEY_DOMAINS) { + if (a92.data[0] > MAX_KEY_DOMAINS) { return SW_WRONG_DATA(); } - file_t *tf_xkek = search_dynamic_file(EF_XKEK + p92[0]); + file_t *tf_xkek = search_dynamic_file(EF_XKEK + a92.data[0]); if (!tf_xkek) { return SW_WRONG_DATA(); } - ext_len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( + ext.len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( tf_xkek); - ext = (uint8_t *) calloc(1, ext_len); - uint8_t *pe = ext; + ext.data = (uint8_t *) calloc(1, ext.len); + uint8_t *pe = ext.data; *pe++ = 0x73; - *pe++ = (uint8_t)ext_len - 2; + *pe++ = (uint8_t)ext.len - 2; *pe++ = 0x6; *pe++ = (uint8_t)strlen(OID_ID_KEY_DOMAIN_UID); memcpy(pe, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)); @@ -133,15 +119,15 @@ int cmd_keypair_gen() { } } if ((res_APDU_size = - (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { - if (ext) { - free(ext); + (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext.data, ext.len)) == 0) { + if (ext.data) { + free(ext.data); } mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - if (ext) { - free(ext); + if (ext.data) { + free(ext.data); } ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id); mbedtls_ecdsa_free(&ecdsa); diff --git a/src/hsm/cmd_mse.c b/src/hsm/cmd_mse.c index e3ac568..f930494 100644 --- a/src/hsm/cmd_mse.c +++ b/src/hsm/cmd_mse.c @@ -34,7 +34,9 @@ int cmd_mse() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { if (p2 == 0xA4) { if (tag_len == 10 && diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index db928ee..b75eedb 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -152,8 +152,7 @@ int cmd_signature() { } return SW_EXEC_ERROR(); } - uint8_t *hash = apdu.data; - uint16_t hash_len = (uint16_t)apdu.nc; + asn1_ctx_t hash = {.len = (uint16_t)apdu.nc, .data = apdu.data}; if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached uint16_t nc = (uint16_t)apdu.nc; if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data, @@ -164,35 +163,34 @@ int cmd_signature() { } else { //sc_asn1_print_tags(apdu.data, apdu.nc); - uint16_t tout = 0, oid_len = 0; - uint8_t *p = NULL, *oid = NULL; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { - uint16_t tout30 = 0; - uint8_t *c30 = NULL; - if (asn1_find_tag(p, tout, 0x30, &tout30, &c30) && tout30 > 0 && c30 != NULL) { - asn1_find_tag(c30, tout30, 0x6, &oid_len, &oid); + asn1_ctx_t ctxi, ctxo = { 0 }, oid = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x30, &ctxo) && asn1_len(&ctxo) > 0) { + asn1_ctx_t a30 = { 0 }; + if (asn1_find_tag(&ctxo, 0x30, &a30) && asn1_len(&a30) > 0) { + asn1_find_tag(&a30, 0x6, &oid); } - asn1_find_tag(p, tout, 0x4, &hash_len, &hash); + asn1_find_tag(&ctxo, 0x4, &hash); } - if (oid && oid_len > 0) { - if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA1, oid_len) == 0) { + if (asn1_len(&oid)) { + if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA1, oid.len) == 0) { md = MBEDTLS_MD_SHA1; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA224, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA224, oid.len) == 0) { md = MBEDTLS_MD_SHA224; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA256, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA256, oid.len) == 0) { md = MBEDTLS_MD_SHA256; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA384, oid.len) == 0) { md = MBEDTLS_MD_SHA384; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA512, oid.len) == 0) { md = MBEDTLS_MD_SHA512; } } if (p2 >= ALGO_RSA_PSS && p2 <= ALGO_RSA_PSS_SHA512) { - if (p2 == ALGO_RSA_PSS && !oid) { + if (p2 == ALGO_RSA_PSS && asn1_len(&oid) == 0) { if (apdu.nc == 20) { //default is sha1 md = MBEDTLS_MD_SHA1; } @@ -220,7 +218,7 @@ int cmd_signature() { } else { uint8_t *signature = (uint8_t *) calloc(key_size, sizeof(uint8_t)); - r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hash, signature); + r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash.len, hash.data, signature); memcpy(res_APDU, signature, key_size); free(signature); } diff --git a/src/hsm/cmd_update_ef.c b/src/hsm/cmd_update_ef.c index 9fae86a..4b6ec18 100644 --- a/src/hsm/cmd_update_ef.c +++ b/src/hsm/cmd_update_ef.c @@ -49,7 +49,9 @@ int cmd_update_ef() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x54) { //ofset tag for (size_t i = 1; i <= tag_len; i++) { offset |= (*tag_data++ << (8 * (tag_len - i))); diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index 40c03a2..fcc722c 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -182,28 +182,25 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, valid_size = asn1_len_tag(0x5f24, 6) + asn1_len_tag(0x5f25, 6); } - uint8_t *car = NULL, *chr = NULL; - uint16_t lencar = 0, lenchr = 0; - - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x42, &lencar, - &car) == false || lencar == 0 || car == NULL) { - car = (uint8_t *) dev_name; - lencar = dev_name_len; + asn1_ctx_t ctxi, car = {0}, chr = {0}; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x42, &car) == false || asn1_len(&car) == 0) { + car.data = (uint8_t *) dev_name; + car.len = dev_name_len; if (dev_name == NULL) { - car = (uint8_t *)"ESPICOHSMTR00001"; - lencar = (uint16_t)strlen((const char *)car); + car.data = (uint8_t *)"ESPICOHSMTR00001"; + car.len = (uint16_t)strlen((const char *)car.data); } } - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x5f20, &lenchr, - &chr) == false || lenchr == 0 || chr == NULL) { - chr = (uint8_t *) dev_name; - lenchr = dev_name_len; - if (chr == NULL) { - chr = car; - lenchr = lencar; + if (asn1_find_tag(&ctxi, 0x5f20, &chr) == false || asn1_len(&chr) == 0) { + chr.data = (uint8_t *) dev_name; + chr.len = dev_name_len; + if (chr.data == NULL) { + chr.data = car.data; + chr.len = car.len; } } - uint16_t car_size = asn1_len_tag(0x42, lencar), chr_size = asn1_len_tag(0x5f20, lenchr); + uint16_t car_size = asn1_len_tag(0x42, car.len), chr_size = asn1_len_tag(0x5f20, chr.len); uint16_t tot_len = asn1_len_tag(0x7f4e, cpi_size + car_size + pubkey_size + chr_size + ext_size + role_size + valid_size); @@ -219,7 +216,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, //cpi *p++ = 0x5f; *p++ = 0x29; *p++ = 1; *p++ = 0; //car - *p++ = 0x42; p += format_tlv_len(lencar, p); memcpy(p, car, lencar); p += lencar; + *p++ = 0x42; p += format_tlv_len(car.len, p); memcpy(p, car.data, car.len); p += car.len; //pubkey if (key_type & PICO_KEYS_KEY_RSA) { p += asn1_cvc_public_key_rsa(rsa_ecdsa, p, pubkey_size); @@ -228,7 +225,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, p += asn1_cvc_public_key_ecdsa(rsa_ecdsa, p, pubkey_size); } //chr - *p++ = 0x5f; *p++ = 0x20; p += format_tlv_len(lenchr, p); memcpy(p, chr, lenchr); p += lenchr; + *p++ = 0x5f; *p++ = 0x20; p += format_tlv_len(chr.len, p); memcpy(p, chr.data, chr.len); p += chr.len; if (full) { *p++ = 0x7f; *p++ = 0x4c; @@ -580,14 +577,16 @@ uint16_t asn1_build_prkd_aes(const uint8_t *label, } const uint8_t *cvc_get_field(const uint8_t *data, uint16_t len, uint16_t *olen, uint16_t tag) { - uint8_t *rdata = NULL; - if (data == NULL || len == 0) { + asn1_ctx_t ctxi, ctxo = { 0 }; + asn1_ctx_init((uint8_t *)data, len, &ctxi); + if (asn1_len(&ctxi) == 0) { return NULL; } - if (asn1_find_tag(data, len, tag, olen, &rdata) == false) { + if (asn1_find_tag(&ctxi, tag, &ctxo) == false) { return NULL; } - return rdata; + *olen = ctxo.len; + return ctxo.data; } const uint8_t *cvc_get_body(const uint8_t *data, uint16_t len, uint16_t *olen) { diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 23cdfd2..70f7534 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -52,6 +52,7 @@ static int sc_hsm_unload(); extern int cmd_select(); extern void select_file(file_t *pe); extern int cmd_list_keys(); + extern int cmd_read_binary(); extern int cmd_verify(); extern int cmd_reset_retry(); @@ -230,7 +231,9 @@ void reset_puk_store() { if (fterm) { uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data; uint16_t fterm_data_len = file_get_size(fterm); - while (walk_tlv(fterm_data, fterm_data_len, &p, NULL, NULL, NULL)) { + asn1_ctx_t ctxi; + asn1_ctx_init(fterm_data, fterm_data_len, &ctxi); + while (walk_tlv(&ctxi, &p, NULL, NULL, NULL)) { add_cert_puk_store(pq, (uint16_t)(p - pq), false); pq = p; } @@ -424,7 +427,9 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, uint16_t *tag_len) { if (meta_size > 0 && meta_data != NULL) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - while (walk_tlv(meta_data, meta_size, &p, &tag, tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(meta_data, meta_size, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, tag_len, &tag_data)) { if (tag == meta_tag) { return tag_data; } @@ -469,7 +474,9 @@ uint32_t decrement_key_counter(file_t *fkey) { uint8_t *cmeta = (uint8_t *) calloc(1, meta_size); /* We cannot modify meta_data, as it comes from flash memory. It must be cpied to an aux buffer */ memcpy(cmeta, meta_data, meta_size); - while (walk_tlv(cmeta, meta_size, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(meta_data, meta_size, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x90) { // ofset tag uint32_t val = (tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3]; @@ -559,34 +566,31 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { } int find_and_store_meta_key(uint8_t key_id) { - uint16_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; - uint8_t *pt[4] = { NULL, NULL, NULL, NULL }; + uint16_t meta_size = 0; uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; + asn1_ctx_t ctxi, ctxo[4] = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); for (uint16_t t = 0; t < 4; t++) { - uint8_t *ptt = NULL; - uint16_t ltt = 0; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x90 + t, <t, &ptt) && ptt != NULL && ltt > 0) { - lt[t] = ltt; - pt[t] = ptt; - meta_size += asn1_len_tag(0x90 + t, lt[t]); + if (asn1_find_tag(&ctxi, 0x90 + t, &ctxo[t]) && asn1_len(&ctxo[t]) > 0) { + meta_size += asn1_len_tag(0x90 + t, ctxo[t].len); } } - if (lt[0] == 0 && pt[0] == NULL) { + if (asn1_len(&ctxo[0]) == 0) { uint16_t opts = get_device_options(); if (opts & HSM_OPT_KEY_COUNTER_ALL) { - lt[0] = 4; - pt[0] = t90; + ctxo[0].len = 4; + ctxo[0].data = t90; meta_size += 6; } } if (meta_size) { uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta; for (uint8_t t = 0; t < 4; t++) { - if (lt[t] > 0 && pt[t] != NULL) { + if (asn1_len(&ctxo[t]) > 0) { *m++ = 0x90 + t; - m += format_tlv_len(lt[t], m); - memcpy(m, pt[t], lt[t]); - m += lt[t]; + m += format_tlv_len(ctxo[t].len, m); + memcpy(m, ctxo[t].data, ctxo[t].len); + m += ctxo[t].len; } } int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size);