Switching to new style.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2023-02-15 00:10:35 +01:00
parent e7495d11f2
commit cd6e280f4f
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
33 changed files with 1067 additions and 642 deletions

317
.uncrustify.cfg Normal file
View file

@ -0,0 +1,317 @@
#
# Uncrustify Configuration File
# File Created With UncrustifyX 0.4.3 (252)
#
# Code-Modifying
# --------------
## Braces
# Braces on single-line do statement
mod_full_brace_do = add # string (add/force/ignore/remove)
# Braces on single-line else statement
mod_full_brace_if = add # string (add/force/ignore/remove)
# Braces on single-line for statement
mod_full_brace_for = add # string (add/force/ignore/remove)
# Braces on single-line while statement
mod_full_brace_while = add # string (add/force/ignore/remove)
## Parentheses
# Remove unnecessary parentheses on return statement
mod_paren_on_return = remove # string (add/force/ignore/remove)
# Comments
# --------
## Other
# Remove leading spaces from multi-line comments
cmt_multi_check_last = false # boolean (false/true)
# General
# -------
## Other
# Input tab size
input_tab_size = 4 # number
# Indentation
# -----------
## Indentation Size
# Indentation column size
indent_columns = 4 # number
# Indentation size between case and switch
indent_switch_case = 4 # number
## Other
# Align strings broken by backslash
indent_align_string = true # boolean (false/true)
# Indent with tabs
indent_with_tabs = 0 # number
# Line-Splitting
# --------------
## Splitting
# Code width
code_width = 100 # number
# Split long for statements at semicolons
ls_for_split_full = true # boolean (false/true)
# Split long function prototypes/calls at commas
ls_func_split_full = true # boolean (false/true)
# Newlines
# --------
## Newline Between
# Newline between assignment and open brace
nl_assign_brace = remove # string (add/force/ignore/remove)
# Newline between close brace and else
nl_brace_else = add # string (add/force/ignore/remove)
# Newline between close brace and while
nl_brace_while = remove # string (add/force/ignore/remove)
# Newline between do and open brace
nl_do_brace = remove # string (add/force/ignore/remove)
# Newline between else and open brace
nl_else_brace = remove # string (add/force/ignore/remove)
# Newline between enum and open brace
nl_enum_brace = remove # string (add/force/ignore/remove)
# Newline between for and open brace
nl_for_brace = remove # string (add/force/ignore/remove)
# Newline between function call and open brace
nl_fcall_brace = add # string (add/force/ignore/remove)
# Newline between function signature and open brace
nl_fdef_brace = remove # string (add/force/ignore/remove)
# Newline between if and open brace
nl_if_brace = remove # string (add/force/ignore/remove)
# Newline between struct and open brace
nl_struct_brace = remove # string (add/force/ignore/remove)
# Newline between switch and open brace
nl_switch_brace = remove # string (add/force/ignore/remove)
# Newline between union and open brace
nl_union_brace = remove # string (add/force/ignore/remove)
# Newline between while and open brace
nl_while_brace = remove # string (add/force/ignore/remove)
## Other
# Newline count at end of file
nl_end_of_file_min = 1 # number
# Newlines at end of file
nl_end_of_file = add # string (add/force/ignore/remove)
# Newlines at start of file
nl_start_of_file = remove # string (add/force/ignore/remove)
# Spacing
# -------
## Space After
# Space after address-of operator
sp_addr = remove # string (add/force/ignore/remove)
# Space after cast
sp_after_cast = add # string (add/force/ignore/remove)
# Space after comma
sp_after_comma = add # string (add/force/ignore/remove)
# Space after dereference operator
sp_deref = remove # string (add/force/ignore/remove)
# Space after final semicolon in empty for statement
sp_after_semi_for_empty = remove # string (add/force/ignore/remove)
# Space after invert operator
sp_inv = remove # string (add/force/ignore/remove)
# Space after not operator
sp_not = remove # string (add/force/ignore/remove)
# Space after pointer star
sp_after_ptr_star = remove # string (add/force/ignore/remove)
# Space after pointer star followed by function
sp_after_ptr_star_func = remove # string (add/force/ignore/remove)
# Space after semicolon
sp_after_semi = add # string (add/force/ignore/remove)
# Space after semicolon in non-empty for statements
sp_after_semi_for = add # string (add/force/ignore/remove)
# Space after sign in assignment
sp_sign = remove # string (add/force/ignore/remove)
# Space after type
sp_after_type = add # string (add/force/ignore/remove)
## Space Around
# Space around arithmetic operators
sp_arith = add # string (add/force/ignore/remove)
# Space around assignment operator
sp_assign = add # string (add/force/ignore/remove)
# Space around boolean operators
sp_bool = add # string (add/force/ignore/remove)
# Space around compare operators
sp_compare = add # string (add/force/ignore/remove)
# Space around increment/decrement operators
sp_incdec = remove # string (add/force/ignore/remove)
# Space around member operators
sp_member = remove # string (add/force/ignore/remove)
# Space around preprocessor concatenation operator
sp_pp_concat = ignore # string (add/force/ignore/remove)
# Space around ternary condition colon
sp_cond_colon = add # string (add/force/ignore/remove)
# Space around ternary condition question mark
sp_cond_question = add # string (add/force/ignore/remove)
## Space Before
# Space before backslash-newline at end of line
sp_before_nl_cont = add # string (add/force/ignore/remove)
# Space before case colon
sp_before_case_colon = remove # string (add/force/ignore/remove)
# Space before comma
sp_before_comma = remove # string (add/force/ignore/remove)
# Space before if/for/switch/while open parenthesis
sp_before_sparen = force # string (add/force/ignore/remove)
# Space before pointer star
sp_before_ptr_star = add # string (add/force/ignore/remove)
# Space before semicolon
sp_before_semi = remove # string (add/force/ignore/remove)
# Space before semicolon in empty for statement
sp_before_semi_for_empty = remove # string (add/force/ignore/remove)
# Space before semicolon in for statements
sp_before_semi_for = remove # string (add/force/ignore/remove)
## Space Between
# Space between __attribute__ and open parenthesis
sp_attribute_paren = remove # string (add/force/ignore/remove)
# Space between close brace and else
sp_brace_else = remove # string (add/force/ignore/remove)
# Space between close brace and typedef name
sp_brace_typedef = force # string (add/force/ignore/remove)
# Space between closing parenthesis and open brace
sp_fparen_brace = add # string (add/force/ignore/remove)
# Space between defined and open parenthesis
sp_defined_paren = remove # string (add/force/ignore/remove)
# Space between else and open brace
sp_else_brace = force # string (add/force/ignore/remove)
# Space between function name and open parenthesis
sp_func_call_paren = remove # string (add/force/ignore/remove)
# Space between function name and open parenthesis in declaration
sp_func_proto_paren = remove # string (add/force/ignore/remove)
# Space between function name and open parenthesis in function definition
sp_func_def_paren = remove # string (add/force/ignore/remove)
# Space between if/for/switch/while close parenthesis and open brace
sp_sparen_brace = force # string (add/force/ignore/remove)
# Space between macro and value
sp_macro = add # string (add/force/ignore/remove)
# Space between macro function close parenthesis and value
sp_macro_func = add # string (add/force/ignore/remove)
# Space between nested parentheses
sp_paren_paren = remove # string (add/force/ignore/remove)
# Space between pointer stars
sp_between_ptr_star = remove # string (add/force/ignore/remove)
# Space between preprocessor else and comment
sp_endif_cmt = add # string (add/force/ignore/remove)
# Space between return type and function name
sp_type_func = add # string (add/force/ignore/remove)
# Space between sizeof and open parenthesis
sp_sizeof_paren = remove # string (add/force/ignore/remove)
## Space Inside
# Space inside braces
sp_inside_braces = add # string (add/force/ignore/remove)
# Space inside cast parentheses
sp_inside_paren_cast = remove # string (add/force/ignore/remove)
# Space inside empty function parentheses
sp_inside_fparens = remove # string (add/force/ignore/remove)
# Space inside enum braces
sp_inside_braces_enum = add # string (add/force/ignore/remove)
# Space inside function parentheses
sp_inside_fparen = remove # string (add/force/ignore/remove)
# Space inside if-condition parentheses
sp_inside_sparen = remove # string (add/force/ignore/remove)
# Space inside non-empty square brackets
sp_inside_square = remove # string (add/force/ignore/remove)
# Space inside parentheses
sp_inside_paren = remove # string (add/force/ignore/remove)
# Space inside parentheses in function type
sp_inside_tparen = remove # string (add/force/ignore/remove)
# Space inside struct/union braces
sp_inside_braces_struct = add # string (add/force/ignore/remove)

@ -1 +1 @@
Subproject commit 12bdcbd1f91f5b5763ad66b212be897ae9eb87a8 Subproject commit 43ef33d60b43ddeed5878ded08df37001636d811

View file

