From daaa5bf402d5503596059b032d37488eb0b62bf6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 14 Feb 2023 23:13:46 +0100 Subject: [PATCH] Harmonize coding style. Signed-off-by: Pol Henarejos --- src/hsm/cmd_challenge.c | 8 +- src/hsm/cmd_change_pin.c | 20 +- src/hsm/cmd_cipher_sym.c | 279 +++++++++++------ src/hsm/cmd_decrypt_asym.c | 79 +++-- src/hsm/cmd_delete_file.c | 21 +- src/hsm/cmd_derive_asym.c | 42 +-- src/hsm/cmd_external_authenticate.c | 31 +- src/hsm/cmd_extras.c | 91 ++++-- src/hsm/cmd_general_authenticate.c | 21 +- src/hsm/cmd_initialize.c | 82 ++--- src/hsm/cmd_key_domain.c | 99 +++--- src/hsm/cmd_key_gen.c | 26 +- src/hsm/cmd_key_unwrap.c | 47 +-- src/hsm/cmd_key_wrap.c | 44 ++- src/hsm/cmd_keypair_gen.c | 66 ++-- src/hsm/cmd_list_keys.c | 6 +- src/hsm/cmd_mse.c | 36 ++- src/hsm/cmd_pso.c | 73 +++-- src/hsm/cmd_puk_auth.c | 45 +-- src/hsm/cmd_read_binary.c | 57 ++-- src/hsm/cmd_reset_retry.c | 57 ++-- src/hsm/cmd_select.c | 59 ++-- src/hsm/cmd_session_pin.c | 7 +- src/hsm/cmd_signature.c | 200 ++++++------ src/hsm/cmd_update_ef.c | 46 +-- src/hsm/cmd_verify.c | 33 +- src/hsm/cvc.c | 466 +++++++++++++++++++--------- src/hsm/cvc.h | 45 ++- src/hsm/files.c | 115 +++++-- src/hsm/files.h | 2 +- src/hsm/kek.c | 347 ++++++++++++++------- src/hsm/kek.h | 16 +- src/hsm/sc_hsm.c | 269 +++++++++------- src/hsm/sc_hsm.h | 54 ++-- src/hsm/version.h | 1 - 35 files changed, 1832 insertions(+), 1058 deletions(-) diff --git a/src/hsm/cmd_challenge.c b/src/hsm/cmd_challenge.c index 1fa5215..6d9fd31 100644 --- a/src/hsm/cmd_challenge.c +++ b/src/hsm/cmd_challenge.c @@ -21,10 +21,12 @@ uint8_t challenge[256]; uint8_t challenge_len = 0; -int cmd_challenge() { - uint8_t *rb = (uint8_t *)random_bytes_get(apdu.ne); - if (!rb) +int cmd_challenge() +{ + uint8_t *rb = (uint8_t *) random_bytes_get(apdu.ne); + if (!rb) { return SW_WRONG_LENGTH(); + } memcpy(res_APDU, rb, apdu.ne); challenge_len = MIN(apdu.ne, sizeof(challenge)); memcpy(challenge, rb, challenge_len); diff --git a/src/hsm/cmd_change_pin.c b/src/hsm/cmd_change_pin.c index df21ffd..4c84add 100644 --- a/src/hsm/cmd_change_pin.c +++ b/src/hsm/cmd_change_pin.c @@ -19,14 +19,16 @@ #include "sc_hsm.h" #include "kek.h" -int cmd_change_pin() { +int cmd_change_pin() +{ if (P1(apdu) == 0x0) { if (P2(apdu) == 0x81 || P2(apdu) == 0x88) { file_t *file_pin = NULL; - if (P2(apdu) == 0x81) + if (P2(apdu) == 0x81) { file_pin = file_pin1; - else if (P2(apdu) == 0x88) + } else if (P2(apdu) == 0x88) { file_pin = file_sopin; + } if (!file_pin) { return SW_FILE_NOT_FOUND(); } @@ -35,26 +37,28 @@ int cmd_change_pin() { } uint8_t pin_len = file_read_uint8(file_get_data(file_pin)); int r = check_pin(file_pin, apdu.data, pin_len); - if (r != 0x9000) + if (r != 0x9000) { return r; + } uint8_t mkek[MKEK_SIZE]; r = load_mkek(mkek); //loads the MKEK with old pin - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } //encrypt MKEK with new pin if (P2(apdu) == 0x81) { hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_pin); has_session_pin = true; - } - else if (P2(apdu) == 0x88) { + } else if (P2(apdu) == 0x88) { hash_multi(apdu.data+pin_len, apdu.nc-pin_len, session_sopin); has_session_sopin = true; } r = store_mkek(mkek); release_mkek(mkek); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } uint8_t dhash[33]; dhash[0] = apdu.nc-pin_len; double_hash_pin(apdu.data+pin_len, apdu.nc-pin_len, dhash+1); diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index 13e03d3..6a46e75 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -36,18 +36,19 @@ /* This is copied from pkcs5.c Mbedtls */ /** Unfortunately it is declared as static, so I cannot call it. **/ -static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, - mbedtls_asn1_buf *salt, int *iterations, - int *keylen, mbedtls_md_type_t *md_type ) +static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, + mbedtls_asn1_buf *salt, int *iterations, + int *keylen, mbedtls_md_type_t *md_type) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_asn1_buf prf_alg_oid; unsigned char *p = params->p; const unsigned char *end = params->p + params->len; - if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ); + if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG); + } /* * PBKDF2-params ::= SEQUENCE { * salt OCTET STRING, @@ -57,42 +58,57 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, * } * */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) ); + if ((ret = mbedtls_asn1_get_tag(&p, end, &salt->len, + MBEDTLS_ASN1_OCTET_STRING)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); + } salt->p = p; p += salt->len; - if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) ); - - if( p == end ) - return( 0 ); - - if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 ) { - if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) ); + if ((ret = mbedtls_asn1_get_int(&p, end, iterations)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); } - if( p == end ) - return( 0 ); + if (p == end) { + return 0; + } - if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) ); + if ((ret = mbedtls_asn1_get_int(&p, end, keylen)) != 0) { + if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); + } + } - if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 ) - return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + if (p == end) { + return 0; + } - if( p != end ) - return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) ); + if ((ret = mbedtls_asn1_get_alg_null(&p, end, &prf_alg_oid)) != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); + } - return( 0 ); + if (mbedtls_oid_get_md_hmac(&prf_alg_oid, md_type) != 0) { + return MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE; + } + + if (p != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } + + return 0; } /* Taken from https://github.com/Mbed-TLS/mbedtls/issues/2335 */ -int mbedtls_ansi_x936_kdf(mbedtls_md_type_t md_type, size_t input_len, uint8_t *input, size_t shared_info_len, uint8_t *shared_info, size_t output_len, uint8_t *output) { +int mbedtls_ansi_x936_kdf(mbedtls_md_type_t md_type, + size_t input_len, + uint8_t *input, + size_t shared_info_len, + uint8_t *shared_info, + size_t output_len, + uint8_t *output) +{ mbedtls_md_context_t md_ctx; const mbedtls_md_info_t *md_info = NULL; int hashlen = 0, exit_code = MBEDTLS_ERR_MD_BAD_INPUT_DATA; @@ -143,18 +159,23 @@ int mbedtls_ansi_x936_kdf(mbedtls_md_type_t md_type, size_t input_len, uint8_t * return 0; } -int cmd_cipher_sym() { +int cmd_cipher_sym() +{ int key_id = P1(apdu); int algo = P2(apdu); - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); - if (!ef) + if (!ef) { return SW_FILE_NOT_FOUND(); - if (key_has_purpose(ef, algo) == false) + } + if (key_has_purpose(ef, algo) == false) { return SW_CONDITIONS_NOT_SATISFIED(); - if (wait_button_pressed() == true) // timeout + } + if (wait_button_pressed() == true) { // timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); + } int key_size = file_get_size(ef); uint8_t kdata[32]; //maximum AES key size memcpy(kdata, file_get_data(ef), key_size); @@ -176,21 +197,30 @@ int cmd_cipher_sym() { mbedtls_aes_free(&aes); return SW_EXEC_ERROR(); } - r = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, apdu.nc, tmp_iv, apdu.data, res_APDU); + r = mbedtls_aes_crypt_cbc(&aes, + MBEDTLS_AES_ENCRYPT, + apdu.nc, + tmp_iv, + apdu.data, + res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { mbedtls_aes_free(&aes); return SW_EXEC_ERROR(); } - } - else if (algo == ALGO_AES_CBC_DECRYPT) { + } else if (algo == ALGO_AES_CBC_DECRYPT) { int r = mbedtls_aes_setkey_dec(&aes, kdata, key_size*8); if (r != 0) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_aes_free(&aes); return SW_EXEC_ERROR(); } - r = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, apdu.nc, tmp_iv, apdu.data, res_APDU); + r = mbedtls_aes_crypt_cbc(&aes, + MBEDTLS_AES_DECRYPT, + apdu.nc, + tmp_iv, + apdu.data, + res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { mbedtls_aes_free(&aes); @@ -199,36 +229,44 @@ int cmd_cipher_sym() { } res_APDU_size = apdu.nc; mbedtls_aes_free(&aes); - } - else if (algo == ALGO_AES_CMAC) { + } else if (algo == ALGO_AES_CMAC) { const mbedtls_cipher_info_t *cipher_info; - if (key_size == 16) + if (key_size == 16) { cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); - else if (key_size == 24) + } else if (key_size == 24) { cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_192_ECB); - else if (key_size == 32) + } else if (key_size == 32) { cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB); - else { + } else { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } int r = mbedtls_cipher_cmac(cipher_info, kdata, key_size*8, apdu.data, apdu.nc, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = 16; - } - else if (algo == ALGO_AES_DERIVE) { - int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, file_get_data(ef), key_size, apdu.data, apdu.nc, res_APDU, apdu.nc); + } else if (algo == ALGO_AES_DERIVE) { + int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), + NULL, + 0, + file_get_data(ef), + key_size, + apdu.data, + apdu.nc, + res_APDU, + apdu.nc); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = 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) { size_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, apdu.nc, 0x6, &oid_len, &oid) || oid_len == 0 || oid == NULL) { + if (!asn1_find_tag(apdu.data, apdu.nc, 0x6, &oid_len, + &oid) || oid_len == 0 || oid == NULL) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } @@ -246,57 +284,88 @@ int cmd_cipher_sym() { mbedtls_chachapoly_context ctx; mbedtls_chachapoly_init(&ctx); if (algo == ALGO_EXT_CIPHER_ENCRYPT) { - r = mbedtls_chachapoly_encrypt_and_tag(&ctx, enc_len, iv ? iv : tmp_iv, aad, aad_len, enc, res_APDU, 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, res_APDU); + r = mbedtls_chachapoly_encrypt_and_tag(&ctx, + enc_len, + iv ? iv : tmp_iv, + aad, + aad_len, + enc, + res_APDU, + 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, + res_APDU); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_chachapoly_free(&ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); - if (algo == ALGO_EXT_CIPHER_ENCRYPT) + } + if (algo == ALGO_EXT_CIPHER_ENCRYPT) { 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; - } - else if (memcmp(oid, OID_DIGEST, 7) == 0) { + } + } else if (memcmp(oid, OID_DIGEST, 7) == 0) { const mbedtls_md_info_t *md_info = NULL; - if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) + if (memcmp(oid, 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, 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, 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, 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, OID_HMAC_SHA512, oid_len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); - if (md_info == NULL) + } + if (md_info == NULL) { return SW_WRONG_DATA(); + } int r = mbedtls_md_hmac(md_info, kdata, key_size, apdu.data, apdu.nc, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - if (r != 0) + 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, OID_HKDF_SHA256, + oid_len) == 0 || + memcmp(oid, OID_HKDF_SHA384, + oid_len) == 0 || memcmp(oid, 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, 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, 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, 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, kdata, key_size, enc, enc_len, res_APDU, apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info)); + } + int r = mbedtls_hkdf(md_info, + iv, + iv_len, + kdata, + key_size, + enc, + enc_len, + res_APDU, + apdu.ne > 0 && + apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info)); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); - res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne :mbedtls_md_get_size(md_info); - } - else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { + } + res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info); + } else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { int iterations = 0, keylen = 0; - mbedtls_asn1_buf salt, params = { .p = enc, .len = enc_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; + mbedtls_asn1_buf salt, + params = + { .p = enc, .len = enc_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; mbedtls_md_context_t md_ctx; @@ -312,43 +381,63 @@ int cmd_cipher_sym() { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } - r = mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, kdata, key_size, salt.p, salt.len, iterations, keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32), res_APDU); + r = mbedtls_pkcs5_pbkdf2_hmac(&md_ctx, + kdata, + key_size, + salt.p, + salt.len, + iterations, + keylen ? keylen : (apdu.ne > 0 && + apdu.ne < 65536 ? apdu.ne : 32), + res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_md_free(&md_ctx); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32); - } - else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { - mbedtls_asn1_buf params = { .p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; - int r = mbedtls_pkcs5_pbes2(¶ms, algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, kdata, key_size, enc, enc_len, res_APDU); + } else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { + mbedtls_asn1_buf params = + { .p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; + int r = mbedtls_pkcs5_pbes2(¶ms, + algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, + kdata, + key_size, + enc, + enc_len, + res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_WRONG_DATA(); } res_APDU_size = enc_len; - } - else if (memcmp(oid, OID_KDF_X963, oid_len) == 0) { + } else if (memcmp(oid, 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, 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, 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, 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, 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, OID_HMAC_SHA512, enc_len) == 0) { md_type = MBEDTLS_MD_SHA512; - int r = mbedtls_ansi_x936_kdf(md_type, key_size, kdata, aad_len, aad, apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32, res_APDU); + } + int r = mbedtls_ansi_x936_kdf(md_type, + key_size, + kdata, + aad_len, + aad, + apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32, + res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_WRONG_DATA(); } res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32; } - } - else { + } else { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_P1P2(); } diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 6ade4df..73ff62c 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -26,56 +26,65 @@ #include "random.h" #include "oid.h" -int cmd_decrypt_asym() { +int cmd_decrypt_asym() +{ int key_id = P1(apdu); uint8_t p2 = P2(apdu); - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); - if (!ef) + if (!ef) { return SW_FILE_NOT_FOUND(); - if (get_key_counter(ef) == 0) + } + if (get_key_counter(ef) == 0) { return SW_FILE_FULL(); - if (key_has_purpose(ef, p2) == false) + } + if (key_has_purpose(ef, p2) == false) { return SW_CONDITIONS_NOT_SATISFIED(); + } if (p2 >= ALGO_RSA_DECRYPT && p2 <= ALGO_RSA_DECRYPT_OEP) { mbedtls_rsa_context ctx; mbedtls_rsa_init(&ctx); - if (p2 == ALGO_RSA_DECRYPT_OEP) + if (p2 == ALGO_RSA_DECRYPT_OEP) { mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256); + } int r = load_private_key_rsa(&ctx, ef); if (r != CCID_OK) { mbedtls_rsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } int key_size = file_get_size(ef); - if (apdu.nc < key_size) //needs padding + if (apdu.nc < key_size) { //needs padding memset(apdu.data+apdu.nc, 0, key_size-apdu.nc); + } if (p2 == ALGO_RSA_DECRYPT_PKCS1 || p2 == ALGO_RSA_DECRYPT_OEP) { size_t olen = apdu.nc; r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data, res_APDU, 512); - if (r == 0) + if (r == 0) { res_APDU_size = olen; - } - else { + } + } else { r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU); - if (r == 0) + if (r == 0) { res_APDU_size = key_size; + } } if (r != 0) { mbedtls_rsa_free(&ctx); return SW_EXEC_ERROR(); } mbedtls_rsa_free(&ctx); - } - else if (p2 == ALGO_EC_DH || p2 == ALGO_EC_DH_XKEK) { + } else if (p2 == ALGO_EC_DH || p2 == ALGO_EC_DH_XKEK) { mbedtls_ecdh_context ctx; - if (wait_button_pressed() == true) //timeout + if (wait_button_pressed() == true) { //timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); + } int key_size = file_get_size(ef); - uint8_t *kdata = (uint8_t *)calloc(1,key_size); + uint8_t *kdata = (uint8_t *) calloc(1, key_size); memcpy(kdata, file_get_data(ef), key_size); if (mkek_decrypt(kdata, key_size) != 0) { mbedtls_platform_zeroize(kdata, key_size); @@ -100,9 +109,9 @@ int cmd_decrypt_asym() { return SW_DATA_INVALID(); } r = -1; - if (p2 == ALGO_EC_DH) + if (p2 == ALGO_EC_DH) { r = mbedtls_ecdh_read_public(&ctx, apdu.data-1, apdu.nc+1); - else if (p2 == ALGO_EC_DH_XKEK) { + } else if (p2 == ALGO_EC_DH_XKEK) { size_t pub_len = 0; const uint8_t *pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len); if (pub) { @@ -118,19 +127,22 @@ int cmd_decrypt_asym() { return SW_DATA_INVALID(); } size_t olen = 0; - r = mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); + r = + mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU, MBEDTLS_ECP_MAX_BYTES, random_gen, + NULL); mbedtls_ecdh_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - if (p2 == ALGO_EC_DH) + if (p2 == ALGO_EC_DH) { res_APDU_size = olen; - else { + } else { res_APDU_size = 0; size_t ext_len = 0; const uint8_t *ext = NULL; - if ((ext = cvc_get_ext(apdu.data, apdu.nc, &ext_len)) == NULL) + if ((ext = cvc_get_ext(apdu.data, apdu.nc, &ext_len)) == NULL) { return SW_WRONG_DATA(); + } uint8_t *p = NULL, *tag_data = NULL, *kdom_uid = NULL; uint16_t tag = 0; size_t tag_len = 0, kdom_uid_len = 0; @@ -138,31 +150,40 @@ int cmd_decrypt_asym() { if (tag == 0x73) { size_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, 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(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, + strlen(OID_ID_KEY_DOMAIN_UID)) == 0) { + if (asn1_find_tag(tag_data, tag_len, 0x80, &kdom_uid_len, + &kdom_uid) == false) { return SW_WRONG_DATA(); + } break; } } } - if (kdom_uid_len == 0 || kdom_uid == NULL) + if (kdom_uid_len == 0 || kdom_uid == NULL) { return SW_WRONG_DATA(); + } for (int 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, kdom_uid_len) == 0) { file_new(EF_DKEK+n); - if (store_dkek_key(n, res_APDU) != CCID_OK) + if (store_dkek_key(n, res_APDU) != CCID_OK) { return SW_EXEC_ERROR(); + } return SW_OK(); } } } return SW_REFERENCE_NOT_FOUND(); } - } - else + } else { return SW_WRONG_P1P2(); + } decrement_key_counter(ef); return SW_OK(); } diff --git a/src/hsm/cmd_delete_file.c b/src/hsm/cmd_delete_file.c index 3b69e78..8659f48 100644 --- a/src/hsm/cmd_delete_file.c +++ b/src/hsm/cmd_delete_file.c @@ -17,24 +17,29 @@ #include "sc_hsm.h" -int cmd_delete_file() { +int cmd_delete_file() +{ file_t *ef = NULL; - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } if (apdu.nc == 0) { ef = currentEF; - if (!(ef = search_dynamic_file(ef->fid))) + if (!(ef = search_dynamic_file(ef->fid))) { return SW_FILE_NOT_FOUND(); - } - else { + } + } else { uint16_t fid = (apdu.data[0] << 8) | apdu.data[1]; - if (!(ef = search_dynamic_file(fid))) + if (!(ef = search_dynamic_file(fid))) { return SW_FILE_NOT_FOUND(); + } } - if (!authenticate_action(ef, ACL_OP_DELETE_SELF)) + if (!authenticate_action(ef, ACL_OP_DELETE_SELF)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (delete_file(ef) != CCID_OK) + } + if (delete_file(ef) != CCID_OK) { return SW_EXEC_ERROR(); + } return SW_OK(); } diff --git a/src/hsm/cmd_derive_asym.c b/src/hsm/cmd_derive_asym.c index 3eb2121..8bf604e 100644 --- a/src/hsm/cmd_derive_asym.c +++ b/src/hsm/cmd_derive_asym.c @@ -22,33 +22,38 @@ #include "cvc.h" #define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E -#define MOD_ADD( N ) \ - while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) -static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp, - mbedtls_mpi *X, - const mbedtls_mpi *A, - const mbedtls_mpi *B ) +#define MOD_ADD(N) \ + while (mbedtls_mpi_cmp_mpi(&(N), &grp->P) >= 0) \ + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&(N), &(N), &grp->P)) +static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp, + mbedtls_mpi *X, + const mbedtls_mpi *A, + const mbedtls_mpi *B) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) ); - MOD_ADD( *X ); + MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B)); + MOD_ADD(*X); cleanup: - return( ret ); + return ret; } -int cmd_derive_asym() { +int cmd_derive_asym() +{ uint8_t key_id = P1(apdu); uint8_t dest_id = P2(apdu); file_t *fkey; - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) + } + if (!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) { return SW_FILE_NOT_FOUND(); - if (key_has_purpose(fkey, ALGO_EC_DERIVE) == false) + } + if (key_has_purpose(fkey, ALGO_EC_DERIVE) == false) { return SW_CONDITIONS_NOT_SATISFIED(); - if (apdu.nc == 0) + } + if (apdu.nc == 0) { return SW_WRONG_LENGTH(); + } if (apdu.data[0] == ALGO_EC_DERIVE) { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); @@ -57,8 +62,9 @@ int cmd_derive_asym() { r = load_private_key_ecdsa(&ctx, fkey); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } mbedtls_mpi a, nd; @@ -90,8 +96,8 @@ int cmd_derive_asym() { return SW_EXEC_ERROR(); } mbedtls_ecdsa_free(&ctx); - } - else + } else { return SW_WRONG_DATA(); + } return SW_OK(); } diff --git a/src/hsm/cmd_external_authenticate.c b/src/hsm/cmd_external_authenticate.c index c7b9798..5bbccaa 100644 --- a/src/hsm/cmd_external_authenticate.c +++ b/src/hsm/cmd_external_authenticate.c @@ -24,29 +24,42 @@ extern file_t *ef_puk_aut; extern uint8_t challenge[256]; extern uint8_t challenge_len; -int cmd_external_authenticate() { - if (P1(apdu) != 0x0 || P2(apdu) != 0x0) +int cmd_external_authenticate() +{ + if (P1(apdu) != 0x0 || P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); - if (ef_puk_aut == NULL) + } + if (ef_puk_aut == NULL) { return SW_REFERENCE_NOT_FOUND(); - if (apdu.nc == 0) + } + if (apdu.nc == 0) { return SW_WRONG_LENGTH(); + } file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); - if (!file_has_data(ef_puk)) + if (!file_has_data(ef_puk)) { return SW_FILE_NOT_FOUND(); + } uint8_t *puk_data = file_get_data(ef_puk); - uint8_t *input = (uint8_t *)calloc(dev_name_len+challenge_len, sizeof(uint8_t)), hash[32]; + uint8_t *input = (uint8_t *) calloc(dev_name_len+challenge_len, sizeof(uint8_t)), hash[32]; memcpy(input, dev_name, dev_name_len); memcpy(input+dev_name_len, challenge, challenge_len); hash256(input, dev_name_len+challenge_len, hash); - int r = puk_verify(apdu.data, apdu.nc, hash, 32, file_get_data(ef_puk_aut), file_get_size(ef_puk_aut)); + int r = + puk_verify(apdu.data, + apdu.nc, + hash, + 32, + file_get_data(ef_puk_aut), + file_get_size(ef_puk_aut)); free(input); - if (r != 0) + if (r != 0) { return SW_CONDITIONS_NOT_SATISFIED(); + } puk_status[ef_puk_aut->fid & (MAX_PUK-1)] = 1; uint8_t auts = 0; - for (int i = 0; i < puk_data[0]; i++) + for (int i = 0; i < puk_data[0]; i++) { auts += puk_status[i]; + } if (auts >= puk_data[2]) { isUserAuthenticated = true; } diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index c46a520..b04d5f0 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -27,15 +27,18 @@ #include "mbedtls/hkdf.h" #include "mbedtls/chachapoly.h" -int cmd_extras() { +int cmd_extras() +{ if (P1(apdu) == 0xA) { //datetime operations - if (P2(apdu) != 0x0) + if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); + } if (apdu.nc == 0) { #ifndef ENABLE_EMULATION datetime_t dt; - if (!rtc_get_datetime(&dt)) + if (!rtc_get_datetime(&dt)) { return SW_EXEC_ERROR(); + } res_APDU[res_APDU_size++] = dt.year >> 8; res_APDU[res_APDU_size++] = dt.year & 0xff; res_APDU[res_APDU_size++] = dt.month; @@ -45,10 +48,10 @@ int cmd_extras() { res_APDU[res_APDU_size++] = dt.min; res_APDU[res_APDU_size++] = dt.sec; #endif - } - else { - if (apdu.nc != 8) + } else { + if (apdu.nc != 8) { return SW_WRONG_LENGTH(); + } #ifndef ENABLE_EMULATION datetime_t dt; dt.year = (apdu.data[0] << 8) | (apdu.data[1]); @@ -58,29 +61,29 @@ int cmd_extras() { dt.hour = apdu.data[5]; dt.min = apdu.data[6]; dt.sec = apdu.data[7]; - if (!rtc_set_datetime(&dt)) + if (!rtc_set_datetime(&dt)) { return SW_WRONG_DATA(); + } #endif } - } - else if (P1(apdu) == 0x6) { //dynamic options - if (P2(apdu) != 0x0) + } else if (P1(apdu) == 0x6) { //dynamic options + if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); - if (apdu.nc > sizeof(uint8_t)) + } + if (apdu.nc > sizeof(uint8_t)) { return SW_WRONG_LENGTH(); + } uint16_t opts = get_device_options(); if (apdu.nc == 0) { res_APDU[res_APDU_size++] = opts >> 8; res_APDU[res_APDU_size++] = opts & 0xff; - } - else { + } else { uint8_t newopts[] = { apdu.data[0], (opts & 0xff) }; file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); flash_write_data_to_file(tf, newopts, sizeof(newopts)); low_flash_available(); } - } - else if (P1(apdu) == 0x3A) { // secure lock + } else if (P1(apdu) == 0x3A) { // secure lock if (apdu.nc == 0) { return SW_WRONG_LENGTH(); } @@ -88,9 +91,16 @@ int cmd_extras() { mbedtls_ecdh_context hkey; mbedtls_ecdh_init(&hkey); mbedtls_ecdh_setup(&hkey, MBEDTLS_ECP_DP_SECP256R1); - int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.d, &hkey.ctx.mbed_ecdh.Q, random_gen, NULL); + int ret = mbedtls_ecdh_gen_public(&hkey.ctx.mbed_ecdh.grp, + &hkey.ctx.mbed_ecdh.d, + &hkey.ctx.mbed_ecdh.Q, + random_gen, + NULL); mbedtls_mpi_lset(&hkey.ctx.mbed_ecdh.Qp.Z, 1); - ret = mbedtls_ecp_point_read_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Qp, apdu.data, apdu.nc); + ret = mbedtls_ecp_point_read_binary(&hkey.ctx.mbed_ecdh.grp, + &hkey.ctx.mbed_ecdh.Qp, + apdu.data, + apdu.nc); if (ret != 0) { mbedtls_ecdh_free(&hkey); return SW_WRONG_DATA(); @@ -99,30 +109,48 @@ int cmd_extras() { uint8_t buf[MBEDTLS_ECP_MAX_BYTES]; size_t olen = 0; - ret = mbedtls_ecdh_calc_secret(&hkey, &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); + ret = mbedtls_ecdh_calc_secret(&hkey, + &olen, + buf, + MBEDTLS_ECP_MAX_BYTES, + random_gen, + NULL); if (ret != 0) { mbedtls_ecdh_free(&hkey); mbedtls_platform_zeroize(buf, sizeof(buf)); return SW_WRONG_DATA(); } - ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), NULL, 0, buf, olen, mse.Qpt, sizeof(mse.Qpt), mse.key_enc, sizeof(mse.key_enc)); + ret = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), + NULL, + 0, + buf, + olen, + mse.Qpt, + sizeof(mse.Qpt), + mse.key_enc, + sizeof(mse.key_enc)); mbedtls_platform_zeroize(buf, sizeof(buf)); if (ret != 0) { mbedtls_ecdh_free(&hkey); return SW_EXEC_ERROR(); } - ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096); + ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, + &hkey.ctx.mbed_ecdh.Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &olen, + res_APDU, + 4096); mbedtls_ecdh_free(&hkey); if (ret != 0) { return SW_EXEC_ERROR(); } mse.init = true; res_APDU_size = olen; - } - else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) { - if (mse.init == false) + } else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) { + if (mse.init == false) { return SW_COMMAND_NOT_ALLOWED(); + } int ret = mse_decrypt_ct(apdu.data, apdu.nc); if (ret != 0) { @@ -131,12 +159,13 @@ int cmd_extras() { if (P2(apdu) == 0x02 || P2(apdu) == 0x04) { // Enable uint16_t opts = get_device_options(); uint8_t newopts[] = { opts >> 8, (opts & 0xff) }; - if ((P2(apdu) == 0x02 && !(opts & HSM_OPT_SECURE_LOCK)) || (P2(apdu) == 0x04 && (opts & HSM_OPT_SECURE_LOCK))) { + if ((P2(apdu) == 0x02 && !(opts & HSM_OPT_SECURE_LOCK)) || + (P2(apdu) == 0x04 && (opts & HSM_OPT_SECURE_LOCK))) { uint16_t tfids[] = { EF_MKEK, EF_MKEK_SO }; for (int t = 0; t < sizeof(tfids)/sizeof(uint16_t); t++) { file_t *tf = search_by_fid(tfids[t], NULL, SPECIFY_EF); if (tf) { - uint8_t *tmp = (uint8_t *)calloc(1, file_get_size(tf)); + uint8_t *tmp = (uint8_t *) calloc(1, file_get_size(tf)); memcpy(tmp, file_get_data(tf), file_get_size(tf)); for (int i = 0; i < MKEK_KEY_SIZE; i++) { MKEK_KEY(tmp)[i] ^= apdu.data[i]; @@ -146,21 +175,21 @@ int cmd_extras() { } } } - if (P2(apdu) == 0x02) + if (P2(apdu) == 0x02) { newopts[0] |= HSM_OPT_SECURE_LOCK >> 8; - else if (P2(apdu) == 0x04) + } else if (P2(apdu) == 0x04) { newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8; + } file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); flash_write_data_to_file(tf, newopts, sizeof(newopts)); low_flash_available(); - } - else if (P2(apdu) == 0x03) { + } else if (P2(apdu) == 0x03) { memcpy(mkek_mask, apdu.data, apdu.nc); has_mkek_mask = true; } } - } - else + } else { return SW_INCORRECT_P1P2(); + } return SW_OK(); } diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index 6d1620a..7933fe5 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -24,7 +24,8 @@ #include "eac.h" #include "files.h" -int cmd_general_authenticate() { +int cmd_general_authenticate() +{ if (P1(apdu) == 0x0 && P2(apdu) == 0x0) { if (apdu.data[0] == 0x7C) { int r = 0; @@ -40,8 +41,9 @@ int cmd_general_authenticate() { } } file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); - if (!fkey) + if (!fkey) { return SW_EXEC_ERROR(); + } mbedtls_ecdsa_context ectx; mbedtls_ecdsa_init(&ectx); r = load_private_key_ecdsa(&ectx, fkey); @@ -71,7 +73,12 @@ int cmd_general_authenticate() { } size_t olen = 0; uint8_t derived[MBEDTLS_ECP_MAX_BYTES]; - r = mbedtls_ecdh_calc_secret(&ctx, &olen, derived, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); + r = mbedtls_ecdh_calc_secret(&ctx, + &olen, + derived, + MBEDTLS_ECP_MAX_BYTES, + random_gen, + NULL); mbedtls_ecdh_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); @@ -79,10 +86,11 @@ int cmd_general_authenticate() { sm_derive_all_keys(derived, olen); - uint8_t *t = (uint8_t *)calloc(1, pubkey_len+16); + uint8_t *t = (uint8_t *) calloc(1, pubkey_len+16); memcpy(t, "\x7F\x49\x4F\x06\x0A", 5); - if (sm_get_protocol() == MSE_AES) + if (sm_get_protocol() == MSE_AES) { memcpy(t+5, OID_ID_CA_ECDH_AES_CBC_CMAC_128, 10); + } t[15] = 0x86; memcpy(t+16, pubkey, pubkey_len); @@ -98,8 +106,9 @@ int cmd_general_authenticate() { r = sm_sign(t, pubkey_len+16, res_APDU+res_APDU_size); free(t); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } res_APDU_size += 8; } } diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index 70057ac..9b1c6f2 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -27,7 +27,8 @@ extern void scan_all(); extern char __StackLimit; -int heapLeft() { +int heapLeft() +{ #ifndef ENABLE_EMULATION char *p = malloc(256); // try to avoid undue fragmentation int left = &__StackLimit - p; @@ -38,7 +39,8 @@ int heapLeft() { return left; } -int cmd_initialize() { +int cmd_initialize() +{ if (apdu.nc > 0) { uint8_t mkek[MKEK_SIZE]; int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session @@ -52,8 +54,7 @@ int cmd_initialize() { 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); - } - else if (tag == 0x81) { //user pin + } else if (tag == 0x81) { //user pin if (file_pin1 && file_pin1->data) { uint8_t dhash[33]; dhash[0] = tag_len; @@ -62,8 +63,7 @@ int cmd_initialize() { hash_multi(tag_data, tag_len, session_pin); has_session_pin = true; } - } - else if (tag == 0x82) { //sopin pin + } else if (tag == 0x82) { //sopin pin if (file_sopin && file_sopin->data) { uint8_t dhash[33]; dhash[0] = tag_len; @@ -72,8 +72,7 @@ int cmd_initialize() { hash_multi(tag_data, tag_len, session_sopin); has_session_sopin = true; } - } - else if (tag == 0x91) { //retries user pin + } else if (tag == 0x91) { //retries user pin file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF); if (tf && tf->data) { flash_write_data_to_file(tf, tag_data, tag_len); @@ -81,8 +80,7 @@ int cmd_initialize() { if (file_retries_pin1 && file_retries_pin1->data) { flash_write_data_to_file(file_retries_pin1, tag_data, tag_len); } - } - else if (tag == 0x92) { + } else if (tag == 0x92) { dkeks = tag_data; file_t *tf = file_new(EF_DKEK); if (!tf) { @@ -90,14 +88,13 @@ int cmd_initialize() { return SW_MEMORY_FAILURE(); } flash_write_data_to_file(tf, NULL, 0); - } - else if (tag == 0x93) { + } else if (tag == 0x93) { file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); if (!ef_puk) { release_mkek(mkek); return SW_MEMORY_FAILURE(); } - uint8_t pk_status[4], puks = MIN(tag_data[0],MAX_PUK); + uint8_t pk_status[4], puks = MIN(tag_data[0], MAX_PUK); memset(pk_status, 0, sizeof(pk_status)); pk_status[0] = puks; pk_status[1] = puks; @@ -111,17 +108,16 @@ int cmd_initialize() { } flash_write_data_to_file(tf, NULL, 0); } - } - else if (tag == 0x97) { + } else if (tag == 0x97) { kds = tag_data; /* - for (int i = 0; i < MIN(*kds,MAX_KEY_DOMAINS); i++) { + for (int i = 0; i < MIN(*kds,MAX_KEY_DOMAINS); i++) { file_t *tf = file_new(EF_DKEK+i); if (!tf) return SW_MEMORY_FAILURE(); flash_write_data_to_file(tf, NULL, 0); - } - */ + } + */ } } file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF); @@ -129,8 +125,9 @@ int cmd_initialize() { release_mkek(mkek); return SW_EXEC_ERROR(); } - if (ret_mkek != CCID_OK) + if (ret_mkek != CCID_OK) { ret_mkek = load_mkek(mkek); //Try again with new PIN/SO-PIN just in case some is the same + } if (store_mkek(ret_mkek == CCID_OK ? mkek : NULL) != CCID_OK) { release_mkek(mkek); return SW_EXEC_ERROR(); @@ -139,35 +136,39 @@ int cmd_initialize() { if (dkeks) { if (*dkeks > 0) { uint16_t d = *dkeks; - if (flash_write_data_to_file(tf_kd, (const uint8_t *)&d, sizeof(d)) != CCID_OK) + if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); - } - else { + } + } else { int r = save_dkek_key(0, random_bytes_get(32)); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } uint16_t d = 0x0101; - if (flash_write_data_to_file(tf_kd, (const uint8_t *)&d, sizeof(d)) != CCID_OK) + if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); + } } - } - else { + } else { uint16_t d = 0x0000; - if (flash_write_data_to_file(tf_kd, (const uint8_t *)&d, sizeof(d)) != CCID_OK) + if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); + } } if (kds) { - uint8_t t[MAX_KEY_DOMAINS*2], k = MIN(*kds,MAX_KEY_DOMAINS); + uint8_t t[MAX_KEY_DOMAINS*2], k = MIN(*kds, MAX_KEY_DOMAINS); memset(t, 0xff, 2*k); - if (flash_write_data_to_file(tf_kd, t, 2*k) != CCID_OK) + if (flash_write_data_to_file(tf_kd, t, 2*k) != CCID_OK) { return SW_EXEC_ERROR(); + } } /* When initialized, it has all credentials */ isUserAuthenticated = true; /* Create terminal private key */ file_t *fdkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); - if (!fdkey) + if (!fdkey) { return SW_EXEC_ERROR(); + } int ret = 0; if (ret_mkek != CCID_OK || !file_has_data(fdkey)) { mbedtls_ecdsa_context ecdsa; @@ -193,19 +194,28 @@ int cmd_initialize() { file_t *fpk = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF); ret = flash_write_data_to_file(fpk, res_APDU, cvc_len); - if (ret != 0) + if (ret != 0) { return SW_EXEC_ERROR(); + } - const uint8_t *keyid = (const uint8_t *)"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", *label = (const uint8_t *)"ESTERMHSM"; - size_t prkd_len = asn1_build_prkd_ecc(label, strlen((const char *)label), keyid, 20, 192, res_APDU, 4096); + const uint8_t *keyid = + (const uint8_t *) "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", + *label = (const uint8_t *) "ESTERMHSM"; + size_t prkd_len = asn1_build_prkd_ecc(label, + strlen((const char *) label), + keyid, + 20, + 192, + res_APDU, + 4096); fpk = search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF); ret = flash_write_data_to_file(fpk, res_APDU, prkd_len); } - if (ret != 0) + if (ret != 0) { return SW_EXEC_ERROR(); + } low_flash_available(); - } - else { //free memory bytes request + } else { //free memory bytes request int heap_left = heapLeft(); res_APDU[0] = ((heap_left >> 24) & 0xff); res_APDU[1] = ((heap_left >> 16) & 0xff); diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index e32db5d..aa28317 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -21,36 +21,47 @@ #include "kek.h" #include "files.h" -uint8_t get_key_domain(file_t *fkey) { +uint8_t get_key_domain(file_t *fkey) +{ size_t tag_len = 0; const uint8_t *meta_tag = get_meta_tag(fkey, 0x92, &tag_len); - if (meta_tag) + if (meta_tag) { return *meta_tag; + } return 0xff; } -int cmd_key_domain() { +int cmd_key_domain() +{ //if (dkeks == 0) // return SW_COMMAND_NOT_ALLOWED(); uint8_t p1 = P1(apdu), p2 = P2(apdu); - if ((has_session_pin == false || isUserAuthenticated == false) && apdu.nc > 0 && !(p1 == 0x0 && p2 == 0x0)) + if ((has_session_pin == false || isUserAuthenticated == false) && apdu.nc > 0 && + !(p1 == 0x0 && p2 == 0x0)) { return SW_CONDITIONS_NOT_SATISFIED(); - if (p2 >= MAX_KEY_DOMAINS) + } + if (p2 >= MAX_KEY_DOMAINS) { return SW_WRONG_P1P2(); + } file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF); - if (!tf_kd) + if (!tf_kd) { return SW_EXEC_ERROR(); + } uint16_t tf_kd_size = file_get_size(tf_kd); - if (tf_kd_size == 0) + if (tf_kd_size == 0) { return SW_WRONG_P1P2(); - uint8_t *kdata = file_get_data(tf_kd), dkeks = kdata ? kdata[2*p2] : 0, current_dkeks = kdata ? kdata[2*p2+1] : 0; + } + uint8_t *kdata = file_get_data(tf_kd), dkeks = kdata ? kdata[2*p2] : 0, + current_dkeks = kdata ? kdata[2*p2+1] : 0; if (p1 == 0x0) { //dkek import if (apdu.nc > 0) { file_t *tf = file_new(EF_DKEK+p2); - if (!tf) + if (!tf) { return SW_MEMORY_FAILURE(); - if (apdu.nc < 32) + } + if (apdu.nc < 32) { return SW_WRONG_LENGTH(); + } if (current_dkeks == dkeks) { return SW_COMMAND_NOT_ALLOWED(); } @@ -65,25 +76,28 @@ int cmd_key_domain() { uint8_t t[MAX_KEY_DOMAINS*2]; memcpy(t, kdata, tf_kd_size); t[2*p2+1] = current_dkeks; - if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) + if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) { return SW_EXEC_ERROR(); + } low_flash_available(); - } - else { + } else { file_t *tf = search_dynamic_file(EF_XKEK+p2); - if (2*p2 >= tf_kd_size) + if (2*p2 >= tf_kd_size) { return SW_INCORRECT_P1P2(); - if (current_dkeks == 0xff && !tf) //XKEK have always 0xff + } + if (current_dkeks == 0xff && !tf) { //XKEK have always 0xff return SW_REFERENCE_NOT_FOUND(); + } } - } - else if (p1 == 0x1 || p1 == 0x3 || p1 == 0x4) { //key domain setup - if (p1 == 0x1 && apdu.nc != 1) + } else if (p1 == 0x1 || p1 == 0x3 || p1 == 0x4) { //key domain setup + if (p1 == 0x1 && apdu.nc != 1) { return SW_WRONG_LENGTH(); + } if (p1 == 0x3) { //if key domain is not empty, command is denied for (int i = 0; i < dynamic_files; i++) { - if (get_key_domain(&dynamic_file[i]) == p2) + if (get_key_domain(&dynamic_file[i]) == p2) { return SW_FILE_EXISTS(); + } } } uint8_t t[MAX_KEY_DOMAINS*2]; @@ -91,57 +105,64 @@ int cmd_key_domain() { if (p1 == 0x1) { t[2*p2] = dkeks = apdu.data[0]; t[2*p2+1] = current_dkeks = 0; - } - else if (p1 == 0x3) { + } else if (p1 == 0x3) { t[2*p2] = dkeks = 0xff; t[2*p2+1] = 0xff; - } - else if (p1 == 0x4) { + } else if (p1 == 0x4) { t[2*p2+1] = current_dkeks = 0; } - if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) + if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) { return SW_EXEC_ERROR(); + } file_t *tf = NULL; if ((tf = search_dynamic_file(EF_DKEK+p2))) { - if (delete_file(tf) != CCID_OK) + if (delete_file(tf) != CCID_OK) { return SW_EXEC_ERROR(); + } } if (p1 == 0x3 && (tf = search_dynamic_file(EF_XKEK+p2))) { - if (delete_file(tf) != CCID_OK) + if (delete_file(tf) != CCID_OK) { return SW_EXEC_ERROR(); + } } low_flash_available(); - if (p1 == 0x3) + if (p1 == 0x3) { return SW_REFERENCE_NOT_FOUND(); - } - else if (p1 == 0x2) { //XKEK Key Domain creation + } + } else if (p1 == 0x2) { //XKEK Key Domain creation if (apdu.nc > 0) { size_t pub_len = 0; file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); - if (!fterm) + if (!fterm) { return SW_EXEC_ERROR(); + } const uint8_t *pub = cvc_get_pub(file_get_data(fterm), file_get_size(fterm), &pub_len); - if (!pub) + if (!pub) { return SW_EXEC_ERROR(); + } size_t t86_len = 0; const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); - if (!t86 || t86[0] != 0x4) + if (!t86 || t86[0] != 0x4) { return SW_EXEC_ERROR(); + } size_t t54_len = 0; const uint8_t *t54 = cvc_get_field(apdu.data, apdu.nc, &t54_len, 0x54); - if (!t54) + if (!t54) { return SW_WRONG_DATA(); - uint8_t hash[32], *input = (uint8_t *)calloc(1, (t86_len-1)/2+1); + } + uint8_t hash[32], *input = (uint8_t *) calloc(1, (t86_len-1)/2+1); input[0] = 0x54; memcpy(input+1, t86+1, (t86_len-1)/2); hash256(input, (t86_len-1)/2+1, hash); free(input); int r = puk_verify(t54, t54_len, hash, 32, apdu.data, apdu.nc); - if (r != 0) + if (r != 0) { return SW_CONDITIONS_NOT_SATISFIED(); + } file_t *tf = file_new(EF_XKEK+p2); - if (!tf) + if (!tf) { return SW_MEMORY_FAILURE(); + } //All checks done. Get Key Domain UID pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len); @@ -154,10 +175,10 @@ int cmd_key_domain() { } } } - } - else + } else { return SW_INCORRECT_P1P2(); - memset(res_APDU,0,10); + } + memset(res_APDU, 0, 10); res_APDU[0] = dkeks; res_APDU[1] = dkeks > current_dkeks ? dkeks-current_dkeks : 0; dkek_kcv(p2, res_APDU+2); diff --git a/src/hsm/cmd_key_gen.c b/src/hsm/cmd_key_gen.c index 949ddb6..9551895 100644 --- a/src/hsm/cmd_key_gen.c +++ b/src/hsm/cmd_key_gen.c @@ -19,34 +19,40 @@ #include "sc_hsm.h" #include "random.h" -int cmd_key_gen() { +int cmd_key_gen() +{ uint8_t key_id = P1(apdu); uint8_t p2 = P2(apdu); uint8_t key_size = 32; int r; - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (p2 == 0xB2) + } + if (p2 == 0xB2) { key_size = 32; - else if (p2 == 0xB1) + } else if (p2 == 0xB1) { key_size = 24; - else if (p2 == 0xB0) + } else if (p2 == 0xB0) { key_size = 16; + } //at this moment, we do not use the template, as only CBC is supported by the driver (encrypt, decrypt and CMAC) uint8_t aes_key[32]; //maximum AES key size memcpy(aes_key, random_bytes_get(key_size), key_size); int aes_type = 0x0; - if (key_size == 16) + if (key_size == 16) { aes_type = HSM_KEY_AES_128; - else if (key_size == 24) + } else if (key_size == 24) { aes_type = HSM_KEY_AES_192; - else if (key_size == 32) + } else if (key_size == 32) { aes_type = HSM_KEY_AES_256; + } r = store_keys(aes_key, aes_type, key_id); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); - if (find_and_store_meta_key(key_id) != CCID_OK) + } + if (find_and_store_meta_key(key_id) != CCID_OK) { return SW_EXEC_ERROR(); + } low_flash_available(); return SW_OK(); } diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index a6712ed..82167a5 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -20,17 +20,21 @@ #include "kek.h" #include "cvc.h" -int cmd_key_unwrap() { +int cmd_key_unwrap() +{ int key_id = P1(apdu), r = 0; - if (P2(apdu) != 0x93) + if (P2(apdu) != 0x93) { return SW_WRONG_P1P2(); - if (!isUserAuthenticated) + } + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } int key_type = dkek_type_key(apdu.data); uint8_t kdom = -1, *allowed = NULL; size_t allowed_len = 0; - if (key_type == 0x0) + if (key_type == 0x0) { return SW_DATA_INVALID(); + } if (key_type == HSM_KEY_RSA) { mbedtls_rsa_context ctx; mbedtls_rsa_init(&ctx); @@ -50,13 +54,12 @@ int cmd_key_unwrap() { if (r != CCID_OK) { return SW_EXEC_ERROR(); } - } - else if (key_type == HSM_KEY_EC) { + } else if (key_type == HSM_KEY_EC) { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); do { r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL, &allowed, &allowed_len); - } while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); + } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); @@ -70,24 +73,30 @@ int cmd_key_unwrap() { if (r != CCID_OK) { return SW_EXEC_ERROR(); } - } - else if (key_type == HSM_KEY_AES) { + } else if (key_type == HSM_KEY_AES) { uint8_t aes_key[32]; int key_size = 0, aes_type = 0; do { - r = dkek_decode_key(++kdom, aes_key, apdu.data, apdu.nc, &key_size, &allowed, &allowed_len); - } while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); + r = dkek_decode_key(++kdom, + aes_key, + apdu.data, + apdu.nc, + &key_size, + &allowed, + &allowed_len); + } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { return SW_EXEC_ERROR(); } - if (key_size == 32) + if (key_size == 32) { aes_type = HSM_KEY_AES_256; - else if (key_size == 24) + } else if (key_size == 24) { aes_type = HSM_KEY_AES_192; - else if (key_size == 16) + } else if (key_size == 16) { aes_type = HSM_KEY_AES_128; - else + } else { return SW_EXEC_ERROR(); + } r = store_keys(aes_key, aes_type, key_id); if (r != CCID_OK) { return SW_EXEC_ERROR(); @@ -95,7 +104,7 @@ int cmd_key_unwrap() { } if ((allowed != NULL && allowed_len > 0) || kdom >= 0) { size_t meta_len = (allowed_len > 0 ? 2+allowed_len : 0) + (kdom >= 0 ? 3 : 0); - uint8_t *meta = (uint8_t *)calloc(1,meta_len), *m = meta; + uint8_t *meta = (uint8_t *) calloc(1, meta_len), *m = meta; if (allowed_len > 0) { *m++ = 0x91; *m++ = allowed_len; @@ -108,14 +117,16 @@ int cmd_key_unwrap() { } r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_len); free(meta); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } } if (res_APDU_size > 0) { file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id); r = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); - if (r != 0) + if (r != 0) { return SW_EXEC_ERROR(); + } low_flash_available(); res_APDU_size = 0; } diff --git a/src/hsm/cmd_key_wrap.c b/src/hsm/cmd_key_wrap.c index 0f96bed..3c90e5b 100644 --- a/src/hsm/cmd_key_wrap.c +++ b/src/hsm/cmd_key_wrap.c @@ -22,21 +22,28 @@ extern uint8_t get_key_domain(file_t *fkey); -int cmd_key_wrap() { +int cmd_key_wrap() +{ int key_id = P1(apdu), r = 0; - if (P2(apdu) != 0x92) + if (P2(apdu) != 0x92) { return SW_WRONG_P1P2(); - if (!isUserAuthenticated) + } + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); + printf("%d %p\n", key_id, ef); uint8_t kdom = get_key_domain(ef); - if (!ef) + if (!ef) { return SW_FILE_NOT_FOUND(); - if (key_has_purpose(ef, ALGO_WRAP) == false) + } + if (key_has_purpose(ef, ALGO_WRAP) == false) { return SW_CONDITIONS_NOT_SATISFIED(); + } file_t *prkd = search_dynamic_file((PRKD_PREFIX << 8) | key_id); - if (!prkd) + if (!prkd) { return SW_FILE_NOT_FOUND(); + } const uint8_t *dprkd = file_get_data(prkd); size_t wrap_len = MAX_DKEK_ENCODE_KEY_BUFFER; size_t tag_len = 0; @@ -47,47 +54,50 @@ int cmd_key_wrap() { r = load_private_key_rsa(&ctx, ef); if (r != CCID_OK) { mbedtls_rsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len); mbedtls_rsa_free(&ctx); - } - else if (*dprkd == P15_KEYTYPE_ECC) { + } else if (*dprkd == P15_KEYTYPE_ECC) { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); r = load_private_key_ecdsa(&ctx, ef); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len); mbedtls_ecdsa_free(&ctx); - } - else if (*dprkd == P15_KEYTYPE_AES) { + } else if (*dprkd == P15_KEYTYPE_AES) { uint8_t kdata[32]; //maximum AES key size - if (wait_button_pressed() == true) //timeout + if (wait_button_pressed() == true) { //timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); + } int key_size = file_get_size(ef), aes_type = HSM_KEY_AES; memcpy(kdata, file_get_data(ef), key_size); if (mkek_decrypt(kdata, key_size) != 0) { return SW_EXEC_ERROR(); } - if (key_size == 32) + if (key_size == 32) { aes_type = HSM_KEY_AES_256; - else if (key_size == 24) + } else if (key_size == 24) { aes_type = HSM_KEY_AES_192; - else if (key_size == 16) + } else if (key_size == 16) { aes_type = HSM_KEY_AES_128; + } r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len, meta_tag, tag_len); mbedtls_platform_zeroize(kdata, sizeof(kdata)); } - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } res_APDU_size = wrap_len; return SW_OK(); } diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index ba497ac..8422868 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -24,15 +24,18 @@ #include "random.h" #include "kek.h" -int cmd_keypair_gen() { +int cmd_keypair_gen() +{ uint8_t key_id = P1(apdu); - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } int ret = 0; size_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, apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { size_t oid_len = 0; uint8_t *oid = NULL; @@ -55,32 +58,35 @@ int cmd_keypair_gen() { key_size = (key_size << 8) | *dt++; } } - printf("KEYPAIR RSA %lu (%lx)\r\n",(unsigned long)key_size,(unsigned long)exponent); + printf("KEYPAIR RSA %lu (%lx)\r\n", + (unsigned long) key_size, + (unsigned long) exponent); mbedtls_rsa_context rsa; mbedtls_rsa_init(&rsa); uint8_t index = 0; ret = mbedtls_rsa_gen_key(&rsa, random_gen, &index, key_size, exponent); if (ret != 0) { - mbedtls_rsa_free(&rsa); + mbedtls_rsa_free(&rsa); return SW_EXEC_ERROR(); } - if ((res_APDU_size = asn1_cvc_aut(&rsa, HSM_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { + if ((res_APDU_size = + asn1_cvc_aut(&rsa, HSM_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { return SW_EXEC_ERROR(); } - ret = store_keys(&rsa, HSM_KEY_RSA, key_id); - if (ret != CCID_OK) { + ret = store_keys(&rsa, HSM_KEY_RSA, key_id); + if (ret != CCID_OK) { mbedtls_rsa_free(&rsa); return SW_EXEC_ERROR(); } mbedtls_rsa_free(&rsa); - } - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256,MIN(oid_len,10)) == 0) { //ECC + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC size_t prime_len; uint8_t *prime = NULL; - if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) + if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) { return SW_WRONG_DATA(); + } mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime, 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) { return SW_FUNC_NOT_SUPPORTED(); } @@ -99,15 +105,19 @@ int cmd_keypair_gen() { if (p91[n] == ALGO_EC_DH_XKEK) { size_t l92 = 0; uint8_t *p92 = NULL; - if (!asn1_find_tag(apdu.data, apdu.nc, 0x92, &l92, &p92) || p92 == NULL || l92 == 0) + if (!asn1_find_tag(apdu.data, apdu.nc, 0x92, &l92, + &p92) || p92 == NULL || l92 == 0) { return SW_WRONG_DATA(); - if (p92[0] > MAX_KEY_DOMAINS) + } + if (p92[0] > MAX_KEY_DOMAINS) { return SW_WRONG_DATA(); + } file_t *tf_xkek = search_dynamic_file(EF_XKEK+p92[0]); - if (!tf_xkek) + if (!tf_xkek) { return SW_WRONG_DATA(); + } ext_len = 2+2+strlen(OID_ID_KEY_DOMAIN_UID)+2+file_get_size(tf_xkek); - ext = (uint8_t *)calloc(1, ext_len); + ext = (uint8_t *) calloc(1, ext_len); uint8_t *pe = ext; *pe++ = 0x73; *pe++ = ext_len-2; @@ -121,33 +131,39 @@ int cmd_keypair_gen() { } } } - if ((res_APDU_size = asn1_cvc_aut(&ecdsa, HSM_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { - if (ext) + if ((res_APDU_size = + asn1_cvc_aut(&ecdsa, HSM_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { + if (ext) { free(ext); + } mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - if (ext) + if (ext) { free(ext); + } ret = store_keys(&ecdsa, HSM_KEY_EC, key_id); mbedtls_ecdsa_free(&ecdsa); - if (ret != CCID_OK) { + if (ret != CCID_OK) { return SW_EXEC_ERROR(); } } } - } - else + } else { return SW_WRONG_DATA(); - if (find_and_store_meta_key(key_id) != CCID_OK) + } + if (find_and_store_meta_key(key_id) != CCID_OK) { return SW_EXEC_ERROR(); + } file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id); ret = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); - if (ret != 0) + if (ret != 0) { return SW_EXEC_ERROR(); - //if (apdu.ne == 0) - // apdu.ne = res_APDU_size; + } + if (apdu.ne == 0) { + apdu.ne = res_APDU_size; + } low_flash_available(); return SW_OK(); } diff --git a/src/hsm/cmd_list_keys.c b/src/hsm/cmd_list_keys.c index 4d70e98..41f9169 100644 --- a/src/hsm/cmd_list_keys.c +++ b/src/hsm/cmd_list_keys.c @@ -33,16 +33,14 @@ int cmd_list_keys() //first CC for (int i = 0; i < dynamic_files; i++) { file_t *f = &dynamic_file[i]; - if ((f->fid & 0xff00) == (KEY_PREFIX << 8)) - { + if ((f->fid & 0xff00) == (KEY_PREFIX << 8)) { res_APDU[res_APDU_size++] = KEY_PREFIX; res_APDU[res_APDU_size++] = f->fid & 0xff; } } for (int i = 0; i < dynamic_files; i++) { file_t *f = &dynamic_file[i]; - if ((f->fid & 0xff00) == (PRKD_PREFIX << 8)) - { + if ((f->fid & 0xff00) == (PRKD_PREFIX << 8)) { res_APDU[res_APDU_size++] = PRKD_PREFIX; res_APDU[res_APDU_size++] = f->fid & 0xff; } diff --git a/src/hsm/cmd_mse.c b/src/hsm/cmd_mse.c index d0e3a69..501b0ec 100644 --- a/src/hsm/cmd_mse.c +++ b/src/hsm/cmd_mse.c @@ -24,11 +24,13 @@ file_t *ef_puk_aut = NULL; -int cmd_mse() { +int cmd_mse() +{ int p1 = P1(apdu); int p2 = P2(apdu); - if (p2 != 0xA4 && p2 != 0xA6 && p2 != 0xAA && p2 != 0xB4 && p2 != 0xB6 && p2 != 0xB8) + if (p2 != 0xA4 && p2 != 0xA6 && p2 != 0xAA && p2 != 0xB4 && p2 != 0xB6 && p2 != 0xB8) { return SW_INCORRECT_P1P2(); + } if (p1 & 0x1) { //SET uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; @@ -36,28 +38,32 @@ int cmd_mse() { while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { if (p2 == 0xA4) { - if (tag_len == 10 && memcmp(tag_data, OID_ID_CA_ECDH_AES_CBC_CMAC_128, tag_len) == 0) + if (tag_len == 10 && + memcmp(tag_data, OID_ID_CA_ECDH_AES_CBC_CMAC_128, tag_len) == 0) { sm_set_protocol(MSE_AES); + } } - } - else if (tag == 0x83) { + } else if (tag == 0x83) { if (tag_len == 1) { - } - else { + } else { if (p2 == 0xB6) { - if (puk_store_select_chr(tag_data) == CCID_OK) + if (puk_store_select_chr(tag_data) == CCID_OK) { return SW_OK(); - } - else if (p2 == 0xA4) { /* Aut */ + } + } else if (p2 == 0xA4) { /* Aut */ for (int i = 0; i < MAX_PUK; i++) { file_t *ef = search_dynamic_file(EF_PUK+i); - if (!ef) + if (!ef) { break; - if (!file_has_data(ef)) + } + if (!file_has_data(ef)) { break; + } size_t chr_len = 0; - const uint8_t *chr = cvc_get_chr(file_get_data(ef), file_get_size(ef), &chr_len); + const uint8_t *chr = cvc_get_chr(file_get_data(ef), + file_get_size(ef), + &chr_len); if (memcmp(chr, tag_data, chr_len) == 0) { ef_puk_aut = ef; return SW_OK(); @@ -68,8 +74,8 @@ int cmd_mse() { } } } - } - else + } else { return SW_INCORRECT_P1P2(); + } return SW_OK(); } diff --git a/src/hsm/cmd_pso.c b/src/hsm/cmd_pso.c index 48be4fb..f1f0d3e 100644 --- a/src/hsm/cmd_pso.c +++ b/src/hsm/cmd_pso.c @@ -23,13 +23,16 @@ extern int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy); extern PUK *current_puk; -int cmd_pso() { +int cmd_pso() +{ uint8_t p1 = P1(apdu), p2 = P2(apdu); if (p1 == 0x0 && (p2 == 0x92 || p2 == 0xAE || p2 == 0xBE)) { /* Verify certificate */ - if (apdu.nc == 0) + if (apdu.nc == 0) { return SW_WRONG_LENGTH(); - if (current_puk == NULL) + } + if (current_puk == NULL) { return SW_REFERENCE_NOT_FOUND(); + } if (apdu.data[0] != 0x7F || apdu.data[1] != 0x21) { uint8_t tlv_len = 2+format_tlv_len(apdu.nc, NULL); memmove(apdu.data+tlv_len, apdu.data, apdu.nc); @@ -39,10 +42,11 @@ int cmd_pso() { } int r = cvc_verify(apdu.data, apdu.nc, current_puk->cvcert, current_puk->cvcert_len); if (r != CCID_OK) { - if (r == CCID_WRONG_DATA) + if (r == CCID_WRONG_DATA) { return SW_DATA_INVALID(); - else if (r == CCID_WRONG_SIGNATURE) + } else if (r == CCID_WRONG_SIGNATURE) { return SW_CONDITIONS_NOT_SATISFIED(); + } return SW_EXEC_ERROR(); } for (int i = 0; i < 0xfe; i++) { @@ -51,27 +55,32 @@ int cmd_pso() { if (!ca_ef) { ca_ef = file_new(fid); flash_write_data_to_file(ca_ef, apdu.data, apdu.nc); - if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef), false) != CCID_OK) + if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef), + false) != CCID_OK) { return SW_FILE_FULL(); + } size_t chr_len = 0; const uint8_t *chr = cvc_get_chr(apdu.data, apdu.nc, &chr_len); - if (chr == NULL) + if (chr == NULL) { return SW_WRONG_DATA(); + } size_t puk_len = 0, puk_bin_len = 0; const uint8_t *puk = cvc_get_pub(apdu.data, apdu.nc, &puk_len), *puk_bin = NULL; - if (puk == NULL) + if (puk == NULL) { return SW_WRONG_DATA(); + } size_t oid_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); - if (oid == NULL) + if (oid == NULL) { return SW_WRONG_DATA(); + } if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA puk_bin = cvc_get_field(puk, puk_len, &puk_bin_len, 0x81); - if (!puk_bin) + if (!puk_bin) { return SW_WRONG_DATA(); - } - else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC + } + } else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC mbedtls_ecp_group_id ec_id = cvc_inherite_ec_group(apdu.data, apdu.nc); mbedtls_ecp_group grp; mbedtls_ecp_group_init(&grp); @@ -89,21 +98,18 @@ int cmd_pso() { } puk_bin = t86; puk_bin_len = t86_len; - } - else if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { + } else if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS) { if (t86[0] == 0x2 || t86[0] == 0x3) { if (t86_len != plen+1) { mbedtls_ecp_group_free(&grp); return SW_WRONG_DATA(); } - } - else if (t86[0] == 0x4) { + } else if (t86[0] == 0x4) { if (t86_len != 2*plen+1) { mbedtls_ecp_group_free(&grp); return SW_WRONG_DATA(); } - } - else { + } else { mbedtls_ecp_group_free(&grp); return SW_WRONG_DATA(); } @@ -111,26 +117,41 @@ int cmd_pso() { puk_bin_len = plen; } mbedtls_ecp_group_free(&grp); - if (!puk_bin) + if (!puk_bin) { return SW_WRONG_DATA(); + } } file_t *cd_ef = file_new((CD_PREFIX << 8) | i); - size_t cd_len = asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, fid, NULL, 0); - if (cd_len == 0) + size_t cd_len = asn1_build_cert_description(chr, + chr_len, + puk_bin, + puk_bin_len, + fid, + NULL, + 0); + if (cd_len == 0) { return SW_EXEC_ERROR(); - uint8_t *buf = (uint8_t *)calloc(cd_len, sizeof(uint8_t)); - int r = asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, fid, buf, cd_len); + } + uint8_t *buf = (uint8_t *) calloc(cd_len, sizeof(uint8_t)); + int r = asn1_build_cert_description(chr, + chr_len, + puk_bin, + puk_bin_len, + fid, + buf, + cd_len); flash_write_data_to_file(cd_ef, buf, cd_len); free(buf); - if (r == 0) + if (r == 0) { return SW_EXEC_ERROR(); + } low_flash_available(); break; } } return SW_OK(); - } - else + } else { return SW_INCORRECT_P1P2(); + } return SW_OK(); } diff --git a/src/hsm/cmd_puk_auth.c b/src/hsm/cmd_puk_auth.c index 47e6250..6240acc 100644 --- a/src/hsm/cmd_puk_auth.c +++ b/src/hsm/cmd_puk_auth.c @@ -19,53 +19,62 @@ #include "files.h" #include "cvc.h" -int cmd_puk_auth() { +int cmd_puk_auth() +{ uint8_t p1 = P1(apdu), p2 = P2(apdu); file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); - if (!file_has_data(ef_puk)) + if (!file_has_data(ef_puk)) { return SW_FILE_NOT_FOUND(); + } uint8_t *puk_data = file_get_data(ef_puk); if (apdu.nc > 0) { if (p1 == 0x0 || p1 == 0x1) { file_t *ef = NULL; if (p1 == 0x0) { /* Add */ - if (p2 != 0x0) + if (p2 != 0x0) { return SW_INCORRECT_P1P2(); + } for (int i = 0; i < puk_data[0]; i++) { ef = search_dynamic_file(EF_PUK+i); - if (!ef) /* Never should not happen */ + if (!ef) { /* Never should not happen */ return SW_MEMORY_FAILURE(); - if (!file_has_data(ef)) /* found first empty slot */ + } + if (!file_has_data(ef)) { /* found first empty slot */ break; + } } - uint8_t *tmp = (uint8_t *)calloc(file_get_size(ef_puk), sizeof(uint8_t)); + uint8_t *tmp = (uint8_t *) calloc(file_get_size(ef_puk), sizeof(uint8_t)); memcpy(tmp, puk_data, file_get_size(ef_puk)); tmp[1] = puk_data[1]-1; flash_write_data_to_file(ef_puk, tmp, file_get_size(ef_puk)); puk_data = file_get_data(ef_puk); free(tmp); - } - else if (p1 == 0x1) { /* Replace */ - if (p2 >= puk_data[0]) + } else if (p1 == 0x1) { /* Replace */ + if (p2 >= puk_data[0]) { return SW_INCORRECT_P1P2(); + } ef = search_dynamic_file(EF_PUK+p2); - if (!ef) /* Never should not happen */ + if (!ef) { /* Never should not happen */ return SW_MEMORY_FAILURE(); + } } flash_write_data_to_file(ef, apdu.data, apdu.nc); low_flash_available(); - } - else + } else { return SW_INCORRECT_P1P2(); + } } if (p1 == 0x2) { - if (p2 >= puk_data[0]) + if (p2 >= puk_data[0]) { return SW_INCORRECT_P1P2(); + } file_t *ef = search_dynamic_file(EF_PUK+p2); - if (!ef) + if (!ef) { return SW_INCORRECT_P1P2(); - if (!file_has_data(ef)) + } + if (!file_has_data(ef)) { return SW_REFERENCE_NOT_FOUND(); + } size_t chr_len = 0; const uint8_t *chr = cvc_get_chr(file_get_data(ef), file_get_size(ef), &chr_len); if (chr) { @@ -73,12 +82,12 @@ int cmd_puk_auth() { res_APDU_size = chr_len; } return set_res_sw(0x90, puk_status[p2]); - } - else { + } else { memcpy(res_APDU, puk_data, 3); res_APDU[3] = 0; - for (int i = 0; i < puk_data[0]; i++) + for (int i = 0; i < puk_data[0]; i++) { res_APDU[3] += puk_status[i]; + } res_APDU_size = 4; } return SW_OK(); diff --git a/src/hsm/cmd_read_binary.c b/src/hsm/cmd_read_binary.c index 48e2af8..d6d6bd9 100644 --- a/src/hsm/cmd_read_binary.c +++ b/src/hsm/cmd_read_binary.c @@ -17,42 +17,46 @@ #include "sc_hsm.h" -int cmd_read_binary() { +int cmd_read_binary() +{ uint16_t fid = 0x0; uint32_t offset = 0; uint8_t ins = INS(apdu), p1 = P1(apdu), p2 = P2(apdu); const file_t *ef = NULL; - if ((ins & 0x1) == 0) - { + if ((ins & 0x1) == 0) { if ((p1 & 0x80) != 0) { - if (!(ef = search_by_fid(p1&0x1f, NULL, SPECIFY_EF))) - return SW_FILE_NOT_FOUND (); + if (!(ef = search_by_fid(p1&0x1f, NULL, SPECIFY_EF))) { + return SW_FILE_NOT_FOUND(); + } offset = p2; - } - else { + } else { offset = make_uint16_t(p1, p2) & 0x7fff; ef = currentEF; } - } - else { + } else { if (p1 == 0 && (p2 & 0xE0) == 0 && (p2 & 0x1f) != 0 && (p2 & 0x1f) != 0x1f) { - if (!(ef = search_by_fid(p2&0x1f, NULL, SPECIFY_EF))) - return SW_FILE_NOT_FOUND (); - } - else { + if (!(ef = search_by_fid(p2&0x1f, NULL, SPECIFY_EF))) { + return SW_FILE_NOT_FOUND(); + } + } else { uint16_t file_id = make_uint16_t(p1, p2); // & 0x7fff; - if (file_id == 0x0) + if (file_id == 0x0) { ef = currentEF; - else if (!(ef = search_by_fid(file_id, NULL, SPECIFY_EF)) && !(ef = search_dynamic_file(file_id))) - return SW_FILE_NOT_FOUND (); + } else if (!(ef = + search_by_fid(file_id, NULL, + SPECIFY_EF)) && !(ef = search_dynamic_file(file_id))) { + return SW_FILE_NOT_FOUND(); + } - if (apdu.data[0] != 0x54) + if (apdu.data[0] != 0x54) { return SW_WRONG_DATA(); + } offset = 0; - for (int d = 0; d < apdu.data[1]; d++) + for (int d = 0; d < apdu.data[1]; d++) { offset |= apdu.data[2+d]<<(apdu.data[1]-1-d)*8; + } } } @@ -61,26 +65,29 @@ int cmd_read_binary() { } if (ef->data) { if ((ef->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) { - uint16_t data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *)ef, 1); //already copies content to res_APDU - if (offset > data_len) + uint16_t data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, 1); //already copies content to res_APDU + if (offset > data_len) { return SW_WRONG_P1P2(); + } uint16_t maxle = data_len-offset; - if (apdu.ne > maxle) + if (apdu.ne > maxle) { apdu.ne = maxle; + } if (offset) { memmove(res_APDU, res_APDU+offset, res_APDU_size-offset); //res_APDU += offset; res_APDU_size -= offset; } - } - else { + } else { uint16_t data_len = file_get_size(ef); - if (offset > data_len) + if (offset > data_len) { return SW_WRONG_P1P2(); + } uint16_t maxle = data_len-offset; - if (apdu.ne > maxle) + if (apdu.ne > maxle) { apdu.ne = maxle; + } memcpy(res_APDU, file_get_data(ef)+offset, data_len-offset); res_APDU_size = data_len-offset; } diff --git a/src/hsm/cmd_reset_retry.c b/src/hsm/cmd_reset_retry.c index 131233e..72d89f2 100644 --- a/src/hsm/cmd_reset_retry.c +++ b/src/hsm/cmd_reset_retry.c @@ -19,9 +19,11 @@ #include "sc_hsm.h" #include "kek.h" -int cmd_reset_retry() { - if (P2(apdu) != 0x81) +int cmd_reset_retry() +{ + if (P2(apdu) != 0x81) { return SW_REFERENCE_NOT_FOUND(); + } if (!file_sopin || !file_pin1) { return SW_FILE_NOT_FOUND(); } @@ -29,66 +31,77 @@ int cmd_reset_retry() { return SW_REFERENCE_NOT_FOUND(); } uint16_t opts = get_device_options(); - if (!(opts & HSM_OPT_RRC)) + if (!(opts & HSM_OPT_RRC)) { return SW_COMMAND_NOT_ALLOWED(); + } if (P1(apdu) == 0x0 || P1(apdu) == 0x2) { int newpin_len = 0; if (P1(apdu) == 0x0) { - if (apdu.nc <= 8) + if (apdu.nc <= 8) { return SW_WRONG_LENGTH(); + } uint16_t r = check_pin(file_sopin, apdu.data, 8); - if (r != 0x9000) + if (r != 0x9000) { return r; + } newpin_len = apdu.nc-8; has_session_sopin = true; hash_multi(apdu.data, 8, session_sopin); - } - else if (P1(apdu) == 0x2) { - if (!has_session_sopin) + } else if (P1(apdu) == 0x2) { + if (!has_session_sopin) { return SW_CONDITIONS_NOT_SATISFIED(); - if (apdu.nc > 16) + } + if (apdu.nc > 16) { return SW_WRONG_LENGTH(); + } newpin_len = apdu.nc; } uint8_t dhash[33]; dhash[0] = newpin_len; double_hash_pin(apdu.data+(apdu.nc-newpin_len), newpin_len, dhash+1); flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); - if (pin_reset_retries(file_pin1, true) != CCID_OK) + if (pin_reset_retries(file_pin1, true) != CCID_OK) { return SW_MEMORY_FAILURE(); + } uint8_t mkek[MKEK_SIZE]; int r = load_mkek(mkek); //loads the MKEK with SO pin - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } hash_multi(apdu.data+(apdu.nc-newpin_len), newpin_len, session_pin); has_session_pin = true; r = store_mkek(mkek); release_mkek(mkek); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_EXEC_ERROR(); + } low_flash_available(); return SW_OK(); - } - else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) { - if (!(opts & HSM_OPT_RRC_RESET_ONLY)) + } else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) { + if (!(opts & HSM_OPT_RRC_RESET_ONLY)) { return SW_COMMAND_NOT_ALLOWED(); + } if (P1(apdu) == 0x1) { - if (apdu.nc != 8) + if (apdu.nc != 8) { return SW_WRONG_LENGTH(); + } uint16_t r = check_pin(file_sopin, apdu.data, 8); - if (r != 0x9000) + if (r != 0x9000) { return r; + } has_session_sopin = true; hash_multi(apdu.data, 8, session_sopin); - } - else if (P1(apdu) == 0x3) { - if (!has_session_sopin) + } else if (P1(apdu) == 0x3) { + if (!has_session_sopin) { return SW_CONDITIONS_NOT_SATISFIED(); - if (apdu.nc != 0) + } + if (apdu.nc != 0) { return SW_WRONG_LENGTH(); + } } - if (pin_reset_retries(file_pin1, true) != CCID_OK) + if (pin_reset_retries(file_pin1, true) != CCID_OK) { return SW_MEMORY_FAILURE(); + } return SW_OK(); } return SW_INCORRECT_P1P2(); diff --git a/src/hsm/cmd_select.c b/src/hsm/cmd_select.c index e9eaa6c..9df87e6 100644 --- a/src/hsm/cmd_select.c +++ b/src/hsm/cmd_select.c @@ -18,17 +18,15 @@ #include "sc_hsm.h" #include "version.h" -void select_file(file_t *pe) { - if (!pe) - { - currentDF = (file_t *)MF; +void select_file(file_t *pe) +{ + if (!pe) { + currentDF = (file_t *) MF; currentEF = NULL; - } - else if (pe->type & FILE_TYPE_INTERNAL_EF) { + } else if (pe->type & FILE_TYPE_INTERNAL_EF) { currentEF = pe; currentDF = &file_entries[pe->parent]; - } - else { + } else { currentDF = pe; } if (currentEF == file_openpgp || currentEF == file_sc_hsm) { @@ -37,7 +35,8 @@ void select_file(file_t *pe) { } } -int cmd_select() { +int cmd_select() +{ uint8_t p1 = P1(apdu); uint8_t p2 = P2(apdu); file_t *pe = NULL; @@ -48,8 +47,9 @@ int cmd_select() { // return SW_INCORRECT_P1P2(); //} - if (apdu.nc >= 2) + if (apdu.nc >= 2) { fid = get_uint16_t(apdu.data, 0); + } //if ((fid & 0xff00) == (KEY_PREFIX << 8)) // fid = (PRKD_PREFIX << 8) | (fid & 0xff); @@ -63,56 +63,51 @@ int cmd_select() { pfx == DCOD_PREFIX || pfx == DATA_PREFIX || pfx == PROT_DATA_PREFIX) { - if (!(pe = search_dynamic_file(fid)) && !(pe = search_by_fid(fid, NULL, SPECIFY_EF))) + if (!(pe = search_dynamic_file(fid)) && !(pe = search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_FILE_NOT_FOUND(); + } } if (!pe) { if (p1 == 0x0) { //Select MF, DF or EF - File identifier or absent if (apdu.nc == 0) { - pe = (file_t *)MF; - //ac_fini(); - } - else if (apdu.nc == 2) { + pe = (file_t *) MF; + //ac_fini(); + } else if (apdu.nc == 2) { if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) { return SW_FILE_NOT_FOUND(); } } - } - else if (p1 == 0x01) { //Select child DF - DF identifier + } else if (p1 == 0x01) { //Select child DF - DF identifier if (!(pe = search_by_fid(fid, currentDF, SPECIFY_DF))) { return SW_FILE_NOT_FOUND(); } - } - else if (p1 == 0x02) { //Select EF under the current DF - EF identifier + } else if (p1 == 0x02) { //Select EF under the current DF - EF identifier if (!(pe = search_by_fid(fid, currentDF, SPECIFY_EF))) { return SW_FILE_NOT_FOUND(); } - } - else if (p1 == 0x03) { //Select parent DF of the current DF - Absent - if (apdu.nc != 0) + } else if (p1 == 0x03) { //Select parent DF of the current DF - Absent + if (apdu.nc != 0) { return SW_FILE_NOT_FOUND(); - } - else if (p1 == 0x04) { //Select by DF name - e.g., [truncated] application identifier + } + } else if (p1 == 0x04) { //Select by DF name - e.g., [truncated] application identifier if (!(pe = search_by_name(apdu.data, apdu.nc))) { return SW_FILE_NOT_FOUND(); } if (card_terminated) { return set_res_sw(0x62, 0x85); } - } - else if (p1 == 0x08) { //Select from the MF - Path without the MF identifier + } else if (p1 == 0x08) { //Select from the MF - Path without the MF identifier if (!(pe = search_by_path(apdu.data, apdu.nc, MF))) { return SW_FILE_NOT_FOUND(); } - } - else if (p1 == 0x09) { //Select from the current DF - Path without the current DF identifier + } else if (p1 == 0x09) { //Select from the current DF - Path without the current DF identifier if (!(pe = search_by_path(apdu.data, apdu.nc, currentDF))) { return SW_FILE_NOT_FOUND(); } } } if ((p2 & 0xfc) == 0x00 || (p2 & 0xfc) == 0x04) { - process_fci(pe,0); + process_fci(pe, 0); if (pe == file_sc_hsm) { res_APDU[res_APDU_size++] = 0x85; res_APDU[res_APDU_size++] = 5; @@ -124,9 +119,9 @@ int cmd_select() { res_APDU[res_APDU_size++] = HSM_VERSION_MINOR; res_APDU[1] = res_APDU_size-2; } - } - else + } else { return SW_INCORRECT_P1P2(); + } select_file(pe); - return SW_OK (); + return SW_OK(); } diff --git a/src/hsm/cmd_session_pin.c b/src/hsm/cmd_session_pin.c index 4f49f24..573a252 100644 --- a/src/hsm/cmd_session_pin.c +++ b/src/hsm/cmd_session_pin.c @@ -19,7 +19,8 @@ #include "random.h" #include "eac.h" -int cmd_session_pin() { +int cmd_session_pin() +{ if (P1(apdu) == 0x01 && P2(apdu) == 0x81) { memcpy(sm_session_pin, random_bytes_get(8), 8); sm_session_pin_len = 8; @@ -27,8 +28,8 @@ int cmd_session_pin() { memcpy(res_APDU, sm_session_pin, sm_session_pin_len); res_APDU_size = sm_session_pin_len; apdu.ne = sm_session_pin_len; - } - else + } else { return SW_INCORRECT_P1P2(); + } return SW_OK(); } diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index 6f09944..8a94b0a 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -24,94 +24,111 @@ //----- /* From OpenSC */ static const uint8_t hdr_md5[] = { - 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 + 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; static const uint8_t hdr_sha1[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, - 0x05, 0x00, 0x04, 0x14 + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, 0x04, 0x14 }; static const uint8_t hdr_sha256[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, - 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; static const uint8_t hdr_sha384[] = { - 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, - 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; static const uint8_t hdr_sha512[] = { - 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, - 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; static const uint8_t hdr_sha224[] = { - 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, - 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c + 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, + 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c }; static const uint8_t hdr_ripemd160[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01, - 0x05, 0x00, 0x04, 0x14 + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01, + 0x05, 0x00, 0x04, 0x14 }; static const struct digest_info_prefix { - mbedtls_md_type_t algorithm; - const uint8_t * hdr; - size_t hdr_len; - size_t hash_len; + mbedtls_md_type_t algorithm; + const uint8_t *hdr; + size_t hdr_len; + size_t hash_len; } digest_info_prefix[] = { - { MBEDTLS_MD_MD5, hdr_md5, sizeof(hdr_md5), 16 }, - { MBEDTLS_MD_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 }, - { MBEDTLS_MD_SHA256, hdr_sha256, sizeof(hdr_sha256), 32 }, - { MBEDTLS_MD_SHA384, hdr_sha384, sizeof(hdr_sha384), 48 }, - { MBEDTLS_MD_SHA512, hdr_sha512, sizeof(hdr_sha512), 64 }, - { MBEDTLS_MD_SHA224, hdr_sha224, sizeof(hdr_sha224), 28 }, - { MBEDTLS_MD_RIPEMD160,hdr_ripemd160, sizeof(hdr_ripemd160), 20 }, - { 0, NULL, 0, 0 } + { MBEDTLS_MD_MD5, hdr_md5, sizeof(hdr_md5), 16 }, + { MBEDTLS_MD_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 }, + { MBEDTLS_MD_SHA256, hdr_sha256, sizeof(hdr_sha256), 32 }, + { MBEDTLS_MD_SHA384, hdr_sha384, sizeof(hdr_sha384), 48 }, + { MBEDTLS_MD_SHA512, hdr_sha512, sizeof(hdr_sha512), 64 }, + { MBEDTLS_MD_SHA224, hdr_sha224, sizeof(hdr_sha224), 28 }, + { MBEDTLS_MD_RIPEMD160, hdr_ripemd160, sizeof(hdr_ripemd160), 20 }, + { 0, NULL, 0, 0 } }; -int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm, const uint8_t *in_dat, size_t in_len, uint8_t *out_dat, size_t *out_len) +int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm, + const uint8_t *in_dat, + size_t in_len, + uint8_t *out_dat, + size_t *out_len) { - for (int i = 0; digest_info_prefix[i].algorithm != 0; i++) { - size_t hdr_len = digest_info_prefix[i].hdr_len, hash_len = digest_info_prefix[i].hash_len; - const uint8_t *hdr = digest_info_prefix[i].hdr; - if (in_len == (hdr_len + hash_len) && !memcmp(in_dat, hdr, hdr_len)) { - if (algorithm) - *algorithm = digest_info_prefix[i].algorithm; - if (out_dat == NULL) - return CCID_OK; - if (*out_len < hash_len) - return CCID_WRONG_DATA; - memmove(out_dat, in_dat + hdr_len, hash_len); - *out_len = hash_len; - return CCID_OK; - } - } - return CCID_EXEC_ERROR; + for (int i = 0; digest_info_prefix[i].algorithm != 0; i++) { + size_t hdr_len = digest_info_prefix[i].hdr_len, hash_len = digest_info_prefix[i].hash_len; + const uint8_t *hdr = digest_info_prefix[i].hdr; + if (in_len == (hdr_len + hash_len) && !memcmp(in_dat, hdr, hdr_len)) { + if (algorithm) { + *algorithm = digest_info_prefix[i].algorithm; + } + if (out_dat == NULL) { + return CCID_OK; + } + if (*out_len < hash_len) { + return CCID_WRONG_DATA; + } + memmove(out_dat, in_dat + hdr_len, hash_len); + *out_len = hash_len; + return CCID_OK; + } + } + return CCID_EXEC_ERROR; } //----- -int cmd_signature() { +int cmd_signature() +{ uint8_t key_id = P1(apdu); uint8_t p2 = P2(apdu); mbedtls_md_type_t md = MBEDTLS_MD_NONE; file_t *fkey; - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) + } + if (!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) { return SW_FILE_NOT_FOUND(); - if (get_key_counter(fkey) == 0) + } + if (get_key_counter(fkey) == 0) { return SW_FILE_FULL(); - if (key_has_purpose(fkey, p2) == false) + } + if (key_has_purpose(fkey, p2) == false) { return SW_CONDITIONS_NOT_SATISFIED(); + } int key_size = file_get_size(fkey); - if (p2 == ALGO_RSA_PKCS1_SHA1 || p2 == ALGO_RSA_PSS_SHA1 || p2 == ALGO_EC_SHA1) + if (p2 == ALGO_RSA_PKCS1_SHA1 || p2 == ALGO_RSA_PSS_SHA1 || p2 == ALGO_EC_SHA1) { md = MBEDTLS_MD_SHA1; - else if (p2 == ALGO_RSA_PKCS1_SHA256 || p2 == ALGO_RSA_PSS_SHA256 || p2 == ALGO_EC_SHA256) + } else if (p2 == ALGO_RSA_PKCS1_SHA256 || p2 == ALGO_RSA_PSS_SHA256 || p2 == ALGO_EC_SHA256) { md = MBEDTLS_MD_SHA256; - else if (p2 == ALGO_EC_SHA224 || p2 == ALGO_RSA_PKCS1_SHA224 || p2 == ALGO_RSA_PSS_SHA224) + } else if (p2 == ALGO_EC_SHA224 || p2 == ALGO_RSA_PKCS1_SHA224 || p2 == ALGO_RSA_PSS_SHA224) { md = MBEDTLS_MD_SHA224; - else if (p2 == ALGO_EC_SHA384 || p2 == ALGO_RSA_PKCS1_SHA384 || p2 == ALGO_RSA_PSS_SHA384) + } else if (p2 == ALGO_EC_SHA384 || p2 == ALGO_RSA_PKCS1_SHA384 || p2 == ALGO_RSA_PSS_SHA384) { md = MBEDTLS_MD_SHA384; - else if (p2 == ALGO_EC_SHA512 || p2 == ALGO_RSA_PKCS1_SHA512 || p2 == ALGO_RSA_PSS_SHA512) + } else if (p2 == ALGO_EC_SHA512 || p2 == ALGO_RSA_PKCS1_SHA512 || p2 == ALGO_RSA_PSS_SHA512) { md = MBEDTLS_MD_SHA512; - if (p2 == ALGO_RSA_PKCS1_SHA1 || p2 == ALGO_RSA_PSS_SHA1 || p2 == ALGO_EC_SHA1 || p2 == ALGO_RSA_PKCS1_SHA256 || p2 == ALGO_RSA_PSS_SHA256 || p2 == ALGO_EC_SHA256 || p2 == ALGO_EC_SHA224 || p2 == ALGO_EC_SHA384 || p2 == ALGO_EC_SHA512 || p2 == ALGO_RSA_PKCS1_SHA224 || p2 == ALGO_RSA_PKCS1_SHA384 || p2 == ALGO_RSA_PKCS1_SHA512 || p2 == ALGO_RSA_PSS_SHA224 || p2 == ALGO_RSA_PSS_SHA384 || p2 == ALGO_RSA_PSS_SHA512) { + } + if (p2 == ALGO_RSA_PKCS1_SHA1 || p2 == ALGO_RSA_PSS_SHA1 || p2 == ALGO_EC_SHA1 || + p2 == ALGO_RSA_PKCS1_SHA256 || p2 == ALGO_RSA_PSS_SHA256 || p2 == ALGO_EC_SHA256 || + p2 == ALGO_EC_SHA224 || p2 == ALGO_EC_SHA384 || p2 == ALGO_EC_SHA512 || + p2 == ALGO_RSA_PKCS1_SHA224 || p2 == ALGO_RSA_PKCS1_SHA384 || p2 == ALGO_RSA_PKCS1_SHA512 || + p2 == ALGO_RSA_PSS_SHA224 || p2 == ALGO_RSA_PSS_SHA384 || p2 == ALGO_RSA_PSS_SHA512) { generic_hash(md, apdu.data, apdu.nc, apdu.data); apdu.nc = mbedtls_md_get_size(mbedtls_md_info_from_type(md)); } @@ -122,19 +139,21 @@ int cmd_signature() { int r = load_private_key_rsa(&ctx, fkey); if (r != CCID_OK) { mbedtls_rsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } uint8_t *hash = apdu.data; size_t hash_len = apdu.nc; if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached size_t nc = apdu.nc; - if (pkcs1_strip_digest_info_prefix(&md, apdu.data, apdu.nc, apdu.data, &nc) != CCID_OK) //gets the MD algo id and strips it off + if (pkcs1_strip_digest_info_prefix(&md, apdu.data, apdu.nc, apdu.data, + &nc) != CCID_OK) { //gets the MD algo id and strips it off return SW_EXEC_ERROR(); + } apdu.nc = nc; - } - else { + } else { //sc_asn1_print_tags(apdu.data, apdu.nc); size_t tout = 0, oid_len = 0; uint8_t *p = NULL, *oid = NULL; @@ -147,40 +166,42 @@ int cmd_signature() { asn1_find_tag(p, tout, 0x4, &hash_len, &hash); } if (oid && oid_len > 0) { - if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA1, oid_len) == 0) + if (memcmp(oid, 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, 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, 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, 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, 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 (apdu.nc == 20) //default is sha1 + if (apdu.nc == 20) { //default is sha1 md = MBEDTLS_MD_SHA1; - else if (apdu.nc == 28) + } else if (apdu.nc == 28) { md = MBEDTLS_MD_SHA224; - else if (apdu.nc == 32) + } else if (apdu.nc == 32) { md = MBEDTLS_MD_SHA256; - else if (apdu.nc == 48) + } else if (apdu.nc == 48) { md = MBEDTLS_MD_SHA384; - else if (apdu.nc == 64) + } else if (apdu.nc == 64) { md = MBEDTLS_MD_SHA512; + } } mbedtls_rsa_set_padding(&ctx, MBEDTLS_RSA_PKCS_V21, md); } } if (md == MBEDTLS_MD_NONE) { - if (apdu.nc < key_size) //needs padding + if (apdu.nc < key_size) { //needs padding memset(apdu.data+apdu.nc, 0, key_size-apdu.nc); + } r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU); - } - else { - uint8_t *signature = (uint8_t *)calloc(key_size, sizeof(uint8_t)); + } 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); memcpy(res_APDU, signature, key_size); free(signature); @@ -192,52 +213,55 @@ int cmd_signature() { res_APDU_size = key_size; apdu.ne = key_size; mbedtls_rsa_free(&ctx); - } - else if (p2 >= ALGO_EC_RAW && p2 <= ALGO_EC_SHA512) { + } else if (p2 >= ALGO_EC_RAW && p2 <= ALGO_EC_SHA512) { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); md = MBEDTLS_MD_SHA256; if (p2 == ALGO_EC_RAW) { - if (apdu.nc == 32) + if (apdu.nc == 32) { md = MBEDTLS_MD_SHA256; - else if (apdu.nc == 20) + } else if (apdu.nc == 20) { md = MBEDTLS_MD_SHA1; - else if (apdu.nc == 28) + } else if (apdu.nc == 28) { md = MBEDTLS_MD_SHA224; - else if (apdu.nc == 48) + } else if (apdu.nc == 48) { md = MBEDTLS_MD_SHA384; - else if (apdu.nc == 64) + } else if (apdu.nc == 64) { md = MBEDTLS_MD_SHA512; + } } - if (p2 == ALGO_EC_SHA1) + if (p2 == ALGO_EC_SHA1) { md = MBEDTLS_MD_SHA1; - else if (p2 == ALGO_EC_SHA224) + } else if (p2 == ALGO_EC_SHA224) { md = MBEDTLS_MD_SHA224; - else if (p2 == ALGO_EC_SHA256) + } else if (p2 == ALGO_EC_SHA256) { md = MBEDTLS_MD_SHA256; - else if (p2 == ALGO_EC_SHA384) + } else if (p2 == ALGO_EC_SHA384) { md = MBEDTLS_MD_SHA384; - else if (p2 == ALGO_EC_SHA512) + } else if (p2 == ALGO_EC_SHA512) { md = MBEDTLS_MD_SHA512; + } int r = load_private_key_ecdsa(&ctx, fkey); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); - if (r == CCID_VERIFICATION_FAILED) + if (r == CCID_VERIFICATION_FAILED) { return SW_SECURE_MESSAGE_EXEC_ERROR(); + } return SW_EXEC_ERROR(); } size_t olen = 0; uint8_t buf[MBEDTLS_ECDSA_MAX_LEN]; - if (mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, &olen, random_gen, NULL) != 0) { + if (mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, + &olen, random_gen, NULL) != 0) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } memcpy(res_APDU, buf, olen); res_APDU_size = olen; mbedtls_ecdsa_free(&ctx); - } - else + } else { return SW_INCORRECT_P1P2(); + } decrement_key_counter(fkey); return SW_OK(); } diff --git a/src/hsm/cmd_update_ef.c b/src/hsm/cmd_update_ef.c index 8514457..59e2a60 100644 --- a/src/hsm/cmd_update_ef.c +++ b/src/hsm/cmd_update_ef.c @@ -20,32 +20,38 @@ extern void select_file(file_t *pe); -int cmd_update_ef() { +int cmd_update_ef() +{ uint8_t p1 = P1(apdu), p2 = P2(apdu); uint16_t fid = (p1 << 8) | p2; uint8_t *data = NULL; uint16_t offset = 0; uint16_t data_len = 0; file_t *ef = NULL; - if (!isUserAuthenticated) + if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); - if (fid == 0x0) + } + if (fid == 0x0) { ef = currentEF; - else if (p1 != EE_CERTIFICATE_PREFIX && p1 != PRKD_PREFIX && p1 != CA_CERTIFICATE_PREFIX && p1 != CD_PREFIX && p1 != DATA_PREFIX && p1 != DCOD_PREFIX && p1 != PROT_DATA_PREFIX) + } else if (p1 != EE_CERTIFICATE_PREFIX && p1 != PRKD_PREFIX && p1 != CA_CERTIFICATE_PREFIX && + p1 != CD_PREFIX && p1 != DATA_PREFIX && p1 != DCOD_PREFIX && + p1 != PROT_DATA_PREFIX) { return SW_INCORRECT_P1P2(); + } - if (ef && !authenticate_action(ef, ACL_OP_UPDATE_ERASE)) + if (ef && !authenticate_action(ef, ACL_OP_UPDATE_ERASE)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); + } uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; size_t tag_len = 0; while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x54) { //ofset tag - for (int i = 1; i <= tag_len; i++) + for (int i = 1; i <= tag_len; i++) { offset |= (*tag_data++ << (8*(tag_len-i))); - } - else if (tag == 0x53) { //data + } + } else if (tag == 0x53) { //data data_len = tag_len; data = tag_data; } @@ -55,30 +61,34 @@ int cmd_update_ef() { //if ((fid & 0xff00) == (EE_CERTIFICATE_PREFIX << 8)) // add_file_to_chain(ef, &ef_pukdf); select_file(ef); - } - else { - if (fid == 0x0 && !ef) + } else { + if (fid == 0x0 && !ef) { return SW_FILE_NOT_FOUND(); - else if (fid != 0x0 && !(ef = search_by_fid(fid, NULL, SPECIFY_EF)) && !(ef = search_dynamic_file(fid))) { //if does not exist, create it + } else if (fid != 0x0 && + !(ef = + search_by_fid(fid, NULL, + SPECIFY_EF)) && !(ef = search_dynamic_file(fid))) { //if does not exist, create it //return SW_FILE_NOT_FOUND(); ef = file_new(fid); } if (offset == 0) { int r = flash_write_data_to_file(ef, data, data_len); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); - } - else { - if (!file_has_data(ef)) + } + } else { + if (!file_has_data(ef)) { return SW_DATA_INVALID(); + } - uint8_t *data_merge = (uint8_t *)calloc(1, offset+data_len); + uint8_t *data_merge = (uint8_t *) calloc(1, offset+data_len); memcpy(data_merge, file_get_data(ef), offset); memcpy(data_merge+offset, data, data_len); int r = flash_write_data_to_file(ef, data_merge, offset+data_len); free(data_merge); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); + } } low_flash_available(); } diff --git a/src/hsm/cmd_verify.c b/src/hsm/cmd_verify.c index 7a21611..32b2b3b 100644 --- a/src/hsm/cmd_verify.c +++ b/src/hsm/cmd_verify.c @@ -17,41 +17,48 @@ #include "sc_hsm.h" -int cmd_verify() { +int cmd_verify() +{ uint8_t p1 = P1(apdu); uint8_t p2 = P2(apdu); - if (p1 != 0x0 || (p2 & 0x60) != 0x0) + if (p1 != 0x0 || (p2 & 0x60) != 0x0) { return SW_WRONG_P1P2(); + } if (p2 == 0x81) { //UserPin uint16_t opts = get_device_options(); - if (opts & HSM_OPT_TRANSPORT_PIN) + if (opts & HSM_OPT_TRANSPORT_PIN) { return SW_DATA_INVALID(); - if (has_session_pin && apdu.nc == 0) + } + if (has_session_pin && apdu.nc == 0) { return SW_OK(); - if (*file_get_data(file_pin1) == 0 && pka_enabled() == false) //not initialized + } + if (*file_get_data(file_pin1) == 0 && pka_enabled() == false) { //not initialized return SW_REFERENCE_NOT_FOUND(); + } if (apdu.nc > 0) { return check_pin(file_pin1, apdu.data, apdu.nc); } - if (file_read_uint8(file_get_data(file_retries_pin1)) == 0) + if (file_read_uint8(file_get_data(file_retries_pin1)) == 0) { return SW_PIN_BLOCKED(); + } return set_res_sw(0x63, 0xc0 | file_read_uint8(file_get_data(file_retries_pin1))); - } - else if (p2 == 0x88) { //SOPin - if (file_read_uint8(file_get_data(file_sopin)) == 0) //not initialized + } else if (p2 == 0x88) { //SOPin + if (file_read_uint8(file_get_data(file_sopin)) == 0) { //not initialized return SW_REFERENCE_NOT_FOUND(); + } if (apdu.nc > 0) { return check_pin(file_sopin, apdu.data, apdu.nc); } - if (file_read_uint8(file_get_data(file_retries_sopin)) == 0) + if (file_read_uint8(file_get_data(file_retries_sopin)) == 0) { return SW_PIN_BLOCKED(); - if (has_session_sopin) + } + if (has_session_sopin) { return SW_OK(); + } return set_res_sw(0x63, 0xc0 | file_read_uint8(file_get_data(file_retries_sopin))); - } - else if (p2 == 0x85) { + } else if (p2 == 0x85) { return SW_OK(); } return SW_REFERENCE_NOT_FOUND(); diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index 8b042e8..3f64ffe 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -31,125 +31,178 @@ extern const uint8_t *dev_name; extern size_t dev_name_len; -size_t asn1_cvc_public_key_rsa(mbedtls_rsa_context *rsa, uint8_t *buf, size_t buf_len) { +size_t asn1_cvc_public_key_rsa(mbedtls_rsa_context *rsa, uint8_t *buf, size_t buf_len) +{ const uint8_t oid_rsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x01, 0x02 }; size_t n_size = mbedtls_mpi_size(&rsa->N), e_size = mbedtls_mpi_size(&rsa->E); size_t ntot_size = asn1_len_tag(0x81, n_size), etot_size = asn1_len_tag(0x82, e_size); size_t oid_len = asn1_len_tag(0x6, sizeof(oid_rsa)); size_t tot_len = asn1_len_tag(0x7f49, oid_len+ntot_size+etot_size); - if (buf == NULL || buf_len == 0) + if (buf == NULL || buf_len == 0) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; memcpy(p, "\x7F\x49", 2); p += 2; p += format_tlv_len(oid_len+ntot_size+etot_size, p); //oid - *p++ = 0x6; p += format_tlv_len(sizeof(oid_rsa), p); memcpy(p, oid_rsa, sizeof(oid_rsa)); p += sizeof(oid_rsa); + *p++ = 0x6; p += format_tlv_len(sizeof(oid_rsa), p); memcpy(p, oid_rsa, sizeof(oid_rsa)); + p += sizeof(oid_rsa); //n - *p++ = 0x81; p += format_tlv_len(n_size, p); mbedtls_mpi_write_binary(&rsa->N, p, n_size); p += n_size; + *p++ = 0x81; p += format_tlv_len(n_size, p); mbedtls_mpi_write_binary(&rsa->N, p, n_size); + p += n_size; //n - *p++ = 0x82; p += format_tlv_len(e_size, p); mbedtls_mpi_write_binary(&rsa->E, p, e_size); p += e_size; + *p++ = 0x82; p += format_tlv_len(e_size, p); mbedtls_mpi_write_binary(&rsa->E, p, e_size); + p += e_size; return tot_len; } const uint8_t *pointA[] = { NULL, - (uint8_t *)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", - (uint8_t *)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", - (uint8_t *)"\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", - (uint8_t *)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC", - (uint8_t *)"\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", + (uint8_t *) + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", + (uint8_t *) + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", + (uint8_t *) + "\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", + (uint8_t *) + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFC", + (uint8_t *) + "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC", }; -size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, size_t buf_len) { +size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, size_t buf_len) +{ uint8_t Y_buf[MBEDTLS_ECP_MAX_PT_LEN]; const uint8_t oid_ecdsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x03 }; size_t p_size = mbedtls_mpi_size(&ecdsa->grp.P), a_size = mbedtls_mpi_size(&ecdsa->grp.A); - size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), g_size = 1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.X); + size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), + g_size = 1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.X); size_t o_size = mbedtls_mpi_size(&ecdsa->grp.N), y_size = 0; - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &y_size, Y_buf, sizeof(Y_buf)); + mbedtls_ecp_point_write_binary(&ecdsa->grp, + &ecdsa->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &y_size, + Y_buf, + sizeof(Y_buf)); size_t c_size = 1; - size_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? p_size : 1)); + size_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, + a_size ? a_size : ( + pointA[ecdsa->grp.id + ] && + ecdsa->grp.id < + 6 ? p_size : 1)); size_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size); size_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size); size_t ctot_size = asn1_len_tag(0x87, c_size); size_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa)); - size_t tot_len = asn1_len_tag(0x7f49, oid_len+ptot_size+atot_size+btot_size+gtot_size+otot_size+ytot_size+ctot_size); - if (buf == NULL || buf_len == 0) + size_t tot_len = asn1_len_tag(0x7f49, + oid_len+ptot_size+atot_size+btot_size+gtot_size+otot_size+ytot_size+ + ctot_size); + if (buf == NULL || buf_len == 0) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; memcpy(p, "\x7F\x49", 2); p += 2; - p += format_tlv_len(oid_len+ptot_size+atot_size+btot_size+gtot_size+otot_size+ytot_size+ctot_size, p); + p += format_tlv_len( + oid_len+ptot_size+atot_size+btot_size+gtot_size+otot_size+ytot_size+ctot_size, + p); //oid - *p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid_ecdsa, sizeof(oid_ecdsa)); p += sizeof(oid_ecdsa); + *p++ = 0x6; p += format_tlv_len(sizeof(oid_ecdsa), p); memcpy(p, oid_ecdsa, sizeof(oid_ecdsa)); + p += sizeof(oid_ecdsa); //p - *p++ = 0x81; p += format_tlv_len(p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); p += p_size; + *p++ = 0x81; p += format_tlv_len(p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); + p += p_size; //A if (a_size) { - *p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, p, a_size); p += a_size; - } - else { //mbedtls does not set point A for some curves + *p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, + p, + a_size); p += a_size; + } else { //mbedtls does not set point A for some curves if (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6) { - *p++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); p += p_size; - } - else { + *p++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); + p += p_size; + } else { *p++ = 0x82; p += format_tlv_len(1, p); *p++ = 0x0; } } //B - *p++ = 0x83; p += format_tlv_len(b_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.B, p, b_size); p += b_size; + *p++ = 0x83; p += format_tlv_len(b_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.B, p, b_size); + p += b_size; //G size_t g_new_size = 0; - *p++ = 0x84; p += format_tlv_len(g_size, p); mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, &g_new_size, p, g_size); p += g_size; + *p++ = 0x84; p += format_tlv_len(g_size, p); mbedtls_ecp_point_write_binary(&ecdsa->grp, + &ecdsa->grp.G, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &g_new_size, + p, + g_size); + p += g_size; //order - *p++ = 0x85; p += format_tlv_len(o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); p += o_size; + *p++ = 0x85; p += format_tlv_len(o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); + p += o_size; //Y *p++ = 0x86; p += format_tlv_len(y_size, p); memcpy(p, Y_buf, y_size); p += y_size; //cofactor *p++ = 0x87; p += format_tlv_len(c_size, p); - if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE448) + if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE448) { *p++ = 4; - else if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE25519) + } else if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE25519) { *p++ = 8; - else + } else { *p++ = 1; + } return tot_len; } -size_t asn1_cvc_cert_body(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len) { +size_t asn1_cvc_cert_body(void *rsa_ecdsa, + uint8_t key_type, + uint8_t *buf, + size_t buf_len, + const uint8_t *ext, + size_t ext_len) +{ size_t pubkey_size = 0; - if (key_type == HSM_KEY_RSA) + if (key_type == HSM_KEY_RSA) { pubkey_size = asn1_cvc_public_key_rsa(rsa_ecdsa, NULL, 0); - else if (key_type == HSM_KEY_EC) + } else if (key_type == HSM_KEY_EC) { pubkey_size = asn1_cvc_public_key_ecdsa(rsa_ecdsa, NULL, 0); + } size_t cpi_size = 4; size_t ext_size = 0; - if (ext && ext_len > 0) + if (ext && ext_len > 0) { ext_size = asn1_len_tag(0x65, ext_len); + } uint8_t *car = NULL, *chr = NULL; size_t lencar = 0, lenchr = 0; - if (asn1_find_tag(apdu.data, apdu.nc, 0x42, &lencar, &car) == false || lencar == 0 || car == NULL) { - car = (uint8_t *)dev_name; + if (asn1_find_tag(apdu.data, apdu.nc, 0x42, &lencar, + &car) == false || lencar == 0 || car == NULL) { + car = (uint8_t *) dev_name; lencar = dev_name_len; } - if (asn1_find_tag(apdu.data, apdu.nc, 0x5f20, &lenchr, &chr) == false || lenchr == 0 || chr == NULL) { - chr = (uint8_t *)dev_name; + if (asn1_find_tag(apdu.data, apdu.nc, 0x5f20, &lenchr, + &chr) == false || lenchr == 0 || chr == NULL) { + chr = (uint8_t *) dev_name; lenchr = dev_name_len; } size_t car_size = asn1_len_tag(0x42, lencar), chr_size = asn1_len_tag(0x5f20, lenchr); size_t tot_len = asn1_len_tag(0x7f4e, cpi_size+car_size+pubkey_size+chr_size+ext_size); - if (buf_len == 0 || buf == NULL) + if (buf_len == 0 || buf == NULL) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; memcpy(p, "\x7F\x4E", 2); p += 2; p += format_tlv_len(cpi_size+car_size+pubkey_size+chr_size+ext_size, p); @@ -158,10 +211,11 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_ //car *p++ = 0x42; p += format_tlv_len(lencar, p); memcpy(p, car, lencar); p += lencar; //pubkey - if (key_type == HSM_KEY_RSA) + if (key_type == HSM_KEY_RSA) { p += asn1_cvc_public_key_rsa(rsa_ecdsa, p, pubkey_size); - else if (key_type == HSM_KEY_EC) + } else if (key_type == HSM_KEY_EC) { 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; if (ext && ext_len > 0) { @@ -173,18 +227,31 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_ return tot_len; } -size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len) { +size_t asn1_cvc_cert(void *rsa_ecdsa, + uint8_t key_type, + uint8_t *buf, + size_t buf_len, + const uint8_t *ext, + size_t ext_len) +{ size_t key_size = 0; - if (key_type == HSM_KEY_RSA) - key_size = mbedtls_mpi_size(&((mbedtls_rsa_context *)rsa_ecdsa)->N); - else if (key_type == HSM_KEY_EC) - key_size = 2*(int)((mbedtls_ecp_curve_info_from_grp_id(((mbedtls_ecdsa_context *)rsa_ecdsa)->grp.id)->bit_size + 7)/8); - size_t body_size = asn1_cvc_cert_body(rsa_ecdsa, key_type, NULL, 0, ext, ext_len), sig_size = asn1_len_tag(0x5f37, key_size); + if (key_type == HSM_KEY_RSA) { + key_size = mbedtls_mpi_size(&((mbedtls_rsa_context *) rsa_ecdsa)->N); + } else if (key_type == HSM_KEY_EC) { + key_size = 2* + (int) ((mbedtls_ecp_curve_info_from_grp_id(((mbedtls_ecdsa_context *) rsa_ecdsa) + ->grp.id)-> + bit_size + 7)/8); + } + size_t body_size = asn1_cvc_cert_body(rsa_ecdsa, key_type, NULL, 0, ext, ext_len), + sig_size = asn1_len_tag(0x5f37, key_size); size_t tot_len = asn1_len_tag(0x7f21, body_size+sig_size); - if (buf_len == 0 || buf == NULL) + if (buf_len == 0 || buf == NULL) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf, *body = NULL; memcpy(p, "\x7F\x21", 2); p += 2; p += format_tlv_len(body_size+sig_size, p); @@ -195,22 +262,23 @@ size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf memcpy(p, "\x5F\x37", 2); p += 2; p += format_tlv_len(key_size, p); if (key_type == HSM_KEY_RSA) { - if (mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa_ecdsa, random_gen, NULL, MBEDTLS_MD_SHA256, 32, hsh, p) != 0) + if (mbedtls_rsa_rsassa_pkcs1_v15_sign(rsa_ecdsa, random_gen, NULL, MBEDTLS_MD_SHA256, 32, + hsh, p) != 0) { memset(p, 0, key_size); + } p += key_size; - } - else if (key_type == HSM_KEY_EC) { + } else if (key_type == HSM_KEY_EC) { mbedtls_mpi r, s; int ret = 0; - mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)rsa_ecdsa; + mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) rsa_ecdsa; mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); - ret = mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL); + ret = + mbedtls_ecdsa_sign(&ecdsa->grp, &r, &s, &ecdsa->d, hsh, sizeof(hsh), random_gen, NULL); if (ret == 0) { mbedtls_mpi_write_binary(&r, p, key_size/2); p += key_size/2; mbedtls_mpi_write_binary(&s, p, key_size/2); p += key_size/2; - } - else { + } else { memset(p, 0, key_size); p += key_size; } @@ -220,14 +288,21 @@ size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf return p-buf; } -size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len) { +size_t asn1_cvc_aut(void *rsa_ecdsa, + uint8_t key_type, + uint8_t *buf, + size_t buf_len, + const uint8_t *ext, + size_t ext_len) +{ size_t cvcert_size = asn1_cvc_cert(rsa_ecdsa, key_type, NULL, 0, ext, ext_len); size_t outcar_len = dev_name_len; const uint8_t *outcar = dev_name; size_t outcar_size = asn1_len_tag(0x42, outcar_len); file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); - if (!fkey) + if (!fkey) { return 0; + } mbedtls_ecdsa_context ectx; mbedtls_ecdsa_init(&ectx); if (load_private_key_ecdsa(&ectx, fkey) != CCID_OK) { @@ -235,11 +310,15 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_ return 0; } int ret = 0, key_size = 2*mbedtls_mpi_size(&ectx.d); - size_t outsig_size = asn1_len_tag(0x5f37, key_size), tot_len = asn1_len_tag(0x67, cvcert_size+outcar_size+outsig_size); - if (buf_len == 0 || buf == NULL) + size_t outsig_size = asn1_len_tag(0x5f37, key_size), tot_len = asn1_len_tag(0x67, + cvcert_size+outcar_size+ + outsig_size); + if (buf_len == 0 || buf == NULL) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; *p++ = 0x67; p += format_tlv_len(cvcert_size+outcar_size+outsig_size, p); @@ -269,16 +348,27 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_ return p-buf; } -size_t asn1_build_cert_description(const uint8_t *label, size_t label_len, const uint8_t *puk, size_t puk_len, uint16_t fid, uint8_t *buf, size_t buf_len) { +size_t asn1_build_cert_description(const uint8_t *label, + size_t label_len, + const uint8_t *puk, + size_t puk_len, + uint16_t fid, + uint8_t *buf, + size_t buf_len) +{ size_t opt_len = 2; size_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_len)+asn1_len_tag(0x3, opt_len)); size_t seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, 20)); /* SHA1 is 20 bytes length */ - size_t seq3_size = asn1_len_tag(0xA1, asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t))))); + size_t seq3_size = + asn1_len_tag(0xA1, + asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t))))); size_t tot_len = asn1_len_tag(0x30, seq1_size+seq2_size+seq3_size); - if (buf_len == 0 || buf == NULL) + if (buf_len == 0 || buf == NULL) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; *p++ = 0x30; p += format_tlv_len(seq1_size+seq2_size+seq3_size, p); @@ -301,7 +391,8 @@ size_t asn1_build_cert_description(const uint8_t *label, size_t label_len, const //Seq 3 *p++ = 0xA1; - p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t)))), p); + p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t)))), + p); *p++ = 0x30; p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t))), p); *p++ = 0x30; @@ -313,15 +404,29 @@ size_t asn1_build_cert_description(const uint8_t *label, size_t label_len, const return p-buf; } -size_t asn1_build_prkd_generic(const uint8_t *label, size_t label_len, const uint8_t *keyid, size_t keyid_len, size_t keysize, const uint8_t *seq, size_t seq_len, uint8_t *buf, size_t buf_len) { +size_t asn1_build_prkd_generic(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + const uint8_t *seq, + size_t seq_len, + uint8_t *buf, + size_t buf_len) +{ size_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_len)); size_t seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, keyid_len)+asn1_len_tag(0x3, seq_len)); - size_t seq3_size = asn1_len_tag(0xA1, asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2,2))); + size_t seq3_size = + asn1_len_tag(0xA1, + asn1_len_tag(0x30, + asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2, 2))); size_t tot_len = asn1_len_tag(0xA0, seq1_size+seq2_size+seq3_size); - if (buf_len == 0 || buf == NULL) + if (buf_len == 0 || buf == NULL) { return tot_len; - if (buf_len < tot_len) + } + if (buf_len < tot_len) { return 0; + } uint8_t *p = buf; *p++ = 0xA0; p += format_tlv_len(seq1_size+seq2_size+seq3_size, p); @@ -344,9 +449,12 @@ size_t asn1_build_prkd_generic(const uint8_t *label, size_t label_len, const uin //Seq 3 *p++ = 0xA1; - p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2,2)), p); + p += + format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2, + 2)), + p); *p++ = 0x30; - p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2,2), p); + p += format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2, 2), p); *p++ = 0x30; p += format_tlv_len(asn1_len_tag(0x4, 0), p); *p++ = 0x4; @@ -358,65 +466,106 @@ size_t asn1_build_prkd_generic(const uint8_t *label, size_t label_len, const uin return p-buf; } -size_t asn1_build_prkd_ecc(const uint8_t *label, size_t label_len, const uint8_t *keyid, size_t keyid_len, size_t keysize, uint8_t *buf, size_t buf_len) { - return asn1_build_prkd_generic(label, label_len, keyid, keyid_len, keysize, (const uint8_t *)"\x07\x20\x80", 3, buf, buf_len); +size_t asn1_build_prkd_ecc(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + uint8_t *buf, + size_t buf_len) +{ + return asn1_build_prkd_generic(label, + label_len, + keyid, + keyid_len, + keysize, + (const uint8_t *) "\x07\x20\x80", + 3, + buf, + buf_len); } -size_t asn1_build_prkd_rsa(const uint8_t *label, size_t label_len, const uint8_t *keyid, size_t keyid_len, size_t keysize, uint8_t *buf, size_t buf_len) { - return asn1_build_prkd_generic(label, label_len, keyid, keyid_len, keysize, (const uint8_t *)"\x02\x74", 2, buf, buf_len); +size_t asn1_build_prkd_rsa(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + uint8_t *buf, + size_t buf_len) +{ + return asn1_build_prkd_generic(label, + label_len, + keyid, + keyid_len, + keysize, + (const uint8_t *) "\x02\x74", + 2, + buf, + buf_len); } -const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint16_t tag) { +const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint16_t tag) +{ uint8_t *rdata = NULL; - if (data == NULL || len == 0) + if (data == NULL || len == 0) { return NULL; - if (asn1_find_tag(data, len, tag, olen, &rdata) == false) + } + if (asn1_find_tag(data, len, tag, olen, &rdata) == false) { return NULL; + } return rdata; } -const uint8_t *cvc_get_body(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_body(const uint8_t *data, size_t len, size_t *olen) +{ const uint8_t *bkdata = data; - if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) /* Check for CSR */ + if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) { /* Check for CSR */ data = bkdata; + } if ((data = cvc_get_field(data, len, olen, 0x7F21)) != NULL) { return cvc_get_field(data, len, olen, 0x7F4E); } return NULL; } -const uint8_t *cvc_get_sig(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_sig(const uint8_t *data, size_t len, size_t *olen) +{ const uint8_t *bkdata = data; - if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) /* Check for CSR */ + if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) { /* Check for CSR */ data = bkdata; + } if ((data = cvc_get_field(data, len, olen, 0x7F21)) != NULL) { return cvc_get_field(data, len, olen, 0x5F37); } return NULL; } -const uint8_t *cvc_get_car(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_car(const uint8_t *data, size_t len, size_t *olen) +{ if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x42); } return NULL; } -const uint8_t *cvc_get_chr(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_chr(const uint8_t *data, size_t len, size_t *olen) +{ if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x5F20); } return NULL; } -const uint8_t *cvc_get_pub(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_pub(const uint8_t *data, size_t len, size_t *olen) +{ if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x7F49); } return NULL; } -const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen) +{ if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x65); } @@ -426,15 +575,18 @@ const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen) { extern PUK puk_store[MAX_PUK_STORE_ENTRIES]; extern int puk_store_entries; -int puk_store_index(const uint8_t *chr, size_t chr_len) { +int puk_store_index(const uint8_t *chr, size_t chr_len) +{ for (int i = 0; i < puk_store_entries; i++) { - if (memcmp(puk_store[i].chr, chr, chr_len) == 0) + if (memcmp(puk_store[i].chr, chr, chr_len) == 0) { return i; + } } return -1; } -mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) { +mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) +{ size_t chr_len = 0, car_len = 0; const uint8_t *chr = NULL, *car = NULL; int eq = -1; @@ -447,55 +599,67 @@ mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) { if (idx != -1) { ca = puk_store[idx].cvcert; ca_len = puk_store[idx].cvcert_len; - } - else + } else { ca = NULL; + } } } while (car && chr && eq != 0); size_t ca_puk_len = 0; const uint8_t *ca_puk = cvc_get_pub(ca, ca_len, &ca_puk_len); - if (!ca_puk) + if (!ca_puk) { return MBEDTLS_ECP_DP_NONE; + } size_t t81_len = 0; const uint8_t *t81 = cvc_get_field(ca_puk, ca_puk_len, &t81_len, 0x81); - if (!t81) + if (!t81) { return MBEDTLS_ECP_DP_NONE; + } return ec_get_curve_from_prime(t81, t81_len); } -int puk_verify(const uint8_t *sig, size_t sig_len, const uint8_t *hash, size_t hash_len, const uint8_t *ca, size_t ca_len) { +int puk_verify(const uint8_t *sig, + size_t sig_len, + const uint8_t *hash, + size_t hash_len, + const uint8_t *ca, + size_t ca_len) +{ size_t puk_len = 0; const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); - if (!puk) + if (!puk) { return CCID_WRONG_DATA; + } size_t oid_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); - if (!oid) + if (!oid) { return CCID_WRONG_DATA; + } if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA size_t t81_len = 0, t82_len = 0; - const uint8_t *t81 = cvc_get_field(puk, puk_len, &t81_len, 0x81), *t82 = cvc_get_field(puk, puk_len, &t81_len, 0x82); - if (!t81 || !t82) + const uint8_t *t81 = cvc_get_field(puk, puk_len, &t81_len, 0x81), *t82 = cvc_get_field(puk, + puk_len, + &t81_len, + 0x82); + if (!t81 || !t82) { return CCID_WRONG_DATA; + } mbedtls_rsa_context rsa; mbedtls_rsa_init(&rsa); mbedtls_md_type_t md = MBEDTLS_MD_NONE; - if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_1, oid_len) == 0) + if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_512, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_1, oid_len) == 0) { + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); - } - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_256, oid_len) == 0) { + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); - } - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_512, oid_len) == 0) { + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); } @@ -525,31 +689,35 @@ int puk_verify(const uint8_t *sig, size_t sig_len, const uint8_t *hash, size_t h } r = mbedtls_rsa_pkcs1_verify(&rsa, md, hash_len, hash, sig); mbedtls_rsa_free(&rsa); - if (r != 0) + if (r != 0) { return CCID_WRONG_SIGNATURE; - } - else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC + } + } else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC mbedtls_md_type_t md = MBEDTLS_MD_NONE; - if (memcmp(oid, OID_ID_TA_ECDSA_SHA_1, oid_len) == 0) + if (memcmp(oid, OID_ID_TA_ECDSA_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_224, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_224, oid_len) == 0) { md = MBEDTLS_MD_SHA224; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_384, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_384, oid_len) == 0) { md = MBEDTLS_MD_SHA384; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_512, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; - if (md == MBEDTLS_MD_NONE) + } + if (md == MBEDTLS_MD_NONE) { return CCID_WRONG_DATA; + } size_t t86_len = 0; const uint8_t *t86 = cvc_get_field(puk, puk_len, &t86_len, 0x86); - if (!t86) + if (!t86) { return CCID_WRONG_DATA; + } mbedtls_ecp_group_id ec_id = cvc_inherite_ec_group(ca, ca_len); - if (ec_id == MBEDTLS_ECP_DP_NONE) + if (ec_id == MBEDTLS_ECP_DP_NONE) { return CCID_WRONG_DATA; + } mbedtls_ecdsa_context ecdsa; mbedtls_ecdsa_init(&ecdsa); int ret = mbedtls_ecp_group_load(&ecdsa.grp, ec_id); @@ -588,64 +756,74 @@ int puk_verify(const uint8_t *sig, size_t sig_len, const uint8_t *hash, size_t h mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecdsa_free(&ecdsa); - if (ret != 0) + if (ret != 0) { return CCID_WRONG_SIGNATURE; + } } return CCID_OK; } -int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t ca_len) { +int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t ca_len) +{ size_t puk_len = 0; const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); - if (!puk) + if (!puk) { return CCID_WRONG_DATA; + } size_t oid_len = 0, cv_body_len = 0, sig_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); const uint8_t *cv_body = cvc_get_body(cert, cert_len, &cv_body_len); const uint8_t *sig = cvc_get_sig(cert, cert_len, &sig_len); - if (!sig) + if (!sig) { return CCID_WRONG_DATA; - if (!cv_body) + } + if (!cv_body) { return CCID_WRONG_DATA; - if (!oid) + } + if (!oid) { return CCID_WRONG_DATA; + } mbedtls_md_type_t md = MBEDTLS_MD_NONE; if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA - if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_1, oid_len) == 0) + if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_512, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_1, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_256, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_512, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; - } - else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC - if (memcmp(oid, OID_ID_TA_ECDSA_SHA_1, oid_len) == 0) + } + } else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC + if (memcmp(oid, OID_ID_TA_ECDSA_SHA_1, oid_len) == 0) { md = MBEDTLS_MD_SHA1; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_224, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_224, oid_len) == 0) { md = MBEDTLS_MD_SHA224; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, oid_len) == 0) { md = MBEDTLS_MD_SHA256; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_384, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_384, oid_len) == 0) { md = MBEDTLS_MD_SHA384; - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_512, oid_len) == 0) + } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_512, oid_len) == 0) { md = MBEDTLS_MD_SHA512; + } } - if (md == MBEDTLS_MD_NONE) + if (md == MBEDTLS_MD_NONE) { return CCID_WRONG_DATA; + } const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(md); uint8_t hash[64], hash_len = mbedtls_md_get_size(md_info); uint8_t tlv_body = 2+format_tlv_len(cv_body_len, NULL); int r = mbedtls_md(md_info, cv_body-tlv_body, cv_body_len+tlv_body, hash); - if (r != 0) + if (r != 0) { return CCID_EXEC_ERROR; + } r = puk_verify(sig, sig_len, hash, hash_len, ca, ca_len); - if (r != 0) + if (r != 0) { return CCID_WRONG_SIGNATURE; + } return CCID_OK; } diff --git a/src/hsm/cvc.h b/src/hsm/cvc.h index e87e224..1ef1f3b 100644 --- a/src/hsm/cvc.h +++ b/src/hsm/cvc.h @@ -40,9 +40,25 @@ typedef struct PUK { #define MAX_PUK_STORE_ENTRIES 4 -extern size_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len); -extern size_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, size_t buf_len, const uint8_t *ext, size_t ext_len); -extern size_t asn1_build_cert_description(const uint8_t *label, size_t label_len, const uint8_t *puk, size_t puk_len, uint16_t fid, uint8_t *buf, size_t buf_len); +extern size_t asn1_cvc_cert(void *rsa_ecdsa, + uint8_t key_type, + uint8_t *buf, + size_t buf_len, + const uint8_t *ext, + size_t ext_len); +extern size_t asn1_cvc_aut(void *rsa_ecdsa, + uint8_t key_type, + uint8_t *buf, + size_t buf_len, + const uint8_t *ext, + size_t ext_len); +extern size_t asn1_build_cert_description(const uint8_t *label, + size_t label_len, + const uint8_t *puk, + size_t puk_len, + uint16_t fid, + uint8_t *buf, + size_t buf_len); extern const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint16_t tag); extern const uint8_t *cvc_get_car(const uint8_t *data, size_t len, size_t *olen); extern const uint8_t *cvc_get_chr(const uint8_t *data, size_t len, size_t *olen); @@ -50,7 +66,24 @@ extern const uint8_t *cvc_get_pub(const uint8_t *data, size_t len, size_t *olen) extern const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen); extern int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t ca_len); extern mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len); -extern int puk_verify(const uint8_t *sig, size_t sig_len, const uint8_t *hash, size_t hash_len, const uint8_t *ca, size_t ca_len); -extern size_t asn1_build_prkd_ecc(const uint8_t *label, size_t label_len, const uint8_t *keyid, size_t keyid_len, size_t keysize, uint8_t *buf, size_t buf_len); -extern size_t asn1_build_prkd_rsa(const uint8_t *label, size_t label_len, const uint8_t *keyid, size_t keyid_len, size_t keysize, uint8_t *buf, size_t buf_len); +extern int puk_verify(const uint8_t *sig, + size_t sig_len, + const uint8_t *hash, + size_t hash_len, + const uint8_t *ca, + size_t ca_len); +extern size_t asn1_build_prkd_ecc(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + uint8_t *buf, + size_t buf_len); +extern size_t asn1_build_prkd_rsa(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + uint8_t *buf, + size_t buf_len); #endif diff --git a/src/hsm/files.c b/src/hsm/files.c index 327d469..aa63e00 100644 --- a/src/hsm/files.c +++ b/src/hsm/files.c @@ -21,39 +21,88 @@ extern const uint8_t sc_hsm_aid[]; extern int parse_token_info(const file_t *f, int mode); file_t file_entries[] = { - /* 0 */ { .fid = 0x3f00 , .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, // MF - /* 1 */ { .fid = 0x2f00 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DIR - /* 2 */ { .fid = 0x2f01 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ATR - /* 3 */ { .fid = EF_TERMCA , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.GDO - /* 4 */ { .fid = 0x2f03 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC,.data = (uint8_t *)parse_token_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo - /* 5 */ { .fid = 0x5015 , .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = {0} }, //DF.PKCS15 - /* 6 */ { .fid = 0x5031 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.ODF - /* 7 */ { .fid = 0x5032 , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.TokenInfo - /* 8 */ { .fid = 0x5033 , .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.UnusedSpace - /* 9 */ { .fid = 0x1081 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (PIN1) - /* 10 */ { .fid = 0x1082 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (PIN1) - /* 11 */ { .fid = 0x1083 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (PIN1) - /* 12 */ { .fid = 0x1088 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PIN (SOPIN) - /* 13 */ { .fid = 0x1089 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN) - /* 14 */ { .fid = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN) - /* 15 */ { .fid = EF_DEVOPS , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device options - /* 16 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs - /* 17 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs - /* 18 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs - /* 19 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs - /* 20 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs - /* 21 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs - /* 22 */ { .fid = EF_KEY_DOMAIN, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Key domain options - /* 23 */ { .fid = EF_META , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //EF.CDFs - /* 24 */ { .fid = EF_PUKAUT, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Public Key Authentication - /* 25 */ { .fid = EF_KEY_DEV, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device Key - /* 26 */ { .fid = EF_PRKD_DEV, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //PrKD Device - /* 27 */ { .fid = EF_EE_DEV, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //End Entity Certificate Device - /* 28 */ { .fid = EF_MKEK , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //MKEK - /* 29 */ { .fid = EF_MKEK_SO , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //MKEK with SO-PIN + /* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, + .ef_structure = 0, .acl = { 0 } }, // MF + /* 1 */ { .fid = 0x2f00, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.DIR + /* 2 */ { .fid = 0x2f01, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.ATR + /* 3 */ { .fid = EF_TERMCA, .parent = 0, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.GDO + /* 4 */ { .fid = 0x2f03, .parent = 5, .name = NULL, + .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_token_info, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.TokenInfo + /* 5 */ { .fid = 0x5015, .parent = 0, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, + .ef_structure = 0, .acl = { 0 } }, //DF.PKCS15 + /* 6 */ { .fid = 0x5031, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.ODF + /* 7 */ { .fid = 0x5032, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.TokenInfo + /* 8 */ { .fid = 0x5033, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.UnusedSpace + /* 9 */ { .fid = 0x1081, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //PIN (PIN1) + /* 10 */ { .fid = 0x1082, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //max retries PIN (PIN1) + /* 11 */ { .fid = 0x1083, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (PIN1) + /* 12 */ { .fid = 0x1088, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //PIN (SOPIN) + /* 13 */ { .fid = 0x1089, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //max retries PIN (SOPIN) + /* 14 */ { .fid = 0x108A, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (SOPIN) + /* 15 */ { .fid = EF_DEVOPS, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Device options + /* 16 */ { .fid = EF_PRKDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.PrKDFs + /* 17 */ { .fid = EF_PUKDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.PuKDFs + /* 18 */ { .fid = EF_CDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.CDFs + /* 19 */ { .fid = EF_AODFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.AODFs + /* 20 */ { .fid = EF_DODFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.DODFs + /* 21 */ { .fid = EF_SKDFS, .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.SKDFs + /* 22 */ { .fid = EF_KEY_DOMAIN, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Key domain options + /* 23 */ { .fid = EF_META, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //EF.CDFs + /* 24 */ { .fid = EF_PUKAUT, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Public Key Authentication + /* 25 */ { .fid = EF_KEY_DEV, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //Device Key + /* 26 */ { .fid = EF_PRKD_DEV, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //PrKD Device + /* 27 */ { .fid = EF_EE_DEV, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //End Entity Certificate Device + /* 28 */ { .fid = EF_MKEK, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //MKEK + /* 29 */ { .fid = EF_MKEK_SO, .parent = 5, .name = NULL, + .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH | FILE_PERSISTENT, .data = NULL, + .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //MKEK with SO-PIN ///* 30 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, - /* 31 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, - /* 32 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end + /* 31 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, + .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, + /* 32 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, + .ef_structure = 0, .acl = { 0 } } //end }; const file_t *MF = &file_entries[0]; @@ -63,4 +112,4 @@ const file_t *file_sc_hsm = &file_entries[sizeof(file_entries)/sizeof(file_t)-2] file_t *file_pin1 = NULL; file_t *file_retries_pin1 = NULL; file_t *file_sopin = NULL; -file_t *file_retries_sopin = NULL; \ No newline at end of file +file_t *file_retries_sopin = NULL; diff --git a/src/hsm/files.h b/src/hsm/files.h index 6090d55..e33a4d0 100644 --- a/src/hsm/files.h +++ b/src/hsm/files.h @@ -47,4 +47,4 @@ extern file_t *file_retries_pin1; extern file_t *file_sopin; extern file_t *file_retries_sopin; -#endif \ No newline at end of file +#endif diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 2c1f260..a12ee51 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -44,15 +44,18 @@ uint32_t crc32c(const uint8_t *buf, size_t len) uint32_t crc = ~0; while (len--) { crc ^= *buf++; - for (int k = 0; k < 8; k++) + for (int k = 0; k < 8; k++) { crc = (crc >> 1) ^ (POLY & (0 - (crc & 1))); + } } return ~crc; } -int load_mkek(uint8_t *mkek) { - if (has_session_pin == false && has_session_sopin == false) +int load_mkek(uint8_t *mkek) +{ + if (has_session_pin == false && has_session_sopin == false) { return CCID_NO_LOGIN; + } const uint8_t *pin = NULL; if (pin == NULL && has_session_pin == true) { file_t *tf = search_by_fid(EF_MKEK, NULL, SPECIFY_EF); @@ -68,56 +71,73 @@ int load_mkek(uint8_t *mkek) { pin = session_sopin; } } - if (pin == NULL) //Should never happen + if (pin == NULL) { //Should never happen return CCID_EXEC_ERROR; + } if (has_mkek_mask) { for (int i = 0; i < MKEK_KEY_SIZE; i++) { MKEK_KEY(mkek)[i] ^= mkek_mask[i]; } } - int ret = aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE); - if (ret != 0) + int ret = + aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE); + if (ret != 0) { return CCID_EXEC_ERROR; - if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *)MKEK_CHECKSUM(mkek)) + } + if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *) MKEK_CHECKSUM(mkek)) { return CCID_WRONG_DKEK; + } return CCID_OK; } -mse_t mse = {.init = false}; +mse_t mse = { .init = false }; -int mse_decrypt_ct(uint8_t *data, size_t len) { +int mse_decrypt_ct(uint8_t *data, size_t len) +{ mbedtls_chachapoly_context chatx; mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12); - int ret = mbedtls_chachapoly_auth_decrypt(&chatx, len - 16, mse.key_enc, mse.Qpt, 65, data + len - 16, data, data); + int ret = mbedtls_chachapoly_auth_decrypt(&chatx, + len - 16, + mse.key_enc, + mse.Qpt, + 65, + data + len - 16, + data, + data); mbedtls_chachapoly_free(&chatx); return ret; } -int load_dkek(uint8_t id, uint8_t *dkek) { +int load_dkek(uint8_t id, uint8_t *dkek) +{ file_t *tf = search_dynamic_file(EF_DKEK+id); - if (!tf) + if (!tf) { return CCID_ERR_FILE_NOT_FOUND; + } memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE); return mkek_decrypt(dkek, DKEK_KEY_SIZE); } -void release_mkek(uint8_t *mkek) { +void release_mkek(uint8_t *mkek) +{ mbedtls_platform_zeroize(mkek, MKEK_SIZE); } -int store_mkek(const uint8_t *mkek) { - if (has_session_pin == false && has_session_sopin == false) +int store_mkek(const uint8_t *mkek) +{ + if (has_session_pin == false && has_session_sopin == false) { return CCID_NO_LOGIN; + } uint8_t tmp_mkek[MKEK_SIZE]; if (mkek == NULL) { const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE+MKEK_KEY_SIZE); memcpy(tmp_mkek, rd, MKEK_IV_SIZE+MKEK_KEY_SIZE); - } - else + } else { memcpy(tmp_mkek, mkek, MKEK_SIZE); - *(uint32_t*)MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE); + } + *(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE); if (has_session_pin) { uint8_t tmp_mkek_pin[MKEK_SIZE]; memcpy(tmp_mkek_pin, tmp_mkek, MKEK_SIZE); @@ -127,7 +147,10 @@ int store_mkek(const uint8_t *mkek) { release_mkek(tmp_mkek_pin); return CCID_ERR_FILE_NOT_FOUND; } - aes_encrypt_cfb_256(session_pin, MKEK_IV(tmp_mkek_pin), MKEK_KEY(tmp_mkek_pin), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE); + aes_encrypt_cfb_256(session_pin, + MKEK_IV(tmp_mkek_pin), + MKEK_KEY(tmp_mkek_pin), + MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE); flash_write_data_to_file(tf, tmp_mkek_pin, MKEK_SIZE); release_mkek(tmp_mkek_pin); } @@ -140,7 +163,10 @@ int store_mkek(const uint8_t *mkek) { release_mkek(tmp_mkek_sopin); return CCID_ERR_FILE_NOT_FOUND; } - aes_encrypt_cfb_256(session_sopin, MKEK_IV(tmp_mkek_sopin), MKEK_KEY(tmp_mkek_sopin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE); + aes_encrypt_cfb_256(session_sopin, + MKEK_IV(tmp_mkek_sopin), + MKEK_KEY(tmp_mkek_sopin), + MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE); flash_write_data_to_file(tf, tmp_mkek_sopin, MKEK_SIZE); release_mkek(tmp_mkek_sopin); } @@ -149,106 +175,133 @@ int store_mkek(const uint8_t *mkek) { return CCID_OK; } -int store_dkek_key(uint8_t id, uint8_t *dkek) { +int store_dkek_key(uint8_t id, uint8_t *dkek) +{ file_t *tf = search_dynamic_file(EF_DKEK+id); - if (!tf) + if (!tf) { return CCID_ERR_FILE_NOT_FOUND; + } int r = mkek_encrypt(dkek, DKEK_KEY_SIZE); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } flash_write_data_to_file(tf, dkek, DKEK_KEY_SIZE); low_flash_available(); return CCID_OK; } -int save_dkek_key(uint8_t id, const uint8_t *key) { +int save_dkek_key(uint8_t id, const uint8_t *key) +{ uint8_t dkek[DKEK_KEY_SIZE]; if (!key) { file_t *tf = search_dynamic_file(EF_DKEK+id); - if (!tf) + if (!tf) { return CCID_ERR_FILE_NOT_FOUND; + } memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE); - } - else + } else { memcpy(dkek, key, DKEK_KEY_SIZE); + } return store_dkek_key(id, dkek); } -int import_dkek_share(uint8_t id, const uint8_t *share) { +int import_dkek_share(uint8_t id, const uint8_t *share) +{ uint8_t tmp_dkek[DKEK_KEY_SIZE]; file_t *tf = search_dynamic_file(EF_DKEK+id); - if (!tf) + if (!tf) { return CCID_ERR_FILE_NOT_FOUND; + } memset(tmp_dkek, 0, sizeof(tmp_dkek)); - if (file_get_size(tf) == DKEK_KEY_SIZE) - memcpy(tmp_dkek, file_get_data(tf),DKEK_KEY_SIZE); - for (int i = 0; i < DKEK_KEY_SIZE; i++) + if (file_get_size(tf) == DKEK_KEY_SIZE) { + memcpy(tmp_dkek, file_get_data(tf), DKEK_KEY_SIZE); + } + for (int i = 0; i < DKEK_KEY_SIZE; i++) { tmp_dkek[i] ^= share[i]; + } flash_write_data_to_file(tf, tmp_dkek, DKEK_KEY_SIZE); low_flash_available(); return CCID_OK; } -int dkek_kcv(uint8_t id, uint8_t *kcv) { //kcv 8 bytes +int dkek_kcv(uint8_t id, uint8_t *kcv) //kcv 8 bytes +{ uint8_t hsh[32], dkek[DKEK_KEY_SIZE]; memset(kcv, 0, 8); memset(hsh, 0, sizeof(hsh)); int r = load_dkek(id, dkek); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } hash256(dkek, DKEK_KEY_SIZE, hsh); mbedtls_platform_zeroize(dkek, sizeof(dkek)); memcpy(kcv, hsh, 8); return CCID_OK; } -int dkek_kenc(uint8_t id, uint8_t *kenc) { //kenc 32 bytes +int dkek_kenc(uint8_t id, uint8_t *kenc) //kenc 32 bytes +{ uint8_t dkek[DKEK_KEY_SIZE+4]; memset(kenc, 0, 32); int r = load_dkek(id, dkek); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } memcpy(dkek+DKEK_KEY_SIZE, "\x0\x0\x0\x1", 4); hash256(dkek, sizeof(dkek), kenc); mbedtls_platform_zeroize(dkek, sizeof(dkek)); return CCID_OK; } -int dkek_kmac(uint8_t id, uint8_t *kmac) { //kmac 32 bytes +int dkek_kmac(uint8_t id, uint8_t *kmac) //kmac 32 bytes +{ uint8_t dkek[DKEK_KEY_SIZE+4]; memset(kmac, 0, 32); int r = load_dkek(id, dkek); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } memcpy(dkek+DKEK_KEY_SIZE, "\x0\x0\x0\x2", 4); hash256(dkek, DKEK_KEY_SIZE+4, kmac); mbedtls_platform_zeroize(dkek, sizeof(dkek)); return CCID_OK; } -int mkek_encrypt(uint8_t *data, size_t len) { +int mkek_encrypt(uint8_t *data, size_t len) +{ int r; uint8_t mkek[MKEK_SIZE+4]; - if ((r = load_mkek(mkek)) != CCID_OK) + if ((r = load_mkek(mkek)) != CCID_OK) { return r; + } r = aes_encrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), data, len); release_mkek(mkek); return r; } -int mkek_decrypt(uint8_t *data, size_t len) { +int mkek_decrypt(uint8_t *data, size_t len) +{ int r; uint8_t mkek[MKEK_SIZE+4]; - if ((r = load_mkek(mkek)) != CCID_OK) + if ((r = load_mkek(mkek)) != CCID_OK) { return r; + } r = aes_decrypt_cfb_256(MKEK_KEY(mkek), MKEK_IV(mkek), data, len); release_mkek(mkek); return r; } -int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_t *out_len, const uint8_t *allowed, size_t allowed_len) { - if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES)) +int dkek_encode_key(uint8_t id, + void *key_ctx, + int key_type, + uint8_t *out, + size_t *out_len, + const uint8_t *allowed, + size_t allowed_len) +{ + if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES)) { return CCID_WRONG_DATA; + } uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding) memset(kb, 0, sizeof(kb)); @@ -258,84 +311,104 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_ uint8_t kenc[32]; memset(kenc, 0, sizeof(kenc)); r = dkek_kenc(id, kenc); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } uint8_t kcv[8]; memset(kcv, 0, sizeof(kcv)); r = dkek_kcv(id, kcv); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } uint8_t kmac[32]; memset(kmac, 0, sizeof(kmac)); r = dkek_kmac(id, kmac); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } if (key_type & HSM_KEY_AES) { - if (key_type & HSM_KEY_AES_128) + if (key_type & HSM_KEY_AES_128) { kb_len = 16; - else if (key_type & HSM_KEY_AES_192) + } else if (key_type & HSM_KEY_AES_192) { kb_len = 24; - else if (key_type & HSM_KEY_AES_256) + } else if (key_type & HSM_KEY_AES_256) { kb_len = 32; + } - if (kb_len != 16 && kb_len != 24 && kb_len != 32) + if (kb_len != 16 && kb_len != 24 && kb_len != 32) { return CCID_WRONG_DATA; - if (*out_len < 8+1+10+6+4+(2+32+14)+16) + } + if (*out_len < 8+1+10+6+4+(2+32+14)+16) { return CCID_WRONG_LENGTH; + } put_uint16_t(kb_len, kb+8); memcpy(kb+10, key_ctx, kb_len); kb_len += 2; - algo = (uint8_t *)"\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01"; //2.16.840.1.101.3.4.1 (2+8) + algo = (uint8_t *) "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01"; //2.16.840.1.101.3.4.1 (2+8) algo_len = 10; - } - else if (key_type & HSM_KEY_RSA) { - if (*out_len < 8+1+12+6+(8+2*4+2*4096/8+3+13)+16) //13 bytes pading + } else if (key_type & HSM_KEY_RSA) { + if (*out_len < 8+1+12+6+(8+2*4+2*4096/8+3+13)+16) { //13 bytes pading return CCID_WRONG_LENGTH; - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx; + } + mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; kb_len = 0; put_uint16_t(mbedtls_rsa_get_len(rsa)*8, kb+8+kb_len); kb_len += 2; put_uint16_t(mbedtls_mpi_size(&rsa->D), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&rsa->D, kb+8+kb_len, mbedtls_mpi_size(&rsa->D)); kb_len += mbedtls_mpi_size(&rsa->D); + mbedtls_mpi_write_binary(&rsa->D, kb+8+kb_len, mbedtls_mpi_size(&rsa->D)); + kb_len += mbedtls_mpi_size(&rsa->D); put_uint16_t(mbedtls_mpi_size(&rsa->N), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&rsa->N, kb+8+kb_len, mbedtls_mpi_size(&rsa->N)); kb_len += mbedtls_mpi_size(&rsa->N); + mbedtls_mpi_write_binary(&rsa->N, kb+8+kb_len, mbedtls_mpi_size(&rsa->N)); + kb_len += mbedtls_mpi_size(&rsa->N); put_uint16_t(mbedtls_mpi_size(&rsa->E), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&rsa->E, kb+8+kb_len, mbedtls_mpi_size(&rsa->E)); kb_len += mbedtls_mpi_size(&rsa->E); + mbedtls_mpi_write_binary(&rsa->E, kb+8+kb_len, mbedtls_mpi_size(&rsa->E)); + kb_len += mbedtls_mpi_size(&rsa->E); - algo = (uint8_t *)"\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02"; + algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02"; algo_len = 12; - } - else if (key_type & HSM_KEY_EC) { - if (*out_len < 8+1+12+6+(8+2*8+9*66+2+4)+16) //4 bytes pading + } else if (key_type & HSM_KEY_EC) { + if (*out_len < 8+1+12+6+(8+2*8+9*66+2+4)+16) { //4 bytes pading return CCID_WRONG_LENGTH; - mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx; + } + mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; kb_len = 0; put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P)*8, kb+8+kb_len); kb_len += 2; put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.A), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&ecdsa->grp.A, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.A)); kb_len += mbedtls_mpi_size(&ecdsa->grp.A); + mbedtls_mpi_write_binary(&ecdsa->grp.A, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.A)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.A); put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.B), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&ecdsa->grp.B, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.B)); kb_len += mbedtls_mpi_size(&ecdsa->grp.B); + mbedtls_mpi_write_binary(&ecdsa->grp.B, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.B)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.B); put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&ecdsa->grp.P, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.P)); kb_len += mbedtls_mpi_size(&ecdsa->grp.P); + mbedtls_mpi_write_binary(&ecdsa->grp.P, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.P)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.P); put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.N), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&ecdsa->grp.N, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.N)); kb_len += mbedtls_mpi_size(&ecdsa->grp.N); - put_uint16_t(1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.Y), kb+8+kb_len); kb_len += 2; + mbedtls_mpi_write_binary(&ecdsa->grp.N, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.N)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.N); + put_uint16_t(1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.Y), + kb+8+kb_len); kb_len += 2; kb[8+kb_len++] = 0x4; - mbedtls_mpi_write_binary(&ecdsa->grp.G.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.X)); kb_len += mbedtls_mpi_size(&ecdsa->grp.G.X); - mbedtls_mpi_write_binary(&ecdsa->grp.G.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.Y)); kb_len += mbedtls_mpi_size(&ecdsa->grp.G.Y); + mbedtls_mpi_write_binary(&ecdsa->grp.G.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.X)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.G.X); + mbedtls_mpi_write_binary(&ecdsa->grp.G.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.Y)); + kb_len += mbedtls_mpi_size(&ecdsa->grp.G.Y); put_uint16_t(mbedtls_mpi_size(&ecdsa->d), kb+8+kb_len); kb_len += 2; - mbedtls_mpi_write_binary(&ecdsa->d, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->d)); kb_len += mbedtls_mpi_size(&ecdsa->d); - put_uint16_t(1+mbedtls_mpi_size(&ecdsa->Q.X)+mbedtls_mpi_size(&ecdsa->Q.Y), kb+8+kb_len); kb_len += 2; + mbedtls_mpi_write_binary(&ecdsa->d, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->d)); + kb_len += mbedtls_mpi_size(&ecdsa->d); + put_uint16_t(1+mbedtls_mpi_size(&ecdsa->Q.X)+mbedtls_mpi_size(&ecdsa->Q.Y), kb+8+kb_len); + kb_len += 2; kb[8+kb_len++] = 0x4; - mbedtls_mpi_write_binary(&ecdsa->Q.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.X)); kb_len += mbedtls_mpi_size(&ecdsa->Q.X); - mbedtls_mpi_write_binary(&ecdsa->Q.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.Y)); kb_len += mbedtls_mpi_size(&ecdsa->Q.Y); + mbedtls_mpi_write_binary(&ecdsa->Q.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.X)); + kb_len += mbedtls_mpi_size(&ecdsa->Q.X); + mbedtls_mpi_write_binary(&ecdsa->Q.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.Y)); + kb_len += mbedtls_mpi_size(&ecdsa->Q.Y); - algo = (uint8_t *)"\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03"; + algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03"; algo_len = 12; } memset(out, 0, *out_len); @@ -344,107 +417,142 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_ memcpy(out+*out_len, kcv, 8); *out_len += 8; - if (key_type & HSM_KEY_AES) + if (key_type & HSM_KEY_AES) { out[*out_len] = 15; - else if (key_type & HSM_KEY_RSA) + } else if (key_type & HSM_KEY_RSA) { out[*out_len] = 5; - else if (key_type & HSM_KEY_EC) + } else if (key_type & HSM_KEY_EC) { out[*out_len] = 12; + } *out_len += 1; if (algo) { memcpy(out+*out_len, algo, algo_len); *out_len += algo_len; - } - else + } else { *out_len += 2; + } if (allowed && allowed_len > 0) { put_uint16_t(allowed_len, out+*out_len); *out_len += 2; memcpy(out+*out_len, allowed, allowed_len); *out_len += allowed_len; - } - else + } else { *out_len += 2; + } //add 4 zeros *out_len += 4; memcpy(kb, random_bytes_get(8), 8); kb_len += 8; //8 random bytes - int kb_len_pad = ((int)(kb_len/16))*16; - if (kb_len % 16 > 0) - kb_len_pad = ((int)(kb_len/16)+1)*16; + int kb_len_pad = ((int) (kb_len/16))*16; + if (kb_len % 16 > 0) { + kb_len_pad = ((int) (kb_len/16)+1)*16; + } //key already copied at kb+10 if (kb_len < kb_len_pad) { kb[kb_len] = 0x80; } r = aes_encrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, kb_len_pad); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } memcpy(out+*out_len, kb, kb_len_pad); *out_len += kb_len_pad; - r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, out, *out_len, out+*out_len); + r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), + kmac, + 256, + out, + *out_len, + out+*out_len); *out_len += 16; - if (r != 0) + if (r != 0) { return r; + } return CCID_OK; } -int dkek_type_key(const uint8_t *in) { - if (in[8] == 5 || in[8] == 6) +int dkek_type_key(const uint8_t *in) +{ + if (in[8] == 5 || in[8] == 6) { return HSM_KEY_RSA; - else if (in[8] == 12) + } else if (in[8] == 12) { return HSM_KEY_EC; - else if (in[8] == 15) + } else if (in[8] == 15) { return HSM_KEY_AES; + } return 0x0; } -int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out, uint8_t **allowed, size_t *allowed_len) { +int dkek_decode_key(uint8_t id, + void *key_ctx, + const uint8_t *in, + size_t in_len, + int *key_size_out, + uint8_t **allowed, + size_t *allowed_len) +{ uint8_t kcv[8]; int r = 0; memset(kcv, 0, sizeof(kcv)); r = dkek_kcv(id, kcv); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } uint8_t kmac[32]; memset(kmac, 0, sizeof(kmac)); r = dkek_kmac(id, kmac); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } uint8_t kenc[32]; memset(kenc, 0, sizeof(kenc)); r = dkek_kenc(id, kenc); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } - if (memcmp(kcv, in, 8) != 0) + if (memcmp(kcv, in, 8) != 0) { return CCID_WRONG_DKEK; + } uint8_t signature[16]; - r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), kmac, 256, in, in_len-16, signature); - if (r != 0) + r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB), + kmac, + 256, + in, + in_len-16, + signature); + if (r != 0) { return CCID_WRONG_SIGNATURE; - if (memcmp(signature, in+in_len-16, 16) != 0) + } + if (memcmp(signature, in+in_len-16, 16) != 0) { return CCID_WRONG_SIGNATURE; + } int key_type = in[8]; - if (key_type != 5 && key_type != 6 && key_type != 12 && key_type != 15) + if (key_type != 5 && key_type != 6 && key_type != 12 && key_type != 15) { return CCID_WRONG_DATA; + } - if ((key_type == 5 || key_type == 6) && memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0) + if ((key_type == 5 || key_type == 6) && + memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0) { return CCID_WRONG_DATA; + } - if (key_type == 12 && memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0) + if (key_type == 12 && + memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0) { return CCID_WRONG_DATA; + } - if (key_type == 15 && memcmp(in+9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0) + if (key_type == 15 && memcmp(in+9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0) { return CCID_WRONG_DATA; + } size_t ofs = 9; @@ -454,7 +562,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, //Allowed algorithms len = get_uint16_t(in, ofs); - *allowed = (uint8_t *)(in+ofs+2); + *allowed = (uint8_t *) (in+ofs+2); *allowed_len = len; ofs += len+2; @@ -466,21 +574,24 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, len = get_uint16_t(in, ofs); ofs += len+2; - if ((in_len-16-ofs) % 16 != 0) + if ((in_len-16-ofs) % 16 != 0) { return CCID_WRONG_PADDING; + } uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding) memset(kb, 0, sizeof(kb)); memcpy(kb, in+ofs, in_len-16-ofs); r = aes_decrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len-16-ofs); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } int key_size = get_uint16_t(kb, 8); - if (key_size_out) + if (key_size_out) { *key_size_out = key_size; + } ofs = 10; if (key_type == 5 || key_type == 6) { - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx; + mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; mbedtls_rsa_init(rsa); if (key_type == 5) { len = get_uint16_t(kb, ofs); ofs += 2; @@ -496,8 +607,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, mbedtls_rsa_free(rsa); return CCID_WRONG_DATA; } - } - else if (key_type == 6) { + } else if (key_type == 6) { //DP-1 len = get_uint16_t(kb, ofs); ofs += len+2; @@ -537,8 +647,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, mbedtls_rsa_free(rsa); return CCID_EXEC_ERROR; } - } - else if (key_type == 6) { + } else if (key_type == 6) { r = mbedtls_rsa_import(rsa, NULL, &rsa->P, &rsa->Q, NULL, &rsa->E); if (r != 0) { mbedtls_rsa_free(rsa); @@ -556,9 +665,8 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, mbedtls_rsa_free(rsa); return CCID_EXEC_ERROR; } - } - else if (key_type == 12) { - mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx; + } else if (key_type == 12) { + mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; mbedtls_ecdsa_init(ecdsa); //A @@ -603,8 +711,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, mbedtls_ecdsa_free(ecdsa); return CCID_EXEC_ERROR; } - } - else if (key_type == 15) { + } else if (key_type == 15) { memcpy(key_ctx, kb+ofs, key_size); } return CCID_OK; diff --git a/src/hsm/kek.h b/src/hsm/kek.h index f7b48e0..9f5e22c 100644 --- a/src/hsm/kek.h +++ b/src/hsm/kek.h @@ -33,9 +33,21 @@ extern int import_dkek_share(uint8_t, const uint8_t *share); extern int dkek_kcv(uint8_t, uint8_t *kcv); extern int mkek_encrypt(uint8_t *data, size_t len); extern int mkek_decrypt(uint8_t *data, size_t len); -extern int dkek_encode_key(uint8_t, void *key_ctx, int key_type, uint8_t *out, size_t *out_len, const uint8_t *, size_t); +extern int dkek_encode_key(uint8_t, + void *key_ctx, + int key_type, + uint8_t *out, + size_t *out_len, + const uint8_t *, + size_t); extern int dkek_type_key(const uint8_t *in); -extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out, uint8_t **, size_t *); +extern int dkek_decode_key(uint8_t, + void *key_ctx, + const uint8_t *in, + size_t in_len, + int *key_size_out, + uint8_t **, + size_t *); #define MAX_DKEK_ENCODE_KEY_BUFFER (8+1+12+6+(8+2*4+2*4096/8+3+13)+16) diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index bc46711..d74db76 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -29,12 +29,13 @@ const uint8_t sc_hsm_aid[] = { 11, - 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01 + 0xE8, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xC3, 0x1F, 0x02, 0x01 }; const uint8_t atr_sc_hsm[] = { 24, - 0x3B,0xFE,0x18,0x00,0x00,0x81,0x31,0xFE,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xFA + 0x3B, 0xFE, 0x18, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x45, 0x80, 0x31, 0x81, 0x54, 0x48, 0x53, 0x4D, + 0x31, 0x73, 0x80, 0x21, 0x40, 0x81, 0x07, 0xFA }; uint8_t session_pin[32], session_sopin[32]; @@ -77,8 +78,9 @@ extern int cmd_pso(); extern const uint8_t *ccid_atr; -app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) { - if (!memcmp(aid, sc_hsm_aid+1, MIN(aid_len,sc_hsm_aid[0]))) { +app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) +{ + if (!memcmp(aid, sc_hsm_aid+1, MIN(aid_len, sc_hsm_aid[0]))) { a->aid = sc_hsm_aid; a->process_apdu = sc_hsm_process_apdu; a->unload = sc_hsm_unload; @@ -88,12 +90,14 @@ app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) { return NULL; } -void __attribute__ ((constructor)) sc_hsm_ctor() { +void __attribute__((constructor)) sc_hsm_ctor() +{ ccid_atr = atr_sc_hsm; register_app(sc_hsm_select_aid); } -void scan_files() { +void scan_files() +{ file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF); if (file_pin1) { if (!file_pin1->data) { @@ -101,8 +105,7 @@ void scan_files() { const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_pin1, empty, sizeof(empty)); } - } - else { + } else { printf("FATAL ERROR: PIN1 not found in memory!\r\n"); } file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF); @@ -112,8 +115,7 @@ void scan_files() { const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_sopin, empty, sizeof(empty)); } - } - else { + } else { printf("FATAL ERROR: SOPIN not found in memory!\r\n"); } file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF); @@ -123,8 +125,7 @@ void scan_files() { const uint8_t retries = 3; flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t)); } - } - else { + } else { printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n"); } file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF); @@ -134,8 +135,7 @@ void scan_files() { const uint8_t retries = 15; flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t)); } - } - else { + } else { printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); } file_t *tf = NULL; @@ -147,8 +147,7 @@ void scan_files() { const uint8_t retries = 3; flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); } - } - else { + } else { printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n"); } tf = search_by_fid(0x1089, NULL, SPECIFY_EF); @@ -158,14 +157,14 @@ void scan_files() { const uint8_t retries = 15; flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); } - } - else { + } else { printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); } low_flash_available(); } -void scan_all() { +void scan_all() +{ scan_flash(); scan_files(); } @@ -175,30 +174,40 @@ int puk_store_entries = 0; PUK *current_puk = NULL; uint8_t puk_status[MAX_PUK]; -int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) { - if (data == NULL || data_len == 0) +int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) +{ + if (data == NULL || data_len == 0) { return CCID_ERR_NULL_PARAM; - if (puk_store_entries == MAX_PUK_STORE_ENTRIES) + } + if (puk_store_entries == MAX_PUK_STORE_ENTRIES) { return CCID_ERR_MEMORY_FATAL; + } puk_store[puk_store_entries].copied = copy; if (copy == true) { - uint8_t *tmp = (uint8_t *)calloc(data_len, sizeof(uint8_t)); + uint8_t *tmp = (uint8_t *) calloc(data_len, sizeof(uint8_t)); memcpy(tmp, data, data_len); puk_store[puk_store_entries].cvcert = tmp; - } - else + } else { puk_store[puk_store_entries].cvcert = data; + } puk_store[puk_store_entries].cvcert_len = data_len; - puk_store[puk_store_entries].chr = cvc_get_chr(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].chr_len); - puk_store[puk_store_entries].car = cvc_get_car(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].car_len); - puk_store[puk_store_entries].puk = cvc_get_pub(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].puk_len); + puk_store[puk_store_entries].chr = cvc_get_chr(puk_store[puk_store_entries].cvcert, + data_len, + &puk_store[puk_store_entries].chr_len); + puk_store[puk_store_entries].car = cvc_get_car(puk_store[puk_store_entries].cvcert, + data_len, + &puk_store[puk_store_entries].car_len); + puk_store[puk_store_entries].puk = cvc_get_pub(puk_store[puk_store_entries].cvcert, + data_len, + &puk_store[puk_store_entries].puk_len); puk_store_entries++; return CCID_OK; } -int puk_store_select_chr(const uint8_t *chr) { +int puk_store_select_chr(const uint8_t *chr) +{ for (int i = 0; i < puk_store_entries; i++) { if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) { current_puk = &puk_store[i]; @@ -208,48 +217,56 @@ int puk_store_select_chr(const uint8_t *chr) { return CCID_ERR_FILE_NOT_FOUND; } -void init_sc_hsm() { +void init_sc_hsm() +{ scan_all(); has_session_pin = has_session_sopin = false; isUserAuthenticated = false; cmd_select(); if (puk_store_entries > 0) { /* From previous session */ for (int i = 0; i < puk_store_entries; i++) { - if (puk_store[i].copied == true) - free((uint8_t *)puk_store[i].cvcert); + if (puk_store[i].copied == true) { + free((uint8_t *) puk_store[i].cvcert); + } } } memset(puk_store, 0, sizeof(puk_store)); puk_store_entries = 0; file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); - if (fterm) + if (fterm) { add_cert_puk_store(file_get_data(fterm), file_get_size(fterm), false); + } for (int i = 0; i < 0xfe; i++) { file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | i); - if (ef && file_get_size(ef) > 0) + if (ef && file_get_size(ef) > 0) { add_cert_puk_store(file_get_data(ef), file_get_size(ef), false); + } } dev_name = cvc_get_chr(file_get_data(fterm), file_get_size(fterm), &dev_name_len); memset(puk_status, 0, sizeof(puk_status)); } -int sc_hsm_unload() { +int sc_hsm_unload() +{ has_session_pin = has_session_sopin = false; isUserAuthenticated = false; sm_session_pin_len = 0; return CCID_OK; } -uint16_t get_device_options() { +uint16_t get_device_options() +{ file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); - if (file_has_data(ef)) + if (file_has_data(ef)) { return (file_read_uint8(file_get_data(ef)) << 8) | file_read_uint8(file_get_data(ef)+1); + } return 0x0; } extern uint32_t board_button_read(void); -bool wait_button_pressed() { +bool wait_button_pressed() +{ uint32_t val = EV_PRESS_BUTTON; #ifndef ENABLE_EMULATION uint16_t opts = get_device_options(); @@ -257,14 +274,14 @@ bool wait_button_pressed() { queue_try_add(&card_to_usb_q, &val); do { queue_remove_blocking(&usb_to_card_q, &val); - } - while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT); + } while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT); } #endif return val == EV_BUTTON_TIMEOUT; } -int parse_token_info(const file_t *f, int mode) { +int parse_token_info(const file_t *f, int mode) +{ char *label = "SmartCard-HSM"; char *manu = "Pol Henarejos"; if (mode == 1) { @@ -273,12 +290,12 @@ int parse_token_info(const file_t *f, int mode) { *p++ = 0; //set later *p++ = 0x2; *p++ = 1; *p++ = HSM_VERSION_MAJOR; #ifndef ENABLE_EMULATION - *p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *)p); p += 8; + *p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *) p); p += 8; #else *p++ = 0x4; *p++ = 8; memset(p, 0, 8); p += 8; #endif - *p++ = 0xC; *p++ = strlen(manu); strcpy((char *)p, manu); p += strlen(manu); - *p++ = 0x80; *p++ = strlen(label); strcpy((char *)p, label); p += strlen(label); + *p++ = 0xC; *p++ = strlen(manu); strcpy((char *) p, manu); p += strlen(manu); + *p++ = 0x80; *p++ = strlen(label); strcpy((char *) p, label); p += strlen(label); *p++ = 0x3; *p++ = 2; *p++ = 4; *p++ = 0x30; res_APDU_size = p-res_APDU; res_APDU[1] = res_APDU_size-2; @@ -286,95 +303,113 @@ int parse_token_info(const file_t *f, int mode) { return 2+(2+1)+(2+8)+(2+strlen(manu))+(2+strlen(label))+(2+2); } -int pin_reset_retries(const file_t *pin, bool force) { - if (!pin) +int pin_reset_retries(const file_t *pin, bool force) +{ + if (!pin) { return CCID_ERR_NULL_PARAM; + } const file_t *max = search_by_fid(pin->fid+1, NULL, SPECIFY_EF); const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF); - if (!max || !act) + if (!max || !act) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t retries = file_read_uint8(file_get_data(act)); - if (retries == 0 && force == false) //blocked + if (retries == 0 && force == false) { //blocked return CCID_ERR_BLOCKED; + } retries = file_read_uint8(file_get_data(max)); - int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries)); + int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries)); low_flash_available(); return r; } -int pin_wrong_retry(const file_t *pin) { - if (!pin) +int pin_wrong_retry(const file_t *pin) +{ + if (!pin) { return CCID_ERR_NULL_PARAM; + } const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF); - if (!act) + if (!act) { return CCID_ERR_FILE_NOT_FOUND; + } uint8_t retries = file_read_uint8(file_get_data(act)); if (retries > 0) { retries -= 1; - int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries)); - if (r != CCID_OK) + int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries)); + if (r != CCID_OK) { return r; + } low_flash_available(); - if (retries == 0) + if (retries == 0) { return CCID_ERR_BLOCKED; + } return retries; } return CCID_ERR_BLOCKED; } -bool pka_enabled() { +bool pka_enabled() +{ file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); return file_has_data(ef_puk) && file_read_uint8(file_get_data(ef_puk)) > 0; } -int check_pin(const file_t *pin, const uint8_t *data, size_t len) { - if (!file_has_data((file_t *)pin)) { +int check_pin(const file_t *pin, const uint8_t *data, size_t len) +{ + if (!file_has_data((file_t *) pin)) { return SW_REFERENCE_NOT_FOUND(); } - if (pka_enabled() == false) + if (pka_enabled() == false) { isUserAuthenticated = false; + } has_session_pin = has_session_sopin = false; if (is_secured_apdu() && sm_session_pin_len > 0 && pin == file_pin1) { if (len == sm_session_pin_len && memcmp(data, sm_session_pin, len) != 0) { int retries; - if ((retries = pin_wrong_retry(pin)) < CCID_OK) + if ((retries = pin_wrong_retry(pin)) < CCID_OK) { return SW_PIN_BLOCKED(); + } return set_res_sw(0x63, 0xc0 | retries); } - } - else { + } else { uint8_t dhash[32]; double_hash_pin(data, len, dhash); - if (sizeof(dhash) != file_get_size(pin)-1) //1 byte for pin len + if (sizeof(dhash) != file_get_size(pin)-1) { //1 byte for pin len return SW_CONDITIONS_NOT_SATISFIED(); + } if (memcmp(file_get_data(pin)+1, dhash, sizeof(dhash)) != 0) { int retries; - if ((retries = pin_wrong_retry(pin)) < CCID_OK) + if ((retries = pin_wrong_retry(pin)) < CCID_OK) { return SW_PIN_BLOCKED(); + } return set_res_sw(0x63, 0xc0 | retries); } } int r = pin_reset_retries(pin, false); - if (r == CCID_ERR_BLOCKED) + if (r == CCID_ERR_BLOCKED) { return SW_PIN_BLOCKED(); - if (r != CCID_OK) + } + if (r != CCID_OK) { return SW_MEMORY_FAILURE(); - if (pka_enabled() == false) + } + if (pka_enabled() == false) { isUserAuthenticated = true; + } if (pin == file_pin1) { hash_multi(data, len, session_pin); has_session_pin = true; - } - else if (pin == file_sopin) { + } else if (pin == file_sopin) { hash_multi(data, len, session_sopin); has_session_sopin = true; } return SW_OK(); } -const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) { - if (ef == NULL) +const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) +{ + if (ef == NULL) { return NULL; + } uint8_t *meta_data = NULL; uint8_t meta_size = meta_find(ef->fid, &meta_data); if (meta_size > 0 && meta_data != NULL) { @@ -389,42 +424,49 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) { return NULL; } -uint32_t get_key_counter(file_t *fkey) { +uint32_t get_key_counter(file_t *fkey) +{ size_t tag_len = 0; const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len); - if (meta_tag) + if (meta_tag) { return (meta_tag[0] << 24) | (meta_tag[1] << 16) | (meta_tag[2] << 8) | meta_tag[3]; + } return 0xffffffff; } -bool key_has_purpose(file_t *ef, uint8_t purpose) { +bool key_has_purpose(file_t *ef, uint8_t purpose) +{ size_t tag_len = 0; const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len); if (meta_tag) { for (int i = 0; i < tag_len; i++) { - if (meta_tag[i] == purpose) + if (meta_tag[i] == purpose) { return true; + } } return false; } return true; } -uint32_t decrement_key_counter(file_t *fkey) { - if (!fkey) +uint32_t decrement_key_counter(file_t *fkey) +{ + if (!fkey) { return 0xffffff; + } uint8_t *meta_data = NULL; uint8_t meta_size = meta_find(fkey->fid, &meta_data); if (meta_size > 0 && meta_data != NULL) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; size_t tag_len = 0; - 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 */ memcpy(cmeta, meta_data, meta_size); while (walk_tlv(cmeta, meta_size, &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]; + uint32_t val = + (tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3]; val--; tag_data[0] = (val >> 24) & 0xff; tag_data[1] = (val >> 16) & 0xff; @@ -433,8 +475,9 @@ uint32_t decrement_key_counter(file_t *fkey) { int r = meta_add(fkey->fid, cmeta, meta_size); free(cmeta); - if (r != 0) + if (r != 0) { return 0xffffffff; + } low_flash_available(); return val; } @@ -445,50 +488,53 @@ uint32_t decrement_key_counter(file_t *fkey) { } //Stores the private and public keys in flash -int store_keys(void *key_ctx, int type, uint8_t key_id) { +int store_keys(void *key_ctx, int type, uint8_t key_id) +{ int r, key_size = 0; uint8_t kdata[4096/8]; //worst case if (type == HSM_KEY_RSA) { - mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx; + mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; key_size = mbedtls_mpi_size(&rsa->P)+mbedtls_mpi_size(&rsa->Q); mbedtls_mpi_write_binary(&rsa->P, kdata, key_size/2); mbedtls_mpi_write_binary(&rsa->Q, kdata+key_size/2, key_size/2); - } - else if (type == HSM_KEY_EC) { - mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx; + } else if (type == HSM_KEY_EC) { + mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; key_size = mbedtls_mpi_size(&ecdsa->d); kdata[0] = ecdsa->grp.id & 0xff; mbedtls_mpi_write_binary(&ecdsa->d, kdata+1, key_size); key_size++; - } - else if (type & HSM_KEY_AES) { - if (type == HSM_KEY_AES_128) + } else if (type & HSM_KEY_AES) { + if (type == HSM_KEY_AES_128) { key_size = 16; - else if (type == HSM_KEY_AES_192) + } else if (type == HSM_KEY_AES_192) { key_size = 24; - else if (type == HSM_KEY_AES_256) + } else if (type == HSM_KEY_AES_256) { key_size = 32; + } memcpy(kdata, key_ctx, key_size); - } - else + } else { return CCID_WRONG_DATA; + } file_t *fpk = file_new((KEY_PREFIX << 8) | key_id); - if (!fpk) + if (!fpk) { return CCID_ERR_MEMORY_FATAL; + } r = mkek_encrypt(kdata, key_size); if (r != CCID_OK) { return r; } r = flash_write_data_to_file(fpk, kdata, key_size); - if (r != CCID_OK) + if (r != CCID_OK) { return r; + } low_flash_available(); return CCID_OK; } -int find_and_store_meta_key(uint8_t key_id) { - size_t lt[4] = { 0,0,0,0 }, meta_size = 0; - uint8_t *pt[4] = { NULL,NULL,NULL,NULL }; +int find_and_store_meta_key(uint8_t key_id) +{ + size_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; + uint8_t *pt[4] = { NULL, NULL, NULL, NULL }; uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; for (int t = 0; t < 4; t++) { uint8_t *ptt = NULL; @@ -508,7 +554,7 @@ int find_and_store_meta_key(uint8_t key_id) { } } 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 (int t = 0; t < 4; t++) { if (lt[t] > 0 && pt[t] != NULL) { *m++ = 0x90+t; @@ -519,15 +565,18 @@ int find_and_store_meta_key(uint8_t key_id) { } int r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_size); free(meta); - if (r != 0) + if (r != 0) { return CCID_EXEC_ERROR; + } } return CCID_OK; } -int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) { - if (wait_button_pressed() == true) //timeout +int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) +{ + if (wait_button_pressed() == true) { //timeout return CCID_VERIFICATION_FAILED; + } int key_size = file_get_size(fkey); uint8_t kdata[4096/8]; @@ -568,9 +617,11 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) { return CCID_OK; } -int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) { - if (wait_button_pressed() == true) //timeout +int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) +{ + if (wait_button_pressed() == true) { //timeout return CCID_VERIFICATION_FAILED; + } int key_size = file_get_size(fkey); uint8_t kdata[67]; //Worst case, 521 bit + 1byte @@ -611,8 +662,8 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) { #define INS_EXTERNAL_AUTHENTICATE 0x82 #define INS_CHALLENGE 0x84 #define INS_GENERAL_AUTHENTICATE 0x86 -#define INS_SELECT_FILE 0xA4 -#define INS_READ_BINARY 0xB0 +#define INS_SELECT_FILE 0xA4 +#define INS_READ_BINARY 0xB0 #define INS_READ_BINARY_ODD 0xB1 #define INS_UPDATE_EF 0xD7 #define INS_DELETE_FILE 0xE4 @@ -645,13 +696,15 @@ static const cmd_t cmds[] = { { INS_PUK_AUTH, cmd_puk_auth }, { INS_PSO, cmd_pso }, { INS_EXTERNAL_AUTHENTICATE, cmd_external_authenticate }, - { 0x00, 0x0} + { 0x00, 0x0 } }; -int sc_hsm_process_apdu() { +int sc_hsm_process_apdu() +{ int r = sm_unwrap(); - if (r != CCID_OK) + if (r != CCID_OK) { return SW_DATA_INVALID(); + } for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) { if (cmd->ins == INS(apdu)) { int r = cmd->cmd_handler(); diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index 93ce9f8..3211d4a 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -31,31 +31,31 @@ extern const uint8_t sc_hsm_aid[]; -#define ALGO_RSA_RAW 0x20 /* RSA signature with external padding */ -#define ALGO_RSA_DECRYPT 0x21 /* RSA raw decrypt */ +#define ALGO_RSA_RAW 0x20 /* RSA signature with external padding */ +#define ALGO_RSA_DECRYPT 0x21 /* RSA raw decrypt */ #define ALGO_RSA_DECRYPT_PKCS1 0x22 #define ALGO_RSA_DECRYPT_OEP 0x23 -#define ALGO_RSA_PKCS1 0x30 /* RSA signature with DigestInfo input and PKCS#1 V1.5 padding */ -#define ALGO_RSA_PKCS1_SHA1 0x31 /* RSA signature with SHA-1 hash and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PKCS1 0x30 /* RSA signature with DigestInfo input and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PKCS1_SHA1 0x31 /* RSA signature with SHA-1 hash and PKCS#1 V1.5 padding */ #define ALGO_RSA_PKCS1_SHA224 0x32 -#define ALGO_RSA_PKCS1_SHA256 0x33 /* RSA signature with SHA-256 hash and PKCS#1 V1.5 padding */ +#define ALGO_RSA_PKCS1_SHA256 0x33 /* RSA signature with SHA-256 hash and PKCS#1 V1.5 padding */ #define ALGO_RSA_PKCS1_SHA384 0x34 #define ALGO_RSA_PKCS1_SHA512 0x35 -#define ALGO_RSA_PSS 0x40 /* RSA signature with external hash and PKCS#1 PSS padding*/ -#define ALGO_RSA_PSS_SHA1 0x41 /* RSA signature with SHA-1 hash and PKCS#1 PSS padding */ +#define ALGO_RSA_PSS 0x40 /* RSA signature with external hash and PKCS#1 PSS padding*/ +#define ALGO_RSA_PSS_SHA1 0x41 /* RSA signature with SHA-1 hash and PKCS#1 PSS padding */ #define ALGO_RSA_PSS_SHA224 0x42 -#define ALGO_RSA_PSS_SHA256 0x43 /* RSA signature with SHA-256 hash and PKCS#1 PSS padding */ +#define ALGO_RSA_PSS_SHA256 0x43 /* RSA signature with SHA-256 hash and PKCS#1 PSS padding */ #define ALGO_RSA_PSS_SHA384 0x44 #define ALGO_RSA_PSS_SHA512 0x45 -#define ALGO_EC_RAW 0x70 /* ECDSA signature with hash input */ -#define ALGO_EC_SHA1 0x71 /* ECDSA signature with SHA-1 hash */ -#define ALGO_EC_SHA224 0x72 /* ECDSA signature with SHA-224 hash */ -#define ALGO_EC_SHA256 0x73 /* ECDSA signature with SHA-256 hash */ +#define ALGO_EC_RAW 0x70 /* ECDSA signature with hash input */ +#define ALGO_EC_SHA1 0x71 /* ECDSA signature with SHA-1 hash */ +#define ALGO_EC_SHA224 0x72 /* ECDSA signature with SHA-224 hash */ +#define ALGO_EC_SHA256 0x73 /* ECDSA signature with SHA-256 hash */ #define ALGO_EC_SHA384 0x74 #define ALGO_EC_SHA512 0x75 -#define ALGO_EC_DH 0x80 /* ECDH key derivation */ +#define ALGO_EC_DH 0x80 /* ECDH key derivation */ #define ALGO_EC_DH_AUTPUK 0x83 #define ALGO_EC_DH_XKEK 0x84 @@ -63,14 +63,14 @@ extern const uint8_t sc_hsm_aid[]; #define ALGO_UNWRAP 0x93 #define ALGO_REPLACE 0x94 -#define ALGO_EC_DERIVE 0x98 /* Derive EC key from EC key */ +#define ALGO_EC_DERIVE 0x98 /* Derive EC key from EC key */ -#define ALGO_AES_CBC_ENCRYPT 0x10 -#define ALGO_AES_CBC_DECRYPT 0x11 -#define ALGO_AES_CMAC 0x18 +#define ALGO_AES_CBC_ENCRYPT 0x10 +#define ALGO_AES_CBC_DECRYPT 0x11 +#define ALGO_AES_CMAC 0x18 #define ALGO_EXT_CIPHER_ENCRYPT 0x51 /* Extended ciphering Encrypt */ #define ALGO_EXT_CIPHER_DECRYPT 0x52 /* Extended ciphering Decrypt */ -#define ALGO_AES_DERIVE 0x99 +#define ALGO_AES_DERIVE 0x99 #define HSM_OPT_RRC 0x0001 #define HSM_OPT_TRANSPORT_PIN 0x0002 @@ -83,14 +83,14 @@ extern const uint8_t sc_hsm_aid[]; #define HSM_OPT_KEY_COUNTER_ALL 0x0200 #define HSM_OPT_SECURE_LOCK 0x0400 -#define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */ -#define CD_PREFIX 0xC8 /* Hi byte in file identifier for PKCS#15 CD objects */ -#define DCOD_PREFIX 0xC9 /* Hi byte in file identifier for PKCS#15 DCOD objects */ -#define CA_CERTIFICATE_PREFIX 0xCA /* Hi byte in file identifier for CA certificates */ -#define KEY_PREFIX 0xCC /* Hi byte in file identifier for key objects */ -#define PROT_DATA_PREFIX 0xCD /* Hi byte in file identifier for PIN protected data objects */ -#define EE_CERTIFICATE_PREFIX 0xCE /* Hi byte in file identifier for EE certificates */ -#define DATA_PREFIX 0xCF /* Hi byte in file identifier for readable data objects */ +#define PRKD_PREFIX 0xC4 /* Hi byte in file identifier for PKCS#15 PRKD objects */ +#define CD_PREFIX 0xC8 /* Hi byte in file identifier for PKCS#15 CD objects */ +#define DCOD_PREFIX 0xC9 /* Hi byte in file identifier for PKCS#15 DCOD objects */ +#define CA_CERTIFICATE_PREFIX 0xCA /* Hi byte in file identifier for CA certificates */ +#define KEY_PREFIX 0xCC /* Hi byte in file identifier for key objects */ +#define PROT_DATA_PREFIX 0xCD /* Hi byte in file identifier for PIN protected data objects */ +#define EE_CERTIFICATE_PREFIX 0xCE /* Hi byte in file identifier for EE certificates */ +#define DATA_PREFIX 0xCF /* Hi byte in file identifier for readable data objects */ #define P15_KEYTYPE_RSA 0x30 #define P15_KEYTYPE_ECC 0xA0 @@ -124,4 +124,4 @@ extern int find_and_store_meta_key(uint8_t key_id); extern uint32_t get_key_counter(file_t *fkey); extern uint32_t decrement_key_counter(file_t *fkey); -#endif \ No newline at end of file +#endif diff --git a/src/hsm/version.h b/src/hsm/version.h index 851b084..86583c7 100644 --- a/src/hsm/version.h +++ b/src/hsm/version.h @@ -24,4 +24,3 @@ #define HSM_VERSION_MINOR (HSM_VERSION & 0xff) #endif -