mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2024-09-20 03:10:09 +00:00
Use new asn1 structs.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
3ca23b932c
commit
c3b66773e8
@ -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
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit caddf87c236a068f94e5283e10b9411d1cfa39e0
|
||||
Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 &&
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)));
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user