Use new asn1 structs.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2024-03-13 18:11:28 +01:00
parent 3ca23b932c
commit c3b66773e8
13 changed files with 244 additions and 249 deletions

View File

@@ -89,7 +89,7 @@ target_compile_options(pico_hsm PUBLIC
-Wall -Wall
) )
if (NOT MSVC) if (NOT MSVC)
target_compile_options(pico_hsm PUBLIC target_compile_options(pico_hsm PUBLIC
-Werror -Werror
) )
endif() endif()
@@ -106,10 +106,10 @@ target_link_options(pico_hsm PUBLIC
-Wl,-dead_strip -Wl,-dead_strip
) )
elseif(MSVC) elseif(MSVC)
target_compile_options(pico_hsm PUBLIC target_compile_options(pico_hsm PUBLIC
-WX -WX
) )
target_link_libraries(pico_hsm PUBLIC wsock32 ws2_32 Bcrypt) target_link_libraries(pico_hsm PUBLIC wsock32 ws2_32 Bcrypt)
else() else()
target_link_options(pico_hsm PUBLIC target_link_options(pico_hsm PUBLIC

View File

@@ -160,7 +160,10 @@ int node_derive_path(const uint8_t *path,
int r = 0; int r = 0;
memset(last_node, 0, 4); memset(last_node, 0, 4);
memset(fingerprint, 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 (tag == 0x02) {
if ((node == 0 && tag_len != 1) || (node != 0 && tag_len != 4)) { if ((node == 0 && tag_len != 1) || (node != 0 && tag_len != 4)) {
return CCID_WRONG_DATA; return CCID_WRONG_DATA;

View File

@@ -269,20 +269,19 @@ int cmd_cipher_sym() {
res_APDU_size = (uint16_t)apdu.nc; res_APDU_size = (uint16_t)apdu.nc;
} }
else if (algo == ALGO_EXT_CIPHER_ENCRYPT || algo == ALGO_EXT_CIPHER_DECRYPT) { 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; asn1_ctx_t ctxi, oid = {0}, enc = {0}, iv = {0}, aad = {0};
uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x6, &oid_len, if (!asn1_find_tag(&ctxi, 0x6, &oid) || asn1_len(&oid) == 0) {
&oid) || oid_len == 0 || oid == NULL) {
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x81, &enc_len, &enc); asn1_find_tag(&ctxi, 0x81, &enc);
asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x82, &iv_len, &iv); asn1_find_tag(&ctxi, 0x82, &iv);
asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x83, &aad_len, &aad); asn1_find_tag(&ctxi, 0x83, &aad);
uint8_t tmp_iv[16]; uint8_t tmp_iv[16];
memset(tmp_iv, 0, sizeof(tmp_iv)); memset(tmp_iv, 0, sizeof(tmp_iv));
if (memcmp(oid, OID_CHACHA20_POLY1305, oid_len) == 0) { if (memcmp(oid.data, OID_CHACHA20_POLY1305, oid.len) == 0) {
if (algo == ALGO_EXT_CIPHER_DECRYPT && enc_len < 16) { if (algo == ALGO_EXT_CIPHER_DECRYPT && enc.len < 16) {
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
@@ -292,22 +291,22 @@ int cmd_cipher_sym() {
mbedtls_chachapoly_setkey(&ctx, kdata); mbedtls_chachapoly_setkey(&ctx, kdata);
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_chachapoly_encrypt_and_tag(&ctx, r = mbedtls_chachapoly_encrypt_and_tag(&ctx,
enc_len, enc.len,
iv ? iv : tmp_iv, asn1_len(&iv) > 0 ? iv.data : tmp_iv,
aad, aad.data,
aad_len, aad.len,
enc, enc.data,
res_APDU, res_APDU,
res_APDU + enc_len); res_APDU + enc.len);
} }
else if (algo == ALGO_EXT_CIPHER_DECRYPT) { else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_chachapoly_auth_decrypt(&ctx, r = mbedtls_chachapoly_auth_decrypt(&ctx,
enc_len - 16, enc.len - 16,
iv ? iv : tmp_iv, asn1_len(&iv) > 0 ? iv.data : tmp_iv,
aad, aad.data,
aad_len, aad.len,
enc + enc_len - 16, enc.data + enc.len - 16,
enc, enc.data,
res_APDU); res_APDU);
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
@@ -319,60 +318,60 @@ int cmd_cipher_sym() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { 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) { 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; 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); 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); 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); 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); 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); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
if (md_info == NULL) { if (md_info == NULL) {
return SW_WRONG_DATA(); 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)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = md_info->size; res_APDU_size = md_info->size;
} }
else if (memcmp(oid, OID_HKDF_SHA256, else if (memcmp(oid.data, OID_HKDF_SHA256,
oid_len) == 0 || oid.len) == 0 ||
memcmp(oid, OID_HKDF_SHA384, memcmp(oid.data, OID_HKDF_SHA384,
oid_len) == 0 || memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { oid.len) == 0 || memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) {
const mbedtls_md_info_t *md_info = NULL; 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); 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); 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); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
int r = mbedtls_hkdf(md_info, int r = mbedtls_hkdf(md_info,
iv, iv.data,
iv_len, iv.len,
kdata, kdata,
key_size, key_size,
enc, enc.data,
enc_len, enc.len,
res_APDU, res_APDU,
apdu.ne > 0 && apdu.ne > 0 &&
apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info)); 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); 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; int iterations = 0;
uint16_t keylen = 0; uint16_t keylen = 0;
mbedtls_asn1_buf salt, mbedtls_asn1_buf salt,
params = 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; mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
int r = pkcs5_parse_pbkdf2_params(&params, &salt, &iterations, &keylen, &md_type); int r = pkcs5_parse_pbkdf2_params(&params, &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); 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; size_t olen = 0;
mbedtls_asn1_buf params = 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(&params, int r = mbedtls_pkcs5_pbes2_ext(&params,
algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT,
kdata, kdata,
key_size, key_size,
enc, enc.data,
enc_len, enc.len,
res_APDU, 4096, &olen); res_APDU, 4096, &olen);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) { if (r != 0) {
@@ -428,28 +427,28 @@ int cmd_cipher_sym() {
} }
res_APDU_size = (uint16_t)olen; 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; 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; 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; 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; 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; 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; md_type = MBEDTLS_MD_SHA512;
} }
int r = mbedtls_ansi_x963_kdf(md_type, int r = mbedtls_ansi_x963_kdf(md_type,
key_size, key_size,
kdata, kdata,
aad_len, aad.len,
aad, aad.data,
apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32, apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32,
res_APDU); res_APDU);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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; res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32;
} }
else if (memcmp(oid, OID_NIST_AES, 8) == 0) { else if (memcmp(oid.data, OID_NIST_AES, 8) == 0) {
if (oid_len != 9) { if (oid.len != 9) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
uint8_t aes_algo = oid[8], uint8_t aes_algo = oid.data[8],
mode = mode =
(algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT);
if ((aes_algo >= 0x01 && aes_algo <= 0x09 && key_size != 16) || if ((aes_algo >= 0x01 && aes_algo <= 0x09 && key_size != 16) ||
@@ -473,9 +472,9 @@ int cmd_cipher_sym() {
mbedtls_aes_context ctx; mbedtls_aes_context ctx;
int r = 0; int r = 0;
mbedtls_aes_init(&ctx); mbedtls_aes_init(&ctx);
if (iv == NULL || iv_len == 0) { if (asn1_len(&iv) == 0) {
iv = tmp_iv; iv.data = tmp_iv;
iv_len = sizeof(tmp_iv); iv.len = sizeof(tmp_iv);
} }
if (aes_algo == 0x01 || aes_algo == 0x15 || aes_algo == 0x29) { /* ECB */ if (aes_algo == 0x01 || aes_algo == 0x15 || aes_algo == 0x29) { /* ECB */
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
@@ -485,12 +484,12 @@ int cmd_cipher_sym() {
r = mbedtls_aes_setkey_dec(&ctx, kdata, key_size * 8); r = mbedtls_aes_setkey_dec(&ctx, kdata, key_size * 8);
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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 */ else if (aes_algo == 0x02 || aes_algo == 0x16 || aes_algo == 0x2A) { /* CBC */
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
@@ -503,34 +502,34 @@ int cmd_cipher_sym() {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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 */ else if (aes_algo == 0x03 || aes_algo == 0x17 || aes_algo == 0x2B) { /* OFB */
size_t iv_off = 0; size_t iv_off = 0;
r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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 */ else if (aes_algo == 0x04 || aes_algo == 0x18 || aes_algo == 0x2C) { /* CFB */
size_t iv_off = 0; size_t iv_off = 0;
r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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 */ else if (aes_algo == 0x06 || aes_algo == 0x1A || aes_algo == 0x2E) { /* GCM */
mbedtls_aes_free(&ctx); // No AES ctx used mbedtls_aes_free(&ctx); // No AES ctx used
@@ -541,29 +540,29 @@ int cmd_cipher_sym() {
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_gcm_crypt_and_tag(&gctx, r = mbedtls_gcm_crypt_and_tag(&gctx,
MBEDTLS_GCM_ENCRYPT, MBEDTLS_GCM_ENCRYPT,
enc_len, enc.len,
iv, iv.data,
iv_len, iv.len,
aad, aad.data,
aad_len, aad.len,
enc, enc.data,
res_APDU, res_APDU,
16, 16,
res_APDU + enc_len); res_APDU + enc.len);
res_APDU_size = enc_len + 16; res_APDU_size = enc.len + 16;
} }
else if (algo == ALGO_EXT_CIPHER_DECRYPT) { else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_gcm_auth_decrypt(&gctx, r = mbedtls_gcm_auth_decrypt(&gctx,
enc_len - 16, enc.len - 16,
iv, iv.data,
iv_len, iv.len,
aad, aad.data,
aad_len, aad.len,
enc + enc_len - 16, enc.data + enc.len - 16,
16, 16,
enc, enc.data,
res_APDU); res_APDU);
res_APDU_size = enc_len - 16; res_APDU_size = enc.len - 16;
} }
mbedtls_gcm_free(&gctx); mbedtls_gcm_free(&gctx);
if (r != 0) { if (r != 0) {
@@ -575,12 +574,12 @@ int cmd_cipher_sym() {
uint8_t stream_block[16]; uint8_t stream_block[16];
r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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 */ else if (aes_algo == 0x07 || aes_algo == 0x1B || aes_algo == 0x2F) { /* CCM */
mbedtls_aes_free(&ctx); // No AES ctx used mbedtls_aes_free(&ctx); // No AES ctx used
@@ -590,35 +589,35 @@ int cmd_cipher_sym() {
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (iv_len == 16) { if (iv.len == 16) {
iv_len = 12; iv.len = 12;
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_ccm_encrypt_and_tag(&gctx, r = mbedtls_ccm_encrypt_and_tag(&gctx,
enc_len, enc.len,
iv, iv.data,
iv_len, iv.len,
aad, aad.data,
aad_len, aad.len,
enc, enc.data,
res_APDU, res_APDU,
res_APDU + enc_len, res_APDU + enc.len,
16); 16);
res_APDU_size = enc_len + 16; res_APDU_size = enc.len + 16;
} }
else if (algo == ALGO_EXT_CIPHER_DECRYPT) { else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_ccm_auth_decrypt(&gctx, r = mbedtls_ccm_auth_decrypt(&gctx,
enc_len - 16, enc.len - 16,
iv, iv.data,
iv_len, iv.len,
aad, aad.data,
aad_len, aad.len,
enc, enc.data,
res_APDU, res_APDU,
enc + enc_len - 16, enc.data + enc.len - 16,
16); 16);
res_APDU_size = enc_len - 16; res_APDU_size = enc.len - 16;
} }
mbedtls_ccm_free(&gctx); mbedtls_ccm_free(&gctx);
if (r != 0) { if (r != 0) {
@@ -626,18 +625,18 @@ int cmd_cipher_sym() {
} }
} }
} }
else if (memcmp(oid, OID_IEEE_ALG, 8) == 0) { else if (memcmp(oid.data, OID_IEEE_ALG, 8) == 0) {
if (oid_len != 9) { if (oid.len != 9) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
uint8_t aes_algo = oid[8], uint8_t aes_algo = oid.data[8],
mode = mode =
(algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT);
int r = 0; int r = 0;
memset(tmp_iv, 0, sizeof(tmp_iv)); memset(tmp_iv, 0, sizeof(tmp_iv));
if (iv == NULL || iv_len == 0) { if (asn1_len(&iv) == 0) {
iv = tmp_iv; iv.data = tmp_iv;
iv_len = sizeof(tmp_iv); iv.len = sizeof(tmp_iv);
} }
if ((aes_algo == 0x01 && key_size != 32) || (aes_algo == 0x02 && key_size != 64)) { if ((aes_algo == 0x01 && key_size != 32) || (aes_algo == 0x02 && key_size != 64)) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
@@ -651,14 +650,14 @@ int cmd_cipher_sym() {
r = mbedtls_aes_xts_setkey_dec(&ctx, kdata, key_size * 8); r = mbedtls_aes_xts_setkey_dec(&ctx, kdata, key_size * 8);
} }
mbedtls_platform_zeroize(kdata, sizeof(kdata)); 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); mbedtls_aes_xts_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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; mbedtls_aes_context ctx;
int r = 0; int r = 0;
uint8_t mode = uint8_t mode =
@@ -673,16 +672,16 @@ int cmd_cipher_sym() {
r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512),
kdata, kdata,
key_size, key_size,
aad, aad.data,
aad_len, aad.len,
secret); secret);
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (iv == tmp_iv || iv_len == 0) { if (iv.data == tmp_iv || iv.len == 0) {
iv = secret + 32; iv.data = secret + 32;
iv_len = 16; iv.len = 16;
} }
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
r = mbedtls_aes_setkey_enc(&ctx, secret, key_size * 8); r = mbedtls_aes_setkey_enc(&ctx, secret, key_size * 8);
@@ -693,12 +692,12 @@ int cmd_cipher_sym() {
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); 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); mbedtls_aes_free(&ctx);
if (r != 0) { if (r != 0) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = enc_len; res_APDU_size = enc.len;
mbedtls_ecdsa_free(&hd_context); mbedtls_ecdsa_free(&hd_context);
hd_keytype = 0; hd_keytype = 0;
} }

View File

@@ -152,34 +152,32 @@ int cmd_decrypt_asym() {
if ((ext = cvc_get_ext(apdu.data, (uint16_t)apdu.nc, &ext_len)) == NULL) { if ((ext = cvc_get_ext(apdu.data, (uint16_t)apdu.nc, &ext_len)) == NULL) {
return SW_WRONG_DATA(); 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 = 0;
uint16_t tag_len = 0, kdom_uid_len = 0; asn1_ctx_t ctxi, ctxo = { 0 }, kdom_uid = { 0 };
while (walk_tlv(ext, ext_len, &p, &tag, &tag_len, &tag_data)) { asn1_ctx_init((uint8_t *)ext, ext_len, &ctxi);
while (walk_tlv(&ctxi, &p, &tag, &ctxo.len, &ctxo.data)) {
if (tag == 0x73) { if (tag == 0x73) {
uint16_t oid_len = 0; asn1_ctx_t oid = {0};
uint8_t *oid_data = NULL; if (asn1_find_tag(&ctxo, 0x6, &oid) == true &&
if (asn1_find_tag(tag_data, tag_len, 0x6, &oid_len, oid.len == strlen(OID_ID_KEY_DOMAIN_UID) &&
&oid_data) == true && memcmp(oid.data, OID_ID_KEY_DOMAIN_UID,
oid_len == strlen(OID_ID_KEY_DOMAIN_UID) &&
memcmp(oid_data, OID_ID_KEY_DOMAIN_UID,
strlen(OID_ID_KEY_DOMAIN_UID)) == 0) { strlen(OID_ID_KEY_DOMAIN_UID)) == 0) {
if (asn1_find_tag(tag_data, tag_len, 0x80, &kdom_uid_len, if (asn1_find_tag(&ctxo, 0x80, &kdom_uid) == false) {
&kdom_uid) == false) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
break; break;
} }
} }
} }
if (kdom_uid_len == 0 || kdom_uid == NULL) { if (asn1_len(&kdom_uid) == 0) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) { for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) {
file_t *tf = search_dynamic_file(EF_XKEK + n); file_t *tf = search_dynamic_file(EF_XKEK + n);
if (tf) { if (tf) {
if (file_get_size(tf) == kdom_uid_len && if (file_get_size(tf) == kdom_uid.len &&
memcmp(file_get_data(tf), kdom_uid, kdom_uid_len) == 0) { memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) {
file_new(EF_DKEK + n); file_new(EF_DKEK + n);
if (store_dkek_key(n, res_APDU + 1) != CCID_OK) { if (store_dkek_key(n, res_APDU + 1) != CCID_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();

View File

@@ -33,7 +33,9 @@ int cmd_general_authenticate() {
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL; uint8_t *tag_data = NULL, *p = NULL;
uint16_t tag_len = 0; 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) { if (tag == 0x80) {
pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before
pubkey_len = tag_len + 1; pubkey_len = tag_len + 1;

View File

@@ -49,7 +49,9 @@ int cmd_initialize() {
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL; uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL;
uint16_t tag_len = 0; 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 if (tag == 0x80) { //options
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, tag_data, tag_len); flash_write_data_to_file(tf, tag_data, tag_len);

View File

@@ -31,31 +31,21 @@ int cmd_keypair_gen() {
} }
int ret = 0; int ret = 0;
uint16_t tout = 0;
//sc_asn1_print_tags(apdu.data, apdu.nc); //sc_asn1_print_tags(apdu.data, apdu.nc);
uint8_t *p = NULL;
//DEBUG_DATA(apdu.data,apdu.nc); //DEBUG_DATA(apdu.data,apdu.nc);
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { asn1_ctx_t ctxi, ctxo = { 0 };
uint16_t oid_len = 0; asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
uint8_t *oid = NULL; if (asn1_find_tag(&ctxi, 0x7f49, &ctxo) && asn1_len(&ctxo) > 0) {
if (asn1_find_tag(p, tout, 0x6, &oid_len, &oid) && oid_len > 0 && oid != NULL) { asn1_ctx_t oid = { 0 };
if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { //RSA if (asn1_find_tag(&ctxo, 0x6, &oid) && asn1_len(&oid) > 0) {
uint16_t ex_len = 3, ks_len = 2; if (memcmp(oid.data, OID_ID_TA_RSA_V1_5_SHA_256, oid.len) == 0) { //RSA
uint8_t *ex = NULL, *ks = NULL; asn1_ctx_t ex = { 0 }, ks = { 0 };
uint32_t exponent = 65537, key_size = 2048; uint32_t exponent = 65537, key_size = 2048;
if (asn1_find_tag(p, tout, 0x82, &ex_len, &ex) && ex_len > 0 && ex != NULL) { if (asn1_find_tag(&ctxo, 0x82, &ex) && asn1_len(&ex) > 0) {
uint8_t *dt = ex; exponent = asn1_get_uint(&ex);
exponent = 0;
for (uint16_t i = 0; i < ex_len; i++) {
exponent = (exponent << 8) | *dt++;
}
} }
if (asn1_find_tag(p, tout, 0x2, &ks_len, &ks) && ks_len > 0 && ks != NULL) { if (asn1_find_tag(&ctxo, 0x2, &ks) && asn1_len(&ks) > 0) {
uint8_t *dt = ks; key_size = asn1_get_uint(&ks);
key_size = 0;
for (uint16_t i = 0; i < ks_len; i++) {
key_size = (key_size << 8) | *dt++;
}
} }
printf("KEYPAIR RSA %lu (%lx)\r\n", printf("KEYPAIR RSA %lu (%lx)\r\n",
(unsigned long) key_size, (unsigned long) key_size,
@@ -79,13 +69,12 @@ int cmd_keypair_gen() {
} }
mbedtls_rsa_free(&rsa); mbedtls_rsa_free(&rsa);
} }
else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC else if (memcmp(oid.data, OID_ID_TA_ECDSA_SHA_256, MIN(oid.len, 10)) == 0) { //ECC
uint16_t prime_len; asn1_ctx_t prime = { 0 };
uint8_t *prime = NULL; if (asn1_find_tag(&ctxo, 0x81, &prime) != true) {
if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) {
return SW_WRONG_DATA(); 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); printf("KEYPAIR ECC %d\r\n", ec_id);
if (ec_id == MBEDTLS_ECP_DP_NONE) { if (ec_id == MBEDTLS_ECP_DP_NONE) {
return SW_FUNC_NOT_SUPPORTED(); return SW_FUNC_NOT_SUPPORTED();
@@ -98,30 +87,27 @@ int cmd_keypair_gen() {
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
uint16_t l91 = 0, ext_len = 0; asn1_ctx_t a91 = { 0 }, ext = { 0 };
uint8_t *p91 = NULL, *ext = NULL; if (asn1_find_tag(&ctxi, 0x91, &a91) && asn1_len(&a91) > 0) {
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x91, &l91, &p91) && p91 != NULL && l91 > 0) { for (size_t n = 0; n < a91.len; n++) {
for (size_t n = 0; n < l91; n++) { if (a91.data[n] == ALGO_EC_DH_XKEK) {
if (p91[n] == ALGO_EC_DH_XKEK) { asn1_ctx_t a92 = {0};
uint16_t l92 = 0; if (!asn1_find_tag(&ctxi, 0x92, &a92) || asn1_len(&a92) == 0) {
uint8_t *p92 = NULL;
if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x92, &l92,
&p92) || p92 == NULL || l92 == 0) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
if (p92[0] > MAX_KEY_DOMAINS) { if (a92.data[0] > MAX_KEY_DOMAINS) {
return SW_WRONG_DATA(); 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) { if (!tf_xkek) {
return SW_WRONG_DATA(); 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); tf_xkek);
ext = (uint8_t *) calloc(1, ext_len); ext.data = (uint8_t *) calloc(1, ext.len);
uint8_t *pe = ext; uint8_t *pe = ext.data;
*pe++ = 0x73; *pe++ = 0x73;
*pe++ = (uint8_t)ext_len - 2; *pe++ = (uint8_t)ext.len - 2;
*pe++ = 0x6; *pe++ = 0x6;
*pe++ = (uint8_t)strlen(OID_ID_KEY_DOMAIN_UID); *pe++ = (uint8_t)strlen(OID_ID_KEY_DOMAIN_UID);
memcpy(pe, OID_ID_KEY_DOMAIN_UID, 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 = if ((res_APDU_size =
(uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext.data, ext.len)) == 0) {
if (ext) { if (ext.data) {
free(ext); free(ext.data);
} }
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
if (ext) { if (ext.data) {
free(ext); free(ext.data);
} }
ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id); ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id);
mbedtls_ecdsa_free(&ecdsa); mbedtls_ecdsa_free(&ecdsa);

View File

@@ -34,7 +34,9 @@ int cmd_mse() {
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL; uint8_t *tag_data = NULL, *p = NULL;
uint16_t tag_len = 0; 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 (tag == 0x80) {
if (p2 == 0xA4) { if (p2 == 0xA4) {
if (tag_len == 10 && if (tag_len == 10 &&

View File

@@ -152,8 +152,7 @@ int cmd_signature() {
} }
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
uint8_t *hash = apdu.data; asn1_ctx_t hash = {.len = (uint16_t)apdu.nc, .data = apdu.data};
uint16_t hash_len = (uint16_t)apdu.nc;
if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached
uint16_t nc = (uint16_t)apdu.nc; uint16_t nc = (uint16_t)apdu.nc;
if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data, if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data,
@@ -164,35 +163,34 @@ int cmd_signature() {
} }
else { else {
//sc_asn1_print_tags(apdu.data, apdu.nc); //sc_asn1_print_tags(apdu.data, apdu.nc);
uint16_t tout = 0, oid_len = 0; asn1_ctx_t ctxi, ctxo = { 0 }, oid = { 0 };
uint8_t *p = NULL, *oid = NULL; asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { if (asn1_find_tag(&ctxi, 0x30, &ctxo) && asn1_len(&ctxo) > 0) {
uint16_t tout30 = 0; asn1_ctx_t a30 = { 0 };
uint8_t *c30 = NULL; if (asn1_find_tag(&ctxo, 0x30, &a30) && asn1_len(&a30) > 0) {
if (asn1_find_tag(p, tout, 0x30, &tout30, &c30) && tout30 > 0 && c30 != NULL) { asn1_find_tag(&a30, 0x6, &oid);
asn1_find_tag(c30, tout30, 0x6, &oid_len, &oid);
} }
asn1_find_tag(p, tout, 0x4, &hash_len, &hash); asn1_find_tag(&ctxo, 0x4, &hash);
} }
if (oid && oid_len > 0) { if (asn1_len(&oid)) {
if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA1, oid_len) == 0) { if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA1, oid.len) == 0) {
md = MBEDTLS_MD_SHA1; 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; 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; 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; 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; md = MBEDTLS_MD_SHA512;
} }
} }
if (p2 >= ALGO_RSA_PSS && p2 <= ALGO_RSA_PSS_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 if (apdu.nc == 20) { //default is sha1
md = MBEDTLS_MD_SHA1; md = MBEDTLS_MD_SHA1;
} }
@@ -220,7 +218,7 @@ int cmd_signature() {
} }
else { 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, hash, signature); r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash.len, hash.data, signature);
memcpy(res_APDU, signature, key_size); memcpy(res_APDU, signature, key_size);
free(signature); free(signature);
} }

View File

@@ -49,7 +49,9 @@ int cmd_update_ef() {
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL; uint8_t *tag_data = NULL, *p = NULL;
uint16_t tag_len = 0; 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 if (tag == 0x54) { //ofset tag
for (size_t i = 1; i <= tag_len; i++) { for (size_t i = 1; i <= tag_len; i++) {
offset |= (*tag_data++ << (8 * (tag_len - i))); offset |= (*tag_data++ << (8 * (tag_len - i)));

View File

@@ -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); valid_size = asn1_len_tag(0x5f24, 6) + asn1_len_tag(0x5f25, 6);
} }
uint8_t *car = NULL, *chr = NULL; asn1_ctx_t ctxi, car = {0}, chr = {0};
uint16_t lencar = 0, lenchr = 0; asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
if (asn1_find_tag(&ctxi, 0x42, &car) == false || asn1_len(&car) == 0) {
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x42, &lencar, car.data = (uint8_t *) dev_name;
&car) == false || lencar == 0 || car == NULL) { car.len = dev_name_len;
car = (uint8_t *) dev_name;
lencar = dev_name_len;
if (dev_name == NULL) { if (dev_name == NULL) {
car = (uint8_t *)"ESPICOHSMTR00001"; car.data = (uint8_t *)"ESPICOHSMTR00001";
lencar = (uint16_t)strlen((const char *)car); car.len = (uint16_t)strlen((const char *)car.data);
} }
} }
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x5f20, &lenchr, if (asn1_find_tag(&ctxi, 0x5f20, &chr) == false || asn1_len(&chr) == 0) {
&chr) == false || lenchr == 0 || chr == NULL) { chr.data = (uint8_t *) dev_name;
chr = (uint8_t *) dev_name; chr.len = dev_name_len;
lenchr = dev_name_len; if (chr.data == NULL) {
if (chr == NULL) { chr.data = car.data;
chr = car; chr.len = car.len;
lenchr = lencar;
} }
} }
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); 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 //cpi
*p++ = 0x5f; *p++ = 0x29; *p++ = 1; *p++ = 0; *p++ = 0x5f; *p++ = 0x29; *p++ = 1; *p++ = 0;
//car //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 //pubkey
if (key_type & PICO_KEYS_KEY_RSA) { if (key_type & PICO_KEYS_KEY_RSA) {
p += asn1_cvc_public_key_rsa(rsa_ecdsa, p, pubkey_size); 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); p += asn1_cvc_public_key_ecdsa(rsa_ecdsa, p, pubkey_size);
} }
//chr //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) { if (full) {
*p++ = 0x7f; *p++ = 0x7f;
*p++ = 0x4c; *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) { const uint8_t *cvc_get_field(const uint8_t *data, uint16_t len, uint16_t *olen, uint16_t tag) {
uint8_t *rdata = NULL; asn1_ctx_t ctxi, ctxo = { 0 };
if (data == NULL || len == 0) { asn1_ctx_init((uint8_t *)data, len, &ctxi);
if (asn1_len(&ctxi) == 0) {
return NULL; return NULL;
} }
if (asn1_find_tag(data, len, tag, olen, &rdata) == false) { if (asn1_find_tag(&ctxi, tag, &ctxo) == false) {
return NULL; 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) { const uint8_t *cvc_get_body(const uint8_t *data, uint16_t len, uint16_t *olen) {

View File

@@ -52,6 +52,7 @@ static int sc_hsm_unload();
extern int cmd_select(); extern int cmd_select();
extern void select_file(file_t *pe); extern void select_file(file_t *pe);
extern int cmd_list_keys(); extern int cmd_list_keys();
extern int cmd_read_binary(); extern int cmd_read_binary();
extern int cmd_verify(); extern int cmd_verify();
extern int cmd_reset_retry(); extern int cmd_reset_retry();
@@ -230,7 +231,9 @@ void reset_puk_store() {
if (fterm) { if (fterm) {
uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data; uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data;
uint16_t fterm_data_len = file_get_size(fterm); 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); add_cert_puk_store(pq, (uint16_t)(p - pq), false);
pq = p; 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) { if (meta_size > 0 && meta_data != NULL) {
uint16_t tag = 0x0; uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL; 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) { if (tag == meta_tag) {
return tag_data; return tag_data;
} }
@@ -469,7 +474,9 @@ uint32_t decrement_key_counter(file_t *fkey) {
uint8_t *cmeta = (uint8_t *) calloc(1, meta_size); 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 */ /* 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); 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 if (tag == 0x90) { // ofset tag
uint32_t val = uint32_t val =
(tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3]; (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) { int find_and_store_meta_key(uint8_t key_id) {
uint16_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; uint16_t meta_size = 0;
uint8_t *pt[4] = { NULL, NULL, NULL, NULL };
uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; 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++) { for (uint16_t t = 0; t < 4; t++) {
uint8_t *ptt = NULL; if (asn1_find_tag(&ctxi, 0x90 + t, &ctxo[t]) && asn1_len(&ctxo[t]) > 0) {
uint16_t ltt = 0; meta_size += asn1_len_tag(0x90 + t, ctxo[t].len);
if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x90 + t, &ltt, &ptt) && ptt != NULL && ltt > 0) {
lt[t] = ltt;
pt[t] = ptt;
meta_size += asn1_len_tag(0x90 + t, lt[t]);
} }
} }
if (lt[0] == 0 && pt[0] == NULL) { if (asn1_len(&ctxo[0]) == 0) {
uint16_t opts = get_device_options(); uint16_t opts = get_device_options();
if (opts & HSM_OPT_KEY_COUNTER_ALL) { if (opts & HSM_OPT_KEY_COUNTER_ALL) {
lt[0] = 4; ctxo[0].len = 4;
pt[0] = t90; ctxo[0].data = t90;
meta_size += 6; meta_size += 6;
} }
} }
if (meta_size) { if (meta_size) {
uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta; uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta;
for (uint8_t t = 0; t < 4; t++) { 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++ = 0x90 + t;
m += format_tlv_len(lt[t], m); m += format_tlv_len(ctxo[t].len, m);
memcpy(m, pt[t], lt[t]); memcpy(m, ctxo[t].data, ctxo[t].len);
m += lt[t]; m += ctxo[t].len;
} }
} }
int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size); int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size);