@ -21,8 +21,7 @@
uint8_t challenge[256]; uint8_t challenge[256];
uint8_t challenge_len = 0; uint8_t challenge_len = 0;
int cmd_challenge() int cmd_challenge() {
{
uint8_t *rb = (uint8_t *) random_bytes_get(apdu.ne); uint8_t *rb = (uint8_t *) random_bytes_get(apdu.ne);
if (!rb) { if (!rb) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();

View file

@ -19,14 +19,14 @@
#include "sc_hsm.h" #include "sc_hsm.h"
#include "kek.h" #include "kek.h"
int cmd_change_pin() int cmd_change_pin() {
{
if (P1(apdu) == 0x0) { if (P1(apdu) == 0x0) {
if (P2(apdu) == 0x81 || P2(apdu) == 0x88) { if (P2(apdu) == 0x81 || P2(apdu) == 0x88) {
file_t *file_pin = NULL; file_t *file_pin = NULL;
if (P2(apdu) == 0x81) { if (P2(apdu) == 0x81) {
file_pin = file_pin1; file_pin = file_pin1;
} else if (P2(apdu) == 0x88) { }
else if (P2(apdu) == 0x88) {
file_pin = file_sopin; file_pin = file_sopin;
} }
if (!file_pin) { if (!file_pin) {
@ -50,7 +50,8 @@ int cmd_change_pin()
if (P2(apdu) == 0x81) { if (P2(apdu) == 0x81) {
hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_pin); hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_pin);
has_session_pin = true; 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); hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_sopin);
has_session_sopin = true; has_session_sopin = true;
} }

View file

@ -38,8 +38,7 @@
static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations, mbedtls_asn1_buf *salt, int *iterations,
int *keylen, mbedtls_md_type_t *md_type) int *keylen, mbedtls_md_type_t *md_type) {
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf prf_alg_oid; mbedtls_asn1_buf prf_alg_oid;
unsigned char *p = params->p; unsigned char *p = params->p;
@ -107,8 +106,7 @@ int mbedtls_ansi_x936_kdf(mbedtls_md_type_t md_type,
size_t shared_info_len, size_t shared_info_len,
uint8_t *shared_info, uint8_t *shared_info,
size_t output_len, size_t output_len,
uint8_t *output) uint8_t *output) {
{
mbedtls_md_context_t md_ctx; mbedtls_md_context_t md_ctx;
const mbedtls_md_info_t *md_info = NULL; const mbedtls_md_info_t *md_info = NULL;
int hashlen = 0, exit_code = MBEDTLS_ERR_MD_BAD_INPUT_DATA; int hashlen = 0, exit_code = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
@ -159,8 +157,7 @@ int mbedtls_ansi_x936_kdf(mbedtls_md_type_t md_type,
return 0; return 0;
} }
int cmd_cipher_sym() int cmd_cipher_sym() {
{
int key_id = P1(apdu); int key_id = P1(apdu);
int algo = P2(apdu); int algo = P2(apdu);
if (!isUserAuthenticated) { if (!isUserAuthenticated) {
@ -208,7 +205,8 @@ int cmd_cipher_sym()
mbedtls_aes_free(&aes); mbedtls_aes_free(&aes);
return SW_EXEC_ERROR(); 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); int r = mbedtls_aes_setkey_dec(&aes, kdata, key_size * 8);
if (r != 0) { if (r != 0) {
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
@ -229,15 +227,19 @@ int cmd_cipher_sym()
} }
res_APDU_size = apdu.nc; res_APDU_size = apdu.nc;
mbedtls_aes_free(&aes); mbedtls_aes_free(&aes);
} else if (algo == ALGO_AES_CMAC) { }
else if (algo == ALGO_AES_CMAC) {
const mbedtls_cipher_info_t *cipher_info; 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); 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); 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); cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB);
} else { }
else {
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
@ -247,7 +249,8 @@ int cmd_cipher_sym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = 16; res_APDU_size = 16;
} else if (algo == ALGO_AES_DERIVE) { }
else if (algo == ALGO_AES_DERIVE) {
int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), int r = mbedtls_hkdf(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
NULL, NULL,
0, 0,
@ -262,7 +265,8 @@ int cmd_cipher_sym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = apdu.nc; 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; size_t oid_len = 0, aad_len = 0, iv_len = 0, enc_len = 0;
uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL;
if (!asn1_find_tag(apdu.data, apdu.nc, 0x6, &oid_len, if (!asn1_find_tag(apdu.data, apdu.nc, 0x6, &oid_len,
@ -292,7 +296,8 @@ int cmd_cipher_sym()
enc, enc,
res_APDU, res_APDU,
res_APDU + enc_len); res_APDU + enc_len);
} else if (algo == ALGO_EXT_CIPHER_DECRYPT) { }
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
r = mbedtls_chachapoly_auth_decrypt(&ctx, r = mbedtls_chachapoly_auth_decrypt(&ctx,
enc_len - 16, enc_len - 16,
iv ? iv : tmp_iv, iv ? iv : tmp_iv,
@ -309,20 +314,26 @@ int cmd_cipher_sym()
} }
if (algo == ALGO_EXT_CIPHER_ENCRYPT) { if (algo == ALGO_EXT_CIPHER_ENCRYPT) {
res_APDU_size = enc_len + 16; res_APDU_size = enc_len + 16;
} else if (algo == ALGO_EXT_CIPHER_DECRYPT) { }
else if (algo == ALGO_EXT_CIPHER_DECRYPT) {
res_APDU_size = enc_len - 16; res_APDU_size = enc_len - 16;
} }
} else if (memcmp(oid, OID_DIGEST, 7) == 0) { }
else if (memcmp(oid, OID_DIGEST, 7) == 0) {
const mbedtls_md_info_t *md_info = NULL; const mbedtls_md_info_t *md_info = NULL;
if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) { if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
} else if (memcmp(oid, OID_HMAC_SHA224, oid_len) == 0) { }
else if (memcmp(oid, OID_HMAC_SHA224, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
} else if (memcmp(oid, OID_HMAC_SHA256, oid_len) == 0) { }
else if (memcmp(oid, OID_HMAC_SHA256, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
} else if (memcmp(oid, OID_HMAC_SHA384, oid_len) == 0) { }
else if (memcmp(oid, OID_HMAC_SHA384, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
} else if (memcmp(oid, OID_HMAC_SHA512, oid_len) == 0) { }
else if (memcmp(oid, OID_HMAC_SHA512, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
if (md_info == NULL) { if (md_info == NULL) {
@ -334,16 +345,19 @@ int cmd_cipher_sym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = md_info->size; res_APDU_size = md_info->size;
} else if (memcmp(oid, OID_HKDF_SHA256, }
else if (memcmp(oid, OID_HKDF_SHA256,
oid_len) == 0 || oid_len) == 0 ||
memcmp(oid, OID_HKDF_SHA384, memcmp(oid, OID_HKDF_SHA384,
oid_len) == 0 || memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { oid_len) == 0 || memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) {
const mbedtls_md_info_t *md_info = NULL; const mbedtls_md_info_t *md_info = NULL;
if (memcmp(oid, OID_HKDF_SHA256, oid_len) == 0) { if (memcmp(oid, OID_HKDF_SHA256, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
} else if (memcmp(oid, OID_HKDF_SHA384, oid_len) == 0) { }
else if (memcmp(oid, OID_HKDF_SHA384, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
} else if (memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { }
else if (memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) {
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
} }
int r = mbedtls_hkdf(md_info, int r = mbedtls_hkdf(md_info,
@ -361,7 +375,8 @@ int cmd_cipher_sym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info); 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) { }
else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) {
int iterations = 0, keylen = 0; int iterations = 0, keylen = 0;
mbedtls_asn1_buf salt, mbedtls_asn1_buf salt,
params = params =
@ -396,7 +411,8 @@ int cmd_cipher_sym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32); res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32);
} else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { }
else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) {
mbedtls_asn1_buf params = mbedtls_asn1_buf params =
{ .p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; { .p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) };
int r = mbedtls_pkcs5_pbes2(&params, int r = mbedtls_pkcs5_pbes2(&params,
@ -411,17 +427,22 @@ int cmd_cipher_sym()
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
res_APDU_size = enc_len; 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; 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; 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; 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; 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; 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; md_type = MBEDTLS_MD_SHA512;
} }
int r = mbedtls_ansi_x936_kdf(md_type, int r = mbedtls_ansi_x936_kdf(md_type,
@ -437,7 +458,8 @@ int cmd_cipher_sym()
} }
res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32; res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32;
} }
} else { }
else {
mbedtls_platform_zeroize(kdata, sizeof(kdata)); mbedtls_platform_zeroize(kdata, sizeof(kdata));
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();
} }

View file

@ -26,8 +26,7 @@
#include "random.h" #include "random.h"
#include "oid.h" #include "oid.h"
int cmd_decrypt_asym() int cmd_decrypt_asym() {
{
int key_id = P1(apdu); int key_id = P1(apdu);
uint8_t p2 = P2(apdu); uint8_t p2 = P2(apdu);
if (!isUserAuthenticated) { if (!isUserAuthenticated) {
@ -67,7 +66,8 @@ int cmd_decrypt_asym()
if (r == 0) { if (r == 0) {
res_APDU_size = olen; res_APDU_size = olen;
} }
} else { }
else {
r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU); r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU);
if (r == 0) { if (r == 0) {
res_APDU_size = key_size; res_APDU_size = key_size;
@ -78,7 +78,8 @@ int cmd_decrypt_asym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
mbedtls_rsa_free(&ctx); 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; mbedtls_ecdh_context ctx;
if (wait_button_pressed() == true) { //timeout if (wait_button_pressed() == true) { //timeout
return SW_SECURE_MESSAGE_EXEC_ERROR(); return SW_SECURE_MESSAGE_EXEC_ERROR();
@ -111,7 +112,8 @@ int cmd_decrypt_asym()
r = -1; r = -1;
if (p2 == ALGO_EC_DH) { if (p2 == ALGO_EC_DH) {
r = mbedtls_ecdh_read_public(&ctx, apdu.data - 1, apdu.nc + 1); 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; size_t pub_len = 0;
const uint8_t *pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len); const uint8_t *pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len);
if (pub) { if (pub) {
@ -136,7 +138,8 @@ int cmd_decrypt_asym()
} }
if (p2 == ALGO_EC_DH) { if (p2 == ALGO_EC_DH) {
res_APDU_size = olen; res_APDU_size = olen;
} else { }
else {
res_APDU_size = 0; res_APDU_size = 0;
size_t ext_len = 0; size_t ext_len = 0;
const uint8_t *ext = NULL; const uint8_t *ext = NULL;
@ -181,7 +184,8 @@ int cmd_decrypt_asym()
} }
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
} else { }
else {
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();
} }
decrement_key_counter(ef); decrement_key_counter(ef);

View file

@ -17,8 +17,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
int cmd_delete_file() int cmd_delete_file() {
{
file_t *ef = NULL; file_t *ef = NULL;
if (!isUserAuthenticated) { if (!isUserAuthenticated) {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
@ -29,7 +28,8 @@ int cmd_delete_file()
if (!(ef = search_dynamic_file(ef->fid))) { if (!(ef = search_dynamic_file(ef->fid))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
} else { }
else {
uint16_t fid = (apdu.data[0] << 8) | apdu.data[1]; 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(); return SW_FILE_NOT_FOUND();

View file

@ -28,8 +28,7 @@
static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp, static inline int mbedtls_mpi_add_mod(const mbedtls_ecp_group *grp,
mbedtls_mpi *X, mbedtls_mpi *X,
const mbedtls_mpi *A, const mbedtls_mpi *A,
const mbedtls_mpi *B) const mbedtls_mpi *B) {
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B)); MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, A, B));
MOD_ADD(*X); MOD_ADD(*X);
@ -37,8 +36,7 @@ cleanup:
return ret; return ret;
} }
int cmd_derive_asym() int cmd_derive_asym() {
{
uint8_t key_id = P1(apdu); uint8_t key_id = P1(apdu);
uint8_t dest_id = P2(apdu); uint8_t dest_id = P2(apdu);
file_t *fkey; file_t *fkey;
@ -96,7 +94,8 @@ int cmd_derive_asym()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
} else { }
else {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
return SW_OK(); return SW_OK();

View file

@ -24,8 +24,7 @@ extern file_t *ef_puk_aut;
extern uint8_t challenge[256]; extern uint8_t challenge[256];
extern uint8_t challenge_len; extern uint8_t challenge_len;
int cmd_external_authenticate() int cmd_external_authenticate() {
{
if (P1(apdu) != 0x0 || P2(apdu) != 0x0) { if (P1(apdu) != 0x0 || P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }

View file

@ -27,8 +27,7 @@
#include "mbedtls/hkdf.h" #include "mbedtls/hkdf.h"
#include "mbedtls/chachapoly.h" #include "mbedtls/chachapoly.h"
int cmd_extras() int cmd_extras() {
{
if (P1(apdu) == 0xA) { //datetime operations if (P1(apdu) == 0xA) { //datetime operations
if (P2(apdu) != 0x0) { if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
@ -48,7 +47,8 @@ int cmd_extras()
res_APDU[res_APDU_size++] = dt.min; res_APDU[res_APDU_size++] = dt.min;
res_APDU[res_APDU_size++] = dt.sec; res_APDU[res_APDU_size++] = dt.sec;
#endif #endif
} else { }
else {
if (apdu.nc != 8) { if (apdu.nc != 8) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
@ -66,7 +66,8 @@ int cmd_extras()
} }
#endif #endif
} }
} else if (P1(apdu) == 0x6) { //dynamic options }
else if (P1(apdu) == 0x6) { //dynamic options
if (P2(apdu) != 0x0) { if (P2(apdu) != 0x0) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
@ -77,13 +78,15 @@ int cmd_extras()
if (apdu.nc == 0) { if (apdu.nc == 0) {
res_APDU[res_APDU_size++] = opts >> 8; res_APDU[res_APDU_size++] = opts >> 8;
res_APDU[res_APDU_size++] = opts & 0xff; res_APDU[res_APDU_size++] = opts & 0xff;
} else { }
else {
uint8_t newopts[] = { apdu.data[0], (opts & 0xff) }; uint8_t newopts[] = { apdu.data[0], (opts & 0xff) };
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, newopts, sizeof(newopts)); flash_write_data_to_file(tf, newopts, sizeof(newopts));
low_flash_available(); low_flash_available();
} }
} else if (P1(apdu) == 0x3A) { // secure lock }
else if (P1(apdu) == 0x3A) { // secure lock
if (apdu.nc == 0) { if (apdu.nc == 0) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
@ -147,7 +150,8 @@ int cmd_extras()
} }
mse.init = true; mse.init = true;
res_APDU_size = olen; res_APDU_size = olen;
} else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) { }
else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) {
if (mse.init == false) { if (mse.init == false) {
return SW_COMMAND_NOT_ALLOWED(); return SW_COMMAND_NOT_ALLOWED();
} }
@ -177,18 +181,21 @@ int cmd_extras()
} }
if (P2(apdu) == 0x02) { if (P2(apdu) == 0x02) {
newopts[0] |= HSM_OPT_SECURE_LOCK >> 8; newopts[0] |= HSM_OPT_SECURE_LOCK >> 8;
} else if (P2(apdu) == 0x04) { }
else if (P2(apdu) == 0x04) {
newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8; newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8;
} }
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, newopts, sizeof(newopts)); flash_write_data_to_file(tf, newopts, sizeof(newopts));
low_flash_available(); low_flash_available();
} else if (P2(apdu) == 0x03) { }
else if (P2(apdu) == 0x03) {
memcpy(mkek_mask, apdu.data, apdu.nc); memcpy(mkek_mask, apdu.data, apdu.nc);
has_mkek_mask = true; has_mkek_mask = true;
} }
} }
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
return SW_OK(); return SW_OK();

View file

@ -24,8 +24,7 @@
#include "eac.h" #include "eac.h"
#include "files.h" #include "files.h"
int cmd_general_authenticate() int cmd_general_authenticate() {
{
if (P1(apdu) == 0x0 && P2(apdu) == 0x0) { if (P1(apdu) == 0x0 && P2(apdu) == 0x0) {
if (apdu.data[0] == 0x7C) { if (apdu.data[0] == 0x7C) {
int r = 0; int r = 0;

View file

@ -27,8 +27,7 @@
extern void scan_all(); extern void scan_all();
extern char __StackLimit; extern char __StackLimit;
int heapLeft() int heapLeft() {
{
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
char *p = malloc(256); // try to avoid undue fragmentation char *p = malloc(256); // try to avoid undue fragmentation
int left = &__StackLimit - p; int left = &__StackLimit - p;
@ -39,8 +38,7 @@ int heapLeft()
return left; return left;
} }
int cmd_initialize() int cmd_initialize() {
{
if (apdu.nc > 0) { if (apdu.nc > 0) {
uint8_t mkek[MKEK_SIZE]; uint8_t mkek[MKEK_SIZE];
int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session int ret_mkek = load_mkek(mkek); //Try loading MKEK with previous session
@ -54,7 +52,8 @@ int cmd_initialize()
if (tag == 0x80) { //options if (tag == 0x80) { //options
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
flash_write_data_to_file(tf, tag_data, tag_len); flash_write_data_to_file(tf, tag_data, tag_len);
} else if (tag == 0x81) { //user pin }
else if (tag == 0x81) { //user pin
if (file_pin1 && file_pin1->data) { if (file_pin1 && file_pin1->data) {
uint8_t dhash[33]; uint8_t dhash[33];
dhash[0] = tag_len; dhash[0] = tag_len;
@ -63,7 +62,8 @@ int cmd_initialize()
hash_multi(tag_data, tag_len, session_pin); hash_multi(tag_data, tag_len, session_pin);
has_session_pin = true; has_session_pin = true;
} }
} else if (tag == 0x82) { //sopin pin }
else if (tag == 0x82) { //sopin pin
if (file_sopin && file_sopin->data) { if (file_sopin && file_sopin->data) {
uint8_t dhash[33]; uint8_t dhash[33];
dhash[0] = tag_len; dhash[0] = tag_len;
@ -72,7 +72,8 @@ int cmd_initialize()
hash_multi(tag_data, tag_len, session_sopin); hash_multi(tag_data, tag_len, session_sopin);
has_session_sopin = true; 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); file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF);
if (tf && tf->data) { if (tf && tf->data) {
flash_write_data_to_file(tf, tag_data, tag_len); flash_write_data_to_file(tf, tag_data, tag_len);
@ -80,7 +81,8 @@ int cmd_initialize()
if (file_retries_pin1 && file_retries_pin1->data) { if (file_retries_pin1 && file_retries_pin1->data) {
flash_write_data_to_file(file_retries_pin1, tag_data, tag_len); flash_write_data_to_file(file_retries_pin1, tag_data, tag_len);
} }
} else if (tag == 0x92) { }
else if (tag == 0x92) {
dkeks = tag_data; dkeks = tag_data;
file_t *tf = file_new(EF_DKEK); file_t *tf = file_new(EF_DKEK);
if (!tf) { if (!tf) {
@ -88,7 +90,8 @@ int cmd_initialize()
return SW_MEMORY_FAILURE(); return SW_MEMORY_FAILURE();
} }
flash_write_data_to_file(tf, NULL, 0); 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); file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF);
if (!ef_puk) { if (!ef_puk) {
release_mkek(mkek); release_mkek(mkek);
@ -108,7 +111,8 @@ int cmd_initialize()
} }
flash_write_data_to_file(tf, NULL, 0); flash_write_data_to_file(tf, NULL, 0);
} }
} else if (tag == 0x97) { }
else if (tag == 0x97) {
kds = tag_data; 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++) {
@ -139,7 +143,8 @@ int cmd_initialize()
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(); return SW_EXEC_ERROR();
} }
} else { }
else {
int r = save_dkek_key(0, random_bytes_get(32)); int r = save_dkek_key(0, random_bytes_get(32));
if (r != CCID_OK) { if (r != CCID_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
@ -149,7 +154,8 @@ int cmd_initialize()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
} }
} else { }
else {
uint16_t d = 0x0000; 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(); return SW_EXEC_ERROR();
@ -215,7 +221,8 @@ int cmd_initialize()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
low_flash_available(); low_flash_available();
} else { //free memory bytes request }
else { //free memory bytes request
int heap_left = heapLeft(); int heap_left = heapLeft();
res_APDU[0] = ((heap_left >> 24) & 0xff); res_APDU[0] = ((heap_left >> 24) & 0xff);
res_APDU[1] = ((heap_left >> 16) & 0xff); res_APDU[1] = ((heap_left >> 16) & 0xff);

View file

@ -21,8 +21,7 @@
#include "kek.h" #include "kek.h"
#include "files.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; size_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(fkey, 0x92, &tag_len); const uint8_t *meta_tag = get_meta_tag(fkey, 0x92, &tag_len);
if (meta_tag) { if (meta_tag) {
@ -31,8 +30,7 @@ uint8_t get_key_domain(file_t *fkey)
return 0xff; return 0xff;
} }
int cmd_key_domain() int cmd_key_domain() {
{
//if (dkeks == 0) //if (dkeks == 0)
// return SW_COMMAND_NOT_ALLOWED(); // return SW_COMMAND_NOT_ALLOWED();
uint8_t p1 = P1(apdu), p2 = P2(apdu); uint8_t p1 = P1(apdu), p2 = P2(apdu);
@ -80,7 +78,8 @@ int cmd_key_domain()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
low_flash_available(); low_flash_available();
} else { }
else {
file_t *tf = search_dynamic_file(EF_XKEK + p2); 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(); return SW_INCORRECT_P1P2();
@ -89,7 +88,8 @@ int cmd_key_domain()
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
} }
} else if (p1 == 0x1 || p1 == 0x3 || p1 == 0x4) { //key domain setup }
else if (p1 == 0x1 || p1 == 0x3 || p1 == 0x4) { //key domain setup
if (p1 == 0x1 && apdu.nc != 1) { if (p1 == 0x1 && apdu.nc != 1) {
return SW_WRONG_LENGTH(); return SW_WRONG_LENGTH();
} }
@ -105,10 +105,12 @@ int cmd_key_domain()
if (p1 == 0x1) { if (p1 == 0x1) {
t[2 * p2] = dkeks = apdu.data[0]; t[2 * p2] = dkeks = apdu.data[0];
t[2 * p2 + 1] = current_dkeks = 0; t[2 * p2 + 1] = current_dkeks = 0;
} else if (p1 == 0x3) { }
else if (p1 == 0x3) {
t[2 * p2] = dkeks = 0xff; t[2 * p2] = dkeks = 0xff;
t[2 * p2 + 1] = 0xff; t[2 * p2 + 1] = 0xff;
} else if (p1 == 0x4) { }
else if (p1 == 0x4) {
t[2 * p2 + 1] = current_dkeks = 0; 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) {
@ -129,7 +131,8 @@ int cmd_key_domain()
if (p1 == 0x3) { if (p1 == 0x3) {
return SW_REFERENCE_NOT_FOUND(); 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) { if (apdu.nc > 0) {
size_t pub_len = 0; size_t pub_len = 0;
file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF);
@ -175,7 +178,8 @@ int cmd_key_domain()
} }
} }
} }
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
memset(res_APDU, 0, 10); memset(res_APDU, 0, 10);

View file

@ -19,8 +19,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
#include "random.h" #include "random.h"
int cmd_key_gen() int cmd_key_gen() {
{
uint8_t key_id = P1(apdu); uint8_t key_id = P1(apdu);
uint8_t p2 = P2(apdu); uint8_t p2 = P2(apdu);
uint8_t key_size = 32; uint8_t key_size = 32;
@ -30,9 +29,11 @@ int cmd_key_gen()
} }
if (p2 == 0xB2) { if (p2 == 0xB2) {
key_size = 32; key_size = 32;
} else if (p2 == 0xB1) { }
else if (p2 == 0xB1) {
key_size = 24; key_size = 24;
} else if (p2 == 0xB0) { }
else if (p2 == 0xB0) {
key_size = 16; key_size = 16;
} }
//at this moment, we do not use the template, as only CBC is supported by the driver (encrypt, decrypt and CMAC) //at this moment, we do not use the template, as only CBC is supported by the driver (encrypt, decrypt and CMAC)
@ -41,9 +42,11 @@ int cmd_key_gen()
int aes_type = 0x0; int aes_type = 0x0;
if (key_size == 16) { if (key_size == 16) {
aes_type = HSM_KEY_AES_128; aes_type = HSM_KEY_AES_128;
} else if (key_size == 24) { }
else if (key_size == 24) {
aes_type = HSM_KEY_AES_192; aes_type = HSM_KEY_AES_192;
} else if (key_size == 32) { }
else if (key_size == 32) {
aes_type = HSM_KEY_AES_256; aes_type = HSM_KEY_AES_256;
} }
r = store_keys(aes_key, aes_type, key_id); r = store_keys(aes_key, aes_type, key_id);

View file

@ -20,8 +20,7 @@
#include "kek.h" #include "kek.h"
#include "cvc.h" #include "cvc.h"
int cmd_key_unwrap() int cmd_key_unwrap() {
{
int key_id = P1(apdu), r = 0; int key_id = P1(apdu), r = 0;
if (P2(apdu) != 0x93) { if (P2(apdu) != 0x93) {
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();
@ -54,7 +53,8 @@ int cmd_key_unwrap()
if (r != CCID_OK) { if (r != CCID_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
} else if (key_type == HSM_KEY_EC) { }
else if (key_type == HSM_KEY_EC) {
mbedtls_ecdsa_context ctx; mbedtls_ecdsa_context ctx;
mbedtls_ecdsa_init(&ctx); mbedtls_ecdsa_init(&ctx);
do { do {
@ -73,7 +73,8 @@ int cmd_key_unwrap()
if (r != CCID_OK) { if (r != CCID_OK) {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
} else if (key_type == HSM_KEY_AES) { }
else if (key_type == HSM_KEY_AES) {
uint8_t aes_key[32]; uint8_t aes_key[32];
int key_size = 0, aes_type = 0; int key_size = 0, aes_type = 0;
do { do {
@ -90,11 +91,14 @@ int cmd_key_unwrap()
} }
if (key_size == 32) { if (key_size == 32) {
aes_type = HSM_KEY_AES_256; aes_type = HSM_KEY_AES_256;
} else if (key_size == 24) { }
else if (key_size == 24) {
aes_type = HSM_KEY_AES_192; aes_type = HSM_KEY_AES_192;
} else if (key_size == 16) { }
else if (key_size == 16) {
aes_type = HSM_KEY_AES_128; aes_type = HSM_KEY_AES_128;
} else { }
else {
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
r = store_keys(aes_key, aes_type, key_id); r = store_keys(aes_key, aes_type, key_id);

View file

@ -22,8 +22,7 @@
extern uint8_t get_key_domain(file_t *fkey); extern uint8_t get_key_domain(file_t *fkey);
int cmd_key_wrap() int cmd_key_wrap() {
{
int key_id = P1(apdu), r = 0; int key_id = P1(apdu), r = 0;
if (P2(apdu) != 0x92) { if (P2(apdu) != 0x92) {
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();
@ -61,7 +60,8 @@ int cmd_key_wrap()
} }
r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len); r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len);
mbedtls_rsa_free(&ctx); mbedtls_rsa_free(&ctx);
} else if (*dprkd == P15_KEYTYPE_ECC) { }
else if (*dprkd == P15_KEYTYPE_ECC) {
mbedtls_ecdsa_context ctx; mbedtls_ecdsa_context ctx;
mbedtls_ecdsa_init(&ctx); mbedtls_ecdsa_init(&ctx);
r = load_private_key_ecdsa(&ctx, ef); r = load_private_key_ecdsa(&ctx, ef);
@ -74,7 +74,8 @@ int cmd_key_wrap()
} }
r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len); r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len);
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
} else if (*dprkd == P15_KEYTYPE_AES) { }
else if (*dprkd == P15_KEYTYPE_AES) {
uint8_t kdata[32]; //maximum AES key size 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(); return SW_SECURE_MESSAGE_EXEC_ERROR();
@ -87,9 +88,11 @@ int cmd_key_wrap()
} }
if (key_size == 32) { if (key_size == 32) {
aes_type = HSM_KEY_AES_256; aes_type = HSM_KEY_AES_256;
} else if (key_size == 24) { }
else if (key_size == 24) {
aes_type = HSM_KEY_AES_192; aes_type = HSM_KEY_AES_192;
} else if (key_size == 16) { }
else if (key_size == 16) {
aes_type = HSM_KEY_AES_128; aes_type = HSM_KEY_AES_128;
} }
r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len, meta_tag, tag_len); r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len, meta_tag, tag_len);

View file

@ -24,8 +24,7 @@
#include "random.h" #include "random.h"
#include "kek.h" #include "kek.h"
int cmd_keypair_gen() int cmd_keypair_gen() {
{
uint8_t key_id = P1(apdu); uint8_t key_id = P1(apdu);
if (!isUserAuthenticated) { if (!isUserAuthenticated) {
return SW_SECURITY_STATUS_NOT_SATISFIED(); return SW_SECURITY_STATUS_NOT_SATISFIED();
@ -79,7 +78,8 @@ int cmd_keypair_gen()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
mbedtls_rsa_free(&rsa); mbedtls_rsa_free(&rsa);
} else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC }
else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC
size_t prime_len; size_t prime_len;
uint8_t *prime = NULL; 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) {
@ -116,7 +116,8 @@ int cmd_keypair_gen()
if (!tf_xkek) { if (!tf_xkek) {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
ext_len = 2+2+strlen(OID_ID_KEY_DOMAIN_UID)+2+file_get_size(tf_xkek); 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; uint8_t *pe = ext;
*pe++ = 0x73; *pe++ = 0x73;
@ -150,7 +151,8 @@ int cmd_keypair_gen()
} }
} }
} else { }
else {
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
if (find_and_store_meta_key(key_id) != CCID_OK) { if (find_and_store_meta_key(key_id) != CCID_OK) {

View file

@ -18,8 +18,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
#include "files.h" #include "files.h"
int cmd_list_keys() int cmd_list_keys() {
{
/* First we send DEV private key */ /* First we send DEV private key */
/* Both below conditions should be always TRUE */ /* Both below conditions should be always TRUE */
if (search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF)) { if (search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF)) {

View file

@ -24,8 +24,7 @@
file_t *ef_puk_aut = NULL; file_t *ef_puk_aut = NULL;
int cmd_mse() int cmd_mse() {
{
int p1 = P1(apdu); int p1 = P1(apdu);
int p2 = P2(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) {
@ -43,15 +42,18 @@ int cmd_mse()
sm_set_protocol(MSE_AES); sm_set_protocol(MSE_AES);
} }
} }
} else if (tag == 0x83) { }
else if (tag == 0x83) {
if (tag_len == 1) { if (tag_len == 1) {
} else { }
else {
if (p2 == 0xB6) { if (p2 == 0xB6) {
if (puk_store_select_chr(tag_data) == CCID_OK) { if (puk_store_select_chr(tag_data) == CCID_OK) {
return SW_OK(); return SW_OK();
} }
} else if (p2 == 0xA4) { /* Aut */ }
else if (p2 == 0xA4) { /* Aut */
for (int i = 0; i < MAX_PUK; i++) { for (int i = 0; i < MAX_PUK; i++) {
file_t *ef = search_dynamic_file(EF_PUK + i); file_t *ef = search_dynamic_file(EF_PUK + i);
if (!ef) { if (!ef) {
@ -74,7 +76,8 @@ int cmd_mse()
} }
} }
} }
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
return SW_OK(); return SW_OK();

View file

@ -23,8 +23,7 @@
extern int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy); extern int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy);
extern PUK *current_puk; extern PUK *current_puk;
int cmd_pso() int cmd_pso() {
{
uint8_t p1 = P1(apdu), p2 = P2(apdu); uint8_t p1 = P1(apdu), p2 = P2(apdu);
if (p1 == 0x0 && (p2 == 0x92 || p2 == 0xAE || p2 == 0xBE)) { /* Verify certificate */ if (p1 == 0x0 && (p2 == 0x92 || p2 == 0xAE || p2 == 0xBE)) { /* Verify certificate */
if (apdu.nc == 0) { if (apdu.nc == 0) {
@ -44,7 +43,8 @@ int cmd_pso()
if (r != CCID_OK) { if (r != CCID_OK) {
if (r == CCID_WRONG_DATA) { if (r == CCID_WRONG_DATA) {
return SW_DATA_INVALID(); return SW_DATA_INVALID();
} else if (r == CCID_WRONG_SIGNATURE) { }
else if (r == CCID_WRONG_SIGNATURE) {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
@ -80,7 +80,8 @@ int cmd_pso()
if (!puk_bin) { if (!puk_bin) {
return SW_WRONG_DATA(); 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_id ec_id = cvc_inherite_ec_group(apdu.data, apdu.nc);
mbedtls_ecp_group grp; mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp); mbedtls_ecp_group_init(&grp);
@ -98,18 +99,21 @@ int cmd_pso()
} }
puk_bin = t86; puk_bin = t86;
puk_bin_len = t86_len; 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[0] == 0x2 || t86[0] == 0x3) {
if (t86_len != plen + 1) { if (t86_len != plen + 1) {
mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp);
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
} else if (t86[0] == 0x4) { }
else if (t86[0] == 0x4) {
if (t86_len != 2 * plen + 1) { if (t86_len != 2 * plen + 1) {
mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp);
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
} else { }
else {
mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp);
return SW_WRONG_DATA(); return SW_WRONG_DATA();
} }
@ -150,7 +154,8 @@ int cmd_pso()
} }
} }
return SW_OK(); return SW_OK();
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
return SW_OK(); return SW_OK();

View file

@ -19,8 +19,7 @@
#include "files.h" #include "files.h"
#include "cvc.h" #include "cvc.h"
int cmd_puk_auth() int cmd_puk_auth() {
{
uint8_t p1 = P1(apdu), p2 = P2(apdu); uint8_t p1 = P1(apdu), p2 = P2(apdu);
file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF);
if (!file_has_data(ef_puk)) { if (!file_has_data(ef_puk)) {
@ -49,7 +48,8 @@ int cmd_puk_auth()
flash_write_data_to_file(ef_puk, tmp, file_get_size(ef_puk)); flash_write_data_to_file(ef_puk, tmp, file_get_size(ef_puk));
puk_data = file_get_data(ef_puk); puk_data = file_get_data(ef_puk);
free(tmp); free(tmp);
} else if (p1 == 0x1) { /* Replace */ }
else if (p1 == 0x1) { /* Replace */
if (p2 >= puk_data[0]) { if (p2 >= puk_data[0]) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
@ -60,7 +60,8 @@ int cmd_puk_auth()
} }
flash_write_data_to_file(ef, apdu.data, apdu.nc); flash_write_data_to_file(ef, apdu.data, apdu.nc);
low_flash_available(); low_flash_available();
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
} }
@ -82,7 +83,8 @@ int cmd_puk_auth()
res_APDU_size = chr_len; res_APDU_size = chr_len;
} }
return set_res_sw(0x90, puk_status[p2]); return set_res_sw(0x90, puk_status[p2]);
} else { }
else {
memcpy(res_APDU, puk_data, 3); memcpy(res_APDU, puk_data, 3);
res_APDU[3] = 0; res_APDU[3] = 0;
for (int i = 0; i < puk_data[0]; i++) { for (int i = 0; i < puk_data[0]; i++) {

View file

@ -17,8 +17,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
int cmd_read_binary() int cmd_read_binary() {
{
uint16_t fid = 0x0; uint16_t fid = 0x0;
uint32_t offset = 0; uint32_t offset = 0;
uint8_t ins = INS(apdu), p1 = P1(apdu), p2 = P2(apdu); uint8_t ins = INS(apdu), p1 = P1(apdu), p2 = P2(apdu);
@ -30,20 +29,24 @@ int cmd_read_binary()
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
offset = p2; offset = p2;
} else { }
else {
offset = make_uint16_t(p1, p2) & 0x7fff; offset = make_uint16_t(p1, p2) & 0x7fff;
ef = currentEF; ef = currentEF;
} }
} else { }
else {
if (p1 == 0 && (p2 & 0xE0) == 0 && (p2 & 0x1f) != 0 && (p2 & 0x1f) != 0x1f) { if (p1 == 0 && (p2 & 0xE0) == 0 && (p2 & 0x1f) != 0 && (p2 & 0x1f) != 0x1f) {
if (!(ef = search_by_fid(p2 & 0x1f, NULL, SPECIFY_EF))) { if (!(ef = search_by_fid(p2 & 0x1f, NULL, SPECIFY_EF))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
} else { }
else {
uint16_t file_id = make_uint16_t(p1, p2); // & 0x7fff; uint16_t file_id = make_uint16_t(p1, p2); // & 0x7fff;
if (file_id == 0x0) { if (file_id == 0x0) {
ef = currentEF; ef = currentEF;
} else if (!(ef = }
else if (!(ef =
search_by_fid(file_id, NULL, search_by_fid(file_id, NULL,
SPECIFY_EF)) && !(ef = search_dynamic_file(file_id))) { SPECIFY_EF)) && !(ef = search_dynamic_file(file_id))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
@ -78,7 +81,8 @@ int cmd_read_binary()
//res_APDU += offset; //res_APDU += offset;
res_APDU_size -= offset; res_APDU_size -= offset;
} }
} else { }
else {
uint16_t data_len = file_get_size(ef); uint16_t data_len = file_get_size(ef);
if (offset > data_len) { if (offset > data_len) {
return SW_WRONG_P1P2(); return SW_WRONG_P1P2();

View file

@ -19,8 +19,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
#include "kek.h" #include "kek.h"
int cmd_reset_retry() int cmd_reset_retry() {
{
if (P2(apdu) != 0x81) { if (P2(apdu) != 0x81) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
@ -47,7 +46,8 @@ int cmd_reset_retry()
newpin_len = apdu.nc - 8; newpin_len = apdu.nc - 8;
has_session_sopin = true; has_session_sopin = true;
hash_multi(apdu.data, 8, session_sopin); hash_multi(apdu.data, 8, session_sopin);
} else if (P1(apdu) == 0x2) { }
else if (P1(apdu) == 0x2) {
if (!has_session_sopin) { if (!has_session_sopin) {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }
@ -77,7 +77,8 @@ int cmd_reset_retry()
} }
low_flash_available(); low_flash_available();
return SW_OK(); return SW_OK();
} else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) { }
else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) {
if (!(opts & HSM_OPT_RRC_RESET_ONLY)) { if (!(opts & HSM_OPT_RRC_RESET_ONLY)) {
return SW_COMMAND_NOT_ALLOWED(); return SW_COMMAND_NOT_ALLOWED();
} }
@ -91,7 +92,8 @@ int cmd_reset_retry()
} }
has_session_sopin = true; has_session_sopin = true;
hash_multi(apdu.data, 8, session_sopin); hash_multi(apdu.data, 8, session_sopin);
} else if (P1(apdu) == 0x3) { }
else if (P1(apdu) == 0x3) {
if (!has_session_sopin) { if (!has_session_sopin) {
return SW_CONDITIONS_NOT_SATISFIED(); return SW_CONDITIONS_NOT_SATISFIED();
} }

View file

@ -18,15 +18,16 @@
#include "sc_hsm.h" #include "sc_hsm.h"
#include "version.h" #include "version.h"
void select_file(file_t *pe) void select_file(file_t *pe) {
{
if (!pe) { if (!pe) {
currentDF = (file_t *) MF; currentDF = (file_t *) MF;
currentEF = NULL; currentEF = NULL;
} else if (pe->type & FILE_TYPE_INTERNAL_EF) { }
else if (pe->type & FILE_TYPE_INTERNAL_EF) {
currentEF = pe; currentEF = pe;
currentDF = &file_entries[pe->parent]; currentDF = &file_entries[pe->parent];
} else { }
else {
currentDF = pe; currentDF = pe;
} }
if (currentEF == file_openpgp || currentEF == file_sc_hsm) { if (currentEF == file_openpgp || currentEF == file_sc_hsm) {
@ -35,8 +36,7 @@ void select_file(file_t *pe)
} }
} }
int cmd_select() int cmd_select() {
{
uint8_t p1 = P1(apdu); uint8_t p1 = P1(apdu);
uint8_t p2 = P2(apdu); uint8_t p2 = P2(apdu);
file_t *pe = NULL; file_t *pe = NULL;
@ -72,35 +72,42 @@ int cmd_select()
if (apdu.nc == 0) { if (apdu.nc == 0) {
pe = (file_t *) MF; pe = (file_t *) MF;
//ac_fini(); //ac_fini();
} else if (apdu.nc == 2) { }
else if (apdu.nc == 2) {
if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) { if (!(pe = search_by_fid(fid, NULL, SPECIFY_ANY))) {
return SW_FILE_NOT_FOUND(); 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))) { if (!(pe = search_by_fid(fid, currentDF, SPECIFY_DF))) {
return SW_FILE_NOT_FOUND(); 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))) { if (!(pe = search_by_fid(fid, currentDF, SPECIFY_EF))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
} else if (p1 == 0x03) { //Select parent DF of the current DF - Absent }
else if (p1 == 0x03) { //Select parent DF of the current DF - Absent
if (apdu.nc != 0) { if (apdu.nc != 0) {
return SW_FILE_NOT_FOUND(); 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))) { if (!(pe = search_by_name(apdu.data, apdu.nc))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
if (card_terminated) { if (card_terminated) {
return set_res_sw(0x62, 0x85); 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))) { if (!(pe = search_by_path(apdu.data, apdu.nc, MF))) {
return SW_FILE_NOT_FOUND(); 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))) { if (!(pe = search_by_path(apdu.data, apdu.nc, currentDF))) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} }
@ -119,7 +126,8 @@ int cmd_select()
res_APDU[res_APDU_size++] = HSM_VERSION_MINOR; res_APDU[res_APDU_size++] = HSM_VERSION_MINOR;
res_APDU[1] = res_APDU_size - 2; res_APDU[1] = res_APDU_size - 2;
} }
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
select_file(pe); select_file(pe);

View file

@ -19,8 +19,7 @@
#include "random.h" #include "random.h"
#include "eac.h" #include "eac.h"
int cmd_session_pin() int cmd_session_pin() {
{
if (P1(apdu) == 0x01 && P2(apdu) == 0x81) { if (P1(apdu) == 0x01 && P2(apdu) == 0x81) {
memcpy(sm_session_pin, random_bytes_get(8), 8); memcpy(sm_session_pin, random_bytes_get(8), 8);
sm_session_pin_len = 8; sm_session_pin_len = 8;
@ -28,7 +27,8 @@ int cmd_session_pin()
memcpy(res_APDU, sm_session_pin, sm_session_pin_len); memcpy(res_APDU, sm_session_pin, sm_session_pin_len);
res_APDU_size = sm_session_pin_len; res_APDU_size = sm_session_pin_len;
apdu.ne = sm_session_pin_len; apdu.ne = sm_session_pin_len;
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
return SW_OK(); return SW_OK();

View file

@ -70,8 +70,7 @@ int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm,
const uint8_t *in_dat, const uint8_t *in_dat,
size_t in_len, size_t in_len,
uint8_t *out_dat, uint8_t *out_dat,
size_t *out_len) size_t *out_len) {
{
for (int i = 0; digest_info_prefix[i].algorithm != 0; i++) { 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; 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; const uint8_t *hdr = digest_info_prefix[i].hdr;
@ -94,8 +93,7 @@ int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm,
} }
//----- //-----
int cmd_signature() int cmd_signature() {
{
uint8_t key_id = P1(apdu); uint8_t key_id = P1(apdu);
uint8_t p2 = P2(apdu); uint8_t p2 = P2(apdu);
mbedtls_md_type_t md = MBEDTLS_MD_NONE; mbedtls_md_type_t md = MBEDTLS_MD_NONE;
@ -115,13 +113,17 @@ int cmd_signature()
int key_size = file_get_size(fkey); 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; 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; 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; 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; 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; md = MBEDTLS_MD_SHA512;
} }
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 ||
@ -153,7 +155,8 @@ int cmd_signature()
return SW_EXEC_ERROR(); return SW_EXEC_ERROR();
} }
apdu.nc = nc; apdu.nc = nc;
} else { }
else {
//sc_asn1_print_tags(apdu.data, apdu.nc); //sc_asn1_print_tags(apdu.data, apdu.nc);
size_t tout = 0, oid_len = 0; size_t tout = 0, oid_len = 0;
uint8_t *p = NULL, *oid = NULL; uint8_t *p = NULL, *oid = NULL;
@ -168,13 +171,17 @@ int cmd_signature()
if (oid && oid_len > 0) { 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; 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; 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; 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; 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; md = MBEDTLS_MD_SHA512;
} }
} }
@ -182,13 +189,17 @@ int cmd_signature()
if (p2 == ALGO_RSA_PSS && !oid) { if (p2 == ALGO_RSA_PSS && !oid) {
if (apdu.nc == 20) { //default is sha1 if (apdu.nc == 20) { //default is sha1
md = MBEDTLS_MD_SHA1; md = MBEDTLS_MD_SHA1;
} else if (apdu.nc == 28) { }
else if (apdu.nc == 28) {
md = MBEDTLS_MD_SHA224; md = MBEDTLS_MD_SHA224;
} else if (apdu.nc == 32) { }
else if (apdu.nc == 32) {
md = MBEDTLS_MD_SHA256; md = MBEDTLS_MD_SHA256;
} else if (apdu.nc == 48) { }
else if (apdu.nc == 48) {
md = MBEDTLS_MD_SHA384; md = MBEDTLS_MD_SHA384;
} else if (apdu.nc == 64) { }
else if (apdu.nc == 64) {
md = MBEDTLS_MD_SHA512; md = MBEDTLS_MD_SHA512;
} }
} }
@ -200,7 +211,8 @@ int cmd_signature()
memset(apdu.data + apdu.nc, 0, key_size - apdu.nc); memset(apdu.data + apdu.nc, 0, key_size - apdu.nc);
} }
r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU); r = mbedtls_rsa_private(&ctx, random_gen, NULL, apdu.data, res_APDU);
} else { }
else {
uint8_t *signature = (uint8_t *) calloc(key_size, sizeof(uint8_t)); uint8_t *signature = (uint8_t *) calloc(key_size, sizeof(uint8_t));
r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hash, signature); r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hash, signature);
memcpy(res_APDU, signature, key_size); memcpy(res_APDU, signature, key_size);
@ -213,32 +225,41 @@ int cmd_signature()
res_APDU_size = key_size; res_APDU_size = key_size;
apdu.ne = key_size; apdu.ne = key_size;
mbedtls_rsa_free(&ctx); 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_context ctx;
mbedtls_ecdsa_init(&ctx); mbedtls_ecdsa_init(&ctx);
md = MBEDTLS_MD_SHA256; md = MBEDTLS_MD_SHA256;
if (p2 == ALGO_EC_RAW) { if (p2 == ALGO_EC_RAW) {
if (apdu.nc == 32) { if (apdu.nc == 32) {
md = MBEDTLS_MD_SHA256; md = MBEDTLS_MD_SHA256;
} else if (apdu.nc == 20) { }
else if (apdu.nc == 20) {
md = MBEDTLS_MD_SHA1; md = MBEDTLS_MD_SHA1;
} else if (apdu.nc == 28) { }
else if (apdu.nc == 28) {
md = MBEDTLS_MD_SHA224; md = MBEDTLS_MD_SHA224;
} else if (apdu.nc == 48) { }
else if (apdu.nc == 48) {
md = MBEDTLS_MD_SHA384; md = MBEDTLS_MD_SHA384;
} else if (apdu.nc == 64) { }
else if (apdu.nc == 64) {
md = MBEDTLS_MD_SHA512; md = MBEDTLS_MD_SHA512;
} }
} }
if (p2 == ALGO_EC_SHA1) { if (p2 == ALGO_EC_SHA1) {
md = MBEDTLS_MD_SHA1; md = MBEDTLS_MD_SHA1;
} else if (p2 == ALGO_EC_SHA224) { }
else if (p2 == ALGO_EC_SHA224) {
md = MBEDTLS_MD_SHA224; md = MBEDTLS_MD_SHA224;
} else if (p2 == ALGO_EC_SHA256) { }
else if (p2 == ALGO_EC_SHA256) {
md = MBEDTLS_MD_SHA256; md = MBEDTLS_MD_SHA256;
} else if (p2 == ALGO_EC_SHA384) { }
else if (p2 == ALGO_EC_SHA384) {
md = MBEDTLS_MD_SHA384; md = MBEDTLS_MD_SHA384;
} else if (p2 == ALGO_EC_SHA512) { }
else if (p2 == ALGO_EC_SHA512) {
md = MBEDTLS_MD_SHA512; md = MBEDTLS_MD_SHA512;
} }
int r = load_private_key_ecdsa(&ctx, fkey); int r = load_private_key_ecdsa(&ctx, fkey);
@ -259,7 +280,8 @@ int cmd_signature()
memcpy(res_APDU, buf, olen); memcpy(res_APDU, buf, olen);
res_APDU_size = olen; res_APDU_size = olen;
mbedtls_ecdsa_free(&ctx); mbedtls_ecdsa_free(&ctx);
} else { }
else {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
} }
decrement_key_counter(fkey); decrement_key_counter(fkey);

View file

@ -20,8 +20,7 @@
extern void select_file(file_t *pe); extern void select_file(file_t *pe);
int cmd_update_ef() int cmd_update_ef() {
{
uint8_t p1 = P1(apdu), p2 = P2(apdu); uint8_t p1 = P1(apdu), p2 = P2(apdu);
uint16_t fid = (p1 << 8) | p2; uint16_t fid = (p1 << 8) | p2;
uint8_t *data = NULL; uint8_t *data = NULL;
@ -33,7 +32,8 @@ int cmd_update_ef()
} }
if (fid == 0x0) { if (fid == 0x0) {
ef = currentEF; ef = currentEF;
} else if (p1 != EE_CERTIFICATE_PREFIX && p1 != PRKD_PREFIX && p1 != CA_CERTIFICATE_PREFIX && }
else if (p1 != EE_CERTIFICATE_PREFIX && p1 != PRKD_PREFIX && p1 != CA_CERTIFICATE_PREFIX &&
p1 != CD_PREFIX && p1 != DATA_PREFIX && p1 != DCOD_PREFIX && p1 != CD_PREFIX && p1 != DATA_PREFIX && p1 != DCOD_PREFIX &&
p1 != PROT_DATA_PREFIX) { p1 != PROT_DATA_PREFIX) {
return SW_INCORRECT_P1P2(); return SW_INCORRECT_P1P2();
@ -51,7 +51,8 @@ int cmd_update_ef()
for (int i = 1; i <= tag_len; i++) { for (int i = 1; i <= tag_len; i++) {
offset |= (*tag_data++ << (8 * (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_len = tag_len;
data = tag_data; data = tag_data;
} }
@ -61,10 +62,12 @@ int cmd_update_ef()
//if ((fid & 0xff00) == (EE_CERTIFICATE_PREFIX << 8)) //if ((fid & 0xff00) == (EE_CERTIFICATE_PREFIX << 8))
// add_file_to_chain(ef, &ef_pukdf); // add_file_to_chain(ef, &ef_pukdf);
select_file(ef); select_file(ef);
} else { }
else {
if (fid == 0x0 && !ef) { if (fid == 0x0 && !ef) {
return SW_FILE_NOT_FOUND(); return SW_FILE_NOT_FOUND();
} else if (fid != 0x0 && }
else if (fid != 0x0 &&
!(ef = !(ef =
search_by_fid(fid, NULL, search_by_fid(fid, NULL,
SPECIFY_EF)) && !(ef = search_dynamic_file(fid))) { //if does not exist, create it SPECIFY_EF)) && !(ef = search_dynamic_file(fid))) { //if does not exist, create it
@ -76,7 +79,8 @@ int cmd_update_ef()
if (r != CCID_OK) { if (r != CCID_OK) {
return SW_MEMORY_FAILURE(); return SW_MEMORY_FAILURE();
} }
} else { }
else {
if (!file_has_data(ef)) { if (!file_has_data(ef)) {
return SW_DATA_INVALID(); return SW_DATA_INVALID();
} }

View file

@ -17,8 +17,7 @@
#include "sc_hsm.h" #include "sc_hsm.h"
int cmd_verify() int cmd_verify() {
{
uint8_t p1 = P1(apdu); uint8_t p1 = P1(apdu);
uint8_t p2 = P2(apdu); uint8_t p2 = P2(apdu);
@ -44,7 +43,8 @@ int cmd_verify()
return SW_PIN_BLOCKED(); return SW_PIN_BLOCKED();
} }
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_get_data(file_retries_pin1))); return set_res_sw(0x63, 0xc0 | file_read_uint8(file_get_data(file_retries_pin1)));
} else if (p2 == 0x88) { //SOPin }
else if (p2 == 0x88) { //SOPin
if (file_read_uint8(file_get_data(file_sopin)) == 0) { //not initialized if (file_read_uint8(file_get_data(file_sopin)) == 0) { //not initialized
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
@ -58,7 +58,8 @@ int cmd_verify()
return SW_OK(); return SW_OK();
} }
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_get_data(file_retries_sopin))); 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_OK();
} }
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();

View file

@ -31,8 +31,7 @@
extern const uint8_t *dev_name; extern const uint8_t *dev_name;
extern size_t dev_name_len; 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 }; 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 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 ntot_size = asn1_len_tag(0x81, n_size), etot_size = asn1_len_tag(0x82, e_size);
@ -73,8 +72,7 @@ const uint8_t *pointA[] = {
"\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", "\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]; uint8_t Y_buf[MBEDTLS_ECP_MAX_PT_LEN];
const uint8_t oid_ecdsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x03 }; 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 p_size = mbedtls_mpi_size(&ecdsa->grp.P), a_size = mbedtls_mpi_size(&ecdsa->grp.A);
@ -123,11 +121,13 @@ size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, siz
*p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, *p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A,
p, p,
a_size); p += a_size; a_size); p += a_size;
} else { //mbedtls does not set point A for some curves }
else { //mbedtls does not set point A for some curves
if (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6) { 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++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size);
p += p_size; p += p_size;
} else { }
else {
*p++ = 0x82; p += format_tlv_len(1, p); *p++ = 0x82; p += format_tlv_len(1, p);
*p++ = 0x0; *p++ = 0x0;
} }
@ -153,9 +153,11 @@ size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, siz
*p++ = 0x87; p += format_tlv_len(c_size, p); *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; *p++ = 4;
} else if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE25519) { }
else if (ecdsa->grp.id == MBEDTLS_ECP_DP_CURVE25519) {
*p++ = 8; *p++ = 8;
} else { }
else {
*p++ = 1; *p++ = 1;
} }
return tot_len; return tot_len;
@ -166,12 +168,12 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa,
uint8_t *buf, uint8_t *buf,
size_t buf_len, size_t buf_len,
const uint8_t *ext, const uint8_t *ext,
size_t ext_len) size_t ext_len) {
{
size_t pubkey_size = 0; 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); 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); pubkey_size = asn1_cvc_public_key_ecdsa(rsa_ecdsa, NULL, 0);
} }
size_t cpi_size = 4; size_t cpi_size = 4;
@ -213,7 +215,8 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa,
//pubkey //pubkey
if (key_type == HSM_KEY_RSA) { if (key_type == HSM_KEY_RSA) {
p += asn1_cvc_public_key_rsa(rsa_ecdsa, p, pubkey_size); 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); p += asn1_cvc_public_key_ecdsa(rsa_ecdsa, p, pubkey_size);
} }
//chr //chr
@ -232,12 +235,12 @@ size_t asn1_cvc_cert(void *rsa_ecdsa,
uint8_t *buf, uint8_t *buf,
size_t buf_len, size_t buf_len,
const uint8_t *ext, const uint8_t *ext,
size_t ext_len) size_t ext_len) {
{
size_t key_size = 0; size_t key_size = 0;
if (key_type == HSM_KEY_RSA) { if (key_type == HSM_KEY_RSA) {
key_size = mbedtls_mpi_size(&((mbedtls_rsa_context *) rsa_ecdsa)->N); key_size = mbedtls_mpi_size(&((mbedtls_rsa_context *) rsa_ecdsa)->N);
} else if (key_type == HSM_KEY_EC) { }
else if (key_type == HSM_KEY_EC) {
key_size = 2 * key_size = 2 *
(int) ((mbedtls_ecp_curve_info_from_grp_id(((mbedtls_ecdsa_context *) rsa_ecdsa) (int) ((mbedtls_ecp_curve_info_from_grp_id(((mbedtls_ecdsa_context *) rsa_ecdsa)
->grp.id)-> ->grp.id)->
@ -267,7 +270,8 @@ size_t asn1_cvc_cert(void *rsa_ecdsa,
memset(p, 0, key_size); memset(p, 0, key_size);
} }
p += key_size; p += key_size;
} else if (key_type == HSM_KEY_EC) { }
else if (key_type == HSM_KEY_EC) {
mbedtls_mpi r, s; mbedtls_mpi r, s;
int ret = 0; int ret = 0;
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) rsa_ecdsa; mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) rsa_ecdsa;
@ -278,7 +282,8 @@ size_t asn1_cvc_cert(void *rsa_ecdsa,
if (ret == 0) { if (ret == 0) {
mbedtls_mpi_write_binary(&r, p, key_size / 2); p += key_size / 2; 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; mbedtls_mpi_write_binary(&s, p, key_size / 2); p += key_size / 2;
} else { }
else {
memset(p, 0, key_size); memset(p, 0, key_size);
p += key_size; p += key_size;
} }
@ -293,8 +298,7 @@ size_t asn1_cvc_aut(void *rsa_ecdsa,
uint8_t *buf, uint8_t *buf,
size_t buf_len, size_t buf_len,
const uint8_t *ext, const uint8_t *ext,
size_t ext_len) size_t ext_len) {
{
size_t cvcert_size = asn1_cvc_cert(rsa_ecdsa, key_type, NULL, 0, ext, 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; size_t outcar_len = dev_name_len;
const uint8_t *outcar = dev_name; const uint8_t *outcar = dev_name;
@ -354,10 +358,10 @@ size_t asn1_build_cert_description(const uint8_t *label,
size_t puk_len, size_t puk_len,
uint16_t fid, uint16_t fid,
uint8_t *buf, uint8_t *buf,
size_t buf_len) size_t buf_len) {
{
size_t opt_len = 2; 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 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 seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, 20)); /* SHA1 is 20 bytes length */
size_t seq3_size = size_t seq3_size =
asn1_len_tag(0xA1, asn1_len_tag(0xA1,
@ -412,10 +416,10 @@ size_t asn1_build_prkd_generic(const uint8_t *label,
const uint8_t *seq, const uint8_t *seq,
size_t seq_len, size_t seq_len,
uint8_t *buf, uint8_t *buf,
size_t buf_len) size_t buf_len) {
{
size_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_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 seq2_size =
asn1_len_tag(0x30, asn1_len_tag(0x4, keyid_len) + asn1_len_tag(0x3, seq_len));
size_t seq3_size = size_t seq3_size =
asn1_len_tag(0xA1, asn1_len_tag(0xA1,
asn1_len_tag(0x30, asn1_len_tag(0x30,
@ -450,7 +454,8 @@ size_t asn1_build_prkd_generic(const uint8_t *label,
//Seq 3 //Seq 3
*p++ = 0xA1; *p++ = 0xA1;
p += p +=
format_tlv_len(asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0))+asn1_len_tag(0x2, format_tlv_len(asn1_len_tag(0x30,
asn1_len_tag(0x30, asn1_len_tag(0x4, 0)) + asn1_len_tag(0x2,
2)), 2)),
p); p);
*p++ = 0x30; *p++ = 0x30;
@ -472,8 +477,7 @@ size_t asn1_build_prkd_ecc(const uint8_t *label,
size_t keyid_len, size_t keyid_len,
size_t keysize, size_t keysize,
uint8_t *buf, uint8_t *buf,
size_t buf_len) size_t buf_len) {
{
return asn1_build_prkd_generic(label, return asn1_build_prkd_generic(label,
label_len, label_len,
keyid, keyid,
@ -491,8 +495,7 @@ size_t asn1_build_prkd_rsa(const uint8_t *label,
size_t keyid_len, size_t keyid_len,
size_t keysize, size_t keysize,
uint8_t *buf, uint8_t *buf,
size_t buf_len) size_t buf_len) {
{
return asn1_build_prkd_generic(label, return asn1_build_prkd_generic(label,
label_len, label_len,
keyid, keyid,
@ -504,8 +507,7 @@ size_t asn1_build_prkd_rsa(const uint8_t *label,
buf_len); 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; uint8_t *rdata = NULL;
if (data == NULL || len == 0) { if (data == NULL || len == 0) {
return NULL; return NULL;
@ -516,8 +518,7 @@ const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint
return rdata; 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; 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; data = bkdata;
@ -528,8 +529,7 @@ const uint8_t *cvc_get_body(const uint8_t *data, size_t len, size_t *olen)
return NULL; 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; 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; data = bkdata;
@ -540,32 +540,28 @@ const uint8_t *cvc_get_sig(const uint8_t *data, size_t len, size_t *olen)
return NULL; 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) { if ((data = cvc_get_body(data, len, olen)) != NULL) {
return cvc_get_field(data, len, olen, 0x42); return cvc_get_field(data, len, olen, 0x42);
} }
return NULL; 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) { if ((data = cvc_get_body(data, len, olen)) != NULL) {
return cvc_get_field(data, len, olen, 0x5F20); return cvc_get_field(data, len, olen, 0x5F20);
} }
return NULL; 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) { if ((data = cvc_get_body(data, len, olen)) != NULL) {
return cvc_get_field(data, len, olen, 0x7F49); return cvc_get_field(data, len, olen, 0x7F49);
} }
return NULL; 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) { if ((data = cvc_get_body(data, len, olen)) != NULL) {
return cvc_get_field(data, len, olen, 0x65); return cvc_get_field(data, len, olen, 0x65);
} }
@ -575,8 +571,7 @@ 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 PUK puk_store[MAX_PUK_STORE_ENTRIES];
extern int 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++) { 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 i;
@ -585,8 +580,7 @@ int puk_store_index(const uint8_t *chr, size_t chr_len)
return -1; 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; size_t chr_len = 0, car_len = 0;
const uint8_t *chr = NULL, *car = NULL; const uint8_t *chr = NULL, *car = NULL;
int eq = -1; int eq = -1;
@ -599,7 +593,8 @@ mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len)
if (idx != -1) { if (idx != -1) {
ca = puk_store[idx].cvcert; ca = puk_store[idx].cvcert;
ca_len = puk_store[idx].cvcert_len; ca_len = puk_store[idx].cvcert_len;
} else { }
else {
ca = NULL; ca = NULL;
} }
} }
@ -623,8 +618,7 @@ int puk_verify(const uint8_t *sig,
const uint8_t *hash, const uint8_t *hash,
size_t hash_len, size_t hash_len,
const uint8_t *ca, const uint8_t *ca,
size_t ca_len) size_t ca_len) {
{
size_t puk_len = 0; size_t puk_len = 0;
const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len);
if (!puk) { if (!puk) {
@ -649,17 +643,22 @@ int puk_verify(const uint8_t *sig,
mbedtls_md_type_t md = MBEDTLS_MD_NONE; 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; 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; 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; 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; md = MBEDTLS_MD_SHA1;
mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); 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; md = MBEDTLS_MD_SHA256;
mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); 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; md = MBEDTLS_MD_SHA512;
mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md); mbedtls_rsa_set_padding(&rsa, MBEDTLS_RSA_PKCS_V21, md);
} }
@ -692,17 +691,22 @@ int puk_verify(const uint8_t *sig,
if (r != 0) { if (r != 0) {
return CCID_WRONG_SIGNATURE; 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; 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; 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; 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; 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; 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; md = MBEDTLS_MD_SHA512;
} }
if (md == MBEDTLS_MD_NONE) { if (md == MBEDTLS_MD_NONE) {
@ -763,8 +767,7 @@ int puk_verify(const uint8_t *sig,
return CCID_OK; 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; size_t puk_len = 0;
const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len);
if (!puk) { if (!puk) {
@ -787,27 +790,37 @@ int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t c
if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA 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; 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; md = MBEDTLS_MD_SHA256;
} 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_V1_5_SHA_512, 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) {
md = MBEDTLS_MD_SHA256;
} else if (memcmp(oid, OID_ID_TA_RSA_PSS_SHA_512, oid_len) == 0) {
md = MBEDTLS_MD_SHA512; md = MBEDTLS_MD_SHA512;
} }
} else if (memcmp(oid, OID_ID_TA_ECDSA, 9) == 0) { //ECC 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) {
md = MBEDTLS_MD_SHA256;
}
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) { if (memcmp(oid, OID_ID_TA_ECDSA_SHA_1, oid_len) == 0) {
md = MBEDTLS_MD_SHA1; 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; 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; 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; 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; md = MBEDTLS_MD_SHA512;
} }
} }

View file

@ -39,8 +39,7 @@ bool has_mkek_mask = false;
#define POLY 0xedb88320 #define POLY 0xedb88320
uint32_t crc32c(const uint8_t *buf, size_t len) uint32_t crc32c(const uint8_t *buf, size_t len) {
{
uint32_t crc = ~0; uint32_t crc = ~0;
while (len--) { while (len--) {
crc ^= *buf++; crc ^= *buf++;
@ -51,8 +50,7 @@ uint32_t crc32c(const uint8_t *buf, size_t len)
return ~crc; return ~crc;
} }
int load_mkek(uint8_t *mkek) int load_mkek(uint8_t *mkek) {
{
if (has_session_pin == false && has_session_sopin == false) { if (has_session_pin == false && has_session_sopin == false) {
return CCID_NO_LOGIN; return CCID_NO_LOGIN;
} }
@ -93,8 +91,7 @@ int load_mkek(uint8_t *mkek)
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_context chatx;
mbedtls_chachapoly_init(&chatx); mbedtls_chachapoly_init(&chatx);
mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12); mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12);
@ -110,8 +107,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len)
return ret; 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); file_t *tf = search_dynamic_file(EF_DKEK + id);
if (!tf) { if (!tf) {
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
@ -120,13 +116,11 @@ int load_dkek(uint8_t id, uint8_t *dkek)
return mkek_decrypt(dkek, 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); mbedtls_platform_zeroize(mkek, MKEK_SIZE);
} }
int store_mkek(const uint8_t *mkek) int store_mkek(const uint8_t *mkek) {
{
if (has_session_pin == false && has_session_sopin == false) { if (has_session_pin == false && has_session_sopin == false) {
return CCID_NO_LOGIN; return CCID_NO_LOGIN;
} }
@ -134,7 +128,8 @@ int store_mkek(const uint8_t *mkek)
if (mkek == NULL) { if (mkek == NULL) {
const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE + MKEK_KEY_SIZE); const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE + MKEK_KEY_SIZE);
memcpy(tmp_mkek, rd, MKEK_IV_SIZE + MKEK_KEY_SIZE); memcpy(tmp_mkek, rd, MKEK_IV_SIZE + MKEK_KEY_SIZE);
} else { }
else {
memcpy(tmp_mkek, mkek, MKEK_SIZE); 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);
@ -175,8 +170,7 @@ int store_mkek(const uint8_t *mkek)
return CCID_OK; 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); file_t *tf = search_dynamic_file(EF_DKEK + id);
if (!tf) { if (!tf) {
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
@ -190,8 +184,7 @@ int store_dkek_key(uint8_t id, uint8_t *dkek)
return CCID_OK; 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]; uint8_t dkek[DKEK_KEY_SIZE];
if (!key) { if (!key) {
file_t *tf = search_dynamic_file(EF_DKEK + id); file_t *tf = search_dynamic_file(EF_DKEK + id);
@ -199,14 +192,14 @@ int save_dkek_key(uint8_t id, const uint8_t *key)
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
} }
memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE); memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE);
} else { }
else {
memcpy(dkek, key, DKEK_KEY_SIZE); memcpy(dkek, key, DKEK_KEY_SIZE);
} }
return store_dkek_key(id, dkek); 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]; uint8_t tmp_dkek[DKEK_KEY_SIZE];
file_t *tf = search_dynamic_file(EF_DKEK + id); file_t *tf = search_dynamic_file(EF_DKEK + id);
if (!tf) { if (!tf) {
@ -224,8 +217,7 @@ int import_dkek_share(uint8_t id, const uint8_t *share)
return CCID_OK; 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]; uint8_t hsh[32], dkek[DKEK_KEY_SIZE];
memset(kcv, 0, 8); memset(kcv, 0, 8);
memset(hsh, 0, sizeof(hsh)); memset(hsh, 0, sizeof(hsh));
@ -239,8 +231,7 @@ int dkek_kcv(uint8_t id, uint8_t *kcv) //kcv 8 bytes
return CCID_OK; 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]; uint8_t dkek[DKEK_KEY_SIZE + 4];
memset(kenc, 0, 32); memset(kenc, 0, 32);
int r = load_dkek(id, dkek); int r = load_dkek(id, dkek);
@ -253,8 +244,7 @@ int dkek_kenc(uint8_t id, uint8_t *kenc) //kenc 32 bytes
return CCID_OK; 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]; uint8_t dkek[DKEK_KEY_SIZE + 4];
memset(kmac, 0, 32); memset(kmac, 0, 32);
int r = load_dkek(id, dkek); int r = load_dkek(id, dkek);
@ -267,8 +257,7 @@ int dkek_kmac(uint8_t id, uint8_t *kmac) //kmac 32 bytes
return CCID_OK; return CCID_OK;
} }
int mkek_encrypt(uint8_t *data, size_t len) int mkek_encrypt(uint8_t *data, size_t len) {
{
int r; int r;
uint8_t mkek[MKEK_SIZE + 4]; uint8_t mkek[MKEK_SIZE + 4];
if ((r = load_mkek(mkek)) != CCID_OK) { if ((r = load_mkek(mkek)) != CCID_OK) {
@ -279,8 +268,7 @@ int mkek_encrypt(uint8_t *data, size_t len)
return r; return r;
} }
int mkek_decrypt(uint8_t *data, size_t len) int mkek_decrypt(uint8_t *data, size_t len) {
{
int r; int r;
uint8_t mkek[MKEK_SIZE + 4]; uint8_t mkek[MKEK_SIZE + 4];
if ((r = load_mkek(mkek)) != CCID_OK) { if ((r = load_mkek(mkek)) != CCID_OK) {
@ -297,8 +285,7 @@ int dkek_encode_key(uint8_t id,
uint8_t *out, uint8_t *out,
size_t *out_len, size_t *out_len,
const uint8_t *allowed, const uint8_t *allowed,
size_t allowed_len) size_t allowed_len) {
{
if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES)) { if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES)) {
return CCID_WRONG_DATA; return CCID_WRONG_DATA;
} }
@ -332,9 +319,11 @@ int dkek_encode_key(uint8_t id,
if (key_type & HSM_KEY_AES) { if (key_type & HSM_KEY_AES) {
if (key_type & HSM_KEY_AES_128) { if (key_type & HSM_KEY_AES_128) {
kb_len = 16; kb_len = 16;
} else if (key_type & HSM_KEY_AES_192) { }
else if (key_type & HSM_KEY_AES_192) {
kb_len = 24; kb_len = 24;
} else if (key_type & HSM_KEY_AES_256) { }
else if (key_type & HSM_KEY_AES_256) {
kb_len = 32; kb_len = 32;
} }
@ -351,7 +340,8 @@ int dkek_encode_key(uint8_t id,
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; algo_len = 10;
} else if (key_type & HSM_KEY_RSA) { }
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 if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13) + 16) { //13 bytes pading
return CCID_WRONG_LENGTH; return CCID_WRONG_LENGTH;
} }
@ -371,7 +361,8 @@ int dkek_encode_key(uint8_t id,
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; algo_len = 12;
} else if (key_type & HSM_KEY_EC) { }
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 if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 8 + 9 * 66 + 2 + 4) + 16) { //4 bytes pading
return CCID_WRONG_LENGTH; return CCID_WRONG_LENGTH;
} }
@ -393,14 +384,17 @@ int dkek_encode_key(uint8_t id,
put_uint16_t(1 + mbedtls_mpi_size(&ecdsa->grp.G.X) + mbedtls_mpi_size(&ecdsa->grp.G.Y), 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); kb_len += 2;
kb[8 + kb_len++] = 0x4; kb[8 + kb_len++] = 0x4;
mbedtls_mpi_write_binary(&ecdsa->grp.G.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.X)); 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); 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)); 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); kb_len += mbedtls_mpi_size(&ecdsa->grp.G.Y);
put_uint16_t(mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2; 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)); mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d));
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); put_uint16_t(1 + mbedtls_mpi_size(&ecdsa->Q.X) + mbedtls_mpi_size(&ecdsa->Q.Y),
kb + 8 + kb_len);
kb_len += 2; kb_len += 2;
kb[8 + kb_len++] = 0x4; kb[8 + kb_len++] = 0x4;
mbedtls_mpi_write_binary(&ecdsa->Q.X, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->Q.X)); mbedtls_mpi_write_binary(&ecdsa->Q.X, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->Q.X));
@ -419,9 +413,11 @@ int dkek_encode_key(uint8_t id,
if (key_type & HSM_KEY_AES) { if (key_type & HSM_KEY_AES) {
out[*out_len] = 15; out[*out_len] = 15;
} else if (key_type & HSM_KEY_RSA) { }
else if (key_type & HSM_KEY_RSA) {
out[*out_len] = 5; out[*out_len] = 5;
} else if (key_type & HSM_KEY_EC) { }
else if (key_type & HSM_KEY_EC) {
out[*out_len] = 12; out[*out_len] = 12;
} }
*out_len += 1; *out_len += 1;
@ -429,7 +425,8 @@ int dkek_encode_key(uint8_t id,
if (algo) { if (algo) {
memcpy(out + *out_len, algo, algo_len); memcpy(out + *out_len, algo, algo_len);
*out_len += algo_len; *out_len += algo_len;
} else { }
else {
*out_len += 2; *out_len += 2;
} }
@ -437,7 +434,8 @@ int dkek_encode_key(uint8_t id,
put_uint16_t(allowed_len, out + *out_len); *out_len += 2; put_uint16_t(allowed_len, out + *out_len); *out_len += 2;
memcpy(out + *out_len, allowed, allowed_len); memcpy(out + *out_len, allowed, allowed_len);
*out_len += allowed_len; *out_len += allowed_len;
} else { }
else {
*out_len += 2; *out_len += 2;
} }
//add 4 zeros //add 4 zeros
@ -475,13 +473,14 @@ int dkek_encode_key(uint8_t id,
return CCID_OK; return CCID_OK;
} }
int dkek_type_key(const uint8_t *in) int dkek_type_key(const uint8_t *in) {
{
if (in[8] == 5 || in[8] == 6) { if (in[8] == 5 || in[8] == 6) {
return HSM_KEY_RSA; return HSM_KEY_RSA;
} else if (in[8] == 12) { }
else if (in[8] == 12) {
return HSM_KEY_EC; return HSM_KEY_EC;
} else if (in[8] == 15) { }
else if (in[8] == 15) {
return HSM_KEY_AES; return HSM_KEY_AES;
} }
return 0x0; return 0x0;
@ -493,8 +492,7 @@ int dkek_decode_key(uint8_t id,
size_t in_len, size_t in_len,
int *key_size_out, int *key_size_out,
uint8_t **allowed, uint8_t **allowed,
size_t *allowed_len) size_t *allowed_len) {
{
uint8_t kcv[8]; uint8_t kcv[8];
int r = 0; int r = 0;
memset(kcv, 0, sizeof(kcv)); memset(kcv, 0, sizeof(kcv));
@ -607,7 +605,8 @@ int dkek_decode_key(uint8_t id,
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
return CCID_WRONG_DATA; return CCID_WRONG_DATA;
} }
} else if (key_type == 6) { }
else if (key_type == 6) {
//DP-1 //DP-1
len = get_uint16_t(kb, ofs); ofs += len + 2; len = get_uint16_t(kb, ofs); ofs += len + 2;
@ -647,7 +646,8 @@ int dkek_decode_key(uint8_t id,
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR; 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); r = mbedtls_rsa_import(rsa, NULL, &rsa->P, &rsa->Q, NULL, &rsa->E);
if (r != 0) { if (r != 0) {
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
@ -665,7 +665,8 @@ int dkek_decode_key(uint8_t id,
mbedtls_rsa_free(rsa); mbedtls_rsa_free(rsa);
return CCID_EXEC_ERROR; return CCID_EXEC_ERROR;
} }
} else if (key_type == 12) { }
else if (key_type == 12) {
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
mbedtls_ecdsa_init(ecdsa); mbedtls_ecdsa_init(ecdsa);
@ -711,7 +712,8 @@ int dkek_decode_key(uint8_t id,
mbedtls_ecdsa_free(ecdsa); mbedtls_ecdsa_free(ecdsa);
return CCID_EXEC_ERROR; return CCID_EXEC_ERROR;
} }
} else if (key_type == 15) { }
else if (key_type == 15) {
memcpy(key_ctx, kb + ofs, key_size); memcpy(key_ctx, kb + ofs, key_size);
} }
return CCID_OK; return CCID_OK;

View file

@ -78,8 +78,7 @@ extern int cmd_pso();
extern const uint8_t *ccid_atr; extern const uint8_t *ccid_atr;
app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) 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]))) { if (!memcmp(aid, sc_hsm_aid + 1, MIN(aid_len, sc_hsm_aid[0]))) {
a->aid = sc_hsm_aid; a->aid = sc_hsm_aid;
a->process_apdu = sc_hsm_process_apdu; a->process_apdu = sc_hsm_process_apdu;
@ -90,14 +89,12 @@ app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len)
return NULL; return NULL;
} }
void __attribute__((constructor)) sc_hsm_ctor() void __attribute__((constructor)) sc_hsm_ctor() {
{
ccid_atr = atr_sc_hsm; ccid_atr = atr_sc_hsm;
register_app(sc_hsm_select_aid); register_app(sc_hsm_select_aid);
} }
void scan_files() void scan_files() {
{
file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF); file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF);
if (file_pin1) { if (file_pin1) {
if (!file_pin1->data) { if (!file_pin1->data) {
@ -105,7 +102,8 @@ void scan_files()
const uint8_t empty[33] = { 0 }; const uint8_t empty[33] = { 0 };
flash_write_data_to_file(file_pin1, empty, sizeof(empty)); flash_write_data_to_file(file_pin1, empty, sizeof(empty));
} }
} else { }
else {
printf("FATAL ERROR: PIN1 not found in memory!\r\n"); printf("FATAL ERROR: PIN1 not found in memory!\r\n");
} }
file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF); file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF);
@ -115,7 +113,8 @@ void scan_files()
const uint8_t empty[33] = { 0 }; const uint8_t empty[33] = { 0 };
flash_write_data_to_file(file_sopin, empty, sizeof(empty)); flash_write_data_to_file(file_sopin, empty, sizeof(empty));
} }
} else { }
else {
printf("FATAL ERROR: SOPIN not found in memory!\r\n"); printf("FATAL ERROR: SOPIN not found in memory!\r\n");
} }
file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF); file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF);
@ -125,7 +124,8 @@ void scan_files()
const uint8_t retries = 3; const uint8_t retries = 3;
flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t)); 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"); printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n");
} }
file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF); file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF);
@ -135,7 +135,8 @@ void scan_files()
const uint8_t retries = 15; const uint8_t retries = 15;
flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t)); 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"); printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
} }
file_t *tf = NULL; file_t *tf = NULL;
@ -147,7 +148,8 @@ void scan_files()
const uint8_t retries = 3; const uint8_t retries = 3;
flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
} }
} else { }
else {
printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n"); printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n");
} }
tf = search_by_fid(0x1089, NULL, SPECIFY_EF); tf = search_by_fid(0x1089, NULL, SPECIFY_EF);
@ -157,14 +159,14 @@ void scan_files()
const uint8_t retries = 15; const uint8_t retries = 15;
flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
} }
} else { }
else {
printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
} }
low_flash_available(); low_flash_available();
} }
void scan_all() void scan_all() {
{
scan_flash(); scan_flash();
scan_files(); scan_files();
} }
@ -174,8 +176,7 @@ int puk_store_entries = 0;
PUK *current_puk = NULL; PUK *current_puk = NULL;
uint8_t puk_status[MAX_PUK]; uint8_t puk_status[MAX_PUK];
int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) {
{
if (data == NULL || data_len == 0) { if (data == NULL || data_len == 0) {
return CCID_ERR_NULL_PARAM; return CCID_ERR_NULL_PARAM;
} }
@ -188,7 +189,8 @@ int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
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); memcpy(tmp, data, data_len);
puk_store[puk_store_entries].cvcert = tmp; puk_store[puk_store_entries].cvcert = tmp;
} else { }
else {
puk_store[puk_store_entries].cvcert = data; puk_store[puk_store_entries].cvcert = data;
} }
puk_store[puk_store_entries].cvcert_len = data_len; puk_store[puk_store_entries].cvcert_len = data_len;
@ -206,8 +208,7 @@ int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
return CCID_OK; 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++) { for (int i = 0; i < puk_store_entries; i++) {
if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) { if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) {
current_puk = &puk_store[i]; current_puk = &puk_store[i];
@ -217,8 +218,7 @@ int puk_store_select_chr(const uint8_t *chr)
return CCID_ERR_FILE_NOT_FOUND; return CCID_ERR_FILE_NOT_FOUND;
} }
void init_sc_hsm() void init_sc_hsm() {
{
scan_all(); scan_all();
has_session_pin = has_session_sopin = false; has_session_pin = has_session_sopin = false;
isUserAuthenticated = false; isUserAuthenticated = false;
@ -246,16 +246,14 @@ void init_sc_hsm()
memset(puk_status, 0, sizeof(puk_status)); memset(puk_status, 0, sizeof(puk_status));
} }
int sc_hsm_unload() int sc_hsm_unload() {
{
has_session_pin = has_session_sopin = false; has_session_pin = has_session_sopin = false;
isUserAuthenticated = false; isUserAuthenticated = false;
sm_session_pin_len = 0; sm_session_pin_len = 0;
return CCID_OK; return CCID_OK;
} }
uint16_t get_device_options() uint16_t get_device_options() {
{
file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); 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 (file_read_uint8(file_get_data(ef)) << 8) | file_read_uint8(file_get_data(ef) + 1);
@ -265,8 +263,7 @@ uint16_t get_device_options()
extern uint32_t board_button_read(void); extern uint32_t board_button_read(void);
bool wait_button_pressed() bool wait_button_pressed() {
{
uint32_t val = EV_PRESS_BUTTON; uint32_t val = EV_PRESS_BUTTON;
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
uint16_t opts = get_device_options(); uint16_t opts = get_device_options();
@ -280,8 +277,7 @@ bool wait_button_pressed()
return val == EV_BUTTON_TIMEOUT; 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 *label = "SmartCard-HSM";
char *manu = "Pol Henarejos"; char *manu = "Pol Henarejos";
if (mode == 1) { if (mode == 1) {
@ -303,8 +299,7 @@ int parse_token_info(const file_t *f, int mode)
return 2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2); return 2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2);
} }
int pin_reset_retries(const file_t *pin, bool force) int pin_reset_retries(const file_t *pin, bool force) {
{
if (!pin) { if (!pin) {
return CCID_ERR_NULL_PARAM; return CCID_ERR_NULL_PARAM;
} }
@ -323,8 +318,7 @@ int pin_reset_retries(const file_t *pin, bool force)
return r; return r;
} }
int pin_wrong_retry(const file_t *pin) int pin_wrong_retry(const file_t *pin) {
{
if (!pin) { if (!pin) {
return CCID_ERR_NULL_PARAM; return CCID_ERR_NULL_PARAM;
} }
@ -348,14 +342,12 @@ int pin_wrong_retry(const file_t *pin)
return CCID_ERR_BLOCKED; return CCID_ERR_BLOCKED;
} }
bool pka_enabled() bool pka_enabled() {
{
file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); 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; 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) int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
{
if (!file_has_data((file_t *) pin)) { if (!file_has_data((file_t *) pin)) {
return SW_REFERENCE_NOT_FOUND(); return SW_REFERENCE_NOT_FOUND();
} }
@ -371,7 +363,8 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len)
} }
return set_res_sw(0x63, 0xc0 | retries); return set_res_sw(0x63, 0xc0 | retries);
} }
} else { }
else {
uint8_t dhash[32]; uint8_t dhash[32];
double_hash_pin(data, len, dhash); 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
@ -398,15 +391,15 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len)
if (pin == file_pin1) { if (pin == file_pin1) {
hash_multi(data, len, session_pin); hash_multi(data, len, session_pin);
has_session_pin = true; has_session_pin = true;
} else if (pin == file_sopin) { }
else if (pin == file_sopin) {
hash_multi(data, len, session_sopin); hash_multi(data, len, session_sopin);
has_session_sopin = true; has_session_sopin = true;
} }
return SW_OK(); return SW_OK();
} }
const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) {
{
if (ef == NULL) { if (ef == NULL) {
return NULL; return NULL;
} }
@ -424,8 +417,7 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len)
return NULL; return NULL;
} }
uint32_t get_key_counter(file_t *fkey) uint32_t get_key_counter(file_t *fkey) {
{
size_t tag_len = 0; size_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len); const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len);
if (meta_tag) { if (meta_tag) {
@ -434,8 +426,7 @@ uint32_t get_key_counter(file_t *fkey)
return 0xffffffff; 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; size_t tag_len = 0;
const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len); const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len);
if (meta_tag) { if (meta_tag) {
@ -449,8 +440,7 @@ bool key_has_purpose(file_t *ef, uint8_t purpose)
return true; return true;
} }
uint32_t decrement_key_counter(file_t *fkey) uint32_t decrement_key_counter(file_t *fkey) {
{
if (!fkey) { if (!fkey) {
return 0xffffff; return 0xffffff;
} }
@ -488,8 +478,7 @@ uint32_t decrement_key_counter(file_t *fkey)
} }
//Stores the private and public keys in flash //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; int r, key_size = 0;
uint8_t kdata[4096 / 8]; //worst case uint8_t kdata[4096 / 8]; //worst case
if (type == HSM_KEY_RSA) { if (type == HSM_KEY_RSA) {
@ -497,22 +486,27 @@ int store_keys(void *key_ctx, int type, uint8_t key_id)
key_size = mbedtls_mpi_size(&rsa->P) + mbedtls_mpi_size(&rsa->Q); 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->P, kdata, key_size / 2);
mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2); mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2);
} else if (type == HSM_KEY_EC) { }
else if (type == HSM_KEY_EC) {
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
key_size = mbedtls_mpi_size(&ecdsa->d); key_size = mbedtls_mpi_size(&ecdsa->d);
kdata[0] = ecdsa->grp.id & 0xff; kdata[0] = ecdsa->grp.id & 0xff;
mbedtls_mpi_write_binary(&ecdsa->d, kdata + 1, key_size); mbedtls_mpi_write_binary(&ecdsa->d, kdata + 1, key_size);
key_size++; key_size++;
} else if (type & HSM_KEY_AES) { }
else if (type & HSM_KEY_AES) {
if (type == HSM_KEY_AES_128) { if (type == HSM_KEY_AES_128) {
key_size = 16; key_size = 16;
} else if (type == HSM_KEY_AES_192) { }
else if (type == HSM_KEY_AES_192) {
key_size = 24; key_size = 24;
} else if (type == HSM_KEY_AES_256) { }
else if (type == HSM_KEY_AES_256) {
key_size = 32; key_size = 32;
} }
memcpy(kdata, key_ctx, key_size); memcpy(kdata, key_ctx, key_size);
} else { }
else {
return CCID_WRONG_DATA; return CCID_WRONG_DATA;
} }
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id); file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
@ -531,8 +525,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id)
return CCID_OK; return CCID_OK;
} }
int find_and_store_meta_key(uint8_t key_id) int find_and_store_meta_key(uint8_t key_id) {
{
size_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; size_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0;
uint8_t *pt[4] = { NULL, NULL, NULL, NULL }; uint8_t *pt[4] = { NULL, NULL, NULL, NULL };
uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE };
@ -572,8 +565,7 @@ int find_and_store_meta_key(uint8_t key_id)
return CCID_OK; return CCID_OK;
} }
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
{
if (wait_button_pressed() == true) { //timeout if (wait_button_pressed() == true) { //timeout
return CCID_VERIFICATION_FAILED; return CCID_VERIFICATION_FAILED;
} }
@ -617,8 +609,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey)
return CCID_OK; return CCID_OK;
} }
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
{
if (wait_button_pressed() == true) { //timeout if (wait_button_pressed() == true) { //timeout
return CCID_VERIFICATION_FAILED; return CCID_VERIFICATION_FAILED;
} }
@ -699,8 +690,7 @@ static const cmd_t cmds[] = {
{ 0x00, 0x0 } { 0x00, 0x0 }
}; };
int sc_hsm_process_apdu() int sc_hsm_process_apdu() {
{
int r = sm_unwrap(); int r = sm_unwrap();
if (r != CCID_OK) { if (r != CCID_OK) {
return SW_DATA_INVALID(); return SW_DATA_INVALID();