From d74b3418bc20c7909bf61efcff69f088f75ef3b6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 11 Nov 2023 20:13:38 +0100 Subject: [PATCH 01/85] Fix typo Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 012c15f..61acd4d 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -97,7 +97,7 @@ def parse_args(): parser_opts_unlock = subparser_secure.add_parser('unlock', help='Unlocks the secure lock.') parser_opts_disable = subparser_secure.add_parser('disable', help='Disables secure lock.') - parser_cipher = subparser.add_parser('cipher', help='Implements extended symmetric ciphering with new algorithms and options.\n\tIf no file input/output is specified, stdin/stoud will be used.') + parser_cipher = subparser.add_parser('cipher', help='Implements extended symmetric ciphering with new algorithms and options.\n\tIf no file input/output is specified, stdin/stdout will be used.') subparser_cipher = parser_cipher.add_subparsers(title='commands', dest='subcommand') parser_cipher_encrypt = subparser_cipher.add_parser('encrypt', help='Performs encryption.') parser_cipher_decrypt = subparser_cipher.add_parser('decrypt', help='Performs decryption.') From 1c7cdc85649c8d8e7736f689a9064afa504a36d1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 11 Nov 2023 20:28:13 +0100 Subject: [PATCH 02/85] Added support for CMAC. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 61acd4d..bebba89 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -102,14 +102,12 @@ def parse_args(): parser_cipher_encrypt = subparser_cipher.add_parser('encrypt', help='Performs encryption.') parser_cipher_decrypt = subparser_cipher.add_parser('decrypt', help='Performs decryption.') parser_cipher_keygen = subparser_cipher.add_parser('keygen', help='Generates new AES key.') - parser_cipher_hmac = subparser_cipher.add_parser('hmac', help='Computes HMAC.') + parser_cipher_hmac = subparser_cipher.add_parser('mac', help='Computes MAC (HMAC or CMAC).') parser_cipher_kdf = subparser_cipher.add_parser('kdf', help='Performs key derivation function on a secret key.') parser_cipher_encrypt.add_argument('--alg', choices=['CHACHAPOLY'], required=True) - parser_cipher_encrypt.add_argument('--iteration', help='Iteration count.', required=any(['PBKDF2' in s for s in sys.argv])) parser_cipher_decrypt.add_argument('--alg', choices=['CHACHAPOLY'], required=True) - parser_cipher_decrypt.add_argument('--iteration', help='Iteration count.', required=any(['PBKDF2' in s for s in sys.argv])) - parser_cipher_hmac.add_argument('--alg', choices=['HMAC-SHA1', 'HMAC-SHA224', 'HMAC-SHA256', 'HMAC-SHA384', 'HMAC-SHA512'], help='Selects the algorithm.', required=True) + parser_cipher_hmac.add_argument('--alg', choices=['CMAC', 'HMAC-SHA1', 'HMAC-SHA224', 'HMAC-SHA256', 'HMAC-SHA384', 'HMAC-SHA512'], help='Selects the algorithm.', required=True) parser_cipher_kdf.add_argument('--alg', choices=['HKDF-SHA256', 'HKDF-SHA384', 'HKDF-SHA512', 'PBKDF2-SHA1', 'PBKDF2-SHA224', 'PBKDF2-SHA256', 'PBKDF2-SHA384', 'PBKDF2-SHA512', 'X963-SHA1', 'X963-SHA224', 'X963-SHA256', 'X963-SHA384', 'X963-SHA512'], help='Selects the algorithm.', required=True) parser_cipher_kdf.add_argument('--output-len', help='Specifies the output length of derived material.') parser_cipher_kdf.add_argument('--iteration', help='Iteration count.', required=any(['PBKDF2' in s for s in sys.argv])) @@ -382,6 +380,8 @@ def cipher(picohsm, args): mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT if (args.alg == 'CHACHAPOLY'): ret = picohsm.chachapoly(args.key, mode, data=enc, iv=iv, aad=aad) + elif (args.alg == 'CMAC'): + ret = picohsm.cmac(keyid=args.key, data=enc) elif (args.alg == 'HMAC-SHA1'): ret = picohsm.hmac(hashes.SHA1, args.key, data=enc) elif (args.alg == 'HMAC-SHA224'): From a5ab1cabc53dca977393e084192cc947e160d0cd Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 11 Nov 2023 21:19:31 +0100 Subject: [PATCH 03/85] Add support for AES-ECB, AES-CBC with custom IV, AES-OFB, AES-CFB, AES-GCM, AES-CCM, AES-CTR and AES-XTS. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 65 ++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index bebba89..56c5f75 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -39,7 +39,7 @@ except ModuleNotFoundError: sys.exit(-1) try: - from picohsm import PicoHSM, PinType, DOPrefixes, KeyType, EncryptionMode, utils, APDUResponse, SWCodes + from picohsm import PicoHSM, PinType, DOPrefixes, KeyType, EncryptionMode, utils, APDUResponse, SWCodes, AES except ModuleNotFoundError: print('ERROR: picohsm module not found! Install picohsm package.\nTry with `pip install pypicohsm`') sys.exit(-1) @@ -104,8 +104,8 @@ def parse_args(): parser_cipher_keygen = subparser_cipher.add_parser('keygen', help='Generates new AES key.') parser_cipher_hmac = subparser_cipher.add_parser('mac', help='Computes MAC (HMAC or CMAC).') parser_cipher_kdf = subparser_cipher.add_parser('kdf', help='Performs key derivation function on a secret key.') - parser_cipher_encrypt.add_argument('--alg', choices=['CHACHAPOLY'], required=True) - parser_cipher_decrypt.add_argument('--alg', choices=['CHACHAPOLY'], required=True) + parser_cipher_encrypt.add_argument('--alg', choices=['CHACHAPOLY','AES-ECB','AES-CBC','AES-OFB','AES-CFB','AES-GCM','AES-CCM','AES-CTR','AES-XTS'], required=True) + parser_cipher_decrypt.add_argument('--alg', choices=['CHACHAPOLY','AES-ECB','AES-CBC','AES-OFB','AES-CFB','AES-GCM','AES-CCM','AES-CTR','AES-XTS'], required=True) parser_cipher_hmac.add_argument('--alg', choices=['CMAC', 'HMAC-SHA1', 'HMAC-SHA224', 'HMAC-SHA256', 'HMAC-SHA384', 'HMAC-SHA512'], help='Selects the algorithm.', required=True) parser_cipher_kdf.add_argument('--alg', choices=['HKDF-SHA256', 'HKDF-SHA384', 'HKDF-SHA512', 'PBKDF2-SHA1', 'PBKDF2-SHA224', 'PBKDF2-SHA256', 'PBKDF2-SHA384', 'PBKDF2-SHA512', 'X963-SHA1', 'X963-SHA224', 'X963-SHA256', 'X963-SHA384', 'X963-SHA512'], help='Selects the algorithm.', required=True) @@ -376,48 +376,65 @@ def cipher(picohsm, args): aad = args.aad if (args.aad and args.hex): aad = unhexlify(aad) + kid = int(args.key) mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT if (args.alg == 'CHACHAPOLY'): - ret = picohsm.chachapoly(args.key, mode, data=enc, iv=iv, aad=aad) + ret = picohsm.chachapoly(kid, mode, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-ECB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.ECB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CBC'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CBC, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-OFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.OFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-GCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.GCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CTR'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CTR, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-XTS'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.XTS, data=enc, iv=iv, aad=aad) elif (args.alg == 'CMAC'): - ret = picohsm.cmac(keyid=args.key, data=enc) + ret = picohsm.cmac(keyid=kid, data=enc) elif (args.alg == 'HMAC-SHA1'): - ret = picohsm.hmac(hashes.SHA1, args.key, data=enc) + ret = picohsm.hmac(hashes.SHA1, kid, data=enc) elif (args.alg == 'HMAC-SHA224'): - ret = picohsm.hmac(hashes.SHA224, args.key, data=enc) + ret = picohsm.hmac(hashes.SHA224, kid, data=enc) elif (args.alg == 'HMAC-SHA256'): - ret = picohsm.hmac(hashes.SHA256, args.key, data=enc) + ret = picohsm.hmac(hashes.SHA256, kid, data=enc) elif (args.alg == 'HMAC-SHA384'): - ret = picohsm.hmac(hashes.SHA384, args.key, data=enc) + ret = picohsm.hmac(hashes.SHA384, kid, data=enc) elif (args.alg == 'HMAC-SHA512'): - ret = picohsm.hmac(hashes.SHA512, args.key, data=enc) + ret = picohsm.hmac(hashes.SHA512, kid, data=enc) elif (args.alg == 'HKDF-SHA256'): - ret = picohsm.hkdf(hashes.SHA256, args.key, data=enc, salt=iv, out_len=args.output_len) + ret = picohsm.hkdf(hashes.SHA256, kid, data=enc, salt=iv, out_len=args.output_len) elif (args.alg == 'HKDF-SHA384'): - ret = picohsm.hkdf(hashes.SHA384, args.key, data=enc, salt=iv, out_len=args.output_len) + ret = picohsm.hkdf(hashes.SHA384, kid, data=enc, salt=iv, out_len=args.output_len) elif (args.alg == 'HKDF-SHA512'): - ret = picohsm.hkdf(hashes.SHA512, args.key, data=enc, salt=iv, out_len=args.output_len) + ret = picohsm.hkdf(hashes.SHA512, kid, data=enc, salt=iv, out_len=args.output_len) elif (args.alg == 'PBKDF2-SHA1'): - ret = picohsm.pbkdf2(hashes.SHA1, args.key, salt=iv, iterations=args.iteration, out_len=args.output_len) + ret = picohsm.pbkdf2(hashes.SHA1, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) elif (args.alg == 'PBKDF2-SHA224'): - ret = picohsm.pbkdf2(hashes.SHA224, args.key, salt=iv, iterations=args.iteration, out_len=args.output_len) + ret = picohsm.pbkdf2(hashes.SHA224, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) elif (args.alg == 'PBKDF2-SHA256'): - ret = picohsm.pbkdf2(hashes.SHA256, args.key, salt=iv, iterations=args.iteration, out_len=args.output_len) + ret = picohsm.pbkdf2(hashes.SHA256, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) elif (args.alg == 'PBKDF2-SHA384'): - ret = picohsm.pbkdf2(hashes.SHA384, args.key, salt=iv, iterations=args.iteration, out_len=args.output_len) + ret = picohsm.pbkdf2(hashes.SHA384, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) elif (args.alg == 'PBKDF2-SHA512'): - ret = picohsm.pbkdf2(hashes.SHA512, args.key, salt=iv, iterations=args.iteration, out_len=args.output_len) + ret = picohsm.pbkdf2(hashes.SHA512, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) elif (args.alg == 'X963-SHA1'): - ret = picohsm.x963(hashes.SHA1, args.key, data=enc, out_len=args.output_len) + ret = picohsm.x963(hashes.SHA1, kid, data=enc, out_len=args.output_len) elif (args.alg == 'X963-SHA224'): - ret = picohsm.x963(hashes.SHA224, args.key, data=enc, out_len=args.output_len) + ret = picohsm.x963(hashes.SHA224, kid, data=enc, out_len=args.output_len) elif (args.alg == 'X963-SHA256'): - ret = picohsm.x963(hashes.SHA256, args.key, data=enc, out_len=args.output_len) + ret = picohsm.x963(hashes.SHA256, kid, data=enc, out_len=args.output_len) elif (args.alg == 'X963-SHA384'): - ret = picohsm.x963(hashes.SHA384, args.key, data=enc, out_len=args.output_len) + ret = picohsm.x963(hashes.SHA384, kid, data=enc, out_len=args.output_len) elif (args.alg == 'X963-SHA512'): - ret = picohsm.x963(hashes.SHA512, args.key, data=enc, out_len=args.output_len) + ret = picohsm.x963(hashes.SHA512, kid, data=enc, out_len=args.output_len) if (args.file_out): fout = open(args.file_out, 'wb') @@ -454,7 +471,7 @@ def x25519(picohsm, args): cdata += b'\x42\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' cdata += b'\x7f\x49\x81' + bytes([len(oid)+len(p_data)+len(a_data)+len(g_data)+len(n_data)+len(h_data)]) + oid + p_data + a_data + g_data + n_data + h_data cdata += b'\x5F\x20\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' - ret = picohsm.send(command=0x46, p1=args.key, data=list(cdata)) + ret = picohsm.send(command=0x46, p1=int(args.key), data=list(cdata)) def main(args): sys.stderr.buffer.write(b'Pico HSM Tool v1.10\n') From 58692b2711b363a629d2c8e31986deee27fda162 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 14:14:10 +0100 Subject: [PATCH 04/85] Fix PRKD cert on key unwrap. Signed-off-by: Pol Henarejos --- src/hsm/cmd_key_unwrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index 83b765b..13b7160 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -55,7 +55,7 @@ int cmd_key_unwrap() { if (r != CCID_OK) { return SW_EXEC_ERROR(); } - prkd_len = asn1_build_prkd_ecc(NULL, 0, NULL, 0, key_size * 8, prkd_buf, sizeof(prkd_buf)); + prkd_len = asn1_build_prkd_rsa(NULL, 0, NULL, 0, key_size * 8, prkd_buf, sizeof(prkd_buf)); } else if (key_type & PICO_KEYS_KEY_EC) { mbedtls_ecdsa_context ctx; From 4d47f0224eabac7a8526839cc3dab1e67a8cf1bf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 14:26:46 +0100 Subject: [PATCH 05/85] Fix emulation in apple. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index f0687c1..30f86af 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit f0687c1ef392c2bcb293ea554f1dd8b784484922 +Subproject commit 30f86afe6d456203b34938bafa7b9d274bbb040d From e96e1d0097e9903f805920d7dad12de43172e40d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 15:33:27 +0100 Subject: [PATCH 06/85] When a key is generated and stored, it creates its PRKD. Signed-off-by: Pol Henarejos --- src/hsm/cvc.h | 8 ++++++++ src/hsm/sc_hsm.c | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/hsm/cvc.h b/src/hsm/cvc.h index 3519e59..1959cfd 100644 --- a/src/hsm/cvc.h +++ b/src/hsm/cvc.h @@ -94,4 +94,12 @@ extern size_t asn1_build_prkd_aes(const uint8_t *label, size_t keysize, uint8_t *buf, size_t buf_len); +extern size_t asn1_build_prkd_generic(const uint8_t *label, + size_t label_len, + const uint8_t *keyid, + size_t keyid_len, + size_t keysize, + int key_tpe, + uint8_t *buf, + size_t buf_len); #endif diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 2380839..f4450f2 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -539,6 +539,19 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { if (r != CCID_OK) { return r; } + char key_id_str[4] = {0}; + sprintf(key_id_str, "%u", key_id); + if (type & PICO_KEYS_KEY_EC) { + key_size--; + } + size_t prkd_len = asn1_build_prkd_generic(NULL, 0, (uint8_t *)key_id_str, strlen(key_id_str), key_size * 8, type, kdata, sizeof(kdata)); + if (prkd_len > 0) { + fpk = file_new((PRKD_PREFIX << 8) | key_id); + r = flash_write_data_to_file(fpk, kdata, prkd_len); + if (r != 0) { + return SW_EXEC_ERROR(); + } + } low_flash_available(); return CCID_OK; } From 74afa075124c0c2ea6c8d5a8fb717ace06f357ce Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 15:33:52 +0100 Subject: [PATCH 07/85] Do not make a PRKD on key unwrap since it is already done when storing. Signed-off-by: Pol Henarejos --- src/hsm/cmd_key_unwrap.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index 13b7160..d214bf9 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -30,8 +30,8 @@ int cmd_key_unwrap() { return SW_SECURITY_STATUS_NOT_SATISFIED(); } int key_type = dkek_type_key(apdu.data); - uint8_t kdom = -1, *allowed = NULL, prkd_buf[128]; - size_t allowed_len = 0, prkd_len = 0; + uint8_t kdom = -1, *allowed = NULL; + size_t allowed_len = 0; if (key_type == 0x0) { return SW_DATA_INVALID(); } @@ -50,12 +50,10 @@ int cmd_key_unwrap() { mbedtls_rsa_free(&ctx); return SW_EXEC_ERROR(); } - int key_size = ctx.len; mbedtls_rsa_free(&ctx); if (r != CCID_OK) { return SW_EXEC_ERROR(); } - prkd_len = asn1_build_prkd_rsa(NULL, 0, NULL, 0, key_size * 8, prkd_buf, sizeof(prkd_buf)); } else if (key_type & PICO_KEYS_KEY_EC) { mbedtls_ecdsa_context ctx; @@ -72,12 +70,10 @@ int cmd_key_unwrap() { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } - int key_size = ctx.grp.nbits; mbedtls_ecdsa_free(&ctx); if (r != CCID_OK) { return SW_EXEC_ERROR(); } - prkd_len = asn1_build_prkd_ecc(NULL, 0, NULL, 0, key_size, prkd_buf, sizeof(prkd_buf)); } else if (key_type & PICO_KEYS_KEY_AES) { uint8_t aes_key[64]; @@ -113,7 +109,6 @@ int cmd_key_unwrap() { if (r != CCID_OK) { return SW_EXEC_ERROR(); } - prkd_len = asn1_build_prkd_aes(NULL, 0, NULL, 0, key_size * 8, prkd_buf, sizeof(prkd_buf)); } if ((allowed != NULL && allowed_len > 0) || kdom >= 0) { size_t meta_len = (allowed_len > 0 ? 2 + allowed_len : 0) + (kdom >= 0 ? 3 : 0); @@ -134,13 +129,6 @@ int cmd_key_unwrap() { return r; } } - if (prkd_len > 0) { - file_t *fpk = file_new((PRKD_PREFIX << 8) | key_id); - r = flash_write_data_to_file(fpk, prkd_buf, prkd_len); - if (r != 0) { - return SW_EXEC_ERROR(); - } - } if (res_APDU_size > 0) { file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id); r = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); From 2086a68c53cb99e158f617289a2b6d36f4efe20a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 15:34:21 +0100 Subject: [PATCH 08/85] Key id not needed on keygen. It also returns the fresh new generated key id. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 56c5f75..0be2e36 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -117,7 +117,7 @@ def parse_args(): parser_cipher.add_argument('--file-out', help='File to write the result.') parser_cipher.add_argument('--aad', help='Specifies the authentication data (it can be a string or hex string. Combine with --hex if necesary).') parser_cipher.add_argument('--hex', help='Parses the AAD parameter as a hex string (for binary data).', action='store_true') - parser_cipher.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=True) + parser_cipher.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=all(['keygen' not in s for s in sys.argv])) parser_cipher.add_argument('-s', '--key-size', default=32, help='Size of the key in bytes.') parser_x25519 = argparse.ArgumentParser(add_help=False) @@ -363,6 +363,8 @@ def secure(picohsm, args): def cipher(picohsm, args): if (args.subcommand == 'keygen'): ret = picohsm.key_generation(KeyType.AES, param=args.key_size * 8) + print('Key generated successfully.') + print(f'Key ID: {ret}') else: if (args.file_in): fin = open(args.file_in, 'rb') From e98b26fee5e92337c44a21a5575a8d491f846669 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 15:34:33 +0100 Subject: [PATCH 09/85] Flush stderr. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 0be2e36..76993c7 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -480,6 +480,7 @@ def main(args): sys.stderr.buffer.write(b'Author: Pol Henarejos\n') sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n') sys.stderr.buffer.write(b'\n\n') + sys.stderr.flush() picohsm = PicoHSM(args.pin) From d90b2962374bbab1dd8e66c3d7f09cbc00f3e07f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 16:57:11 +0100 Subject: [PATCH 10/85] Added keygen command to generate AES, X25519 and X448 keys. It replaces x25519/x448 commands and cipher keygen subcommand. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 221 ++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 126 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 76993c7..51fa099 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -101,7 +101,6 @@ def parse_args(): subparser_cipher = parser_cipher.add_subparsers(title='commands', dest='subcommand') parser_cipher_encrypt = subparser_cipher.add_parser('encrypt', help='Performs encryption.') parser_cipher_decrypt = subparser_cipher.add_parser('decrypt', help='Performs decryption.') - parser_cipher_keygen = subparser_cipher.add_parser('keygen', help='Generates new AES key.') parser_cipher_hmac = subparser_cipher.add_parser('mac', help='Computes MAC (HMAC or CMAC).') parser_cipher_kdf = subparser_cipher.add_parser('kdf', help='Performs key derivation function on a secret key.') parser_cipher_encrypt.add_argument('--alg', choices=['CHACHAPOLY','AES-ECB','AES-CBC','AES-OFB','AES-CFB','AES-GCM','AES-CCM','AES-CTR','AES-XTS'], required=True) @@ -120,20 +119,12 @@ def parse_args(): parser_cipher.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=all(['keygen' not in s for s in sys.argv])) parser_cipher.add_argument('-s', '--key-size', default=32, help='Size of the key in bytes.') - parser_x25519 = argparse.ArgumentParser(add_help=False) - subparser_x25519 = parser_x25519.add_subparsers(title='commands', dest='subcommand') - parser_x25519_keygen = subparser_x25519.add_parser('keygen', help='Generates a keypair for X25519 or X448.') - parser_x25519.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID', required=True) - - # Subparsers based on parent - - parser_create = subparser.add_parser("x25519", parents=[parser_x25519], - help='X25519 key management.') - # Add some arguments exclusively for parser_create - - parser_update = subparser.add_parser("x448", parents=[parser_x25519], - help='X448 key management.') - # Add some arguments exclusively for parser_update + parser_keygen = subparser.add_parser('keygen', help='Generates private keypair or secret key.') + subparser_keygen = parser_keygen.add_subparsers(title='commands', dest='subcommand', required=True) + parser_keygen_aes = subparser_keygen.add_parser('aes', help='Generates an AES key.') + parser_keygen_aes.add_argument('--size', help='Specifies the size of AES key [128, 192 or 256]',choices=[128, 192, 256], default=128) + parser_keygen_x25519 = subparser_keygen.add_parser('x25519', help='Generates a private X25519 keypair.') + parser_keygen_x448 = subparser_keygen.add_parser('x448', help='Generates a private X448 keypair.') args = parser.parse_args() return args @@ -361,119 +352,97 @@ def secure(picohsm, args): slck.disable_device_aut() def cipher(picohsm, args): - if (args.subcommand == 'keygen'): - ret = picohsm.key_generation(KeyType.AES, param=args.key_size * 8) - print('Key generated successfully.') - print(f'Key ID: {ret}') + if (args.file_in): + fin = open(args.file_in, 'rb') else: - if (args.file_in): - fin = open(args.file_in, 'rb') - else: - fin = sys.stdin.buffer - enc = fin.read() - fin.close() - iv = args.iv - if (args.iv and args.hex): - iv = unhexlify(iv) - aad = args.aad - if (args.aad and args.hex): - aad = unhexlify(aad) - kid = int(args.key) + fin = sys.stdin.buffer + enc = fin.read() + fin.close() + iv = args.iv + if (args.iv and args.hex): + iv = unhexlify(iv) + aad = args.aad + if (args.aad and args.hex): + aad = unhexlify(aad) + kid = int(args.key) - mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT - if (args.alg == 'CHACHAPOLY'): - ret = picohsm.chachapoly(kid, mode, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-ECB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.ECB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CBC'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CBC, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-OFB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.OFB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CFB'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CFB, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-GCM'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.GCM, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CCM'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CCM, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-CTR'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CTR, data=enc, iv=iv, aad=aad) - elif (args.alg == 'AES-XTS'): - ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.XTS, data=enc, iv=iv, aad=aad) - elif (args.alg == 'CMAC'): - ret = picohsm.cmac(keyid=kid, data=enc) - elif (args.alg == 'HMAC-SHA1'): - ret = picohsm.hmac(hashes.SHA1, kid, data=enc) - elif (args.alg == 'HMAC-SHA224'): - ret = picohsm.hmac(hashes.SHA224, kid, data=enc) - elif (args.alg == 'HMAC-SHA256'): - ret = picohsm.hmac(hashes.SHA256, kid, data=enc) - elif (args.alg == 'HMAC-SHA384'): - ret = picohsm.hmac(hashes.SHA384, kid, data=enc) - elif (args.alg == 'HMAC-SHA512'): - ret = picohsm.hmac(hashes.SHA512, kid, data=enc) - elif (args.alg == 'HKDF-SHA256'): - ret = picohsm.hkdf(hashes.SHA256, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'HKDF-SHA384'): - ret = picohsm.hkdf(hashes.SHA384, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'HKDF-SHA512'): - ret = picohsm.hkdf(hashes.SHA512, kid, data=enc, salt=iv, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA1'): - ret = picohsm.pbkdf2(hashes.SHA1, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA224'): - ret = picohsm.pbkdf2(hashes.SHA224, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA256'): - ret = picohsm.pbkdf2(hashes.SHA256, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA384'): - ret = picohsm.pbkdf2(hashes.SHA384, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'PBKDF2-SHA512'): - ret = picohsm.pbkdf2(hashes.SHA512, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) - elif (args.alg == 'X963-SHA1'): - ret = picohsm.x963(hashes.SHA1, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA224'): - ret = picohsm.x963(hashes.SHA224, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA256'): - ret = picohsm.x963(hashes.SHA256, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA384'): - ret = picohsm.x963(hashes.SHA384, kid, data=enc, out_len=args.output_len) - elif (args.alg == 'X963-SHA512'): - ret = picohsm.x963(hashes.SHA512, kid, data=enc, out_len=args.output_len) + mode = EncryptionMode.ENCRYPT if args.subcommand[0] == 'e' else EncryptionMode.DECRYPT + if (args.alg == 'CHACHAPOLY'): + ret = picohsm.chachapoly(kid, mode, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-ECB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.ECB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CBC'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CBC, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-OFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.OFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CFB'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CFB, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-GCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.GCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CCM'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CCM, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-CTR'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.CTR, data=enc, iv=iv, aad=aad) + elif (args.alg == 'AES-XTS'): + ret = picohsm.aes(keyid=kid, mode=mode, algorithm=AES.XTS, data=enc, iv=iv, aad=aad) + elif (args.alg == 'CMAC'): + ret = picohsm.cmac(keyid=kid, data=enc) + elif (args.alg == 'HMAC-SHA1'): + ret = picohsm.hmac(hashes.SHA1, kid, data=enc) + elif (args.alg == 'HMAC-SHA224'): + ret = picohsm.hmac(hashes.SHA224, kid, data=enc) + elif (args.alg == 'HMAC-SHA256'): + ret = picohsm.hmac(hashes.SHA256, kid, data=enc) + elif (args.alg == 'HMAC-SHA384'): + ret = picohsm.hmac(hashes.SHA384, kid, data=enc) + elif (args.alg == 'HMAC-SHA512'): + ret = picohsm.hmac(hashes.SHA512, kid, data=enc) + elif (args.alg == 'HKDF-SHA256'): + ret = picohsm.hkdf(hashes.SHA256, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'HKDF-SHA384'): + ret = picohsm.hkdf(hashes.SHA384, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'HKDF-SHA512'): + ret = picohsm.hkdf(hashes.SHA512, kid, data=enc, salt=iv, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA1'): + ret = picohsm.pbkdf2(hashes.SHA1, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA224'): + ret = picohsm.pbkdf2(hashes.SHA224, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA256'): + ret = picohsm.pbkdf2(hashes.SHA256, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA384'): + ret = picohsm.pbkdf2(hashes.SHA384, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'PBKDF2-SHA512'): + ret = picohsm.pbkdf2(hashes.SHA512, kid, salt=iv, iterations=args.iteration, out_len=args.output_len) + elif (args.alg == 'X963-SHA1'): + ret = picohsm.x963(hashes.SHA1, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA224'): + ret = picohsm.x963(hashes.SHA224, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA256'): + ret = picohsm.x963(hashes.SHA256, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA384'): + ret = picohsm.x963(hashes.SHA384, kid, data=enc, out_len=args.output_len) + elif (args.alg == 'X963-SHA512'): + ret = picohsm.x963(hashes.SHA512, kid, data=enc, out_len=args.output_len) - if (args.file_out): - fout = open(args.file_out, 'wb') - else: - fout = sys.stdout.buffer - if (args.hex): - fout.write(hexlify(bytes(ret))) - else: - fout.write(bytes(ret)) - if (args.file_out): - fout.close() + if (args.file_out): + fout = open(args.file_out, 'wb') + else: + fout = sys.stdout.buffer + if (args.hex): + fout.write(hexlify(bytes(ret))) + else: + fout.write(bytes(ret)) + if (args.file_out): + fout.close() -def x25519(picohsm, args): - if (args.command == 'x25519'): - P = b'\x7f\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\xed' - A = utils.int_to_bytes(0x01DB42) - N = b'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xDE\xF9\xDE\xA2\xF7\x9C\xD6\x58\x12\x63\x1A\x5C\xF5\xD3\xED' - G = b'\x04\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xd3\xce\x7e\xa2\xc5\xe9\x29\xb2\x61\x7c\x6d\x7e\x4d\x3d\x92\x4c\xd1\x48\x77\x2c\xdd\x1e\xe0\xb4\x86\xa0\xb8\xa1\x19\xae\x20' - h = b'\x08' - elif (args.command == 'x448'): - P = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' - A = utils.int_to_bytes(0x98AA) - N = b'\x3f\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\x7c\xca\x23\xe9\xc4\x4e\xdb\x49\xae\xd6\x36\x90\x21\x6c\xc2\x72\x8d\xc5\x8f\x55\x23\x78\xc2\x92\xab\x58\x44\xf3' - G = b'\x04\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x5b\x7b\x45\x3d\x22\xd7\x6f\xf7\x7a\x67\x50\xb1\xc4\x12\x13\x21\x0d\x43\x46\x23\x7e\x02\xb8\xed\xf6\xf3\x8d\xc2\x5d\xf7\x60\xd0\x45\x55\xf5\x34\x5d\xae\xcb\xce\x6f\x32\x58\x6e\xab\x98\x6c\xf6\xb1\xf5\x95\x12\x5d\x23\x7d' - h = b'\x04' - oid = b'\x06\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03' - p_data = b'\x81' + bytes([len(P)]) + P - a_data = b'\x82' + bytes([len(A)]) + A - g_data = b'\x84' + bytes([len(G)]) + G - n_data = b'\x85' + bytes([len(N)]) + N - h_data = b'\x87' + bytes([len(h)]) + h - - cdata = b'\x5F\x29\x01\x00' - cdata += b'\x42\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' - cdata += b'\x7f\x49\x81' + bytes([len(oid)+len(p_data)+len(a_data)+len(g_data)+len(n_data)+len(h_data)]) + oid + p_data + a_data + g_data + n_data + h_data - cdata += b'\x5F\x20\x0C\x55\x54\x44\x55\x4D\x4D\x59\x30\x30\x30\x30\x31' - ret = picohsm.send(command=0x46, p1=int(args.key), data=list(cdata)) +def keygen(picohsm, args): + if (args.subcommand == 'aes'): + ret = picohsm.key_generation(KeyType.AES, param=args.size) + elif (args.subcommand in ['x25519', 'x448']): + curve = 'curve' + args.subcommand[1:] + ret = picohsm.key_generation(KeyType.ECC, curve) + print('Key generated successfully.') + print(f'Key ID: {ret}') def main(args): sys.stderr.buffer.write(b'Pico HSM Tool v1.10\n') @@ -499,8 +468,8 @@ def main(args): secure(picohsm, args) elif (args.command == 'cipher'): cipher(picohsm, args) - elif (args.command == 'x25519' or args.command == 'x448'): - x25519(picohsm, args) + elif (args.command == 'keygen'): + keygen(picohsm, args) def run(): From 2974aa234a89baaa9dde0470980c8073119191b4 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 13 Nov 2023 16:59:15 +0100 Subject: [PATCH 11/85] Added required for subparsers. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 51fa099..00d9ee6 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -62,7 +62,7 @@ def hexy(a): def parse_args(): parser = argparse.ArgumentParser() - subparser = parser.add_subparsers(title="commands", dest="command") + subparser = parser.add_subparsers(title="commands", dest="command", required=True) parser_init = subparser.add_parser('initialize', help='Performs the first initialization of the Pico HSM.') parser.add_argument('--pin', help='PIN number') parser_init.add_argument('--so-pin', help='SO-PIN number') @@ -72,7 +72,7 @@ def parse_args(): parser_attestate.add_argument('-k', '--key', help='The private key index', metavar='KEY_ID') parser_pki = subparser.add_parser('pki', help='Performs PKI operations.') - subparser_pki = parser_pki.add_subparsers(title='commands', dest='subcommand') + subparser_pki = parser_pki.add_subparsers(title='commands', dest='subcommand', required=True) parser_pki_init = subparser_pki.add_parser('initialize', help='Initializes the Public Key Infrastructure (PKI)') parser_pki_init.add_argument('--certs-dir', help='Store the PKI certificates into this directory.', default='certs') @@ -80,25 +80,25 @@ def parse_args(): parser_pki_init.add_argument('--force', help='Forces the download of certificates.', action='store_true') parser_rtc = subparser.add_parser('datetime', help='Datetime operations with the integrated Real Time Clock (RTC).') - subparser_rtc = parser_rtc.add_subparsers(title='commands', dest='subcommand') + subparser_rtc = parser_rtc.add_subparsers(title='commands', dest='subcommand', required=True) parser_rtc_set = subparser_rtc.add_parser('set', help='Sets the current datetime.') parser_rtc_get = subparser_rtc.add_parser('get', help='Gets the current datetime.') parser_opts = subparser.add_parser('options', help='Manage extra options.', formatter_class=RawTextHelpFormatter) - subparser_opts = parser_opts.add_subparsers(title='commands', dest='subcommand') + subparser_opts = parser_opts.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_set = subparser_opts.add_parser('set', help='Sets option OPT.') parser_opts_get = subparser_opts.add_parser('get', help='Gets optiont OPT.') parser_opts.add_argument('opt', choices=['button', 'counter'], help='button: press-to-confirm button.\ncounter: every generated key has an internal counter.', metavar='OPT') parser_opts_set.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?') parser_secure = subparser.add_parser('secure', help='Manages security of Pico HSM.') - subparser_secure = parser_secure.add_subparsers(title='commands', dest='subcommand') + subparser_secure = parser_secure.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_enable = subparser_secure.add_parser('enable', help='Enables secure lock.') parser_opts_unlock = subparser_secure.add_parser('unlock', help='Unlocks the secure lock.') parser_opts_disable = subparser_secure.add_parser('disable', help='Disables secure lock.') parser_cipher = subparser.add_parser('cipher', help='Implements extended symmetric ciphering with new algorithms and options.\n\tIf no file input/output is specified, stdin/stdout will be used.') - subparser_cipher = parser_cipher.add_subparsers(title='commands', dest='subcommand') + subparser_cipher = parser_cipher.add_subparsers(title='commands', dest='subcommand', required=True) parser_cipher_encrypt = subparser_cipher.add_parser('encrypt', help='Performs encryption.') parser_cipher_decrypt = subparser_cipher.add_parser('decrypt', help='Performs decryption.') parser_cipher_hmac = subparser_cipher.add_parser('mac', help='Computes MAC (HMAC or CMAC).') From 29967c067a4b9a38aff3cffc0a71b460bfaa206e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 11 Dec 2023 18:14:04 +0100 Subject: [PATCH 12/85] Add -DVIDPID= to build a project with a known VID/PID. Supported values: NitroHSM, NitroFIDO2, NitroStart, NitroPro, Nitro3, Yubikey5, YubikeyNeo, YubiHSM, Gnuk, GnuPG Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 30f86af..4d77ca7 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 30f86afe6d456203b34938bafa7b9d274bbb040d +Subproject commit 4d77ca7b75eff04bd401208054a83857844ecca4 From 677cceb130ccdf792b598b11f5f204f15c693c8f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 29 Dec 2023 19:07:20 +0100 Subject: [PATCH 13/85] Update to latest PicoHSM. Signed-off-by: Pol Henarejos --- tests/pico-hsm/test_004_key_domains.py | 13 +++++++++---- tests/pico-hsm/test_005_dkek.py | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tests/pico-hsm/test_004_key_domains.py b/tests/pico-hsm/test_004_key_domains.py index 74a3beb..4176d8d 100644 --- a/tests/pico-hsm/test_004_key_domains.py +++ b/tests/pico-hsm/test_004_key_domains.py @@ -69,14 +69,19 @@ def test_set_key_domain_ok(device): def test_import_dkek_ok(device): resp = device.import_dkek(DEFAULT_DKEK, key_domain=TEST_KEY_DOMAIN) - assert(resp[0] == DEFAULT_DKEK_SHARES) - assert(resp[1] == DEFAULT_DKEK_SHARES-1) + assert('dkek' in resp) + assert('kcv' in resp) + assert(resp['dkek']['total'] == DEFAULT_DKEK_SHARES) + assert(resp['dkek']['missing'] == DEFAULT_DKEK_SHARES-1) resp = device.import_dkek(DEFAULT_DKEK, key_domain=TEST_KEY_DOMAIN) - assert(resp[1] == DEFAULT_DKEK_SHARES-2) + assert('dkek' in resp) + assert('kcv' in resp) + assert(resp['dkek']['total'] == DEFAULT_DKEK_SHARES) + assert(resp['dkek']['missing'] == DEFAULT_DKEK_SHARES-2) kcv = hashlib.sha256(b'\x00'*32).digest()[:8] - assert(resp[2:] == kcv) + assert(resp['kcv'] == kcv) def test_clear_key_domain(device): kd = device.get_key_domain(key_domain=0) diff --git a/tests/pico-hsm/test_005_dkek.py b/tests/pico-hsm/test_005_dkek.py index 5c5fddc..fb7f72e 100644 --- a/tests/pico-hsm/test_005_dkek.py +++ b/tests/pico-hsm/test_005_dkek.py @@ -26,12 +26,17 @@ def test_dkek(device): device.initialize(retries=DEFAULT_RETRIES, dkek_shares=DEFAULT_DKEK_SHARES) device.login(DEFAULT_PIN) resp = device.import_dkek(DEFAULT_DKEK) - assert(resp[0] == DEFAULT_DKEK_SHARES) - assert(resp[1] == DEFAULT_DKEK_SHARES-1) + assert('dkek' in resp) + assert('kcv' in resp) + assert(resp['dkek']['total'] == DEFAULT_DKEK_SHARES) + assert(resp['dkek']['missing'] == DEFAULT_DKEK_SHARES-1) resp = device.import_dkek(DEFAULT_DKEK) - assert(resp[1] == DEFAULT_DKEK_SHARES-2) + assert('dkek' in resp) + assert('kcv' in resp) + assert(resp['dkek']['total'] == DEFAULT_DKEK_SHARES) + assert(resp['dkek']['missing'] == DEFAULT_DKEK_SHARES-2) kcv = hashlib.sha256(b'\x00'*32).digest()[:8] - assert(resp[2:] == kcv) + assert(resp['kcv'] == kcv) From ab31a6615c914979e355d513463c430c3b61fecf Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 29 Dec 2023 19:07:28 +0100 Subject: [PATCH 14/85] Fix ATR overwrite. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 4d77ca7..adf53b4 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 4d77ca7b75eff04bd401208054a83857844ecca4 +Subproject commit adf53b4231726368af387b10255980c8afa76441 From d82affa880e5fc77a1f02d238c1c09b44e2f39b3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 1 Jan 2024 01:55:49 +0100 Subject: [PATCH 15/85] Added support for building emulation in Windows. It has not been tested but it should not break any linux build. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 17 ++- pico-keys-sdk | 2 +- src/hsm/cmd_bip_slip.c | 13 +- src/hsm/cmd_challenge.c | 4 +- src/hsm/cmd_change_pin.c | 2 +- src/hsm/cmd_cipher_sym.c | 25 ++-- src/hsm/cmd_decrypt_asym.c | 26 ++-- src/hsm/cmd_external_authenticate.c | 2 +- src/hsm/cmd_extras.c | 6 +- src/hsm/cmd_general_authenticate.c | 4 +- src/hsm/cmd_initialize.c | 18 +-- src/hsm/cmd_key_domain.c | 22 +-- src/hsm/cmd_key_unwrap.c | 26 ++-- src/hsm/cmd_key_wrap.c | 18 +-- src/hsm/cmd_keypair_gen.c | 36 ++--- src/hsm/cmd_mse.c | 8 +- src/hsm/cmd_pso.c | 19 ++- src/hsm/cmd_puk_auth.c | 4 +- src/hsm/cmd_read_binary.c | 4 +- src/hsm/cmd_reset_retry.c | 8 +- src/hsm/cmd_select.c | 8 +- src/hsm/cmd_signature.c | 28 ++-- src/hsm/cmd_update_ef.c | 8 +- src/hsm/cmd_verify.c | 4 +- src/hsm/cvc.c | 213 ++++++++++++++-------------- src/hsm/cvc.h | 88 ++++++------ src/hsm/files.c | 2 +- src/hsm/kek.c | 65 ++++----- src/hsm/kek.h | 12 +- src/hsm/sc_hsm.c | 76 +++++----- src/hsm/sc_hsm.h | 10 +- 31 files changed, 394 insertions(+), 384 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cc8556..309bca2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,6 @@ set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/hsm/cvc.c ${CMAKE_CURRENT_LIST_DIR}/src/hsm/files.c ${CMAKE_CURRENT_LIST_DIR}/src/hsm/kek.c - ${CMAKE_CURRENT_LIST_DIR}/src/hsm/oid.c ) set(USB_ITF_CCID 1) @@ -88,19 +87,30 @@ target_include_directories(pico_hsm PUBLIC ${INCLUDES}) target_compile_options(pico_hsm PUBLIC -Wall - -Werror ) +if (NOT MSVC) + target_compile_options(pico_hsm PUBLIC + -Werror + ) +endif() if(ENABLE_EMULATION) - +if (NOT MSVC) target_compile_options(pico_hsm PUBLIC -fdata-sections -ffunction-sections ) +endif() if(APPLE) target_link_options(pico_hsm PUBLIC -Wl,-dead_strip ) +elseif(MSVC) + target_compile_options(pico_hsm PUBLIC + -WX + ) + + target_link_libraries(pico_hsm PUBLIC wsock32 ws2_32 Bcrypt) else() target_link_options(pico_hsm PUBLIC -Wl,--gc-sections @@ -108,6 +118,5 @@ target_link_options(pico_hsm PUBLIC endif (APPLE) else() pico_add_extra_outputs(pico_hsm) - target_link_libraries(pico_hsm PRIVATE pico_keys_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board) endif() diff --git a/pico-keys-sdk b/pico-keys-sdk index adf53b4..a9dc6fd 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit adf53b4231726368af387b10255980c8afa76441 +Subproject commit a9dc6fd7f87fff7505ad526c7392ec1bc3a811a9 diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 3811714..2a8aed7 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -109,7 +109,7 @@ int node_fingerprint_slip(mbedtls_ecp_keypair *ctx, uint8_t fingerprint[4]) { return CCID_OK; } -int load_master_bip(uint32_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32], +int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32], uint8_t key_type[1]) { uint8_t mkey[65]; mbedtls_ecp_keypair_init(ctx); @@ -147,7 +147,7 @@ int load_master_bip(uint32_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32], } int node_derive_path(const uint8_t *path, - size_t path_len, + uint16_t path_len, mbedtls_ecp_keypair *ctx, uint8_t chain[32], uint8_t fingerprint[4], @@ -155,8 +155,7 @@ int node_derive_path(const uint8_t *path, uint8_t last_node[4], uint8_t key_type[1]) { uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - uint16_t tag = 0x0; + uint16_t tag_len = 0, tag = 0x0; uint8_t node = 0, N[64] = { 0 }; int r = 0; memset(last_node, 0, 4); @@ -231,7 +230,7 @@ int cmd_bip_slip() { random_gen(NULL, seed, seed_len); } else { - seed_len = MIN(apdu.nc, 64); + seed_len = MIN((uint8_t)apdu.nc, 64); memcpy(seed, apdu.data, seed_len); } if (p1 == 0x1 || p1 == 0x2) { @@ -266,7 +265,7 @@ int cmd_bip_slip() { } mbedtls_ecp_keypair ctx; uint8_t chain[32] = { 0 }, fgpt[4] = { 0 }, last_node[4] = { 0 }, key_type = 0, nodes = 0; - size_t olen = 0; + uint16_t olen = 0; int r = node_derive_path(apdu.data, apdu.nc, &ctx, chain, fgpt, &nodes, last_node, &key_type); if (r != CCID_OK) { @@ -288,7 +287,7 @@ int cmd_bip_slip() { mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_COMPRESSED, - &olen, + (size_t *)&olen, pubkey, sizeof(pubkey)); memcpy(res_APDU + res_APDU_size, pubkey, olen); diff --git a/src/hsm/cmd_challenge.c b/src/hsm/cmd_challenge.c index a9bb1b7..6f77658 100644 --- a/src/hsm/cmd_challenge.c +++ b/src/hsm/cmd_challenge.c @@ -27,8 +27,8 @@ int cmd_challenge() { return SW_WRONG_LENGTH(); } memcpy(res_APDU, rb, apdu.ne); - challenge_len = MIN(apdu.ne, sizeof(challenge)); + challenge_len = (uint8_t)MIN(apdu.ne, sizeof(challenge)); memcpy(challenge, rb, challenge_len); - res_APDU_size = apdu.ne; + res_APDU_size = (uint16_t)apdu.ne; return SW_OK(); } diff --git a/src/hsm/cmd_change_pin.c b/src/hsm/cmd_change_pin.c index cff6b75..0da02a1 100644 --- a/src/hsm/cmd_change_pin.c +++ b/src/hsm/cmd_change_pin.c @@ -61,7 +61,7 @@ int cmd_change_pin() { return SW_EXEC_ERROR(); } uint8_t dhash[33]; - dhash[0] = apdu.nc - pin_len; + dhash[0] = (uint8_t)apdu.nc - pin_len; double_hash_pin(apdu.data + pin_len, apdu.nc - pin_len, dhash + 1); flash_write_data_to_file(file_pin, dhash, sizeof(dhash)); low_flash_available(); diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index 68a1f36..a9aa86e 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -43,7 +43,7 @@ extern uint8_t hd_keytype; static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, mbedtls_asn1_buf *salt, int *iterations, - int *keylen, mbedtls_md_type_t *md_type) { + uint16_t *keylen, mbedtls_md_type_t *md_type) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_asn1_buf prf_alg_oid; unsigned char *p = params->p; @@ -78,7 +78,7 @@ static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, return 0; } - if ((ret = mbedtls_asn1_get_int(&p, end, keylen)) != 0) { + if ((ret = mbedtls_asn1_get_int(&p, end, (int *)keylen)) != 0) { if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret); } @@ -106,11 +106,11 @@ static int pkcs5_parse_pbkdf2_params(const mbedtls_asn1_buf *params, /* Taken from https://github.com/Mbed-TLS/mbedtls/issues/2335 */ int mbedtls_ansi_x963_kdf(mbedtls_md_type_t md_type, - size_t input_len, + uint16_t input_len, uint8_t *input, - size_t shared_info_len, + uint16_t shared_info_len, uint8_t *shared_info, - size_t output_len, + uint16_t output_len, uint8_t *output) { mbedtls_md_context_t md_ctx; const mbedtls_md_info_t *md_info = NULL; @@ -163,8 +163,7 @@ int mbedtls_ansi_x963_kdf(mbedtls_md_type_t md_type, } int cmd_cipher_sym() { - int key_id = P1(apdu); - int algo = P2(apdu); + uint8_t key_id = P1(apdu), algo = P2(apdu); if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } @@ -180,7 +179,7 @@ int cmd_cipher_sym() { return SW_CONDITIONS_NOT_SATISFIED(); } } - int key_size = file_get_size(ef); + uint16_t key_size = file_get_size(ef); uint8_t kdata[64]; //maximum AES key size memcpy(kdata, file_get_data(ef), key_size); if (hd_keytype == 0 && mkek_decrypt(kdata, key_size) != 0) { @@ -270,7 +269,7 @@ int cmd_cipher_sym() { res_APDU_size = apdu.nc; } 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; + uint16_t oid_len = 0, aad_len = 0, iv_len = 0, enc_len = 0; uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; if (!asn1_find_tag(apdu.data, apdu.nc, 0x6, &oid_len, &oid) || oid_len == 0 || oid == NULL) { @@ -384,7 +383,8 @@ int cmd_cipher_sym() { res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info); } else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { - int iterations = 0, keylen = 0; + int iterations = 0; + uint16_t keylen = 0; mbedtls_asn1_buf salt, params = { .p = enc, .len = enc_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; @@ -412,7 +412,7 @@ int cmd_cipher_sym() { res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32); } else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { - size_t olen = 0; + uint16_t olen = 0; mbedtls_asn1_buf params = {.p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; int r = mbedtls_pkcs5_pbes2_ext(¶ms, @@ -421,7 +421,7 @@ int cmd_cipher_sym() { key_size, enc, enc_len, - res_APDU, 4096, &olen); + res_APDU, 4096, (size_t *)&olen); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_WRONG_DATA(); @@ -634,7 +634,6 @@ int cmd_cipher_sym() { mode = (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); int r = 0; - uint8_t tmp_iv[16]; memset(tmp_iv, 0, sizeof(tmp_iv)); if (iv == NULL || iv_len == 0) { iv = tmp_iv; diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 72681c7..690e0b2 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -27,7 +27,7 @@ #include "oid.h" int cmd_decrypt_asym() { - int key_id = P1(apdu); + uint8_t key_id = P1(apdu); uint8_t p2 = P2(apdu); if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); @@ -56,13 +56,13 @@ int cmd_decrypt_asym() { } return SW_EXEC_ERROR(); } - int key_size = file_get_size(ef); + uint16_t key_size = file_get_size(ef); if (apdu.nc < key_size) { //needs padding memset(apdu.data + apdu.nc, 0, key_size - apdu.nc); } if (p2 == ALGO_RSA_DECRYPT_PKCS1 || p2 == ALGO_RSA_DECRYPT_OEP) { - size_t olen = apdu.nc; - r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data, res_APDU, 512); + uint16_t olen = apdu.nc; + r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, (size_t *)&olen, apdu.data, res_APDU, 512); if (r == 0) { res_APDU_size = olen; } @@ -84,7 +84,7 @@ int cmd_decrypt_asym() { if (wait_button_pressed() == true) { //timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); } - int key_size = file_get_size(ef); + uint16_t key_size = file_get_size(ef); uint8_t *kdata = (uint8_t *) calloc(1, key_size); memcpy(kdata, file_get_data(ef), key_size); if (mkek_decrypt(kdata, key_size) != 0) { @@ -114,10 +114,10 @@ int cmd_decrypt_asym() { r = mbedtls_ecdh_read_public(&ctx, apdu.data - 1, apdu.nc + 1); } else if (p2 == ALGO_EC_DH_XKEK) { - size_t pub_len = 0; + uint16_t pub_len = 0; const uint8_t *pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len); if (pub) { - size_t t86_len = 0; + uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); if (t86) { r = mbedtls_ecdh_read_public(&ctx, t86 - 1, t86_len + 1); @@ -128,12 +128,12 @@ int cmd_decrypt_asym() { mbedtls_ecdh_free(&ctx); return SW_DATA_INVALID(); } - size_t olen = 0; + uint16_t olen = 0; // The SmartCard-HSM returns the point result of the DH operation // with a leading '04' res_APDU[0] = 0x04; r = - mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_gen, + mbedtls_ecdh_calc_secret(&ctx, (size_t *)&olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); mbedtls_ecdh_free(&ctx); if (r != 0) { @@ -144,17 +144,17 @@ int cmd_decrypt_asym() { } else { res_APDU_size = 0; - size_t ext_len = 0; + uint16_t ext_len = 0; const uint8_t *ext = NULL; if ((ext = cvc_get_ext(apdu.data, apdu.nc, &ext_len)) == NULL) { return SW_WRONG_DATA(); } uint8_t *p = NULL, *tag_data = NULL, *kdom_uid = NULL; uint16_t tag = 0; - size_t tag_len = 0, kdom_uid_len = 0; + uint16_t tag_len = 0, kdom_uid_len = 0; while (walk_tlv(ext, ext_len, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x73) { - size_t oid_len = 0; + uint16_t oid_len = 0; uint8_t *oid_data = NULL; if (asn1_find_tag(tag_data, tag_len, 0x6, &oid_len, &oid_data) == true && @@ -172,7 +172,7 @@ int cmd_decrypt_asym() { if (kdom_uid_len == 0 || kdom_uid == NULL) { return SW_WRONG_DATA(); } - for (int n = 0; n < MAX_KEY_DOMAINS; n++) { + for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) { file_t *tf = search_dynamic_file(EF_XKEK + n); if (tf) { if (file_get_size(tf) == kdom_uid_len && diff --git a/src/hsm/cmd_external_authenticate.c b/src/hsm/cmd_external_authenticate.c index b003109..8d5ae4d 100644 --- a/src/hsm/cmd_external_authenticate.c +++ b/src/hsm/cmd_external_authenticate.c @@ -46,7 +46,7 @@ int cmd_external_authenticate() { hash256(input, dev_name_len + challenge_len, hash); int r = puk_verify(apdu.data, - apdu.nc, + (uint16_t)apdu.nc, hash, 32, file_get_data(ef_puk_aut), diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index e0f26ba..cddb33e 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -111,9 +111,9 @@ int cmd_extras() { memcpy(mse.Qpt, apdu.data, sizeof(mse.Qpt)); uint8_t buf[MBEDTLS_ECP_MAX_BYTES]; - size_t olen = 0; + uint16_t olen = 0; ret = mbedtls_ecdh_calc_secret(&hkey, - &olen, + (size_t *)&olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, @@ -141,7 +141,7 @@ int cmd_extras() { ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, + (size_t *)&olen, res_APDU, 4096); mbedtls_ecdh_free(&hkey); diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index af41cb0..a666305 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -28,11 +28,11 @@ int cmd_general_authenticate() { if (P1(apdu) == 0x0 && P2(apdu) == 0x0) { if (apdu.data[0] == 0x7C) { int r = 0; - size_t pubkey_len = 0; + uint16_t pubkey_len = 0; const uint8_t *pubkey = NULL; uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; while (walk_tlv(apdu.data + 2, apdu.nc - 2, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index 8dd45c1..33c3b81 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -48,8 +48,8 @@ int cmd_initialize() { has_session_pin = has_session_sopin = false; uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { + uint16_t tag_len = 0; + while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { //options file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); flash_write_data_to_file(tf, tag_data, tag_len); @@ -57,7 +57,7 @@ int cmd_initialize() { else if (tag == 0x81) { //user pin if (file_pin1 && file_pin1->data) { uint8_t dhash[33]; - dhash[0] = tag_len; + dhash[0] = (uint8_t)tag_len; double_hash_pin(tag_data, tag_len, dhash + 1); flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); hash_multi(tag_data, tag_len, session_pin); @@ -67,7 +67,7 @@ int cmd_initialize() { else if (tag == 0x82) { //sopin pin if (file_sopin && file_sopin->data) { uint8_t dhash[33]; - dhash[0] = tag_len; + dhash[0] = (uint8_t)tag_len; double_hash_pin(tag_data, tag_len, dhash + 1); flash_write_data_to_file(file_sopin, dhash, sizeof(dhash)); hash_multi(tag_data, tag_len, session_sopin); @@ -104,7 +104,7 @@ int cmd_initialize() { pk_status[1] = puks; pk_status[2] = tag_data[1]; flash_write_data_to_file(ef_puk, pk_status, sizeof(pk_status)); - for (int i = 0; i < puks; i++) { + for (uint8_t i = 0; i < puks; i++) { file_t *tf = file_new(EF_PUK + i); if (!tf) { release_mkek(mkek); @@ -199,7 +199,7 @@ int cmd_initialize() { } file_t *fpk = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF); - ret = flash_write_data_to_file(fpk, res_APDU, cvc_len); + ret = flash_write_data_to_file(fpk, res_APDU, (uint16_t)cvc_len); if (ret != 0) { mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); @@ -212,7 +212,7 @@ int cmd_initialize() { memcpy(res_APDU + cvc_len, res_APDU, cvc_len); mbedtls_ecdsa_free(&ecdsa); fpk = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); - ret = flash_write_data_to_file(fpk, res_APDU, 2 * cvc_len); + ret = flash_write_data_to_file(fpk, res_APDU, (uint16_t)(2 * cvc_len)); if (ret != 0) { return SW_EXEC_ERROR(); } @@ -220,8 +220,8 @@ int cmd_initialize() { const uint8_t *keyid = (const uint8_t *) "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", *label = (const uint8_t *) "ESPICOHSMTR"; - size_t prkd_len = asn1_build_prkd_ecc(label, - strlen((const char *) label), + uint16_t prkd_len = asn1_build_prkd_ecc(label, + (uint16_t)strlen((const char *) label), keyid, 20, 256, diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index aeecb31..827fe75 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -22,7 +22,7 @@ #include "files.h" uint8_t get_key_domain(file_t *fkey) { - size_t tag_len = 0; + uint16_t tag_len = 0; if (!file_has_data(fkey)) { return 0xff; } @@ -103,7 +103,7 @@ int cmd_key_domain() { return SW_WRONG_LENGTH(); } if (p1 == 0x3) { //if key domain is not empty, command is denied - for (int i = 1; i < 256; i++) { + for (uint8_t i = 1; i < 256; i++) { file_t *fkey = search_dynamic_file(KEY_PREFIX << 8 | i); if (get_key_domain(fkey) == p2) { return SW_FILE_EXISTS(); @@ -150,7 +150,7 @@ int cmd_key_domain() { } else if (p1 == 0x2) { //XKEK Key Domain creation if (apdu.nc > 0) { - size_t pub_len = 0; + uint16_t pub_len = 0; file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); if (!fterm) { return SW_EXEC_ERROR(); @@ -159,13 +159,13 @@ int cmd_key_domain() { if (!pub) { return SW_EXEC_ERROR(); } - size_t t86_len = 0; + uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); if (!t86 || t86[0] != 0x4) { return SW_EXEC_ERROR(); } - size_t t54_len = 0; - const uint8_t *t54 = cvc_get_field(apdu.data, apdu.nc, &t54_len, 0x54); + uint16_t t54_len = 0; + const uint8_t *t54 = cvc_get_field(apdu.data, (uint16_t)apdu.nc, &t54_len, 0x54); if (!t54) { return SW_WRONG_DATA(); } @@ -174,7 +174,7 @@ int cmd_key_domain() { memcpy(input + 1, t86 + 1, (t86_len - 1) / 2); hash256(input, (t86_len - 1) / 2 + 1, hash); free(input); - int r = puk_verify(t54, t54_len, hash, 32, apdu.data, apdu.nc); + int r = puk_verify(t54, t54_len, hash, 32, apdu.data, (uint16_t)apdu.nc); if (r != 0) { return SW_CONDITIONS_NOT_SATISFIED(); } @@ -184,12 +184,12 @@ int cmd_key_domain() { } //All checks done. Get Key Domain UID - pub = cvc_get_pub(apdu.data, apdu.nc, &pub_len); + pub = cvc_get_pub(apdu.data, (uint16_t)apdu.nc, &pub_len); if (pub) { - size_t t86_len = 0; - const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); + t86_len = 0; + t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); if (t86) { - flash_write_data_to_file(tf, t86 + 1, t86_len - 1); + flash_write_data_to_file(tf, t86 + 1, (uint16_t)t86_len - 1); low_flash_available(); } } diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index d214bf9..1eb0ecb 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -22,7 +22,8 @@ #include "cvc.h" int cmd_key_unwrap() { - int key_id = P1(apdu), r = 0; + uint8_t key_id = P1(apdu); + int r = 0; if (P2(apdu) != 0x93) { return SW_WRONG_P1P2(); } @@ -30,8 +31,9 @@ int cmd_key_unwrap() { return SW_SECURITY_STATUS_NOT_SATISFIED(); } int key_type = dkek_type_key(apdu.data); - uint8_t kdom = -1, *allowed = NULL; - size_t allowed_len = 0; + uint8_t *allowed = NULL; + int16_t kdom = -1; + uint16_t allowed_len = 0; if (key_type == 0x0) { return SW_DATA_INVALID(); } @@ -39,14 +41,14 @@ int cmd_key_unwrap() { mbedtls_rsa_context ctx; mbedtls_rsa_init(&ctx); do { - r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL, &allowed, &allowed_len); + r = dkek_decode_key((uint8_t)++kdom, &ctx, apdu.data, (uint16_t)apdu.nc, NULL, &allowed, &allowed_len); } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { mbedtls_rsa_free(&ctx); return SW_EXEC_ERROR(); } r = store_keys(&ctx, PICO_KEYS_KEY_RSA, key_id); - if ((res_APDU_size = asn1_cvc_aut(&ctx, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { + if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { mbedtls_rsa_free(&ctx); return SW_EXEC_ERROR(); } @@ -59,14 +61,14 @@ int cmd_key_unwrap() { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); do { - r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL, &allowed, &allowed_len); + r = dkek_decode_key((uint8_t)++kdom, &ctx, apdu.data, (uint16_t)apdu.nc, NULL, &allowed, &allowed_len); } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } r = store_keys(&ctx, PICO_KEYS_KEY_EC, key_id); - if ((res_APDU_size = asn1_cvc_aut(&ctx, PICO_KEYS_KEY_EC, res_APDU, 4096, NULL, 0)) == 0) { + if ((res_APDU_size = (uint16_t)asn1_cvc_aut(&ctx, PICO_KEYS_KEY_EC, res_APDU, 4096, NULL, 0)) == 0) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } @@ -79,10 +81,10 @@ int cmd_key_unwrap() { uint8_t aes_key[64]; int key_size = 0, aes_type = 0; do { - r = dkek_decode_key(++kdom, + r = dkek_decode_key((uint8_t)++kdom, aes_key, apdu.data, - apdu.nc, + (uint16_t)apdu.nc, &key_size, &allowed, &allowed_len); @@ -111,17 +113,17 @@ int cmd_key_unwrap() { } } if ((allowed != NULL && allowed_len > 0) || kdom >= 0) { - size_t meta_len = (allowed_len > 0 ? 2 + allowed_len : 0) + (kdom >= 0 ? 3 : 0); + uint16_t meta_len = (allowed_len > 0 ? 2 + allowed_len : 0) + (kdom >= 0 ? 3 : 0); uint8_t *meta = (uint8_t *) calloc(1, meta_len), *m = meta; if (allowed_len > 0) { *m++ = 0x91; - *m++ = allowed_len; + *m++ = (uint8_t)allowed_len; memcpy(m, allowed, allowed_len); m += allowed_len; } if (kdom >= 0) { *m++ = 0x92; *m++ = 1; - *m++ = kdom; + *m++ = (uint8_t)kdom; } r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_len); free(meta); diff --git a/src/hsm/cmd_key_wrap.c b/src/hsm/cmd_key_wrap.c index 938f543..d303ddc 100644 --- a/src/hsm/cmd_key_wrap.c +++ b/src/hsm/cmd_key_wrap.c @@ -24,7 +24,8 @@ extern uint8_t get_key_domain(file_t *fkey); int cmd_key_wrap() { - int key_id = P1(apdu), r = 0; + int r = 0; + uint8_t key_id = P1(apdu); if (P2(apdu) != 0x92) { return SW_WRONG_P1P2(); } @@ -53,8 +54,7 @@ int cmd_key_wrap() { return SW_FILE_NOT_FOUND(); } const uint8_t *dprkd = file_get_data(prkd); - size_t wrap_len = MAX_DKEK_ENCODE_KEY_BUFFER; - size_t tag_len = 0; + uint16_t wrap_len = MAX_DKEK_ENCODE_KEY_BUFFER, tag_len = 0; const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len); if (*dprkd == P15_KEYTYPE_RSA) { mbedtls_rsa_context ctx; @@ -85,14 +85,14 @@ int cmd_key_wrap() { mbedtls_ecdsa_free(&ctx); } else if (*dprkd == P15_KEYTYPE_AES) { - uint8_t kdata[64]; //maximum AES key size + uint8_t kdata_aes[64]; //maximum AES key size if (wait_button_pressed() == true) { //timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); } - int key_size = file_get_size(ef), aes_type = PICO_KEYS_KEY_AES; - memcpy(kdata, file_get_data(ef), key_size); - if (mkek_decrypt(kdata, key_size) != 0) { + uint16_t key_size = file_get_size(ef), aes_type = PICO_KEYS_KEY_AES; + memcpy(kdata_aes, file_get_data(ef), key_size); + if (mkek_decrypt(kdata_aes, key_size) != 0) { return SW_EXEC_ERROR(); } if (key_size == 64) { @@ -107,8 +107,8 @@ int cmd_key_wrap() { else if (key_size == 16) { aes_type = PICO_KEYS_KEY_AES_128; } - r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len, meta_tag, tag_len); - mbedtls_platform_zeroize(kdata, sizeof(kdata)); + r = dkek_encode_key(kdom, kdata_aes, aes_type, res_APDU, &wrap_len, meta_tag, tag_len); + mbedtls_platform_zeroize(kdata_aes, sizeof(kdata_aes)); } if (r != CCID_OK) { return SW_EXEC_ERROR(); diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 25a4dd0..7b3b1a3 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -31,29 +31,29 @@ int cmd_keypair_gen() { } int ret = 0; - size_t tout = 0; + uint16_t tout = 0; //sc_asn1_print_tags(apdu.data, apdu.nc); uint8_t *p = NULL; //DEBUG_DATA(apdu.data,apdu.nc); - if (asn1_find_tag(apdu.data, apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { - size_t oid_len = 0; + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { + uint16_t oid_len = 0; uint8_t *oid = NULL; if (asn1_find_tag(p, tout, 0x6, &oid_len, &oid) && oid_len > 0 && oid != NULL) { if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { //RSA - size_t ex_len = 3, ks_len = 2; + uint16_t ex_len = 3, ks_len = 2; uint8_t *ex = NULL, *ks = NULL; uint32_t exponent = 65537, key_size = 2048; if (asn1_find_tag(p, tout, 0x82, &ex_len, &ex) && ex_len > 0 && ex != NULL) { uint8_t *dt = ex; exponent = 0; - for (int i = 0; i < ex_len; i++) { + for (uint16_t i = 0; i < ex_len; i++) { exponent = (exponent << 8) | *dt++; } } if (asn1_find_tag(p, tout, 0x2, &ks_len, &ks) && ks_len > 0 && ks != NULL) { uint8_t *dt = ks; key_size = 0; - for (int i = 0; i < ks_len; i++) { + for (uint16_t i = 0; i < ks_len; i++) { key_size = (key_size << 8) | *dt++; } } @@ -69,7 +69,7 @@ int cmd_keypair_gen() { return SW_EXEC_ERROR(); } if ((res_APDU_size = - asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { + (uint16_t)asn1_cvc_aut(&rsa, PICO_KEYS_KEY_RSA, res_APDU, 4096, NULL, 0)) == 0) { return SW_EXEC_ERROR(); } ret = store_keys(&rsa, PICO_KEYS_KEY_RSA, key_id); @@ -80,7 +80,7 @@ int cmd_keypair_gen() { mbedtls_rsa_free(&rsa); } else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC - size_t prime_len; + uint16_t prime_len; uint8_t *prime = NULL; if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) { return SW_WRONG_DATA(); @@ -98,14 +98,14 @@ int cmd_keypair_gen() { mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - size_t l91 = 0, ext_len = 0; + uint16_t l91 = 0, ext_len = 0; uint8_t *p91 = NULL, *ext = NULL; - if (asn1_find_tag(apdu.data, apdu.nc, 0x91, &l91, &p91) && p91 != NULL && l91 > 0) { - for (int n = 0; n < l91; n++) { + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x91, &l91, &p91) && p91 != NULL && l91 > 0) { + for (size_t n = 0; n < l91; n++) { if (p91[n] == ALGO_EC_DH_XKEK) { - size_t l92 = 0; + uint16_t l92 = 0; uint8_t *p92 = NULL; - if (!asn1_find_tag(apdu.data, apdu.nc, 0x92, &l92, + if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x92, &l92, &p92) || p92 == NULL || l92 == 0) { return SW_WRONG_DATA(); } @@ -116,24 +116,24 @@ int cmd_keypair_gen() { if (!tf_xkek) { return SW_WRONG_DATA(); } - ext_len = 2 + 2 + strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( + ext_len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( tf_xkek); ext = (uint8_t *) calloc(1, ext_len); uint8_t *pe = ext; *pe++ = 0x73; - *pe++ = ext_len - 2; + *pe++ = (uint8_t)ext_len - 2; *pe++ = 0x6; - *pe++ = strlen(OID_ID_KEY_DOMAIN_UID); + *pe++ = (uint8_t)strlen(OID_ID_KEY_DOMAIN_UID); memcpy(pe, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)); pe += strlen(OID_ID_KEY_DOMAIN_UID); *pe++ = 0x80; - *pe++ = file_get_size(tf_xkek); + *pe++ = (uint8_t)file_get_size(tf_xkek); memcpy(pe, file_get_data(tf_xkek), file_get_size(tf_xkek)); } } } if ((res_APDU_size = - asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { + (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { if (ext) { free(ext); } diff --git a/src/hsm/cmd_mse.c b/src/hsm/cmd_mse.c index b1545dd..e3ac568 100644 --- a/src/hsm/cmd_mse.c +++ b/src/hsm/cmd_mse.c @@ -33,8 +33,8 @@ int cmd_mse() { if (p1 & 0x1) { //SET uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { + uint16_t tag_len = 0; + while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { if (p2 == 0xA4) { if (tag_len == 10 && @@ -54,7 +54,7 @@ int cmd_mse() { } } else if (p2 == 0xA4) { /* Aut */ - for (int i = 0; i < MAX_PUK; i++) { + for (uint8_t i = 0; i < MAX_PUK; i++) { file_t *ef = search_dynamic_file(EF_PUK + i); if (!ef) { break; @@ -62,7 +62,7 @@ int cmd_mse() { if (!file_has_data(ef)) { break; } - size_t chr_len = 0; + uint16_t chr_len = 0; const uint8_t *chr = cvc_get_chr(file_get_data(ef), file_get_size(ef), &chr_len); diff --git a/src/hsm/cmd_pso.c b/src/hsm/cmd_pso.c index e06a3dd..fe513a5 100644 --- a/src/hsm/cmd_pso.c +++ b/src/hsm/cmd_pso.c @@ -20,7 +20,7 @@ #include "asn1.h" #include "cvc.h" -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, uint16_t data_len, bool copy); extern PUK *current_puk; int cmd_pso() { @@ -49,7 +49,7 @@ int cmd_pso() { } return SW_EXEC_ERROR(); } - for (int i = 0; i < 0xfe; i++) { + for (uint8_t i = 0; i < 0xfe; i++) { uint16_t fid = (CA_CERTIFICATE_PREFIX << 8) | i; file_t *ca_ef = search_dynamic_file(fid); if (!ca_ef) { @@ -60,17 +60,17 @@ int cmd_pso() { return SW_FILE_FULL(); } - size_t chr_len = 0; + uint16_t chr_len = 0; const uint8_t *chr = cvc_get_chr(apdu.data, apdu.nc, &chr_len); if (chr == NULL) { return SW_WRONG_DATA(); } - size_t puk_len = 0, puk_bin_len = 0; + uint16_t puk_len = 0, puk_bin_len = 0; const uint8_t *puk = cvc_get_pub(apdu.data, apdu.nc, &puk_len), *puk_bin = NULL; if (puk == NULL) { return SW_WRONG_DATA(); } - size_t oid_len = 0; + uint16_t oid_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); if (oid == NULL) { return SW_WRONG_DATA(); @@ -89,8 +89,8 @@ int cmd_pso() { mbedtls_ecp_group_free(&grp); return SW_WRONG_DATA(); } - size_t plen = mbedtls_mpi_size(&grp.P); - size_t t86_len = 0; + uint16_t plen = (uint16_t)mbedtls_mpi_size(&grp.P); + uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(puk, puk_len, &t86_len, 0x86); if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { if (plen != t86_len) { @@ -126,7 +126,7 @@ int cmd_pso() { } } file_t *cd_ef = file_new((CD_PREFIX << 8) | i); - size_t cd_len = asn1_build_cert_description(chr, + uint16_t cd_len = (uint16_t)asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, @@ -137,7 +137,7 @@ int cmd_pso() { return SW_EXEC_ERROR(); } uint8_t *buf = (uint8_t *) calloc(cd_len, sizeof(uint8_t)); - int r = asn1_build_cert_description(chr, + r = (int)asn1_build_cert_description(chr, chr_len, puk_bin, puk_bin_len, @@ -153,7 +153,6 @@ int cmd_pso() { break; } } - return SW_OK(); } else { return SW_INCORRECT_P1P2(); diff --git a/src/hsm/cmd_puk_auth.c b/src/hsm/cmd_puk_auth.c index 76f55cd..2457003 100644 --- a/src/hsm/cmd_puk_auth.c +++ b/src/hsm/cmd_puk_auth.c @@ -36,7 +36,7 @@ int cmd_puk_auth() { if (p2 != 0x0) { return SW_INCORRECT_P1P2(); } - for (int i = 0; i < puk_data[0]; i++) { + for (uint8_t i = 0; i < puk_data[0]; i++) { ef = search_dynamic_file(EF_PUK + i); if (!ef) { /* Never should not happen */ return SW_MEMORY_FAILURE(); @@ -79,7 +79,7 @@ int cmd_puk_auth() { if (!file_has_data(ef)) { return SW_REFERENCE_NOT_FOUND(); } - size_t chr_len = 0; + uint16_t chr_len = 0; const uint8_t *chr = cvc_get_chr(file_get_data(ef), file_get_size(ef), &chr_len); if (chr) { memcpy(res_APDU, chr, chr_len); diff --git a/src/hsm/cmd_read_binary.c b/src/hsm/cmd_read_binary.c index 2fb7496..7c4a6df 100644 --- a/src/hsm/cmd_read_binary.c +++ b/src/hsm/cmd_read_binary.c @@ -19,7 +19,7 @@ int cmd_read_binary() { uint16_t fid = 0x0; - uint32_t offset = 0; + uint16_t offset = 0; uint8_t ins = INS(apdu), p1 = P1(apdu), p2 = P2(apdu); const file_t *ef = NULL; @@ -68,7 +68,7 @@ int cmd_read_binary() { } if (ef->data) { if ((ef->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) { - uint16_t data_len = ((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, 1); //already copies content to res_APDU + uint16_t data_len = (uint16_t)((int (*)(const file_t *, int))(ef->data))((const file_t *) ef, 1); //already copies content to res_APDU if (offset > data_len) { return SW_WRONG_P1P2(); } diff --git a/src/hsm/cmd_reset_retry.c b/src/hsm/cmd_reset_retry.c index 2388d75..f4567d5 100644 --- a/src/hsm/cmd_reset_retry.c +++ b/src/hsm/cmd_reset_retry.c @@ -34,17 +34,17 @@ int cmd_reset_retry() { return SW_COMMAND_NOT_ALLOWED(); } if (P1(apdu) == 0x0 || P1(apdu) == 0x2) { - int newpin_len = 0; + uint8_t newpin_len = 0; if (P1(apdu) == 0x0) { uint8_t so_pin_len = file_read_uint8(file_get_data(file_sopin)); - if (apdu.nc <= so_pin_len + 1) { + if ((uint16_t)apdu.nc <= so_pin_len + 1) { return SW_WRONG_LENGTH(); } uint16_t r = check_pin(file_sopin, apdu.data, so_pin_len); if (r != 0x9000) { return r; } - newpin_len = apdu.nc - so_pin_len; + newpin_len = (uint8_t)apdu.nc - so_pin_len; } else if (P1(apdu) == 0x2) { if (!has_session_sopin) { @@ -53,7 +53,7 @@ int cmd_reset_retry() { if (apdu.nc > 16) { return SW_WRONG_LENGTH(); } - newpin_len = apdu.nc; + newpin_len = (uint8_t)apdu.nc; } uint8_t dhash[33]; dhash[0] = newpin_len; diff --git a/src/hsm/cmd_select.c b/src/hsm/cmd_select.c index bed5a7a..3c8da6d 100644 --- a/src/hsm/cmd_select.c +++ b/src/hsm/cmd_select.c @@ -96,7 +96,7 @@ int cmd_select() { } } 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, (uint16_t)apdu.nc))) { return SW_FILE_NOT_FOUND(); } if (card_terminated) { @@ -104,12 +104,12 @@ int cmd_select() { } } 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, (uint8_t)apdu.nc, MF))) { return SW_FILE_NOT_FOUND(); } } 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, (uint8_t)apdu.nc, currentDF))) { return SW_FILE_NOT_FOUND(); } } @@ -125,7 +125,7 @@ int cmd_select() { res_APDU[res_APDU_size++] = 0xFF; res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR; res_APDU[res_APDU_size++] = HSM_VERSION_MINOR; - res_APDU[1] = res_APDU_size - 2; + res_APDU[1] = (uint8_t)res_APDU_size - 2; } } else { diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index 30f0344..42a7272 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -57,8 +57,8 @@ static const uint8_t hdr_ripemd160[] = { static const struct digest_info_prefix { mbedtls_md_type_t algorithm; const uint8_t *hdr; - size_t hdr_len; - size_t hash_len; + uint16_t hdr_len; + uint16_t hash_len; } digest_info_prefix[] = { { MBEDTLS_MD_MD5, hdr_md5, sizeof(hdr_md5), 16 }, { MBEDTLS_MD_SHA1, hdr_sha1, sizeof(hdr_sha1), 20 }, @@ -71,11 +71,11 @@ static const struct digest_info_prefix { }; int pkcs1_strip_digest_info_prefix(mbedtls_md_type_t *algorithm, const uint8_t *in_dat, - size_t in_len, + uint16_t in_len, uint8_t *out_dat, - size_t *out_len) { + uint16_t *out_len) { for (int i = 0; digest_info_prefix[i].algorithm != 0; i++) { - size_t hdr_len = digest_info_prefix[i].hdr_len, hash_len = digest_info_prefix[i].hash_len; + uint16_t hdr_len = digest_info_prefix[i].hdr_len, hash_len = digest_info_prefix[i].hash_len; const uint8_t *hdr = digest_info_prefix[i].hdr; if (in_len == (hdr_len + hash_len) && !memcmp(in_dat, hdr, hdr_len)) { if (algorithm) { @@ -116,7 +116,7 @@ int cmd_signature() { if (key_has_purpose(fkey, p2) == false) { return SW_CONDITIONS_NOT_SATISFIED(); } - int key_size = file_get_size(fkey); + uint16_t key_size = file_get_size(fkey); if (p2 == ALGO_RSA_PKCS1_SHA1 || p2 == ALGO_RSA_PSS_SHA1 || p2 == ALGO_EC_SHA1) { md = MBEDTLS_MD_SHA1; } @@ -153,9 +153,9 @@ int cmd_signature() { return SW_EXEC_ERROR(); } uint8_t *hash = apdu.data; - size_t hash_len = apdu.nc; + uint16_t hash_len = apdu.nc; if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached - size_t nc = apdu.nc; + uint16_t nc = apdu.nc; if (pkcs1_strip_digest_info_prefix(&md, apdu.data, apdu.nc, apdu.data, &nc) != CCID_OK) { //gets the MD algo id and strips it off return SW_EXEC_ERROR(); @@ -164,10 +164,10 @@ int cmd_signature() { } else { //sc_asn1_print_tags(apdu.data, apdu.nc); - size_t tout = 0, oid_len = 0; + uint16_t tout = 0, oid_len = 0; uint8_t *p = NULL, *oid = NULL; if (asn1_find_tag(apdu.data, apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { - size_t tout30 = 0; + uint16_t tout30 = 0; uint8_t *c30 = NULL; if (asn1_find_tag(p, tout, 0x30, &tout30, &c30) && tout30 > 0 && c30 != NULL) { asn1_find_tag(c30, tout30, 0x6, &oid_len, &oid); @@ -276,10 +276,10 @@ int cmd_signature() { } return SW_EXEC_ERROR(); } - size_t olen = 0; + uint16_t olen = 0; uint8_t buf[MBEDTLS_ECDSA_MAX_LEN]; if (mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, - &olen, random_gen, NULL) != 0) { + (size_t *)&olen, random_gen, NULL) != 0) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } @@ -288,7 +288,7 @@ int cmd_signature() { mbedtls_ecdsa_free(&ctx); } else if (p2 == ALGO_HD) { - size_t olen = 0; + uint16_t olen = 0; uint8_t buf[MBEDTLS_ECDSA_MAX_LEN]; if (hd_context.grp.id == MBEDTLS_ECP_DP_NONE) { return SW_CONDITIONS_NOT_SATISFIED(); @@ -299,7 +299,7 @@ int cmd_signature() { md = MBEDTLS_MD_SHA256; if (mbedtls_ecdsa_write_signature(&hd_context, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, - &olen, random_gen, NULL) != 0) { + (size_t *)&olen, random_gen, NULL) != 0) { mbedtls_ecdsa_free(&hd_context); return SW_EXEC_ERROR(); } diff --git a/src/hsm/cmd_update_ef.c b/src/hsm/cmd_update_ef.c index 97051f5..9fae86a 100644 --- a/src/hsm/cmd_update_ef.c +++ b/src/hsm/cmd_update_ef.c @@ -48,15 +48,15 @@ int cmd_update_ef() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; - while (walk_tlv(apdu.data, apdu.nc, &p, &tag, &tag_len, &tag_data)) { + uint16_t tag_len = 0; + while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x54) { //ofset tag - for (int i = 1; i <= tag_len; i++) { + for (size_t i = 1; i <= tag_len; i++) { offset |= (*tag_data++ << (8 * (tag_len - i))); } } else if (tag == 0x53) { //data - data_len = tag_len; + data_len = (uint16_t)tag_len; data = tag_data; } } diff --git a/src/hsm/cmd_verify.c b/src/hsm/cmd_verify.c index 7211ed8..66a725a 100644 --- a/src/hsm/cmd_verify.c +++ b/src/hsm/cmd_verify.c @@ -37,7 +37,7 @@ int cmd_verify() { return SW_REFERENCE_NOT_FOUND(); } if (apdu.nc > 0) { - return check_pin(file_pin1, apdu.data, apdu.nc); + return check_pin(file_pin1, apdu.data, (uint16_t)apdu.nc); } if (file_read_uint8(file_get_data(file_retries_pin1)) == 0) { return SW_PIN_BLOCKED(); @@ -49,7 +49,7 @@ int cmd_verify() { return SW_REFERENCE_NOT_FOUND(); } if (apdu.nc > 0) { - return check_pin(file_sopin, apdu.data, apdu.nc); + return check_pin(file_sopin, apdu.data, (uint16_t)apdu.nc); } if (file_read_uint8(file_get_data(file_retries_sopin)) == 0) { return SW_PIN_BLOCKED(); diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index 93434a5..ded1157 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -29,14 +29,14 @@ #include "files.h" extern const uint8_t *dev_name; -extern size_t dev_name_len; +extern uint16_t dev_name_len; -size_t asn1_cvc_public_key_rsa(mbedtls_rsa_context *rsa, uint8_t *buf, size_t buf_len) { +uint16_t asn1_cvc_public_key_rsa(mbedtls_rsa_context *rsa, uint8_t *buf, uint16_t buf_len) { const uint8_t oid_rsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x01, 0x02 }; - size_t n_size = mbedtls_mpi_size(&rsa->N), e_size = mbedtls_mpi_size(&rsa->E); - size_t ntot_size = asn1_len_tag(0x81, n_size), etot_size = asn1_len_tag(0x82, e_size); - size_t oid_len = asn1_len_tag(0x6, sizeof(oid_rsa)); - size_t tot_len = asn1_len_tag(0x7f49, oid_len + ntot_size + etot_size); + uint16_t n_size = (uint16_t)mbedtls_mpi_size(&rsa->N), e_size = (uint16_t)mbedtls_mpi_size(&rsa->E); + uint16_t ntot_size = asn1_len_tag(0x81, n_size), etot_size = asn1_len_tag(0x82, e_size); + uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_rsa)); + uint16_t tot_len = asn1_len_tag(0x7f49, oid_len + ntot_size + etot_size); if (buf == NULL || buf_len == 0) { return tot_len; } @@ -72,23 +72,23 @@ 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", }; -size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, size_t buf_len) { +uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, uint16_t buf_len) { uint8_t Y_buf[MBEDTLS_ECP_MAX_PT_LEN], G_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_ri[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x05, 0x02, 0x03 }; const uint8_t *oid = oid_ecdsa; - size_t p_size = mbedtls_mpi_size(&ecdsa->grp.P), a_size = mbedtls_mpi_size(&ecdsa->grp.A); - size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), g_size = 0; - size_t o_size = mbedtls_mpi_size(&ecdsa->grp.N), y_size = 0; - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, &g_size, G_buf, sizeof(G_buf)); - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &y_size, Y_buf, sizeof(Y_buf)); - size_t c_size = 1; - size_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? p_size : 1)); - size_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size); - size_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size); - size_t ctot_size = asn1_len_tag(0x87, c_size); - size_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa)); - size_t tot_len = 0, tot_data_len = 0; + uint16_t p_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), a_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A); + uint16_t b_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), g_size = 0; + uint16_t o_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), y_size = 0; + mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, (size_t *)&g_size, G_buf, sizeof(G_buf)); + mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, (size_t *)&y_size, Y_buf, sizeof(Y_buf)); + uint16_t c_size = 1; + uint16_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? p_size : 1)); + uint16_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size); + uint16_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size); + uint16_t ctot_size = asn1_len_tag(0x87, c_size); + uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa)); + uint16_t tot_len = 0, tot_data_len = 0; if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { tot_data_len = oid_len + ptot_size + otot_size + gtot_size + ytot_size; oid = oid_ri; @@ -157,33 +157,33 @@ size_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, siz return tot_len; } -size_t asn1_cvc_cert_body(void *rsa_ecdsa, +uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, - size_t buf_len, + uint16_t buf_len, const uint8_t *ext, - size_t ext_len, + uint16_t ext_len, bool full) { - size_t pubkey_size = 0; + uint16_t pubkey_size = 0; if (key_type & PICO_KEYS_KEY_RSA) { pubkey_size = asn1_cvc_public_key_rsa(rsa_ecdsa, NULL, 0); } else if (key_type & PICO_KEYS_KEY_EC) { pubkey_size = asn1_cvc_public_key_ecdsa(rsa_ecdsa, NULL, 0); } - size_t cpi_size = 4, ext_size = 0, role_size = 0, valid_size = 0; + uint16_t cpi_size = 4, ext_size = 0, role_size = 0, valid_size = 0; if (ext && ext_len > 0) { ext_size = asn1_len_tag(0x65, ext_len); } const uint8_t *role = (const uint8_t *)"\x06\x09\x04\x00\x7F\x00\x07\x03\x01\x02\x02\x53\x01\x00"; - size_t rolelen = 14; + uint16_t rolelen = 14; if (full) { role_size = asn1_len_tag(0x7f4c, rolelen); valid_size = asn1_len_tag(0x5f24, 6) + asn1_len_tag(0x5f25, 6); } uint8_t *car = NULL, *chr = NULL; - size_t lencar = 0, lenchr = 0; + uint16_t lencar = 0, lenchr = 0; if (asn1_find_tag(apdu.data, apdu.nc, 0x42, &lencar, &car) == false || lencar == 0 || car == NULL) { @@ -191,7 +191,7 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa, lencar = dev_name_len; if (dev_name == NULL) { car = (uint8_t *)"ESPICOHSMTR00001"; - lencar = strlen((const char *)car); + lencar = (uint16_t)strlen((const char *)car); } } if (asn1_find_tag(apdu.data, apdu.nc, 0x5f20, &lenchr, @@ -203,9 +203,9 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa, lenchr = lencar; } } - size_t car_size = asn1_len_tag(0x42, lencar), chr_size = asn1_len_tag(0x5f20, lenchr); + uint16_t car_size = asn1_len_tag(0x42, lencar), chr_size = asn1_len_tag(0x5f20, lenchr); - size_t tot_len = asn1_len_tag(0x7f4e, cpi_size + car_size + pubkey_size + chr_size + ext_size + role_size + valid_size); + uint16_t tot_len = asn1_len_tag(0x7f4e, cpi_size + car_size + pubkey_size + chr_size + ext_size + role_size + valid_size); if (buf_len == 0 || buf == NULL) { return tot_len; @@ -257,22 +257,22 @@ size_t asn1_cvc_cert_body(void *rsa_ecdsa, return tot_len; } -size_t asn1_cvc_cert(void *rsa_ecdsa, +uint16_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, - size_t buf_len, + uint16_t buf_len, const uint8_t *ext, - size_t ext_len, + uint16_t ext_len, bool full) { - size_t key_size = 0; + uint16_t key_size = 0; if (key_type & PICO_KEYS_KEY_RSA) { - key_size = mbedtls_mpi_size(&((mbedtls_rsa_context *) rsa_ecdsa)->N); + key_size = (uint16_t)mbedtls_mpi_size(&((mbedtls_rsa_context *) rsa_ecdsa)->N); } else if (key_type & PICO_KEYS_KEY_EC) { key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(((mbedtls_ecdsa_context *) rsa_ecdsa)->grp.id)->bit_size + 7) / 8); } - size_t body_size = asn1_cvc_cert_body(rsa_ecdsa, key_type, NULL, 0, ext, ext_len, full), sig_size = asn1_len_tag(0x5f37, key_size); - size_t tot_len = asn1_len_tag(0x7f21, body_size + sig_size); + uint16_t body_size = asn1_cvc_cert_body(rsa_ecdsa, key_type, NULL, 0, ext, ext_len, full), sig_size = asn1_len_tag(0x5f37, key_size); + uint16_t tot_len = asn1_len_tag(0x7f21, body_size + sig_size); if (buf_len == 0 || buf == NULL) { return tot_len; } @@ -313,19 +313,19 @@ size_t asn1_cvc_cert(void *rsa_ecdsa, mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); } - return p - buf; + return (uint16_t)(p - buf); } -size_t asn1_cvc_aut(void *rsa_ecdsa, +uint16_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, - size_t buf_len, + uint16_t buf_len, const uint8_t *ext, - size_t ext_len) { - size_t cvcert_size = asn1_cvc_cert(rsa_ecdsa, key_type, NULL, 0, ext, ext_len, false); - size_t outcar_len = dev_name_len; + uint16_t ext_len) { + uint16_t cvcert_size = asn1_cvc_cert(rsa_ecdsa, key_type, NULL, 0, ext, ext_len, false); + uint16_t outcar_len = dev_name_len; const uint8_t *outcar = dev_name; - size_t outcar_size = asn1_len_tag(0x42, outcar_len); + uint16_t outcar_size = asn1_len_tag(0x42, outcar_len); file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); if (!fkey) { return 0; @@ -336,8 +336,9 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, mbedtls_ecdsa_free(&ectx); return 0; } - int ret = 0, key_size = 2 * mbedtls_mpi_size(&ectx.d); - size_t outsig_size = asn1_len_tag(0x5f37, key_size), tot_len = asn1_len_tag(0x67, cvcert_size + outcar_size + outsig_size); + int ret = 0; + uint16_t key_size = 2 * (uint16_t)mbedtls_mpi_size(&ectx.d); + uint16_t outsig_size = asn1_len_tag(0x5f37, key_size), tot_len = asn1_len_tag(0x67, cvcert_size + outcar_size + outsig_size); if (buf_len == 0 || buf == NULL) { return tot_len; } @@ -370,24 +371,24 @@ size_t asn1_cvc_aut(void *rsa_ecdsa, mbedtls_mpi_write_binary(&s, p, mbedtls_mpi_size(&s)); p += mbedtls_mpi_size(&s); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); - return p - buf; + return (uint16_t)(p - buf); } -size_t asn1_build_cert_description(const uint8_t *label, - size_t label_len, +uint16_t asn1_build_cert_description(const uint8_t *label, + uint16_t label_len, const uint8_t *puk, - size_t puk_len, + uint16_t puk_len, uint16_t fid, uint8_t *buf, - size_t buf_len) { - size_t opt_len = 2; - size_t seq1_size = + uint16_t buf_len) { + uint16_t opt_len = 2; + uint16_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_len) + asn1_len_tag(0x3, opt_len)); - size_t seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, 20)); /* SHA1 is 20 bytes length */ - size_t seq3_size = + uint16_t seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, 20)); /* SHA1 is 20 bytes length */ + uint16_t seq3_size = asn1_len_tag(0xA1, asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, sizeof(uint16_t))))); - size_t tot_len = asn1_len_tag(0x30, seq1_size + seq2_size + seq3_size); + uint16_t tot_len = asn1_len_tag(0x30, seq1_size + seq2_size + seq3_size); if (buf_len == 0 || buf == NULL) { return tot_len; } @@ -426,18 +427,18 @@ size_t asn1_build_cert_description(const uint8_t *label, p += format_tlv_len(sizeof(uint16_t), p); *p++ = fid >> 8; *p++ = fid & 0xff; - return p - buf; + return (uint16_t)(p - buf); } -size_t asn1_build_prkd_generic(const uint8_t *label, - size_t label_len, +uint16_t asn1_build_prkd_generic(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, int key_type, uint8_t *buf, - size_t buf_len) { - size_t seq_len = 0; + uint16_t buf_len) { + uint16_t seq_len = 0; const uint8_t *seq = NULL; uint8_t first_tag = 0x0; if (key_type & PICO_KEYS_KEY_EC) { @@ -455,10 +456,10 @@ size_t asn1_build_prkd_generic(const uint8_t *label, seq_len = 3; first_tag = 0xA8; } - size_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_len)); - size_t seq2_size = + uint16_t seq1_size = asn1_len_tag(0x30, asn1_len_tag(0xC, label_len)); + uint16_t seq2_size = asn1_len_tag(0x30, asn1_len_tag(0x4, keyid_len) + asn1_len_tag(0x3, seq_len)); - size_t seq3_size = 0, seq4_size = 0; + uint16_t seq3_size = 0, seq4_size = 0; if (key_type & PICO_KEYS_KEY_EC || key_type & PICO_KEYS_KEY_RSA) { seq4_size = asn1_len_tag(0xA1, asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0)) + asn1_len_tag(0x2, 2))); } @@ -466,7 +467,7 @@ size_t asn1_build_prkd_generic(const uint8_t *label, seq3_size = asn1_len_tag(0xA0, asn1_len_tag(0x30, asn1_len_tag(0x2, 2))); seq4_size = asn1_len_tag(0xA1, asn1_len_tag(0x30, asn1_len_tag(0x30, asn1_len_tag(0x4, 0)))); } - size_t tot_len = asn1_len_tag(first_tag, seq1_size + seq2_size + seq4_size); + uint16_t tot_len = asn1_len_tag(first_tag, seq1_size + seq2_size + seq4_size); if (buf_len == 0 || buf == NULL) { return tot_len; } @@ -507,7 +508,7 @@ size_t asn1_build_prkd_generic(const uint8_t *label, //Seq 4 *p++ = 0xA1; - size_t inseq4_len = asn1_len_tag(0x30, asn1_len_tag(0x4, 0)); + uint16_t inseq4_len = asn1_len_tag(0x30, asn1_len_tag(0x4, 0)); if (key_type & PICO_KEYS_KEY_EC || key_type & PICO_KEYS_KEY_RSA) { inseq4_len += asn1_len_tag(0x2, 2); } @@ -524,16 +525,16 @@ size_t asn1_build_prkd_generic(const uint8_t *label, *p++ = (keysize >> 8) & 0xff; *p++ = keysize & 0xff; } - return p - buf; + return (uint16_t)(p - buf); } -size_t asn1_build_prkd_ecc(const uint8_t *label, - size_t label_len, +uint16_t asn1_build_prkd_ecc(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len) { + uint16_t buf_len) { return asn1_build_prkd_generic(label, label_len, keyid, @@ -544,13 +545,13 @@ size_t asn1_build_prkd_ecc(const uint8_t *label, buf_len); } -size_t asn1_build_prkd_rsa(const uint8_t *label, - size_t label_len, +uint16_t asn1_build_prkd_rsa(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len) { + uint16_t buf_len) { return asn1_build_prkd_generic(label, label_len, keyid, @@ -561,13 +562,13 @@ size_t asn1_build_prkd_rsa(const uint8_t *label, buf_len); } -size_t asn1_build_prkd_aes(const uint8_t *label, - size_t label_len, +uint16_t asn1_build_prkd_aes(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len) { + uint16_t buf_len) { return asn1_build_prkd_generic(label, label_len, keyid, @@ -578,7 +579,7 @@ size_t asn1_build_prkd_aes(const uint8_t *label, 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, uint16_t len, uint16_t *olen, uint16_t tag) { uint8_t *rdata = NULL; if (data == NULL || len == 0) { return NULL; @@ -589,7 +590,7 @@ const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint 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, uint16_t len, uint16_t *olen) { const uint8_t *bkdata = data; if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) { /* Check for CSR */ data = bkdata; @@ -600,7 +601,7 @@ const uint8_t *cvc_get_body(const uint8_t *data, size_t len, size_t *olen) { 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, uint16_t len, uint16_t *olen) { const uint8_t *bkdata = data; if ((data = cvc_get_field(data, len, olen, 0x67)) == NULL) { /* Check for CSR */ data = bkdata; @@ -611,28 +612,28 @@ const uint8_t *cvc_get_sig(const uint8_t *data, size_t len, size_t *olen) { 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, uint16_t len, uint16_t *olen) { if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x42); } return NULL; } -const uint8_t *cvc_get_chr(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_chr(const uint8_t *data, uint16_t len, uint16_t *olen) { if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x5F20); } return NULL; } -const uint8_t *cvc_get_pub(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_pub(const uint8_t *data, uint16_t len, uint16_t *olen) { if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x7F49); } return NULL; } -const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen) { +const uint8_t *cvc_get_ext(const uint8_t *data, uint16_t len, uint16_t *olen) { if ((data = cvc_get_body(data, len, olen)) != NULL) { return cvc_get_field(data, len, olen, 0x65); } @@ -642,7 +643,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 int puk_store_entries; -int puk_store_index(const uint8_t *chr, size_t chr_len) { +int puk_store_index(const uint8_t *chr, uint16_t chr_len) { for (int i = 0; i < puk_store_entries; i++) { if (memcmp(puk_store[i].chr, chr, chr_len) == 0) { return i; @@ -651,8 +652,8 @@ int puk_store_index(const uint8_t *chr, size_t chr_len) { return -1; } -mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) { - size_t chr_len = 0, car_len = 0; +mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, uint16_t ca_len) { + uint16_t chr_len = 0, car_len = 0; const uint8_t *chr = NULL, *car = NULL; int eq = -1; do { @@ -670,12 +671,12 @@ mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) { } } } while (car && chr && eq != 0); - size_t ca_puk_len = 0; + uint16_t ca_puk_len = 0; const uint8_t *ca_puk = cvc_get_pub(ca, ca_len, &ca_puk_len); if (!ca_puk) { return MBEDTLS_ECP_DP_NONE; } - size_t t81_len = 0; + uint16_t t81_len = 0; const uint8_t *t81 = cvc_get_field(ca_puk, ca_puk_len, &t81_len, 0x81); if (!t81) { return MBEDTLS_ECP_DP_NONE; @@ -685,23 +686,23 @@ mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len) { } int puk_verify(const uint8_t *sig, - size_t sig_len, + uint16_t sig_len, const uint8_t *hash, - size_t hash_len, + uint16_t hash_len, const uint8_t *ca, - size_t ca_len) { - size_t puk_len = 0; + uint16_t ca_len) { + uint16_t puk_len = 0; const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); if (!puk) { return CCID_WRONG_DATA; } - size_t oid_len = 0; + uint16_t oid_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); if (!oid) { return CCID_WRONG_DATA; } if (memcmp(oid, OID_ID_TA_RSA, 9) == 0) { //RSA - size_t t81_len = 0, t82_len = 0; + uint16_t t81_len = 0, t82_len = 0; const uint8_t *t81 = cvc_get_field(puk, puk_len, &t81_len, 0x81), *t82 = cvc_get_field(puk, puk_len, &t81_len, @@ -757,7 +758,7 @@ int puk_verify(const uint8_t *sig, mbedtls_rsa_free(&rsa); return CCID_EXEC_ERROR; } - r = mbedtls_rsa_pkcs1_verify(&rsa, md, hash_len, hash, sig); + r = mbedtls_rsa_pkcs1_verify(&rsa, md, (unsigned int)hash_len, hash, sig); mbedtls_rsa_free(&rsa); if (r != 0) { return CCID_WRONG_SIGNATURE; @@ -784,7 +785,7 @@ int puk_verify(const uint8_t *sig, return CCID_WRONG_DATA; } - size_t t86_len = 0; + uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(puk, puk_len, &t86_len, 0x86); if (!t86) { return CCID_WRONG_DATA; @@ -838,13 +839,13 @@ int puk_verify(const uint8_t *sig, return CCID_OK; } -int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t ca_len) { - size_t puk_len = 0; +int cvc_verify(const uint8_t *cert, uint16_t cert_len, const uint8_t *ca, uint16_t ca_len) { + uint16_t puk_len = 0; const uint8_t *puk = cvc_get_pub(ca, ca_len, &puk_len); if (!puk) { return CCID_WRONG_DATA; } - size_t oid_len = 0, cv_body_len = 0, sig_len = 0; + uint16_t oid_len = 0, cv_body_len = 0, sig_len = 0; const uint8_t *oid = cvc_get_field(puk, puk_len, &oid_len, 0x6); const uint8_t *cv_body = cvc_get_body(cert, cert_len, &cv_body_len); const uint8_t *sig = cvc_get_sig(cert, cert_len, &sig_len); diff --git a/src/hsm/cvc.h b/src/hsm/cvc.h index 1959cfd..1eb217a 100644 --- a/src/hsm/cvc.h +++ b/src/hsm/cvc.h @@ -28,78 +28,78 @@ typedef struct PUK { const uint8_t *puk; - size_t puk_len; + uint16_t puk_len; const uint8_t *car; - size_t car_len; + uint16_t car_len; const uint8_t *chr; - size_t chr_len; + uint16_t chr_len; const uint8_t *cvcert; - size_t cvcert_len; + uint16_t cvcert_len; bool copied; } PUK; #define MAX_PUK_STORE_ENTRIES 4 -extern size_t asn1_cvc_cert(void *rsa_ecdsa, +extern uint16_t asn1_cvc_cert(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, - size_t buf_len, + uint16_t buf_len, const uint8_t *ext, - size_t ext_len, + uint16_t ext_len, bool full); -extern size_t asn1_cvc_aut(void *rsa_ecdsa, +extern uint16_t asn1_cvc_aut(void *rsa_ecdsa, uint8_t key_type, uint8_t *buf, - size_t buf_len, + uint16_t buf_len, const uint8_t *ext, - size_t ext_len); -extern size_t asn1_build_cert_description(const uint8_t *label, - size_t label_len, + uint16_t ext_len); +extern uint16_t asn1_build_cert_description(const uint8_t *label, + uint16_t label_len, const uint8_t *puk, - size_t puk_len, + uint16_t puk_len, uint16_t fid, uint8_t *buf, - size_t buf_len); -extern const uint8_t *cvc_get_field(const uint8_t *data, size_t len, size_t *olen, uint16_t tag); -extern const uint8_t *cvc_get_car(const uint8_t *data, size_t len, size_t *olen); -extern const uint8_t *cvc_get_chr(const uint8_t *data, size_t len, size_t *olen); -extern const uint8_t *cvc_get_pub(const uint8_t *data, size_t len, size_t *olen); -extern const uint8_t *cvc_get_ext(const uint8_t *data, size_t len, size_t *olen); -extern int cvc_verify(const uint8_t *cert, size_t cert_len, const uint8_t *ca, size_t ca_len); -extern mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, size_t ca_len); + uint16_t buf_len); +extern const uint8_t *cvc_get_field(const uint8_t *data, uint16_t len, uint16_t *olen, uint16_t tag); +extern const uint8_t *cvc_get_car(const uint8_t *data, uint16_t len, uint16_t *olen); +extern const uint8_t *cvc_get_chr(const uint8_t *data, uint16_t len, uint16_t *olen); +extern const uint8_t *cvc_get_pub(const uint8_t *data, uint16_t len, uint16_t *olen); +extern const uint8_t *cvc_get_ext(const uint8_t *data, uint16_t len, uint16_t *olen); +extern int cvc_verify(const uint8_t *cert, uint16_t cert_len, const uint8_t *ca, uint16_t ca_len); +extern mbedtls_ecp_group_id cvc_inherite_ec_group(const uint8_t *ca, uint16_t ca_len); extern int puk_verify(const uint8_t *sig, - size_t sig_len, + uint16_t sig_len, const uint8_t *hash, - size_t hash_len, + uint16_t hash_len, const uint8_t *ca, - size_t ca_len); -extern size_t asn1_build_prkd_ecc(const uint8_t *label, - size_t label_len, + uint16_t ca_len); +extern uint16_t asn1_build_prkd_ecc(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len); -extern size_t asn1_build_prkd_rsa(const uint8_t *label, - size_t label_len, + uint16_t buf_len); +extern uint16_t asn1_build_prkd_rsa(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len); -extern size_t asn1_build_prkd_aes(const uint8_t *label, - size_t label_len, + uint16_t buf_len); +extern uint16_t asn1_build_prkd_aes(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, uint8_t *buf, - size_t buf_len); -extern size_t asn1_build_prkd_generic(const uint8_t *label, - size_t label_len, + uint16_t buf_len); +extern uint16_t asn1_build_prkd_generic(const uint8_t *label, + uint16_t label_len, const uint8_t *keyid, - size_t keyid_len, - size_t keysize, + uint16_t keyid_len, + uint16_t keysize, int key_tpe, uint8_t *buf, - size_t buf_len); + uint16_t buf_len); #endif diff --git a/src/hsm/files.c b/src/hsm/files.c index f863ab1..8a5fb4b 100644 --- a/src/hsm/files.c +++ b/src/hsm/files.c @@ -101,7 +101,7 @@ file_t file_entries[] = { ///* 30 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, /* 31 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, - /* 32 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, + /* 32 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_NOT_KNOWN, .data = NULL, .ef_structure = 0, .acl = { 0 } } //end }; diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 2144c1e..3bfb378 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -41,7 +41,7 @@ uint8_t pending_save_dkek = 0xff; #define POLY 0xedb88320 uint32_t crc32c(const uint8_t *buf, size_t len) { - uint32_t crc = ~0; + uint32_t crc = 0xffffffffffffffff; while (len--) { crc ^= *buf++; for (int k = 0; k < 8; k++) { @@ -258,7 +258,7 @@ int dkek_kmac(uint8_t id, uint8_t *kmac) { //kmac 32 bytes return CCID_OK; } -int mkek_encrypt(uint8_t *data, size_t len) { +int mkek_encrypt(uint8_t *data, uint16_t len) { int r; uint8_t mkek[MKEK_SIZE + 4]; if ((r = load_mkek(mkek)) != CCID_OK) { @@ -269,7 +269,7 @@ int mkek_encrypt(uint8_t *data, size_t len) { return r; } -int mkek_decrypt(uint8_t *data, size_t len) { +int mkek_decrypt(uint8_t *data, uint16_t len) { int r; uint8_t mkek[MKEK_SIZE + 4]; if ((r = load_mkek(mkek)) != CCID_OK) { @@ -284,16 +284,17 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, - size_t *out_len, + uint16_t *out_len, const uint8_t *allowed, - size_t allowed_len) { + uint16_t allowed_len) { if (!(key_type & PICO_KEYS_KEY_RSA) && !(key_type & PICO_KEYS_KEY_EC) && !(key_type & PICO_KEYS_KEY_AES)) { return CCID_WRONG_DATA; } uint8_t kb[8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13]; //worst case: RSA-4096 (plus, 13 bytes padding) memset(kb, 0, sizeof(kb)); - int kb_len = 0, r = 0; + uint16_t kb_len = 0; + int r = 0; uint8_t *algo = NULL; uint8_t algo_len = 0; uint8_t kenc[32]; @@ -351,17 +352,17 @@ int dkek_encode_key(uint8_t id, } mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; kb_len = 0; - put_uint16_t(mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len); kb_len += 2; + put_uint16_t((uint16_t)mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len); kb_len += 2; - put_uint16_t(mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len); kb_len += 2; + put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&rsa->D, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->D)); - kb_len += mbedtls_mpi_size(&rsa->D); - put_uint16_t(mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len); kb_len += 2; + kb_len += (uint16_t)mbedtls_mpi_size(&rsa->D); + put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&rsa->N, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->N)); - kb_len += mbedtls_mpi_size(&rsa->N); - put_uint16_t(mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len); kb_len += 2; + kb_len += (uint16_t)mbedtls_mpi_size(&rsa->N); + put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&rsa->E, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->E)); - kb_len += mbedtls_mpi_size(&rsa->E); + kb_len += (uint16_t)mbedtls_mpi_size(&rsa->E); algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02"; algo_len = 12; @@ -372,38 +373,38 @@ int dkek_encode_key(uint8_t id, } mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; kb_len = 0; - put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len); kb_len += 2; - put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len); kb_len += 2; + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len); kb_len += 2; + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&ecdsa->grp.A, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.A)); - kb_len += mbedtls_mpi_size(&ecdsa->grp.A); - put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len); kb_len += 2; + kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A); + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&ecdsa->grp.B, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.B)); - kb_len += mbedtls_mpi_size(&ecdsa->grp.B); - put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len); kb_len += 2; + kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B); + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&ecdsa->grp.P, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.P)); - kb_len += mbedtls_mpi_size(&ecdsa->grp.P); - put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len); kb_len += 2; + kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P); + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N)); - kb_len += mbedtls_mpi_size(&ecdsa->grp.N); + kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N); - size_t olen = 0; + uint16_t olen = 0; mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, + (size_t *)&olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2); put_uint16_t(olen, kb + 8 + kb_len); kb_len += 2 + olen; - put_uint16_t(mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2; + put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2; mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d)); - kb_len += mbedtls_mpi_size(&ecdsa->d); + kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->d); mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, + (size_t *)&olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2); put_uint16_t(olen, kb + 8 + kb_len); @@ -450,7 +451,7 @@ int dkek_encode_key(uint8_t id, memcpy(kb, random_bytes_get(8), 8); kb_len += 8; //8 random bytes - int kb_len_pad = ((int) (kb_len / 16)) * 16; + uint16_t kb_len_pad = ((uint16_t) (kb_len / 16)) * 16; if (kb_len % 16 > 0) { kb_len_pad = ((int) (kb_len / 16) + 1) * 16; } @@ -496,10 +497,10 @@ int dkek_type_key(const uint8_t *in) { int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, - size_t in_len, + uint16_t in_len, int *key_size_out, uint8_t **allowed, - size_t *allowed_len) { + uint16_t *allowed_len) { uint8_t kcv[8]; int r = 0; memset(kcv, 0, sizeof(kcv)); @@ -559,10 +560,10 @@ int dkek_decode_key(uint8_t id, return CCID_WRONG_DATA; } - size_t ofs = 9; + uint16_t ofs = 9; //OID - size_t len = get_uint16_t(in, ofs); + uint16_t len = get_uint16_t(in, ofs); ofs += len + 2; //Allowed algorithms diff --git a/src/hsm/kek.h b/src/hsm/kek.h index 5c85c2f..aa095cc 100644 --- a/src/hsm/kek.h +++ b/src/hsm/kek.h @@ -31,23 +31,23 @@ extern void init_mkek(); extern void release_mkek(uint8_t *); extern int import_dkek_share(uint8_t, const uint8_t *share); extern int dkek_kcv(uint8_t, uint8_t *kcv); -extern int mkek_encrypt(uint8_t *data, size_t len); -extern int mkek_decrypt(uint8_t *data, size_t len); +extern int mkek_encrypt(uint8_t *data, uint16_t len); +extern int mkek_decrypt(uint8_t *data, uint16_t len); extern int dkek_encode_key(uint8_t, void *key_ctx, int key_type, uint8_t *out, - size_t *out_len, + uint16_t *out_len, const uint8_t *, - size_t); + uint16_t); extern int dkek_type_key(const uint8_t *in); extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, - size_t in_len, + uint16_t in_len, int *key_size_out, uint8_t **, - size_t *); + uint16_t *); #define MAX_DKEK_ENCODE_KEY_BUFFER (8 + 1 + 12 + 6 + (8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13) + 16) diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index f4450f2..23cdfd2 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -42,7 +42,7 @@ const uint8_t atr_sc_hsm[] = { uint8_t session_pin[32], session_sopin[32]; bool has_session_pin = false, has_session_sopin = false; const uint8_t *dev_name = NULL; -size_t dev_name_len = 0; +uint16_t dev_name_len = 0; static int sc_hsm_process_apdu(); @@ -87,7 +87,7 @@ int sc_hsm_select_aid(app_t *a) { return CCID_OK; } -void __attribute__((constructor)) sc_hsm_ctor() { +INITIALIZER( sc_hsm_ctor ) { ccid_atr = atr_sc_hsm; register_app(sc_hsm_select_aid, sc_hsm_aid); } @@ -174,7 +174,7 @@ int puk_store_entries = 0; PUK *current_puk = NULL; uint8_t puk_status[MAX_PUK]; -int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) { +int add_cert_puk_store(const uint8_t *data, uint16_t data_len, bool copy) { if (data == NULL || data_len == 0) { return CCID_ERR_NULL_PARAM; } @@ -229,14 +229,14 @@ void reset_puk_store() { file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); if (fterm) { uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data; - size_t fterm_data_len = file_get_size(fterm); + uint16_t fterm_data_len = file_get_size(fterm); while (walk_tlv(fterm_data, fterm_data_len, &p, NULL, NULL, NULL)) { - add_cert_puk_store(pq, p - pq, false); + add_cert_puk_store(pq, (uint16_t)(p - pq), false); pq = p; } } for (int i = 0; i < 0xfe; i++) { - file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | i); + file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | (uint8_t)i); if (ef && file_get_size(ef) > 0) { add_cert_puk_store(file_get_data(ef), file_get_size(ef), false); } @@ -285,6 +285,7 @@ bool wait_button_pressed() { } int parse_token_info(const file_t *f, int mode) { + (void)f; #ifdef __FOR_CI char *label = "SmartCard-HSM"; #else @@ -301,13 +302,13 @@ int parse_token_info(const file_t *f, int mode) { #else *p++ = 0x4; *p++ = 8; memset(p, 0, 8); p += 8; #endif - *p++ = 0xC; *p++ = strlen(manu); strcpy((char *) p, manu); p += strlen(manu); - *p++ = 0x80; *p++ = strlen(label); strcpy((char *) p, label); p += strlen(label); + *p++ = 0xC; *p++ = (uint8_t)strlen(manu); strcpy((char *) p, manu); p += strlen(manu); + *p++ = 0x80; *p++ = (uint8_t)strlen(label); strcpy((char *) p, label); p += strlen(label); *p++ = 0x3; *p++ = 2; *p++ = 4; *p++ = 0x30; - res_APDU_size = p - res_APDU; - res_APDU[1] = res_APDU_size - 2; + res_APDU_size = (uint16_t)(p - res_APDU); + res_APDU[1] = (uint8_t)res_APDU_size - 2; } - return 2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2); + return (int)(2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2)); } int pin_reset_retries(const file_t *pin, bool force) { @@ -358,7 +359,7 @@ bool pka_enabled() { 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) { +uint16_t check_pin(const file_t *pin, const uint8_t *data, uint16_t len) { if (!file_has_data((file_t *) pin)) { return SW_REFERENCE_NOT_FOUND(); } @@ -372,7 +373,7 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) { if ((retries = pin_wrong_retry(pin)) < CCID_OK) { return SW_PIN_BLOCKED(); } - return set_res_sw(0x63, 0xc0 | retries); + return set_res_sw(0x63, 0xc0 | (uint8_t)retries); } } else { @@ -386,7 +387,7 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) { if ((retries = pin_wrong_retry(pin)) < CCID_OK) { return SW_PIN_BLOCKED(); } - return set_res_sw(0x63, 0xc0 | retries); + return set_res_sw(0x63, 0xc0 | (uint8_t)retries); } } int r = pin_reset_retries(pin, false); @@ -414,12 +415,12 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) { 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, uint16_t *tag_len) { if (ef == NULL) { return NULL; } uint8_t *meta_data = NULL; - uint8_t meta_size = meta_find(ef->fid, &meta_data); + uint16_t meta_size = meta_find(ef->fid, &meta_data); if (meta_size > 0 && meta_data != NULL) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; @@ -433,7 +434,7 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) { } uint32_t get_key_counter(file_t *fkey) { - size_t tag_len = 0; + uint16_t tag_len = 0; const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len); if (meta_tag) { return (meta_tag[0] << 24) | (meta_tag[1] << 16) | (meta_tag[2] << 8) | meta_tag[3]; @@ -442,10 +443,10 @@ uint32_t get_key_counter(file_t *fkey) { } bool key_has_purpose(file_t *ef, uint8_t purpose) { - size_t tag_len = 0; + uint16_t tag_len = 0; const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len); if (meta_tag) { - for (int i = 0; i < tag_len; i++) { + for (unsigned i = 0; i < tag_len; i++) { if (meta_tag[i] == purpose) { return true; } @@ -460,11 +461,11 @@ uint32_t decrement_key_counter(file_t *fkey) { return 0xffffff; } uint8_t *meta_data = NULL; - uint8_t meta_size = meta_find(fkey->fid, &meta_data); + uint16_t meta_size = meta_find(fkey->fid, &meta_data); if (meta_size > 0 && meta_data != NULL) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - size_t tag_len = 0; + uint16_t tag_len = 0; uint8_t *cmeta = (uint8_t *) calloc(1, meta_size); /* We cannot modify meta_data, as it comes from flash memory. It must be cpied to an aux buffer */ memcpy(cmeta, meta_data, meta_size); @@ -478,7 +479,7 @@ uint32_t decrement_key_counter(file_t *fkey) { tag_data[2] = (val >> 8) & 0xff; tag_data[3] = val & 0xff; - int r = meta_add(fkey->fid, cmeta, meta_size); + int r = meta_add(fkey->fid, cmeta, (uint16_t)meta_size); free(cmeta); if (r != 0) { return 0xffffffff; @@ -494,17 +495,18 @@ uint32_t decrement_key_counter(file_t *fkey) { // Stores the private and public keys in flash int store_keys(void *key_ctx, int type, uint8_t key_id) { - int r, key_size = 0; + int r = 0; + uint16_t key_size = 0; uint8_t kdata[4096 / 8]; // worst case if (type & PICO_KEYS_KEY_RSA) { mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx; - key_size = mbedtls_mpi_size(&rsa->P) + mbedtls_mpi_size(&rsa->Q); + key_size = (uint16_t)mbedtls_mpi_size(&rsa->P) + (uint16_t)mbedtls_mpi_size(&rsa->Q); mbedtls_mpi_write_binary(&rsa->P, kdata, key_size / 2); mbedtls_mpi_write_binary(&rsa->Q, kdata + key_size / 2, key_size / 2); } else if (type & PICO_KEYS_KEY_EC) { mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; - key_size = mbedtls_mpi_size(&ecdsa->d); + key_size = (uint16_t)mbedtls_mpi_size(&ecdsa->d); kdata[0] = ecdsa->grp.id & 0xff; mbedtls_ecp_write_key(ecdsa, kdata + 1, key_size); key_size++; @@ -535,7 +537,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { if (r != CCID_OK) { return r; } - r = flash_write_data_to_file(fpk, kdata, key_size); + r = flash_write_data_to_file(fpk, kdata, (uint16_t)key_size); if (r != CCID_OK) { return r; } @@ -544,7 +546,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { if (type & PICO_KEYS_KEY_EC) { key_size--; } - size_t prkd_len = asn1_build_prkd_generic(NULL, 0, (uint8_t *)key_id_str, strlen(key_id_str), key_size * 8, type, kdata, sizeof(kdata)); + uint16_t prkd_len = asn1_build_prkd_generic(NULL, 0, (uint8_t *)key_id_str, (uint16_t)strlen(key_id_str), key_size * 8, type, kdata, sizeof(kdata)); if (prkd_len > 0) { fpk = file_new((PRKD_PREFIX << 8) | key_id); r = flash_write_data_to_file(fpk, kdata, prkd_len); @@ -557,13 +559,13 @@ int store_keys(void *key_ctx, int type, 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; + uint16_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; uint8_t *pt[4] = { NULL, NULL, NULL, NULL }; uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; - for (int t = 0; t < 4; t++) { + for (uint16_t t = 0; t < 4; t++) { uint8_t *ptt = NULL; - size_t ltt = 0; - if (asn1_find_tag(apdu.data, apdu.nc, 0x90 + t, <t, &ptt) && ptt != NULL && ltt > 0) { + uint16_t ltt = 0; + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x90 + t, <t, &ptt) && ptt != NULL && ltt > 0) { lt[t] = ltt; pt[t] = ptt; meta_size += asn1_len_tag(0x90 + t, lt[t]); @@ -579,7 +581,7 @@ int find_and_store_meta_key(uint8_t key_id) { } if (meta_size) { uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta; - for (int t = 0; t < 4; t++) { + for (uint8_t t = 0; t < 4; t++) { if (lt[t] > 0 && pt[t] != NULL) { *m++ = 0x90 + t; m += format_tlv_len(lt[t], m); @@ -587,7 +589,7 @@ int find_and_store_meta_key(uint8_t key_id) { m += lt[t]; } } - int r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_size); + int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size); free(meta); if (r != 0) { return CCID_EXEC_ERROR; @@ -601,7 +603,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) { return CCID_VERIFICATION_FAILED; } - int key_size = file_get_size(fkey); + uint16_t key_size = file_get_size(fkey); uint8_t kdata[4096 / 8]; memcpy(kdata, file_get_data(fkey), key_size); if (mkek_decrypt(kdata, key_size) != 0) { @@ -645,7 +647,7 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) { return CCID_VERIFICATION_FAILED; } - int key_size = file_get_size(fkey); + uint16_t key_size = file_get_size(fkey); uint8_t kdata[67]; // Worst case, 521 bit + 1byte memcpy(kdata, file_get_data(fkey), key_size); if (mkek_decrypt(kdata, key_size) != 0) { @@ -735,9 +737,9 @@ int sc_hsm_process_apdu() { } for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) { if (cmd->ins == INS(apdu)) { - int r = cmd->cmd_handler(); + int res = cmd->cmd_handler(); sm_wrap(); - return r; + return res; } } return SW_INS_NOT_SUPPORTED(); diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index 9a7b194..fa8d3ff 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -102,20 +102,18 @@ extern const uint8_t sc_hsm_aid[]; extern int pin_reset_retries(const file_t *pin, bool); extern int pin_wrong_retry(const file_t *pin); -extern void hash(const uint8_t *input, size_t len, uint8_t output[32]); -extern void hash_multi(const uint8_t *input, size_t len, uint8_t output[32]); -extern void double_hash_pin(const uint8_t *pin, size_t len, uint8_t output[32]); +extern void hash(const uint8_t *input, uint16_t len, uint8_t output[32]); extern uint16_t get_device_options(); extern bool has_session_pin, has_session_sopin; extern uint8_t session_pin[32], session_sopin[32]; -extern int check_pin(const file_t *pin, const uint8_t *data, size_t len); +extern uint16_t check_pin(const file_t *pin, const uint8_t *data, uint16_t len); extern bool pka_enabled(); extern const uint8_t *dev_name; -extern size_t dev_name_len; +extern uint16_t dev_name_len; extern uint8_t puk_status[MAX_PUK]; extern int puk_store_select_chr(const uint8_t *chr); extern int delete_file(file_t *ef); -extern const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len); +extern const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, uint16_t *tag_len); extern bool key_has_purpose(file_t *ef, uint8_t purpose); extern int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey); extern int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey); From d9a8826a3209bd46a57b35e032d685d89405e59e Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 1 Jan 2024 02:01:22 +0100 Subject: [PATCH 16/85] Stupid bug integer overflow. Signed-off-by: Pol Henarejos --- src/hsm/kek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 3bfb378..7f9dea6 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -41,7 +41,7 @@ uint8_t pending_save_dkek = 0xff; #define POLY 0xedb88320 uint32_t crc32c(const uint8_t *buf, size_t len) { - uint32_t crc = 0xffffffffffffffff; + uint32_t crc = 0xffffffff; while (len--) { crc ^= *buf++; for (int k = 0; k < 8; k++) { From 481cd5fd698d2b7bd80be06af5f1e4e6f020e602 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 1 Jan 2024 20:58:40 +0100 Subject: [PATCH 17/85] Some fixes for emulation. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_key_domain.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index a9dc6fd..b663f5b 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit a9dc6fd7f87fff7505ad526c7392ec1bc3a811a9 +Subproject commit b663f5bebf08355ecc561c7c439ab610f685042e diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index 827fe75..487a7c5 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -103,8 +103,8 @@ int cmd_key_domain() { return SW_WRONG_LENGTH(); } if (p1 == 0x3) { //if key domain is not empty, command is denied - for (uint8_t i = 1; i < 256; i++) { - file_t *fkey = search_dynamic_file(KEY_PREFIX << 8 | i); + for (uint16_t i = 1; i < 256; i++) { + file_t *fkey = search_dynamic_file(KEY_PREFIX << 8 | (uint8_t)i); if (get_key_domain(fkey) == p2) { return SW_FILE_EXISTS(); } From de98e79c992be304880adf917ce03428393da04f Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 1 Jan 2024 21:09:42 +0100 Subject: [PATCH 18/85] Try to fix CodeQL build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index b663f5b..823c1d5 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit b663f5bebf08355ecc561c7c439ab610f685042e +Subproject commit 823c1d53ea0744c98496917502d6910c9dab2527 From 08c0aaee6fec8ef298612e5450258b92737b42a1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 01:03:57 +0100 Subject: [PATCH 19/85] Fix SM wrap for large RAPDU. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 823c1d5..22c9b73 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 823c1d53ea0744c98496917502d6910c9dab2527 +Subproject commit 22c9b7321bdce2953ba0885d1367fca45a584a3a From 4f4e6e09a2ab91acdd22ece5964ae521f248a89d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 02:31:38 +0100 Subject: [PATCH 20/85] Fix size var load. Signed-off-by: Pol Henarejos --- src/hsm/cvc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index ded1157..ebbc3a8 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -77,16 +77,16 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, u const uint8_t oid_ecdsa[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x03 }; const uint8_t oid_ri[] = { 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x05, 0x02, 0x03 }; const uint8_t *oid = oid_ecdsa; - uint16_t p_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), a_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A); - uint16_t b_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), g_size = 0; - uint16_t o_size = (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), y_size = 0; - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, (size_t *)&g_size, G_buf, sizeof(G_buf)); - mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, (size_t *)&y_size, Y_buf, sizeof(Y_buf)); + size_t p_size = mbedtls_mpi_size(&ecdsa->grp.P), a_size = mbedtls_mpi_size(&ecdsa->grp.A); + size_t b_size = mbedtls_mpi_size(&ecdsa->grp.B), g_size = 0; + size_t o_size = mbedtls_mpi_size(&ecdsa->grp.N), y_size = 0; + mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, &g_size, G_buf, sizeof(G_buf)); + mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &y_size, Y_buf, sizeof(Y_buf)); uint16_t c_size = 1; - uint16_t ptot_size = asn1_len_tag(0x81, p_size), atot_size = asn1_len_tag(0x82, a_size ? a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? p_size : 1)); - uint16_t btot_size = asn1_len_tag(0x83, b_size), gtot_size = asn1_len_tag(0x84, g_size); - uint16_t otot_size = asn1_len_tag(0x85, o_size), ytot_size = asn1_len_tag(0x86, y_size); - uint16_t ctot_size = asn1_len_tag(0x87, c_size); + uint16_t ptot_size = asn1_len_tag(0x81, (uint16_t)p_size), atot_size = asn1_len_tag(0x82, a_size ? (uint16_t)a_size : (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6 ? (uint16_t)p_size : 1)); + uint16_t btot_size = asn1_len_tag(0x83, (uint16_t)b_size), gtot_size = asn1_len_tag(0x84, (uint16_t)g_size); + uint16_t otot_size = asn1_len_tag(0x85, (uint16_t)o_size), ytot_size = asn1_len_tag(0x86, (uint16_t)y_size); + uint16_t ctot_size = asn1_len_tag(0x87, (uint16_t)c_size); uint16_t oid_len = asn1_len_tag(0x6, sizeof(oid_ecdsa)); uint16_t tot_len = 0, tot_data_len = 0; if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { From 2e4fc568dba287e69c389fb736702e58908b22f2 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 02:36:09 +0100 Subject: [PATCH 21/85] Fix new return format for import_kek. Signed-off-by: Pol Henarejos --- tests/pico-hsm/test_021_key_import.py | 2 +- tests/pico-hsm/test_022_key_exchange.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pico-hsm/test_021_key_import.py b/tests/pico-hsm/test_021_key_import.py index 1eca43b..6129b17 100644 --- a/tests/pico-hsm/test_021_key_import.py +++ b/tests/pico-hsm/test_021_key_import.py @@ -31,7 +31,7 @@ def test_prepare_dkek(device): resp = device.import_dkek(DEFAULT_DKEK) resp = device.import_dkek(DEFAULT_DKEK) kcv = hashlib.sha256(b'\x00'*32).digest()[:8] - assert(resp[2:] == kcv) + assert(resp['kcv'] == kcv) @pytest.mark.parametrize( "modulus", [1024, 2048, 4096] diff --git a/tests/pico-hsm/test_022_key_exchange.py b/tests/pico-hsm/test_022_key_exchange.py index 707314d..f579732 100644 --- a/tests/pico-hsm/test_022_key_exchange.py +++ b/tests/pico-hsm/test_022_key_exchange.py @@ -29,7 +29,7 @@ def test_prepare_dkek(device): resp = device.import_dkek(DEFAULT_DKEK) resp = device.import_dkek(DEFAULT_DKEK) kcv = hashlib.sha256(b'\x00'*32).digest()[:8] - assert(resp[2:] == kcv) + assert(resp['kcv'] == kcv) @pytest.mark.parametrize( "curve", [ec.SECP192R1, ec.SECP256R1, ec.SECP384R1, ec.SECP521R1, ec.SECP256K1, ec.BrainpoolP256R1, ec.BrainpoolP384R1, ec.BrainpoolP512R1] From 39f1041dbbd3ce4c3096032b14615e14490f5d4b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 02:36:21 +0100 Subject: [PATCH 22/85] Fix byte overwrite for long chained RAPDU. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 22c9b73..bbc06ef 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 22c9b7321bdce2953ba0885d1367fca45a584a3a +Subproject commit bbc06efe6770f033de8f74c2a56e9d0172cb0d13 From a1d7733b950c46e1526722c090fba12f8af88882 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 02:44:59 +0100 Subject: [PATCH 23/85] Fix key exchange. Signed-off-by: Pol Henarejos --- src/hsm/cmd_decrypt_asym.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 690e0b2..4f4dc5b 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -111,6 +111,7 @@ int cmd_decrypt_asym() { } r = -1; if (p2 == ALGO_EC_DH) { + *(apdu.data - 1) = (uint8_t)apdu.nc; r = mbedtls_ecdh_read_public(&ctx, apdu.data - 1, apdu.nc + 1); } else if (p2 == ALGO_EC_DH_XKEK) { @@ -119,7 +120,9 @@ int cmd_decrypt_asym() { if (pub) { uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); + uint8_t *t86w = (uint8_t *)t86; if (t86) { + *(t86w - 1) = (uint8_t)t86_len; r = mbedtls_ecdh_read_public(&ctx, t86 - 1, t86_len + 1); } } From 2b92d89ab7810aeb0c19253646783453fe0a9206 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 19:56:38 +0100 Subject: [PATCH 24/85] Fix size_t casting. Signed-off-by: Pol Henarejos --- src/hsm/cmd_bip_slip.c | 6 +++--- src/hsm/cmd_cipher_sym.c | 8 ++++---- src/hsm/cmd_decrypt_asym.c | 12 ++++++------ src/hsm/cmd_extras.c | 8 ++++---- src/hsm/cmd_signature.c | 12 ++++++------ src/hsm/kek.c | 14 +++++++------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 2a8aed7..95f8b30 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -265,7 +265,7 @@ int cmd_bip_slip() { } mbedtls_ecp_keypair ctx; uint8_t chain[32] = { 0 }, fgpt[4] = { 0 }, last_node[4] = { 0 }, key_type = 0, nodes = 0; - uint16_t olen = 0; + size_t olen = 0; int r = node_derive_path(apdu.data, apdu.nc, &ctx, chain, fgpt, &nodes, last_node, &key_type); if (r != CCID_OK) { @@ -287,11 +287,11 @@ int cmd_bip_slip() { mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_COMPRESSED, - (size_t *)&olen, + &olen, pubkey, sizeof(pubkey)); memcpy(res_APDU + res_APDU_size, pubkey, olen); - res_APDU_size += olen; + res_APDU_size += (uint16_t)olen; } else if (key_type == 0x3) { sha256_sha256(chain, 32, chain); diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index a9aa86e..cacaac4 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -380,7 +380,7 @@ int cmd_cipher_sym() { if (r != 0) { 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 : (uint16_t)mbedtls_md_get_size(md_info); } else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { int iterations = 0; @@ -412,7 +412,7 @@ int cmd_cipher_sym() { res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32); } else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { - uint16_t olen = 0; + size_t olen = 0; mbedtls_asn1_buf params = {.p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; int r = mbedtls_pkcs5_pbes2_ext(¶ms, @@ -421,12 +421,12 @@ int cmd_cipher_sym() { key_size, enc, enc_len, - res_APDU, 4096, (size_t *)&olen); + res_APDU, 4096, &olen); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_WRONG_DATA(); } - res_APDU_size = olen; + res_APDU_size = (uint16_t)olen; } else if (memcmp(oid, OID_KDF_X963, oid_len) == 0) { mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 4f4dc5b..c76ab8f 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -61,10 +61,10 @@ int cmd_decrypt_asym() { memset(apdu.data + apdu.nc, 0, key_size - apdu.nc); } if (p2 == ALGO_RSA_DECRYPT_PKCS1 || p2 == ALGO_RSA_DECRYPT_OEP) { - uint16_t olen = apdu.nc; - r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, (size_t *)&olen, apdu.data, res_APDU, 512); + size_t olen = apdu.nc; + r = mbedtls_rsa_pkcs1_decrypt(&ctx, random_gen, NULL, &olen, apdu.data, res_APDU, 512); if (r == 0) { - res_APDU_size = olen; + res_APDU_size = (uint16_t)olen; } } else { @@ -131,19 +131,19 @@ int cmd_decrypt_asym() { mbedtls_ecdh_free(&ctx); return SW_DATA_INVALID(); } - uint16_t olen = 0; + size_t olen = 0; // The SmartCard-HSM returns the point result of the DH operation // with a leading '04' res_APDU[0] = 0x04; r = - mbedtls_ecdh_calc_secret(&ctx, (size_t *)&olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_gen, + mbedtls_ecdh_calc_secret(&ctx, &olen, res_APDU + 1, MBEDTLS_ECP_MAX_BYTES, random_gen, NULL); mbedtls_ecdh_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } if (p2 == ALGO_EC_DH) { - res_APDU_size = olen + 1; + res_APDU_size = (uint16_t)(olen + 1); } else { res_APDU_size = 0; diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index cddb33e..a5c4499 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -111,9 +111,9 @@ int cmd_extras() { memcpy(mse.Qpt, apdu.data, sizeof(mse.Qpt)); uint8_t buf[MBEDTLS_ECP_MAX_BYTES]; - uint16_t olen = 0; + size_t olen = 0; ret = mbedtls_ecdh_calc_secret(&hkey, - (size_t *)&olen, + &olen, buf, MBEDTLS_ECP_MAX_BYTES, random_gen, @@ -141,7 +141,7 @@ int cmd_extras() { ret = mbedtls_ecp_point_write_binary(&hkey.ctx.mbed_ecdh.grp, &hkey.ctx.mbed_ecdh.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, - (size_t *)&olen, + &olen, res_APDU, 4096); mbedtls_ecdh_free(&hkey); @@ -149,7 +149,7 @@ int cmd_extras() { return SW_EXEC_ERROR(); } mse.init = true; - res_APDU_size = olen; + res_APDU_size = (uint16_t)olen; } else if (P2(apdu) == 0x02 || P2(apdu) == 0x03 || P2(apdu) == 0x04) { if (mse.init == false) { diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index 42a7272..8afb737 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -276,19 +276,19 @@ int cmd_signature() { } return SW_EXEC_ERROR(); } - uint16_t olen = 0; + size_t olen = 0; uint8_t buf[MBEDTLS_ECDSA_MAX_LEN]; if (mbedtls_ecdsa_write_signature(&ctx, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, - (size_t *)&olen, random_gen, NULL) != 0) { + &olen, random_gen, NULL) != 0) { mbedtls_ecdsa_free(&ctx); return SW_EXEC_ERROR(); } memcpy(res_APDU, buf, olen); - res_APDU_size = olen; + res_APDU_size = (uint16_t)olen; mbedtls_ecdsa_free(&ctx); } else if (p2 == ALGO_HD) { - uint16_t olen = 0; + size_t olen = 0; uint8_t buf[MBEDTLS_ECDSA_MAX_LEN]; if (hd_context.grp.id == MBEDTLS_ECP_DP_NONE) { return SW_CONDITIONS_NOT_SATISFIED(); @@ -299,12 +299,12 @@ int cmd_signature() { md = MBEDTLS_MD_SHA256; if (mbedtls_ecdsa_write_signature(&hd_context, md, apdu.data, apdu.nc, buf, MBEDTLS_ECDSA_MAX_LEN, - (size_t *)&olen, random_gen, NULL) != 0) { + &olen, random_gen, NULL) != 0) { mbedtls_ecdsa_free(&hd_context); return SW_EXEC_ERROR(); } memcpy(res_APDU, buf, olen); - res_APDU_size = olen; + res_APDU_size = (uint16_t)olen; mbedtls_ecdsa_free(&hd_context); hd_keytype = 0; } diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 7f9dea6..4d317b8 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -387,15 +387,15 @@ int dkek_encode_key(uint8_t id, mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N)); kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N); - uint16_t olen = 0; + size_t olen = 0; mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, - (size_t *)&olen, + &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2); - put_uint16_t(olen, kb + 8 + kb_len); - kb_len += 2 + olen; + put_uint16_t((uint16_t)olen, kb + 8 + kb_len); + kb_len += 2 + (uint16_t)olen; put_uint16_t((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)); @@ -404,11 +404,11 @@ int dkek_encode_key(uint8_t id, mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, - (size_t *)&olen, + &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2); - put_uint16_t(olen, kb + 8 + kb_len); - kb_len += 2 + olen; + put_uint16_t((uint16_t)olen, kb + 8 + kb_len); + kb_len += 2 + (uint16_t)olen; algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03"; algo_len = 12; From fa9b244c42c8c4e0556a193cd77f19a5384afd07 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 19:57:52 +0100 Subject: [PATCH 25/85] Fix LE computation in a wrapped APDU. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index bbc06ef..5ea372f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit bbc06efe6770f033de8f74c2a56e9d0172cb0d13 +Subproject commit 5ea372f01ccf2c724b50813f4824ba959eddbb14 From 963b6f4f87edb628af382fea692cf8c93438caf1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 20:36:54 +0100 Subject: [PATCH 26/85] Fix CodeQL build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 5ea372f..63a2546 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 5ea372f01ccf2c724b50813f4824ba959eddbb14 +Subproject commit 63a2546166d742a26aa4bcd36f4bc10c5c183212 From de4d95beb816dfe755276e8e80a4598b5ddc9557 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 20:43:24 +0100 Subject: [PATCH 27/85] Fix Pico build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 63a2546..29837e5 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 63a2546166d742a26aa4bcd36f4bc10c5c183212 +Subproject commit 29837e56915bbb1e096ddddc6b89552f304970ff From 215221b30eab31ffca5fca2e9a889bd23c9dd2ec Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 2 Jan 2024 20:51:08 +0100 Subject: [PATCH 28/85] Let's add pico and local CodeQL modes. Signed-off-by: Pol Henarejos --- .github/workflows/codeql.yml | 3 ++- workflows/autobuild.sh | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9d8fa1c..21598af 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,6 +36,7 @@ jobs: language: [ 'cpp', 'python' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + mode: [ 'pico', 'local' ] steps: - name: Checkout repository @@ -67,7 +68,7 @@ jobs: - run: | echo "Run, Build Application using script" - ./workflows/autobuild.sh + ./workflows/autobuild.sh ${{ matrix.mode }} - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/workflows/autobuild.sh b/workflows/autobuild.sh index 09ef1c7..eb9b4ae 100755 --- a/workflows/autobuild.sh +++ b/workflows/autobuild.sh @@ -9,5 +9,9 @@ git submodule update --init cd .. mkdir build cd build +if [[ $1 == "pico" ]]; then cmake -DPICO_SDK_PATH=../pico-sdk .. +else +cmake -DENABLE_EMULATION=1 .. +fi make From 2034e436d1952d3be6c826e53185fa24aaa942fe Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 8 Jan 2024 10:59:34 +0100 Subject: [PATCH 29/85] Fix CVC outer signature length. Signed-off-by: Pol Henarejos --- src/hsm/cvc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index ebbc3a8..fbdc925 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -367,8 +367,8 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa, mbedtls_mpi_free(&s); return 0; } - mbedtls_mpi_write_binary(&r, p, mbedtls_mpi_size(&r)); p += mbedtls_mpi_size(&r); - mbedtls_mpi_write_binary(&s, p, mbedtls_mpi_size(&s)); p += mbedtls_mpi_size(&s); + 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_free(&r); mbedtls_mpi_free(&s); return (uint16_t)(p - buf); From 38bef5b43fd111dc852b5c718c7adc90553550b8 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 9 Jan 2024 11:26:26 +0100 Subject: [PATCH 30/85] Fix error message Signed-off-by: Pol Henarejos --- tools/secure_key/windows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/secure_key/windows.py b/tools/secure_key/windows.py index 79bec21..84cecec 100644 --- a/tools/secure_key/windows.py +++ b/tools/secure_key/windows.py @@ -8,7 +8,7 @@ USERNAME = "Pico-HSM" try: import keyring except: - print('ERROR: keyring module not found! Install keyring package.\nTry with `pip install keyrings.osx-keychain-keys`') + print('ERROR: keyring module not found! Install keyring package.\nTry with `pip install keyring`') sys.exit(-1) try: From 9fad920c3b7995906e9a9fca56de1854e25790c1 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 9 Jan 2024 11:43:46 +0100 Subject: [PATCH 31/85] Fix Windows emulation build. Signed-off-by: Pol Henarejos --- src/hsm/cmd_bip_slip.c | 4 ++-- src/hsm/cmd_change_pin.c | 6 +++--- src/hsm/cmd_cipher_sym.c | 20 ++++++++++---------- src/hsm/cmd_decrypt_asym.c | 4 ++-- src/hsm/cmd_general_authenticate.c | 2 +- src/hsm/cmd_pso.c | 14 +++++++------- src/hsm/cmd_puk_auth.c | 2 +- src/hsm/cmd_signature.c | 8 ++++---- src/hsm/cvc.c | 26 +++++++++++++------------- 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 95f8b30..13db1f2 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -267,7 +267,7 @@ int cmd_bip_slip() { uint8_t chain[32] = { 0 }, fgpt[4] = { 0 }, last_node[4] = { 0 }, key_type = 0, nodes = 0; size_t olen = 0; int r = - node_derive_path(apdu.data, apdu.nc, &ctx, chain, fgpt, &nodes, last_node, &key_type); + node_derive_path(apdu.data, (uint16_t)apdu.nc, &ctx, chain, fgpt, &nodes, last_node, &key_type); if (r != CCID_OK) { mbedtls_ecp_keypair_free(&ctx); return SW_EXEC_ERROR(); @@ -307,7 +307,7 @@ int cmd_bip_slip() { else if (p1 == 0x10) { uint8_t chain[32] = { 0 }, fgpt[4] = { 0 }, last_node[4] = { 0 }, nodes = 0; int r = node_derive_path(apdu.data, - apdu.nc, + (uint16_t)apdu.nc, &hd_context, chain, fgpt, diff --git a/src/hsm/cmd_change_pin.c b/src/hsm/cmd_change_pin.c index 0da02a1..7a2ba98 100644 --- a/src/hsm/cmd_change_pin.c +++ b/src/hsm/cmd_change_pin.c @@ -48,11 +48,11 @@ int cmd_change_pin() { //encrypt MKEK with new pin if (P2(apdu) == 0x81) { - hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_pin); + hash_multi(apdu.data + pin_len, (uint16_t)(apdu.nc - pin_len), session_pin); has_session_pin = true; } else if (P2(apdu) == 0x88) { - hash_multi(apdu.data + pin_len, apdu.nc - pin_len, session_sopin); + hash_multi(apdu.data + pin_len, (uint16_t)(apdu.nc - pin_len), session_sopin); has_session_sopin = true; } r = store_mkek(mkek); @@ -62,7 +62,7 @@ int cmd_change_pin() { } uint8_t dhash[33]; dhash[0] = (uint8_t)apdu.nc - pin_len; - double_hash_pin(apdu.data + pin_len, apdu.nc - pin_len, dhash + 1); + double_hash_pin(apdu.data + pin_len, (uint16_t)(apdu.nc - pin_len), dhash + 1); flash_write_data_to_file(file_pin, dhash, sizeof(dhash)); low_flash_available(); return SW_OK(); diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index cacaac4..c816c63 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -228,7 +228,7 @@ int cmd_cipher_sym() { return SW_EXEC_ERROR(); } } - res_APDU_size = apdu.nc; + res_APDU_size = (uint16_t)apdu.nc; } else if (algo == ALGO_AES_CMAC) { const mbedtls_cipher_info_t *cipher_info; @@ -266,19 +266,19 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = apdu.nc; + res_APDU_size = (uint16_t)apdu.nc; } else if (algo == ALGO_EXT_CIPHER_ENCRYPT || algo == ALGO_EXT_CIPHER_DECRYPT) { uint16_t oid_len = 0, aad_len = 0, iv_len = 0, enc_len = 0; uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; - if (!asn1_find_tag(apdu.data, apdu.nc, 0x6, &oid_len, + if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x6, &oid_len, &oid) || oid_len == 0 || oid == NULL) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } - asn1_find_tag(apdu.data, apdu.nc, 0x81, &enc_len, &enc); - asn1_find_tag(apdu.data, apdu.nc, 0x82, &iv_len, &iv); - asn1_find_tag(apdu.data, apdu.nc, 0x83, &aad_len, &aad); + asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x81, &enc_len, &enc); + asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x82, &iv_len, &iv); + asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x83, &aad_len, &aad); uint8_t tmp_iv[16]; memset(tmp_iv, 0, sizeof(tmp_iv)); if (memcmp(oid, OID_CHACHA20_POLY1305, oid_len) == 0) { @@ -380,7 +380,7 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : (uint16_t)mbedtls_md_get_size(md_info); + res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : (uint16_t)mbedtls_md_get_size(md_info); } else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { int iterations = 0; @@ -409,7 +409,7 @@ int cmd_cipher_sym() { if (r != 0) { 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 ? (uint16_t)apdu.ne : 32); } else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { size_t olen = 0; @@ -450,13 +450,13 @@ int cmd_cipher_sym() { kdata, aad_len, aad, - apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32, + apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_WRONG_DATA(); } - res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : 32; + res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32; } else if (memcmp(oid, OID_NIST_AES, 8) == 0) { if (oid_len != 9) { diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index c76ab8f..55880a2 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -116,7 +116,7 @@ int cmd_decrypt_asym() { } else if (p2 == ALGO_EC_DH_XKEK) { uint16_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, (uint16_t)apdu.nc, &pub_len); if (pub) { uint16_t t86_len = 0; const uint8_t *t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); @@ -149,7 +149,7 @@ int cmd_decrypt_asym() { res_APDU_size = 0; uint16_t ext_len = 0; const uint8_t *ext = NULL; - if ((ext = cvc_get_ext(apdu.data, apdu.nc, &ext_len)) == NULL) { + if ((ext = cvc_get_ext(apdu.data, (uint16_t)apdu.nc, &ext_len)) == NULL) { return SW_WRONG_DATA(); } uint8_t *p = NULL, *tag_data = NULL, *kdom_uid = NULL; diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index a666305..c27e2c9 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -33,7 +33,7 @@ int cmd_general_authenticate() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data + 2, apdu.nc - 2, &p, &tag, &tag_len, &tag_data)) { + while (walk_tlv(apdu.data + 2, (uint16_t)(apdu.nc - 2), &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before pubkey_len = tag_len + 1; diff --git a/src/hsm/cmd_pso.c b/src/hsm/cmd_pso.c index fe513a5..f2ee8e7 100644 --- a/src/hsm/cmd_pso.c +++ b/src/hsm/cmd_pso.c @@ -33,13 +33,13 @@ int cmd_pso() { return SW_REFERENCE_NOT_FOUND(); } if (apdu.data[0] != 0x7F || apdu.data[1] != 0x21) { - uint8_t tlv_len = 2 + format_tlv_len(apdu.nc, NULL); + uint8_t tlv_len = 2 + format_tlv_len((uint16_t)apdu.nc, NULL); memmove(apdu.data + tlv_len, apdu.data, apdu.nc); memcpy(apdu.data, "\x7F\x21", 2); - format_tlv_len(apdu.nc, apdu.data + 2); + format_tlv_len((uint16_t)apdu.nc, apdu.data + 2); apdu.nc += tlv_len; } - int r = cvc_verify(apdu.data, apdu.nc, current_puk->cvcert, current_puk->cvcert_len); + int r = cvc_verify(apdu.data, (uint16_t)apdu.nc, current_puk->cvcert, current_puk->cvcert_len); if (r != CCID_OK) { if (r == CCID_WRONG_DATA) { return SW_DATA_INVALID(); @@ -54,19 +54,19 @@ int cmd_pso() { file_t *ca_ef = search_dynamic_file(fid); if (!ca_ef) { ca_ef = file_new(fid); - flash_write_data_to_file(ca_ef, apdu.data, apdu.nc); + flash_write_data_to_file(ca_ef, apdu.data, (uint16_t)apdu.nc); if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef), false) != CCID_OK) { return SW_FILE_FULL(); } uint16_t chr_len = 0; - const uint8_t *chr = cvc_get_chr(apdu.data, apdu.nc, &chr_len); + const uint8_t *chr = cvc_get_chr(apdu.data, (uint16_t)apdu.nc, &chr_len); if (chr == NULL) { return SW_WRONG_DATA(); } uint16_t puk_len = 0, puk_bin_len = 0; - const uint8_t *puk = cvc_get_pub(apdu.data, apdu.nc, &puk_len), *puk_bin = NULL; + const uint8_t *puk = cvc_get_pub(apdu.data, (uint16_t)apdu.nc, &puk_len), *puk_bin = NULL; if (puk == NULL) { return SW_WRONG_DATA(); } @@ -82,7 +82,7 @@ int cmd_pso() { } } 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, (uint16_t)apdu.nc); mbedtls_ecp_group grp; mbedtls_ecp_group_init(&grp); if (mbedtls_ecp_group_load(&grp, ec_id) != 0) { diff --git a/src/hsm/cmd_puk_auth.c b/src/hsm/cmd_puk_auth.c index 2457003..a6ff158 100644 --- a/src/hsm/cmd_puk_auth.c +++ b/src/hsm/cmd_puk_auth.c @@ -61,7 +61,7 @@ int cmd_puk_auth() { return SW_MEMORY_FAILURE(); } } - flash_write_data_to_file(ef, apdu.data, apdu.nc); + flash_write_data_to_file(ef, apdu.data, (uint16_t)apdu.nc); low_flash_available(); } else { diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index 8afb737..db928ee 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -153,10 +153,10 @@ int cmd_signature() { return SW_EXEC_ERROR(); } uint8_t *hash = apdu.data; - uint16_t hash_len = apdu.nc; + uint16_t hash_len = (uint16_t)apdu.nc; if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached - uint16_t nc = apdu.nc; - if (pkcs1_strip_digest_info_prefix(&md, apdu.data, apdu.nc, apdu.data, + uint16_t nc = (uint16_t)apdu.nc; + if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data, &nc) != CCID_OK) { //gets the MD algo id and strips it off return SW_EXEC_ERROR(); } @@ -166,7 +166,7 @@ int cmd_signature() { //sc_asn1_print_tags(apdu.data, apdu.nc); uint16_t tout = 0, oid_len = 0; uint8_t *p = NULL, *oid = NULL; - if (asn1_find_tag(apdu.data, apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { uint16_t tout30 = 0; uint8_t *c30 = NULL; if (asn1_find_tag(p, tout, 0x30, &tout30, &c30) && tout30 > 0 && c30 != NULL) { diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index fbdc925..40c03a2 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -112,27 +112,27 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, u p += sizeof(oid_ecdsa); if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { //p - *p++ = 0x81; p += format_tlv_len(p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); + *p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); p += p_size; //order - *p++ = 0x82; p += format_tlv_len(o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); + *p++ = 0x82; p += format_tlv_len((uint16_t)o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); p += o_size; //G - *p++ = 0x83; p += format_tlv_len(g_size, p); memcpy(p, G_buf, g_size); p += g_size; + *p++ = 0x83; p += format_tlv_len((uint16_t)g_size, p); memcpy(p, G_buf, g_size); p += g_size; //Y - *p++ = 0x84; p += format_tlv_len(y_size, p); memcpy(p, Y_buf, y_size); p += y_size; + *p++ = 0x84; p += format_tlv_len((uint16_t)y_size, p); memcpy(p, Y_buf, y_size); p += y_size; } else { //p - *p++ = 0x81; p += format_tlv_len(p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); + *p++ = 0x81; p += format_tlv_len((uint16_t)p_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.P, p, p_size); p += p_size; //A if (a_size) { - *p++ = 0x82; p += format_tlv_len(a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, p, a_size); p += a_size; + *p++ = 0x82; p += format_tlv_len((uint16_t)a_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.A, p, a_size); p += a_size; } else { //mbedtls does not set point A for some curves if (pointA[ecdsa->grp.id] && ecdsa->grp.id < 6) { - *p++ = 0x82; p += format_tlv_len(p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); + *p++ = 0x82; p += format_tlv_len((uint16_t)p_size, p); memcpy(p, pointA[ecdsa->grp.id], p_size); p += p_size; } else { @@ -141,15 +141,15 @@ uint16_t asn1_cvc_public_key_ecdsa(mbedtls_ecdsa_context *ecdsa, uint8_t *buf, u } } //B - *p++ = 0x83; p += format_tlv_len(b_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.B, p, b_size); + *p++ = 0x83; p += format_tlv_len((uint16_t)b_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.B, p, b_size); p += b_size; //G - *p++ = 0x84; p += format_tlv_len(g_size, p); memcpy(p, G_buf, g_size); p += g_size; + *p++ = 0x84; p += format_tlv_len((uint16_t)g_size, p); memcpy(p, G_buf, g_size); p += g_size; //order - *p++ = 0x85; p += format_tlv_len(o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); + *p++ = 0x85; p += format_tlv_len((uint16_t)o_size, p); mbedtls_mpi_write_binary(&ecdsa->grp.N, p, o_size); p += o_size; //Y - *p++ = 0x86; p += format_tlv_len(y_size, p); memcpy(p, Y_buf, y_size); p += y_size; + *p++ = 0x86; p += format_tlv_len((uint16_t)y_size, p); memcpy(p, Y_buf, y_size); p += y_size; //cofactor *p++ = 0x87; p += format_tlv_len(c_size, p); *p++ = 1; @@ -185,7 +185,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, uint8_t *car = NULL, *chr = NULL; uint16_t lencar = 0, lenchr = 0; - if (asn1_find_tag(apdu.data, apdu.nc, 0x42, &lencar, + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x42, &lencar, &car) == false || lencar == 0 || car == NULL) { car = (uint8_t *) dev_name; lencar = dev_name_len; @@ -194,7 +194,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, lencar = (uint16_t)strlen((const char *)car); } } - if (asn1_find_tag(apdu.data, apdu.nc, 0x5f20, &lenchr, + if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x5f20, &lenchr, &chr) == false || lenchr == 0 || chr == NULL) { chr = (uint8_t *) dev_name; lenchr = dev_name_len; From 3ca23b932c503ce504ca0cacd59951ffcf536dae Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 9 Jan 2024 11:43:59 +0100 Subject: [PATCH 32/85] Fix Windows emulation build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 29837e5..caddf87 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 29837e56915bbb1e096ddddc6b89552f304970ff +Subproject commit caddf87c236a068f94e5283e10b9411d1cfa39e0 From c3b66773e8f82d3f5667771bb725fe98170df01c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 18:11:28 +0100 Subject: [PATCH 33/85] Use new asn1 structs. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 6 +- pico-keys-sdk | 2 +- src/hsm/cmd_bip_slip.c | 5 +- src/hsm/cmd_cipher_sym.c | 241 ++++++++++++++--------------- src/hsm/cmd_decrypt_asym.c | 26 ++-- src/hsm/cmd_general_authenticate.c | 4 +- src/hsm/cmd_initialize.c | 4 +- src/hsm/cmd_keypair_gen.c | 78 ++++------ src/hsm/cmd_mse.c | 4 +- src/hsm/cmd_signature.c | 34 ++-- src/hsm/cmd_update_ef.c | 4 +- src/hsm/cvc.c | 45 +++--- src/hsm/sc_hsm.c | 40 ++--- 13 files changed, 244 insertions(+), 249 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 309bca2..ee5157b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,7 @@ target_compile_options(pico_hsm PUBLIC -Wall ) if (NOT MSVC) - target_compile_options(pico_hsm PUBLIC + target_compile_options(pico_hsm PUBLIC -Werror ) endif() @@ -106,10 +106,10 @@ target_link_options(pico_hsm PUBLIC -Wl,-dead_strip ) elseif(MSVC) - target_compile_options(pico_hsm PUBLIC + target_compile_options(pico_hsm PUBLIC -WX ) - + target_link_libraries(pico_hsm PUBLIC wsock32 ws2_32 Bcrypt) else() target_link_options(pico_hsm PUBLIC diff --git a/pico-keys-sdk b/pico-keys-sdk index caddf87..e055d4c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit caddf87c236a068f94e5283e10b9411d1cfa39e0 +Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13 diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 13db1f2..41d27d6 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -160,7 +160,10 @@ int node_derive_path(const uint8_t *path, int r = 0; memset(last_node, 0, 4); memset(fingerprint, 0, 4); - for (; walk_tlv(path, path_len, &p, &tag, &tag_len, &tag_data); node++) { + + asn1_ctx_t ctxi; + asn1_ctx_init((uint8_t *)path, path_len, &ctxi); + for (; walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data); node++) { if (tag == 0x02) { if ((node == 0 && tag_len != 1) || (node != 0 && tag_len != 4)) { return CCID_WRONG_DATA; diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index c816c63..6de1409 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -269,20 +269,19 @@ int cmd_cipher_sym() { res_APDU_size = (uint16_t)apdu.nc; } else if (algo == ALGO_EXT_CIPHER_ENCRYPT || algo == ALGO_EXT_CIPHER_DECRYPT) { - uint16_t oid_len = 0, aad_len = 0, iv_len = 0, enc_len = 0; - uint8_t *oid = NULL, *aad = NULL, *iv = NULL, *enc = NULL; - if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x6, &oid_len, - &oid) || oid_len == 0 || oid == NULL) { + asn1_ctx_t ctxi, oid = {0}, enc = {0}, iv = {0}, aad = {0}; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (!asn1_find_tag(&ctxi, 0x6, &oid) || asn1_len(&oid) == 0) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x81, &enc_len, &enc); - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x82, &iv_len, &iv); - asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x83, &aad_len, &aad); + asn1_find_tag(&ctxi, 0x81, &enc); + asn1_find_tag(&ctxi, 0x82, &iv); + asn1_find_tag(&ctxi, 0x83, &aad); uint8_t tmp_iv[16]; memset(tmp_iv, 0, sizeof(tmp_iv)); - if (memcmp(oid, OID_CHACHA20_POLY1305, oid_len) == 0) { - if (algo == ALGO_EXT_CIPHER_DECRYPT && enc_len < 16) { + if (memcmp(oid.data, OID_CHACHA20_POLY1305, oid.len) == 0) { + if (algo == ALGO_EXT_CIPHER_DECRYPT && enc.len < 16) { mbedtls_platform_zeroize(kdata, sizeof(kdata)); return SW_WRONG_DATA(); } @@ -292,22 +291,22 @@ int cmd_cipher_sym() { mbedtls_chachapoly_setkey(&ctx, kdata); if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_chachapoly_encrypt_and_tag(&ctx, - enc_len, - iv ? iv : tmp_iv, - aad, - aad_len, - enc, + enc.len, + asn1_len(&iv) > 0 ? iv.data : tmp_iv, + aad.data, + aad.len, + enc.data, res_APDU, - res_APDU + enc_len); + res_APDU + enc.len); } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_chachapoly_auth_decrypt(&ctx, - enc_len - 16, - iv ? iv : tmp_iv, - aad, - aad_len, - enc + enc_len - 16, - enc, + enc.len - 16, + asn1_len(&iv) > 0 ? iv.data : tmp_iv, + aad.data, + aad.len, + enc.data + enc.len - 16, + enc.data, res_APDU); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); @@ -319,60 +318,60 @@ int cmd_cipher_sym() { return SW_EXEC_ERROR(); } if (algo == ALGO_EXT_CIPHER_ENCRYPT) { - res_APDU_size = enc_len + 16; + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } } - else if (memcmp(oid, OID_DIGEST, 7) == 0) { + else if (memcmp(oid.data, OID_DIGEST, 7) == 0) { const mbedtls_md_info_t *md_info = NULL; - if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) { + if (memcmp(oid.data, OID_HMAC_SHA1, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); } - else if (memcmp(oid, OID_HMAC_SHA224, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA224, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); } - else if (memcmp(oid, OID_HMAC_SHA256, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA256, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); } - else if (memcmp(oid, OID_HMAC_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA384, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); } - else if (memcmp(oid, OID_HMAC_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HMAC_SHA512, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } if (md_info == NULL) { return SW_WRONG_DATA(); } - int r = mbedtls_md_hmac(md_info, kdata, key_size, enc, enc_len, res_APDU); + int r = mbedtls_md_hmac(md_info, kdata, key_size, enc.data, enc.len, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_EXEC_ERROR(); } res_APDU_size = md_info->size; } - else if (memcmp(oid, OID_HKDF_SHA256, - oid_len) == 0 || - memcmp(oid, OID_HKDF_SHA384, - oid_len) == 0 || memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA256, + oid.len) == 0 || + memcmp(oid.data, OID_HKDF_SHA384, + oid.len) == 0 || memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) { const mbedtls_md_info_t *md_info = NULL; - if (memcmp(oid, OID_HKDF_SHA256, oid_len) == 0) { + if (memcmp(oid.data, OID_HKDF_SHA256, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); } - else if (memcmp(oid, OID_HKDF_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA384, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); } - else if (memcmp(oid, OID_HKDF_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, OID_HKDF_SHA512, oid.len) == 0) { md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); } int r = mbedtls_hkdf(md_info, - iv, - iv_len, + iv.data, + iv.len, kdata, key_size, - enc, - enc_len, + enc.data, + enc.len, res_APDU, apdu.ne > 0 && apdu.ne < 65536 ? apdu.ne : mbedtls_md_get_size(md_info)); @@ -382,12 +381,12 @@ int cmd_cipher_sym() { } res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : (uint16_t)mbedtls_md_get_size(md_info); } - else if (memcmp(oid, OID_PKCS5_PBKDF2, oid_len) == 0) { + else if (memcmp(oid.data, OID_PKCS5_PBKDF2, oid.len) == 0) { int iterations = 0; uint16_t keylen = 0; mbedtls_asn1_buf salt, params = - { .p = enc, .len = enc_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; + { .p = enc.data, .len = enc.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) }; mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; int r = pkcs5_parse_pbkdf2_params(¶ms, &salt, &iterations, &keylen, &md_type); @@ -411,16 +410,16 @@ int cmd_cipher_sym() { } res_APDU_size = keylen ? keylen : (apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32); } - else if (memcmp(oid, OID_PKCS5_PBES2, oid_len) == 0) { + else if (memcmp(oid.data, OID_PKCS5_PBES2, oid.len) == 0) { size_t olen = 0; mbedtls_asn1_buf params = - {.p = aad, .len = aad_len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; + {.p = aad.data, .len = aad.len, .tag = (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)}; int r = mbedtls_pkcs5_pbes2_ext(¶ms, algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_PKCS5_ENCRYPT : MBEDTLS_PKCS5_DECRYPT, kdata, key_size, - enc, - enc_len, + enc.data, + enc.len, res_APDU, 4096, &olen); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { @@ -428,28 +427,28 @@ int cmd_cipher_sym() { } res_APDU_size = (uint16_t)olen; } - else if (memcmp(oid, OID_KDF_X963, oid_len) == 0) { + else if (memcmp(oid.data, OID_KDF_X963, oid.len) == 0) { mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; - if (memcmp(enc, OID_HMAC_SHA1, enc_len) == 0) { + if (memcmp(enc.data, OID_HMAC_SHA1, enc.len) == 0) { md_type = MBEDTLS_MD_SHA1; } - else if (memcmp(enc, OID_HMAC_SHA224, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA224, enc.len) == 0) { md_type = MBEDTLS_MD_SHA224; } - else if (memcmp(enc, OID_HMAC_SHA256, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA256, enc.len) == 0) { md_type = MBEDTLS_MD_SHA256; } - else if (memcmp(enc, OID_HMAC_SHA384, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA384, enc.len) == 0) { md_type = MBEDTLS_MD_SHA384; } - else if (memcmp(enc, OID_HMAC_SHA512, enc_len) == 0) { + else if (memcmp(enc.data, OID_HMAC_SHA512, enc.len) == 0) { md_type = MBEDTLS_MD_SHA512; } int r = mbedtls_ansi_x963_kdf(md_type, key_size, kdata, - aad_len, - aad, + aad.len, + aad.data, apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32, res_APDU); mbedtls_platform_zeroize(kdata, sizeof(kdata)); @@ -458,11 +457,11 @@ int cmd_cipher_sym() { } res_APDU_size = apdu.ne > 0 && apdu.ne < 65536 ? (uint16_t)apdu.ne : 32; } - else if (memcmp(oid, OID_NIST_AES, 8) == 0) { - if (oid_len != 9) { + else if (memcmp(oid.data, OID_NIST_AES, 8) == 0) { + if (oid.len != 9) { return SW_WRONG_DATA(); } - uint8_t aes_algo = oid[8], + uint8_t aes_algo = oid.data[8], mode = (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); if ((aes_algo >= 0x01 && aes_algo <= 0x09 && key_size != 16) || @@ -473,9 +472,9 @@ int cmd_cipher_sym() { mbedtls_aes_context ctx; int r = 0; mbedtls_aes_init(&ctx); - if (iv == NULL || iv_len == 0) { - iv = tmp_iv; - iv_len = sizeof(tmp_iv); + if (asn1_len(&iv) == 0) { + iv.data = tmp_iv; + iv.len = sizeof(tmp_iv); } if (aes_algo == 0x01 || aes_algo == 0x15 || aes_algo == 0x29) { /* ECB */ if (algo == ALGO_EXT_CIPHER_ENCRYPT) { @@ -485,12 +484,12 @@ int cmd_cipher_sym() { r = mbedtls_aes_setkey_dec(&ctx, kdata, key_size * 8); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ecb(&ctx, mode, enc, res_APDU); + r = mbedtls_aes_crypt_ecb(&ctx, mode, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = MIN(enc_len, 16); // ECB operates with 16-byte blocks + res_APDU_size = MIN(enc.len, 16); // ECB operates with 16-byte blocks } else if (aes_algo == 0x02 || aes_algo == 0x16 || aes_algo == 0x2A) { /* CBC */ if (algo == ALGO_EXT_CIPHER_ENCRYPT) { @@ -503,34 +502,34 @@ int cmd_cipher_sym() { return SW_EXEC_ERROR(); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_cbc(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cbc(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x03 || aes_algo == 0x17 || aes_algo == 0x2B) { /* OFB */ size_t iv_off = 0; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ofb(&ctx, enc_len, &iv_off, iv, enc, res_APDU); + r = mbedtls_aes_crypt_ofb(&ctx, enc.len, &iv_off, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x04 || aes_algo == 0x18 || aes_algo == 0x2C) { /* CFB */ size_t iv_off = 0; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_cfb128(&ctx, mode, enc_len, &iv_off, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cfb128(&ctx, mode, enc.len, &iv_off, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x06 || aes_algo == 0x1A || aes_algo == 0x2E) { /* GCM */ mbedtls_aes_free(&ctx); // No AES ctx used @@ -541,29 +540,29 @@ int cmd_cipher_sym() { if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_gcm_crypt_and_tag(&gctx, MBEDTLS_GCM_ENCRYPT, - enc_len, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, 16, - res_APDU + enc_len); - res_APDU_size = enc_len + 16; + res_APDU + enc.len); + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_gcm_auth_decrypt(&gctx, - enc_len - 16, - iv, - iv_len, - aad, - aad_len, - enc + enc_len - 16, + enc.len - 16, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data + enc.len - 16, 16, - enc, + enc.data, res_APDU); - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } mbedtls_gcm_free(&gctx); if (r != 0) { @@ -575,12 +574,12 @@ int cmd_cipher_sym() { uint8_t stream_block[16]; r = mbedtls_aes_setkey_enc(&ctx, kdata, key_size * 8); mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_ctr(&ctx, enc_len, &iv_off, iv, stream_block, enc, res_APDU); + r = mbedtls_aes_crypt_ctr(&ctx, enc.len, &iv_off, iv.data, stream_block, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } else if (aes_algo == 0x07 || aes_algo == 0x1B || aes_algo == 0x2F) { /* CCM */ mbedtls_aes_free(&ctx); // No AES ctx used @@ -590,35 +589,35 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - if (iv_len == 16) { - iv_len = 12; + if (iv.len == 16) { + iv.len = 12; } mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_ccm_encrypt_and_tag(&gctx, - enc_len, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, - res_APDU + enc_len, + res_APDU + enc.len, 16); - res_APDU_size = enc_len + 16; + res_APDU_size = enc.len + 16; } else if (algo == ALGO_EXT_CIPHER_DECRYPT) { r = mbedtls_ccm_auth_decrypt(&gctx, - enc_len - 16, - iv, - iv_len, - aad, - aad_len, - enc, + enc.len - 16, + iv.data, + iv.len, + aad.data, + aad.len, + enc.data, res_APDU, - enc + enc_len - 16, + enc.data + enc.len - 16, 16); - res_APDU_size = enc_len - 16; + res_APDU_size = enc.len - 16; } mbedtls_ccm_free(&gctx); if (r != 0) { @@ -626,18 +625,18 @@ int cmd_cipher_sym() { } } } - else if (memcmp(oid, OID_IEEE_ALG, 8) == 0) { - if (oid_len != 9) { + else if (memcmp(oid.data, OID_IEEE_ALG, 8) == 0) { + if (oid.len != 9) { return SW_WRONG_DATA(); } - uint8_t aes_algo = oid[8], + uint8_t aes_algo = oid.data[8], mode = (algo == ALGO_EXT_CIPHER_ENCRYPT ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT); int r = 0; memset(tmp_iv, 0, sizeof(tmp_iv)); - if (iv == NULL || iv_len == 0) { - iv = tmp_iv; - iv_len = sizeof(tmp_iv); + if (asn1_len(&iv) == 0) { + iv.data = tmp_iv; + iv.len = sizeof(tmp_iv); } if ((aes_algo == 0x01 && key_size != 32) || (aes_algo == 0x02 && key_size != 64)) { return SW_WRONG_DATA(); @@ -651,14 +650,14 @@ int cmd_cipher_sym() { r = mbedtls_aes_xts_setkey_dec(&ctx, kdata, key_size * 8); } mbedtls_platform_zeroize(kdata, sizeof(kdata)); - r = mbedtls_aes_crypt_xts(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_xts(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_xts_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; } - else if (memcmp(oid, OID_HD, 11) == 0) { + else if (memcmp(oid.data, OID_HD, 11) == 0) { mbedtls_aes_context ctx; int r = 0; uint8_t mode = @@ -673,16 +672,16 @@ int cmd_cipher_sym() { r = mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA512), kdata, key_size, - aad, - aad_len, + aad.data, + aad.len, secret); mbedtls_platform_zeroize(kdata, sizeof(kdata)); if (r != 0) { return SW_EXEC_ERROR(); } - if (iv == tmp_iv || iv_len == 0) { - iv = secret + 32; - iv_len = 16; + if (iv.data == tmp_iv || iv.len == 0) { + iv.data = secret + 32; + iv.len = 16; } if (algo == ALGO_EXT_CIPHER_ENCRYPT) { r = mbedtls_aes_setkey_enc(&ctx, secret, key_size * 8); @@ -693,12 +692,12 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - r = mbedtls_aes_crypt_cbc(&ctx, mode, enc_len, iv, enc, res_APDU); + r = mbedtls_aes_crypt_cbc(&ctx, mode, enc.len, iv.data, enc.data, res_APDU); mbedtls_aes_free(&ctx); if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = enc_len; + res_APDU_size = enc.len; mbedtls_ecdsa_free(&hd_context); hd_keytype = 0; } diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index 55880a2..e68853e 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -152,34 +152,32 @@ int cmd_decrypt_asym() { if ((ext = cvc_get_ext(apdu.data, (uint16_t)apdu.nc, &ext_len)) == NULL) { return SW_WRONG_DATA(); } - uint8_t *p = NULL, *tag_data = NULL, *kdom_uid = NULL; + uint8_t *p = NULL; uint16_t tag = 0; - uint16_t tag_len = 0, kdom_uid_len = 0; - while (walk_tlv(ext, ext_len, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi, ctxo = { 0 }, kdom_uid = { 0 }; + asn1_ctx_init((uint8_t *)ext, ext_len, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &ctxo.len, &ctxo.data)) { if (tag == 0x73) { - uint16_t oid_len = 0; - uint8_t *oid_data = NULL; - if (asn1_find_tag(tag_data, tag_len, 0x6, &oid_len, - &oid_data) == true && - oid_len == strlen(OID_ID_KEY_DOMAIN_UID) && - memcmp(oid_data, OID_ID_KEY_DOMAIN_UID, + asn1_ctx_t oid = {0}; + if (asn1_find_tag(&ctxo, 0x6, &oid) == true && + oid.len == strlen(OID_ID_KEY_DOMAIN_UID) && + memcmp(oid.data, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)) == 0) { - if (asn1_find_tag(tag_data, tag_len, 0x80, &kdom_uid_len, - &kdom_uid) == false) { + if (asn1_find_tag(&ctxo, 0x80, &kdom_uid) == false) { return SW_WRONG_DATA(); } break; } } } - if (kdom_uid_len == 0 || kdom_uid == NULL) { + if (asn1_len(&kdom_uid) == 0) { return SW_WRONG_DATA(); } for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) { file_t *tf = search_dynamic_file(EF_XKEK + n); if (tf) { - if (file_get_size(tf) == kdom_uid_len && - memcmp(file_get_data(tf), kdom_uid, kdom_uid_len) == 0) { + if (file_get_size(tf) == kdom_uid.len && + memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) { file_new(EF_DKEK + n); if (store_dkek_key(n, res_APDU + 1) != CCID_OK) { return SW_EXEC_ERROR(); diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index c27e2c9..64c5860 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -33,7 +33,9 @@ int cmd_general_authenticate() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data + 2, (uint16_t)(apdu.nc - 2), &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data + 2, (uint16_t)(apdu.nc - 2), &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { pubkey = tag_data - 1; //mbedtls ecdh starts reading one pos before pubkey_len = tag_len + 1; diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index 33c3b81..cf19cb3 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -49,7 +49,9 @@ int cmd_initialize() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { //options file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); flash_write_data_to_file(tf, tag_data, tag_len); diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 7b3b1a3..6a88b85 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -31,31 +31,21 @@ int cmd_keypair_gen() { } int ret = 0; - uint16_t tout = 0; //sc_asn1_print_tags(apdu.data, apdu.nc); - uint8_t *p = NULL; //DEBUG_DATA(apdu.data,apdu.nc); - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x7f49, &tout, &p) && tout > 0 && p != NULL) { - uint16_t oid_len = 0; - uint8_t *oid = NULL; - if (asn1_find_tag(p, tout, 0x6, &oid_len, &oid) && oid_len > 0 && oid != NULL) { - if (memcmp(oid, OID_ID_TA_RSA_V1_5_SHA_256, oid_len) == 0) { //RSA - uint16_t ex_len = 3, ks_len = 2; - uint8_t *ex = NULL, *ks = NULL; + asn1_ctx_t ctxi, ctxo = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x7f49, &ctxo) && asn1_len(&ctxo) > 0) { + asn1_ctx_t oid = { 0 }; + if (asn1_find_tag(&ctxo, 0x6, &oid) && asn1_len(&oid) > 0) { + if (memcmp(oid.data, OID_ID_TA_RSA_V1_5_SHA_256, oid.len) == 0) { //RSA + asn1_ctx_t ex = { 0 }, ks = { 0 }; uint32_t exponent = 65537, key_size = 2048; - if (asn1_find_tag(p, tout, 0x82, &ex_len, &ex) && ex_len > 0 && ex != NULL) { - uint8_t *dt = ex; - exponent = 0; - for (uint16_t i = 0; i < ex_len; i++) { - exponent = (exponent << 8) | *dt++; - } + if (asn1_find_tag(&ctxo, 0x82, &ex) && asn1_len(&ex) > 0) { + exponent = asn1_get_uint(&ex); } - if (asn1_find_tag(p, tout, 0x2, &ks_len, &ks) && ks_len > 0 && ks != NULL) { - uint8_t *dt = ks; - key_size = 0; - for (uint16_t i = 0; i < ks_len; i++) { - key_size = (key_size << 8) | *dt++; - } + if (asn1_find_tag(&ctxo, 0x2, &ks) && asn1_len(&ks) > 0) { + key_size = asn1_get_uint(&ks); } printf("KEYPAIR RSA %lu (%lx)\r\n", (unsigned long) key_size, @@ -79,13 +69,12 @@ int cmd_keypair_gen() { } mbedtls_rsa_free(&rsa); } - else if (memcmp(oid, OID_ID_TA_ECDSA_SHA_256, MIN(oid_len, 10)) == 0) { //ECC - uint16_t prime_len; - uint8_t *prime = NULL; - if (asn1_find_tag(p, tout, 0x81, &prime_len, &prime) != true) { + else if (memcmp(oid.data, OID_ID_TA_ECDSA_SHA_256, MIN(oid.len, 10)) == 0) { //ECC + asn1_ctx_t prime = { 0 }; + if (asn1_find_tag(&ctxo, 0x81, &prime) != true) { return SW_WRONG_DATA(); } - mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime, prime_len); + mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime.data, prime.len); printf("KEYPAIR ECC %d\r\n", ec_id); if (ec_id == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); @@ -98,30 +87,27 @@ int cmd_keypair_gen() { mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - uint16_t l91 = 0, ext_len = 0; - uint8_t *p91 = NULL, *ext = NULL; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x91, &l91, &p91) && p91 != NULL && l91 > 0) { - for (size_t n = 0; n < l91; n++) { - if (p91[n] == ALGO_EC_DH_XKEK) { - uint16_t l92 = 0; - uint8_t *p92 = NULL; - if (!asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x92, &l92, - &p92) || p92 == NULL || l92 == 0) { + asn1_ctx_t a91 = { 0 }, ext = { 0 }; + if (asn1_find_tag(&ctxi, 0x91, &a91) && asn1_len(&a91) > 0) { + for (size_t n = 0; n < a91.len; n++) { + if (a91.data[n] == ALGO_EC_DH_XKEK) { + asn1_ctx_t a92 = {0}; + if (!asn1_find_tag(&ctxi, 0x92, &a92) || asn1_len(&a92) == 0) { return SW_WRONG_DATA(); } - if (p92[0] > MAX_KEY_DOMAINS) { + if (a92.data[0] > MAX_KEY_DOMAINS) { return SW_WRONG_DATA(); } - file_t *tf_xkek = search_dynamic_file(EF_XKEK + p92[0]); + file_t *tf_xkek = search_dynamic_file(EF_XKEK + a92.data[0]); if (!tf_xkek) { return SW_WRONG_DATA(); } - ext_len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( + ext.len = 2 + 2 + (uint16_t)strlen(OID_ID_KEY_DOMAIN_UID) + 2 + file_get_size( tf_xkek); - ext = (uint8_t *) calloc(1, ext_len); - uint8_t *pe = ext; + ext.data = (uint8_t *) calloc(1, ext.len); + uint8_t *pe = ext.data; *pe++ = 0x73; - *pe++ = (uint8_t)ext_len - 2; + *pe++ = (uint8_t)ext.len - 2; *pe++ = 0x6; *pe++ = (uint8_t)strlen(OID_ID_KEY_DOMAIN_UID); memcpy(pe, OID_ID_KEY_DOMAIN_UID, strlen(OID_ID_KEY_DOMAIN_UID)); @@ -133,15 +119,15 @@ int cmd_keypair_gen() { } } if ((res_APDU_size = - (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext, ext_len)) == 0) { - if (ext) { - free(ext); + (uint16_t)asn1_cvc_aut(&ecdsa, PICO_KEYS_KEY_EC, res_APDU, 4096, ext.data, ext.len)) == 0) { + if (ext.data) { + free(ext.data); } mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); } - if (ext) { - free(ext); + if (ext.data) { + free(ext.data); } ret = store_keys(&ecdsa, PICO_KEYS_KEY_EC, key_id); mbedtls_ecdsa_free(&ecdsa); diff --git a/src/hsm/cmd_mse.c b/src/hsm/cmd_mse.c index e3ac568..f930494 100644 --- a/src/hsm/cmd_mse.c +++ b/src/hsm/cmd_mse.c @@ -34,7 +34,9 @@ int cmd_mse() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { if (p2 == 0xA4) { if (tag_len == 10 && diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index db928ee..b75eedb 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -152,8 +152,7 @@ int cmd_signature() { } return SW_EXEC_ERROR(); } - uint8_t *hash = apdu.data; - uint16_t hash_len = (uint16_t)apdu.nc; + asn1_ctx_t hash = {.len = (uint16_t)apdu.nc, .data = apdu.data}; if (p2 == ALGO_RSA_PKCS1) { //DigestInfo attached uint16_t nc = (uint16_t)apdu.nc; if (pkcs1_strip_digest_info_prefix(&md, apdu.data, (uint16_t)apdu.nc, apdu.data, @@ -164,35 +163,34 @@ int cmd_signature() { } else { //sc_asn1_print_tags(apdu.data, apdu.nc); - uint16_t tout = 0, oid_len = 0; - uint8_t *p = NULL, *oid = NULL; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x30, &tout, &p) && tout > 0 && p != NULL) { - uint16_t tout30 = 0; - uint8_t *c30 = NULL; - if (asn1_find_tag(p, tout, 0x30, &tout30, &c30) && tout30 > 0 && c30 != NULL) { - asn1_find_tag(c30, tout30, 0x6, &oid_len, &oid); + asn1_ctx_t ctxi, ctxo = { 0 }, oid = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x30, &ctxo) && asn1_len(&ctxo) > 0) { + asn1_ctx_t a30 = { 0 }; + if (asn1_find_tag(&ctxo, 0x30, &a30) && asn1_len(&a30) > 0) { + asn1_find_tag(&a30, 0x6, &oid); } - asn1_find_tag(p, tout, 0x4, &hash_len, &hash); + asn1_find_tag(&ctxo, 0x4, &hash); } - if (oid && oid_len > 0) { - if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA1, oid_len) == 0) { + if (asn1_len(&oid)) { + if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA1, oid.len) == 0) { md = MBEDTLS_MD_SHA1; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA224, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA224, oid.len) == 0) { md = MBEDTLS_MD_SHA224; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA256, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA256, oid.len) == 0) { md = MBEDTLS_MD_SHA256; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA384, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA384, oid.len) == 0) { md = MBEDTLS_MD_SHA384; } - else if (memcmp(oid, MBEDTLS_OID_DIGEST_ALG_SHA512, oid_len) == 0) { + else if (memcmp(oid.data, MBEDTLS_OID_DIGEST_ALG_SHA512, oid.len) == 0) { md = MBEDTLS_MD_SHA512; } } if (p2 >= ALGO_RSA_PSS && p2 <= ALGO_RSA_PSS_SHA512) { - if (p2 == ALGO_RSA_PSS && !oid) { + if (p2 == ALGO_RSA_PSS && asn1_len(&oid) == 0) { if (apdu.nc == 20) { //default is sha1 md = MBEDTLS_MD_SHA1; } @@ -220,7 +218,7 @@ int cmd_signature() { } else { uint8_t *signature = (uint8_t *) calloc(key_size, sizeof(uint8_t)); - r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash_len, hash, signature); + r = mbedtls_rsa_pkcs1_sign(&ctx, random_gen, NULL, md, hash.len, hash.data, signature); memcpy(res_APDU, signature, key_size); free(signature); } diff --git a/src/hsm/cmd_update_ef.c b/src/hsm/cmd_update_ef.c index 9fae86a..4b6ec18 100644 --- a/src/hsm/cmd_update_ef.c +++ b/src/hsm/cmd_update_ef.c @@ -49,7 +49,9 @@ int cmd_update_ef() { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; uint16_t tag_len = 0; - while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x54) { //ofset tag for (size_t i = 1; i <= tag_len; i++) { offset |= (*tag_data++ << (8 * (tag_len - i))); diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index 40c03a2..fcc722c 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -182,28 +182,25 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, valid_size = asn1_len_tag(0x5f24, 6) + asn1_len_tag(0x5f25, 6); } - uint8_t *car = NULL, *chr = NULL; - uint16_t lencar = 0, lenchr = 0; - - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x42, &lencar, - &car) == false || lencar == 0 || car == NULL) { - car = (uint8_t *) dev_name; - lencar = dev_name_len; + asn1_ctx_t ctxi, car = {0}, chr = {0}; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); + if (asn1_find_tag(&ctxi, 0x42, &car) == false || asn1_len(&car) == 0) { + car.data = (uint8_t *) dev_name; + car.len = dev_name_len; if (dev_name == NULL) { - car = (uint8_t *)"ESPICOHSMTR00001"; - lencar = (uint16_t)strlen((const char *)car); + car.data = (uint8_t *)"ESPICOHSMTR00001"; + car.len = (uint16_t)strlen((const char *)car.data); } } - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x5f20, &lenchr, - &chr) == false || lenchr == 0 || chr == NULL) { - chr = (uint8_t *) dev_name; - lenchr = dev_name_len; - if (chr == NULL) { - chr = car; - lenchr = lencar; + if (asn1_find_tag(&ctxi, 0x5f20, &chr) == false || asn1_len(&chr) == 0) { + chr.data = (uint8_t *) dev_name; + chr.len = dev_name_len; + if (chr.data == NULL) { + chr.data = car.data; + chr.len = car.len; } } - uint16_t car_size = asn1_len_tag(0x42, lencar), chr_size = asn1_len_tag(0x5f20, lenchr); + uint16_t car_size = asn1_len_tag(0x42, car.len), chr_size = asn1_len_tag(0x5f20, chr.len); uint16_t tot_len = asn1_len_tag(0x7f4e, cpi_size + car_size + pubkey_size + chr_size + ext_size + role_size + valid_size); @@ -219,7 +216,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, //cpi *p++ = 0x5f; *p++ = 0x29; *p++ = 1; *p++ = 0; //car - *p++ = 0x42; p += format_tlv_len(lencar, p); memcpy(p, car, lencar); p += lencar; + *p++ = 0x42; p += format_tlv_len(car.len, p); memcpy(p, car.data, car.len); p += car.len; //pubkey if (key_type & PICO_KEYS_KEY_RSA) { p += asn1_cvc_public_key_rsa(rsa_ecdsa, p, pubkey_size); @@ -228,7 +225,7 @@ uint16_t asn1_cvc_cert_body(void *rsa_ecdsa, p += asn1_cvc_public_key_ecdsa(rsa_ecdsa, p, pubkey_size); } //chr - *p++ = 0x5f; *p++ = 0x20; p += format_tlv_len(lenchr, p); memcpy(p, chr, lenchr); p += lenchr; + *p++ = 0x5f; *p++ = 0x20; p += format_tlv_len(chr.len, p); memcpy(p, chr.data, chr.len); p += chr.len; if (full) { *p++ = 0x7f; *p++ = 0x4c; @@ -580,14 +577,16 @@ uint16_t asn1_build_prkd_aes(const uint8_t *label, } const uint8_t *cvc_get_field(const uint8_t *data, uint16_t len, uint16_t *olen, uint16_t tag) { - uint8_t *rdata = NULL; - if (data == NULL || len == 0) { + asn1_ctx_t ctxi, ctxo = { 0 }; + asn1_ctx_init((uint8_t *)data, len, &ctxi); + if (asn1_len(&ctxi) == 0) { return NULL; } - if (asn1_find_tag(data, len, tag, olen, &rdata) == false) { + if (asn1_find_tag(&ctxi, tag, &ctxo) == false) { return NULL; } - return rdata; + *olen = ctxo.len; + return ctxo.data; } const uint8_t *cvc_get_body(const uint8_t *data, uint16_t len, uint16_t *olen) { diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 23cdfd2..70f7534 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -52,6 +52,7 @@ static int sc_hsm_unload(); extern int cmd_select(); extern void select_file(file_t *pe); extern int cmd_list_keys(); + extern int cmd_read_binary(); extern int cmd_verify(); extern int cmd_reset_retry(); @@ -230,7 +231,9 @@ void reset_puk_store() { if (fterm) { uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data; uint16_t fterm_data_len = file_get_size(fterm); - while (walk_tlv(fterm_data, fterm_data_len, &p, NULL, NULL, NULL)) { + asn1_ctx_t ctxi; + asn1_ctx_init(fterm_data, fterm_data_len, &ctxi); + while (walk_tlv(&ctxi, &p, NULL, NULL, NULL)) { add_cert_puk_store(pq, (uint16_t)(p - pq), false); pq = p; } @@ -424,7 +427,9 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, uint16_t *tag_len) { if (meta_size > 0 && meta_data != NULL) { uint16_t tag = 0x0; uint8_t *tag_data = NULL, *p = NULL; - while (walk_tlv(meta_data, meta_size, &p, &tag, tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(meta_data, meta_size, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, tag_len, &tag_data)) { if (tag == meta_tag) { return tag_data; } @@ -469,7 +474,9 @@ uint32_t decrement_key_counter(file_t *fkey) { uint8_t *cmeta = (uint8_t *) calloc(1, meta_size); /* We cannot modify meta_data, as it comes from flash memory. It must be cpied to an aux buffer */ memcpy(cmeta, meta_data, meta_size); - while (walk_tlv(cmeta, meta_size, &p, &tag, &tag_len, &tag_data)) { + asn1_ctx_t ctxi; + asn1_ctx_init(meta_data, meta_size, &ctxi); + while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x90) { // ofset tag uint32_t val = (tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3]; @@ -559,34 +566,31 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { } int find_and_store_meta_key(uint8_t key_id) { - uint16_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0; - uint8_t *pt[4] = { NULL, NULL, NULL, NULL }; + uint16_t meta_size = 0; uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE }; + asn1_ctx_t ctxi, ctxo[4] = { 0 }; + asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); for (uint16_t t = 0; t < 4; t++) { - uint8_t *ptt = NULL; - uint16_t ltt = 0; - if (asn1_find_tag(apdu.data, (uint16_t)apdu.nc, 0x90 + t, <t, &ptt) && ptt != NULL && ltt > 0) { - lt[t] = ltt; - pt[t] = ptt; - meta_size += asn1_len_tag(0x90 + t, lt[t]); + if (asn1_find_tag(&ctxi, 0x90 + t, &ctxo[t]) && asn1_len(&ctxo[t]) > 0) { + meta_size += asn1_len_tag(0x90 + t, ctxo[t].len); } } - if (lt[0] == 0 && pt[0] == NULL) { + if (asn1_len(&ctxo[0]) == 0) { uint16_t opts = get_device_options(); if (opts & HSM_OPT_KEY_COUNTER_ALL) { - lt[0] = 4; - pt[0] = t90; + ctxo[0].len = 4; + ctxo[0].data = t90; meta_size += 6; } } if (meta_size) { uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta; for (uint8_t t = 0; t < 4; t++) { - if (lt[t] > 0 && pt[t] != NULL) { + if (asn1_len(&ctxo[t]) > 0) { *m++ = 0x90 + t; - m += format_tlv_len(lt[t], m); - memcpy(m, pt[t], lt[t]); - m += lt[t]; + m += format_tlv_len(ctxo[t].len, m); + memcpy(m, ctxo[t].data, ctxo[t].len); + m += ctxo[t].len; } } int r = meta_add((KEY_PREFIX << 8) | key_id, meta, (uint16_t)meta_size); From ac781c1db6c8111215b4063f8d3d5c3ad1c58b17 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 13 Mar 2024 21:21:37 +0100 Subject: [PATCH 34/85] Fix asn1 struct initialization. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index e055d4c..151ae5f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit e055d4cfc9df1a41585ac83d484b903088f3db13 +Subproject commit 151ae5fae4c5815042fce5d5cbcc06d76561dc9c From d6456b4ddec23e73feea69be44432a27059d3c0b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 8 Apr 2024 19:41:39 +0200 Subject: [PATCH 35/85] First attempt to add support to ESP32. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 19 ++++++++++++---- pico-keys-sdk | 2 +- sdkconfig.defaults | 18 +++++++++++++++ src/hsm/CMakeLists.txt | 6 +++++ src/hsm/cmd_cipher_sym.c | 9 ++++---- src/hsm/cmd_decrypt_asym.c | 3 +-- src/hsm/cmd_derive_asym.c | 3 +-- src/hsm/cmd_extras.c | 36 +++++++++++++++++++++++++----- src/hsm/cmd_general_authenticate.c | 3 +-- src/hsm/cmd_initialize.c | 2 +- src/hsm/cmd_key_unwrap.c | 3 +-- src/hsm/cvc.c | 3 +-- src/hsm/cvc.h | 2 +- src/hsm/kek.c | 6 ++--- src/hsm/kek.h | 3 ++- src/hsm/sc_hsm.c | 2 +- src/hsm/sc_hsm.h | 6 ++++- 17 files changed, 92 insertions(+), 34 deletions(-) create mode 100755 sdkconfig.defaults create mode 100644 src/hsm/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index ee5157b..23f5cd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,14 @@ cmake_minimum_required(VERSION 3.13) +if(ESP_PLATFORM) +set(EXTRA_COMPONENT_DIRS src pico-keys-sdk/src) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(USB_VID 0x20a0) +set(USB_PID 0x4230) +set(DEBUG_APDU 1) +set(USB_ITF_CCID 1) +else() if(ENABLE_EMULATION) else() include(pico_sdk_import.cmake) @@ -27,8 +35,7 @@ project(pico_hsm C CXX ASM) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) -if(ENABLE_EMULATION) -else() +if(NOT ENABLE_EMULATION) pico_sdk_init() endif() @@ -40,7 +47,7 @@ if (__FOR_CI) endif() add_executable(pico_hsm) - +endif() set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/src/hsm/sc_hsm.c ${CMAKE_CURRENT_LIST_DIR}/src/hsm/cmd_select.c @@ -77,11 +84,14 @@ set(SOURCES ${SOURCES} ) set(USB_ITF_CCID 1) include(pico-keys-sdk/pico_keys_sdk_import.cmake) +if(ESP_PLATFORM) + project(pico_hsm) +endif() set(INCLUDES ${INCLUDES} ${CMAKE_CURRENT_LIST_DIR}/src/hsm ) - +if(NOT ESP_PLATFORM) target_sources(pico_hsm PUBLIC ${SOURCES}) target_include_directories(pico_hsm PUBLIC ${INCLUDES}) @@ -120,3 +130,4 @@ else() pico_add_extra_outputs(pico_hsm) target_link_libraries(pico_hsm PRIVATE pico_keys_sdk pico_stdlib pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc tinyusb_device tinyusb_board) endif() +endif() diff --git a/pico-keys-sdk b/pico-keys-sdk index 151ae5f..1ba109b 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 151ae5fae4c5815042fce5d5cbcc06d76561dc9c +Subproject commit 1ba109bd0a46bed18c097d750f5ebee568d734d4 diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100755 index 0000000..39b5b87 --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,18 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +IGNORE_UNKNOWN_FILES_FOR_MANAGED_COMPONENTS=1 + +CONFIG_TINYUSB=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="pico-keys-sdk/partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/partitions.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_WL_SECTOR_SIZE_512=y +CONFIG_WL_SECTOR_MODE_PERF=y + +CONFIG_MBEDTLS_CHACHA20_C=y +CONFIG_MBEDTLS_POLY1305_C=y +CONFIG_MBEDTLS_CHACHAPOLY_C=y +CONFIG_MBEDTLS_HKDF_C=y diff --git a/src/hsm/CMakeLists.txt b/src/hsm/CMakeLists.txt new file mode 100644 index 0000000..5a60962 --- /dev/null +++ b/src/hsm/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register( + SRCS ${SOURCES} + INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb + REQUIRES bootloader_support esp_partition esp_tinyusb zorxx__neopixel mbedtls +) +idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index 6de1409..0014d14 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -15,16 +15,15 @@ * along with this program. If not, see . */ -#include "common.h" +#include "sc_hsm.h" #include "mbedtls/aes.h" #include "mbedtls/cmac.h" #include "mbedtls/hkdf.h" #include "mbedtls/chachapoly.h" #include "mbedtls/gcm.h" -#include "md_wrap.h" +//#include "mbedtls/md_wrap.h" #include "mbedtls/md.h" #include "crypto_utils.h" -#include "sc_hsm.h" #include "kek.h" #include "asn1.h" #include "oid.h" @@ -134,7 +133,7 @@ int mbedtls_ansi_x963_kdf(mbedtls_md_type_t md_type, } // keydatalen equals output_len - hashlen = md_info->size; + hashlen = mbedtls_md_get_size(md_info); if (output_len >= hashlen * ((1ULL << 32) - 1)) { return exit_code; } @@ -349,7 +348,7 @@ int cmd_cipher_sym() { if (r != 0) { return SW_EXEC_ERROR(); } - res_APDU_size = md_info->size; + res_APDU_size = mbedtls_md_get_size(md_info); } else if (memcmp(oid.data, OID_HKDF_SHA256, oid.len) == 0 || diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index e68853e..fc9c904 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -15,10 +15,9 @@ * along with this program. If not, see . */ -#include "common.h" +#include "sc_hsm.h" #include "mbedtls/ecdh.h" #include "crypto_utils.h" -#include "sc_hsm.h" #include "kek.h" #include "files.h" #include "asn1.h" diff --git a/src/hsm/cmd_derive_asym.c b/src/hsm/cmd_derive_asym.c index ff59009..03ded64 100644 --- a/src/hsm/cmd_derive_asym.c +++ b/src/hsm/cmd_derive_asym.c @@ -15,10 +15,9 @@ * along with this program. If not, see . */ -#include "common.h" +#include "sc_hsm.h" #include "mbedtls/ecdsa.h" #include "crypto_utils.h" -#include "sc_hsm.h" #include "cvc.h" #define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index a5c4499..a0818bc 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -15,11 +15,12 @@ * along with this program. If not, see . */ -#include "common.h" -#include "mbedtls/ecdh.h" #include "sc_hsm.h" -#ifndef ENABLE_EMULATION +#include "mbedtls/ecdh.h" +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "hardware/rtc.h" +#else +#include #endif #include "files.h" #include "random.h" @@ -33,7 +34,7 @@ int cmd_extras() { return SW_INCORRECT_P1P2(); } if (apdu.nc == 0) { -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) datetime_t dt; if (!rtc_get_datetime(&dt)) { return SW_EXEC_ERROR(); @@ -46,13 +47,26 @@ int cmd_extras() { res_APDU[res_APDU_size++] = dt.hour; res_APDU[res_APDU_size++] = dt.min; res_APDU[res_APDU_size++] = dt.sec; +#else + struct timeval tv; + struct tm *tm; + gettimeofday(&tv, NULL); + tm = localtime(&tv.tv_sec); + res_APDU[res_APDU_size++] = (tm->tm_year + 1900) >> 8; + res_APDU[res_APDU_size++] = (tm->tm_year + 1900) & 0xff; + res_APDU[res_APDU_size++] = tm->tm_mon; + res_APDU[res_APDU_size++] = tm->tm_mday; + res_APDU[res_APDU_size++] = tm->tm_wday; + res_APDU[res_APDU_size++] = tm->tm_hour; + res_APDU[res_APDU_size++] = tm->tm_min; + res_APDU[res_APDU_size++] = tm->tm_sec; #endif } else { if (apdu.nc != 8) { return SW_WRONG_LENGTH(); } -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) datetime_t dt; dt.year = (apdu.data[0] << 8) | (apdu.data[1]); dt.month = apdu.data[2]; @@ -64,6 +78,18 @@ int cmd_extras() { if (!rtc_set_datetime(&dt)) { return SW_WRONG_DATA(); } +#else + struct tm tm; + struct timeval tv; + tm.tm_year = ((apdu.data[0] << 8) | (apdu.data[1])) - 1900; + tm.tm_mon = apdu.data[2]; + tm.tm_mday = apdu.data[3]; + tm.tm_wday = apdu.data[4]; + tm.tm_hour = apdu.data[5]; + tm.tm_min = apdu.data[6]; + tm.tm_sec = apdu.data[7]; + tv.tv_sec = mktime(&tm); + settimeofday(&tv, NULL); #endif } } diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index 64c5860..47aabc3 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -15,10 +15,9 @@ * along with this program. If not, see . */ -#include "common.h" +#include "sc_hsm.h" #include "mbedtls/ecdh.h" #include "asn1.h" -#include "sc_hsm.h" #include "random.h" #include "oid.h" #include "eac.h" diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index cf19cb3..8a5ebb4 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -28,7 +28,7 @@ extern void scan_all(); extern char __StackLimit; int heapLeft() { -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) char *p = malloc(256); // try to avoid undue fragmentation int left = &__StackLimit - p; free(p); diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index 1eb0ecb..85b8288 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -15,9 +15,8 @@ * along with this program. If not, see . */ -#include "common.h" -#include "crypto_utils.h" #include "sc_hsm.h" +#include "crypto_utils.h" #include "kek.h" #include "cvc.h" diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index fcc722c..c2df5dc 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -15,9 +15,8 @@ * along with this program. If not, see . */ -#include "common.h" -#include "cvc.h" #include "sc_hsm.h" +#include "cvc.h" #include "mbedtls/rsa.h" #include "mbedtls/ecdsa.h" #include diff --git a/src/hsm/cvc.h b/src/hsm/cvc.h index 1eb217a..a0b878a 100644 --- a/src/hsm/cvc.h +++ b/src/hsm/cvc.h @@ -19,7 +19,7 @@ #define _CVC_H_ #include -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #else #include diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 4d317b8..66c0710 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -15,16 +15,14 @@ * along with this program. If not, see . */ -#include -#include "common.h" +#include "sc_hsm.h" #include "stdlib.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif #include "kek.h" #include "crypto_utils.h" #include "random.h" -#include "sc_hsm.h" #include "mbedtls/md.h" #include "mbedtls/cmac.h" #include "mbedtls/rsa.h" diff --git a/src/hsm/kek.h b/src/hsm/kek.h index aa095cc..f0aca86 100644 --- a/src/hsm/kek.h +++ b/src/hsm/kek.h @@ -19,10 +19,11 @@ #define _DKEK_H_ #include "crypto_utils.h" -#ifdef ENABLE_EMULATION +#if defined(ENABLE_EMULATION) || defined(ESP_PLATFORM) #include #endif + extern int load_mkek(uint8_t *); extern int store_mkek(const uint8_t *); extern int save_dkek_key(uint8_t, const uint8_t *key); diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 70f7534..bd43567 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -17,7 +17,6 @@ #include "sc_hsm.h" #include "files.h" -#include "common.h" #include "version.h" #include "crypto_utils.h" #include "kek.h" @@ -89,6 +88,7 @@ int sc_hsm_select_aid(app_t *a) { } INITIALIZER( sc_hsm_ctor ) { + printf("INITIALIZER\n"); ccid_atr = atr_sc_hsm; register_app(sc_hsm_select_aid, sc_hsm_aid); } diff --git a/src/hsm/sc_hsm.h b/src/hsm/sc_hsm.h index fa8d3ff..e187d26 100644 --- a/src/hsm/sc_hsm.h +++ b/src/hsm/sc_hsm.h @@ -19,10 +19,14 @@ #define _SC_HSM_H_ #include +#ifndef ESP_PLATFORM #include "common.h" +#else +#define MBEDTLS_ALLOW_PRIVATE_ACCESS +#endif #include "mbedtls/rsa.h" #include "mbedtls/ecdsa.h" -#ifndef ENABLE_EMULATION +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "pico/stdlib.h" #endif #include "file.h" From d8c7fb0856600ea69d873be34916742a1d2847d6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 10 Apr 2024 18:16:38 +0200 Subject: [PATCH 36/85] Remove carriage return \r for better debug. Signed-off-by: Pol Henarejos --- src/hsm/cmd_keypair_gen.c | 4 ++-- src/hsm/sc_hsm.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 6a88b85..22c1e05 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -47,7 +47,7 @@ int cmd_keypair_gen() { if (asn1_find_tag(&ctxo, 0x2, &ks) && asn1_len(&ks) > 0) { key_size = asn1_get_uint(&ks); } - printf("KEYPAIR RSA %lu (%lx)\r\n", + printf("KEYPAIR RSA %lu (%lx)\n", (unsigned long) key_size, (unsigned long) exponent); mbedtls_rsa_context rsa; @@ -75,7 +75,7 @@ int cmd_keypair_gen() { return SW_WRONG_DATA(); } mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime.data, prime.len); - printf("KEYPAIR ECC %d\r\n", ec_id); + printf("KEYPAIR ECC %d\n", ec_id); if (ec_id == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); } diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index bd43567..d4ccb68 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -97,24 +97,24 @@ void scan_files() { file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF); if (file_pin1) { if (!file_pin1->data) { - printf("PIN1 is empty. Initializing with default password\r\n"); + printf("PIN1 is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_pin1, empty, sizeof(empty)); } } else { - printf("FATAL ERROR: PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: PIN1 not found in memory!\n"); } file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF); if (file_sopin) { if (!file_sopin->data) { - printf("SOPIN is empty. Initializing with default password\r\n"); + printf("SOPIN is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_sopin, empty, sizeof(empty)); } } else { - printf("FATAL ERROR: SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: SOPIN not found in memory!\n"); } file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF); if (file_retries_pin1) { @@ -125,18 +125,18 @@ void scan_files() { } } else { - printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: Retries PIN1 not found in memory!\n"); } file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF); if (file_retries_sopin) { if (!file_retries_sopin->data) { - printf("Retries SOPIN is empty. Initializing with default retries\r\n"); + printf("Retries SOPIN is empty. Initializing with default retries\n"); const uint8_t retries = 15; flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t)); } } else { - printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: Retries SOPIN not found in memory!\n"); } file_t *tf = NULL; @@ -149,18 +149,18 @@ void scan_files() { } } else { - printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: Max Retries PIN1 not found in memory!\n"); } tf = search_by_fid(0x1089, NULL, SPECIFY_EF); if (tf) { if (!tf->data) { - printf("Max Retries SOPIN is empty. Initializing with default max retries\r\n"); + printf("Max Retries SOPIN is empty. Initializing with default max retries\n"); const uint8_t retries = 15; flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); } } else { - printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: Retries SOPIN not found in memory!\n"); } low_flash_available(); } From 60038f934574163be6022008b96b55bf4a34343a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 10 Apr 2024 20:29:02 +0200 Subject: [PATCH 37/85] Fix flash issues. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 1ba109b..7def35f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 1ba109bd0a46bed18c097d750f5ebee568d734d4 +Subproject commit 7def35f87cfb79ac52c203a31bb5282b20dde0a9 From 3dbcefea8574e82959d2000a65e9285fa615bd33 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 11 Apr 2024 15:15:18 +0200 Subject: [PATCH 38/85] Upate build parameters. Signed-off-by: Pol Henarejos --- sdkconfig.defaults | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 39b5b87..180cb70 100755 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -12,7 +12,50 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_MODE_PERF=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_CHACHA20_C=y CONFIG_MBEDTLS_POLY1305_C=y CONFIG_MBEDTLS_CHACHAPOLY_C=y +CONFIG_MBEDTLS_AES_C=y +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +CONFIG_MBEDTLS_RIPEMD160_C=y CONFIG_MBEDTLS_HKDF_C=y +CONFIG_MBEDTLS_HARDWARE_ECC=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +# CONFIG_MBEDTLS_HARDWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_DES_C=y +# CONFIG_MBEDTLS_ROM_MD5 is not set +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_DISABLED=y +# CONFIG_MBEDTLS_TLS_ENABLED is not set +# CONFIG_ESP_TLS_USE_DS_PERIPHERAL is not set +# CONFIG_ESP_WIFI_ENABLED is not set +# CONFIG_ESP_WIFI_MBEDTLS_CRYPTO is not set +# CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT is not set +# CONFIG_WPA_MBEDTLS_CRYPTO is not set +# CONFIG_MBEDTLS_PSK_MODES is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_RSA is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA is not set +# CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA is not set +# CONFIG_MBEDTLS_SSL_RENEGOTIATION is not set +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 is not set +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +# CONFIG_MBEDTLS_SSL_ALPN is not set +# CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS is not set +# CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS is not set +# CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE is not set +# CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA is not set +# CONFIG_ESP_WIFI_ENABLE_WPA3_SAE is not set +# CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA is not set + +CONFIG_ESP_COREDUMP_ENABLE_TO_UART=y From 842919a26b9027027ca6a2ba49419c4162fffdda Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 15 Apr 2024 23:45:30 +0200 Subject: [PATCH 39/85] Use external unique ID. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/CMakeLists.txt | 2 +- src/hsm/sc_hsm.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 7def35f..8d86a8c 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 7def35f87cfb79ac52c203a31bb5282b20dde0a9 +Subproject commit 8d86a8c56b4e8dd4b525570d2ca324a29d5b901a diff --git a/src/hsm/CMakeLists.txt b/src/hsm/CMakeLists.txt index 5a60962..31d66c9 100644 --- a/src/hsm/CMakeLists.txt +++ b/src/hsm/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register( SRCS ${SOURCES} INCLUDE_DIRS . ../../pico-keys-sdk/src ../../pico-keys-sdk/src/fs ../../pico-keys-sdk/src/rng ../../pico-keys-sdk/src/usb - REQUIRES bootloader_support esp_partition esp_tinyusb zorxx__neopixel mbedtls + REQUIRES bootloader_support esp_partition esp_tinyusb zorxx__neopixel mbedtls efuse ) idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE ON) diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index d4ccb68..82a2334 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -301,7 +301,7 @@ int parse_token_info(const file_t *f, int mode) { *p++ = 0; //set later *p++ = 0x2; *p++ = 1; *p++ = HSM_VERSION_MAJOR; #ifndef ENABLE_EMULATION - *p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *) p); p += 8; + *p++ = 0x4; *p++ = 8; memcpy(p, pico_serial.id, 8); p += 8; #else *p++ = 0x4; *p++ = 8; memset(p, 0, 8); p += 8; #endif From 45b633cc9d2922647a81848768128190581e7b3d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 16 Apr 2024 00:04:33 +0200 Subject: [PATCH 40/85] More defaults. Signed-off-by: Pol Henarejos --- sdkconfig.defaults | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 180cb70..f8a8d9f 100755 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -12,24 +12,16 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_MODE_PERF=y -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y CONFIG_MBEDTLS_CMAC_C=y CONFIG_MBEDTLS_CHACHA20_C=y CONFIG_MBEDTLS_POLY1305_C=y CONFIG_MBEDTLS_CHACHAPOLY_C=y -CONFIG_MBEDTLS_AES_C=y -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -CONFIG_MBEDTLS_RIPEMD160_C=y CONFIG_MBEDTLS_HKDF_C=y CONFIG_MBEDTLS_HARDWARE_ECC=y CONFIG_MBEDTLS_HARDWARE_GCM=y # CONFIG_MBEDTLS_HARDWARE_MPI is not set CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_DES_C=y # CONFIG_MBEDTLS_ROM_MD5 is not set CONFIG_MBEDTLS_SHA512_C=y CONFIG_MBEDTLS_TLS_DISABLED=y From 8bbbdb4dd8104484ae7be7438f97c41ffba43ae2 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 16 Apr 2024 00:04:48 +0200 Subject: [PATCH 41/85] Build WCID interface. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23f5cd9..1e926f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ set(USB_VID 0x20a0) set(USB_PID 0x4230) set(DEBUG_APDU 1) set(USB_ITF_CCID 1) +set(USB_ITF_WCID 1) else() if(ENABLE_EMULATION) else() From be071b0bc1d63ac9b3ba2d1efbb21011581cd749 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 16 Apr 2024 00:05:01 +0200 Subject: [PATCH 42/85] Add support for dynamic VID / PID. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 8d86a8c..6f7ab69 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 8d86a8c56b4e8dd4b525570d2ca324a29d5b901a +Subproject commit 6f7ab69a9df3950c9b538a72661bc3810e978778 From aeeb540a2ff9108289e999047fd93a30e190e1af Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 16 Apr 2024 23:22:49 +0200 Subject: [PATCH 43/85] Add support for PHY command to store and change VIDPID and LED no. dynamically on reboot. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_extras.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 6f7ab69..ade730f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 6f7ab69a9df3950c9b538a72661bc3810e978778 +Subproject commit ade730ffb5e38b37afaab21247a2c9ac6db2ac1b diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index a0818bc..5aefd81 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -221,6 +221,40 @@ int cmd_extras() { } } } +#ifndef ENABLE_EMULATION + else if (P1(apdu) == 0x1B) { // Set PHY + if (apdu.nc == 0) { + if (file_has_data(ef_phy)) { + res_APDU_size = file_get_size(ef_phy); + memcpy(res_APDU, file_get_data(ef_phy), res_APDU_size); + } + } + else { + uint8_t tmp[PHY_MAX_SIZE]; + memset(tmp, 0, sizeof(tmp)); + if (file_has_data(ef_phy)) { + memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy))); + } + if (P2(apdu) == PHY_VID) { // VIDPID + if (apdu.nc != 4) { + return SW_WRONG_LENGTH(); + } + memcpy(tmp + PHY_VID, apdu.data, 4); + } + else if (P2(apdu) == PHY_LED_GPIO || P2(apdu) == PHY_LED_MODE) { + if (apdu.nc != 1) { + return SW_WRONG_LENGTH(); + } + tmp[P2(apdu)] = apdu.data[0]; + } + else { + return SW_INCORRECT_P1P2(); + } + flash_write_data_to_file(ef_phy, tmp, sizeof(tmp)); + low_flash_available(); + } + } +#endif else { return SW_INCORRECT_P1P2(); } From 920d22212aa2f12ac057f63c86a8b31688841537 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 16 Apr 2024 23:23:20 +0200 Subject: [PATCH 44/85] Add phy command to pico-hsm-tool to change VIDPID dynamically. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 00d9ee6..7d7813f 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -87,10 +87,17 @@ def parse_args(): parser_opts = subparser.add_parser('options', help='Manage extra options.', formatter_class=RawTextHelpFormatter) subparser_opts = parser_opts.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_set = subparser_opts.add_parser('set', help='Sets option OPT.') - parser_opts_get = subparser_opts.add_parser('get', help='Gets optiont OPT.') + parser_opts_get = subparser_opts.add_parser('get', help='Gets option OPT.') parser_opts.add_argument('opt', choices=['button', 'counter'], help='button: press-to-confirm button.\ncounter: every generated key has an internal counter.', metavar='OPT') parser_opts_set.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?') + parser_phy = subparser.add_parser('phy', help='Set PHY options.') + subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True) + parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)') + parser_phy_ledn = subparser_phy.add_parser('led', help='Sets LED GPIO number.') + parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_phy_ledn.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_secure = subparser.add_parser('secure', help='Manages security of Pico HSM.') subparser_secure = parser_secure.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_enable = subparser_secure.add_parser('enable', help='Enables secure lock.') @@ -444,8 +451,22 @@ def keygen(picohsm, args): print('Key generated successfully.') print(f'Key ID: {ret}') +def phy(picohsm, args): + val = args.value if 'value' in args else None + if (val): + if (args.subcommand == 'vidpid'): + sp = val.split(':') + if (len(sp) != 2): + print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)') + val = int(sp[0],16).to_bytes(2, 'big') + int(sp[1],16).to_bytes(2, 'big') + elif (args.subcommand == 'led'): + val = [int(val)] + ret = picohsm.phy(args.subcommand, val) + if (ret): + print(f'Current value: {hexlify(ret)}') + def main(args): - sys.stderr.buffer.write(b'Pico HSM Tool v1.10\n') + sys.stderr.buffer.write(b'Pico HSM Tool v1.12\n') sys.stderr.buffer.write(b'Author: Pol Henarejos\n') sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n') sys.stderr.buffer.write(b'\n\n') @@ -470,6 +491,8 @@ def main(args): cipher(picohsm, args) elif (args.command == 'keygen'): keygen(picohsm, args) + elif (args.command == 'phy'): + phy(picohsm, args) def run(): From a6744108268a7fe9024052f4276992f18f1e41b7 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 11:46:34 +0200 Subject: [PATCH 45/85] Remove carriage return \r for better debug. Signed-off-by: Pol Henarejos --- src/hsm/cmd_keypair_gen.c | 4 ++-- src/hsm/sc_hsm.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 6a88b85..22c1e05 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -47,7 +47,7 @@ int cmd_keypair_gen() { if (asn1_find_tag(&ctxo, 0x2, &ks) && asn1_len(&ks) > 0) { key_size = asn1_get_uint(&ks); } - printf("KEYPAIR RSA %lu (%lx)\r\n", + printf("KEYPAIR RSA %lu (%lx)\n", (unsigned long) key_size, (unsigned long) exponent); mbedtls_rsa_context rsa; @@ -75,7 +75,7 @@ int cmd_keypair_gen() { return SW_WRONG_DATA(); } mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(prime.data, prime.len); - printf("KEYPAIR ECC %d\r\n", ec_id); + printf("KEYPAIR ECC %d\n", ec_id); if (ec_id == MBEDTLS_ECP_DP_NONE) { return SW_FUNC_NOT_SUPPORTED(); } diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 70f7534..a9e894b 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -97,24 +97,24 @@ void scan_files() { file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF); if (file_pin1) { if (!file_pin1->data) { - printf("PIN1 is empty. Initializing with default password\r\n"); + printf("PIN1 is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_pin1, empty, sizeof(empty)); } } else { - printf("FATAL ERROR: PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: PIN1 not found in memory!\n"); } file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF); if (file_sopin) { if (!file_sopin->data) { - printf("SOPIN is empty. Initializing with default password\r\n"); + printf("SOPIN is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; flash_write_data_to_file(file_sopin, empty, sizeof(empty)); } } else { - printf("FATAL ERROR: SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: SOPIN not found in memory!\n"); } file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF); if (file_retries_pin1) { @@ -125,18 +125,18 @@ void scan_files() { } } else { - printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: Retries PIN1 not found in memory!\n"); } file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF); if (file_retries_sopin) { if (!file_retries_sopin->data) { - printf("Retries SOPIN is empty. Initializing with default retries\r\n"); + printf("Retries SOPIN is empty. Initializing with default retries\n"); const uint8_t retries = 15; flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t)); } } else { - printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: Retries SOPIN not found in memory!\n"); } file_t *tf = NULL; @@ -149,18 +149,18 @@ void scan_files() { } } else { - printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n"); + printf("FATAL ERROR: Max Retries PIN1 not found in memory!\n"); } tf = search_by_fid(0x1089, NULL, SPECIFY_EF); if (tf) { if (!tf->data) { - printf("Max Retries SOPIN is empty. Initializing with default max retries\r\n"); + printf("Max Retries SOPIN is empty. Initializing with default max retries\n"); const uint8_t retries = 15; flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); } } else { - printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n"); + printf("FATAL ERROR: Retries SOPIN not found in memory!\n"); } low_flash_available(); } From 5d0dc210da42609824698cc2455581c2542dd630 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 11:48:23 +0200 Subject: [PATCH 46/85] Use external unique ID. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/sc_hsm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 151ae5f..6f2721a 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 151ae5fae4c5815042fce5d5cbcc06d76561dc9c +Subproject commit 6f2721aba343adab1aa0a336e4b15e41fbb77569 diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index a9e894b..03252ba 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -301,7 +301,7 @@ int parse_token_info(const file_t *f, int mode) { *p++ = 0; //set later *p++ = 0x2; *p++ = 1; *p++ = HSM_VERSION_MAJOR; #ifndef ENABLE_EMULATION - *p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *) p); p += 8; + *p++ = 0x4; *p++ = 8; memcpy(p, pico_serial.id, 8); p += 8; #else *p++ = 0x4; *p++ = 8; memset(p, 0, 8); p += 8; #endif From fdc41e5856db9ee691d3418ac31cfe86ee185a90 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 11:50:44 +0200 Subject: [PATCH 47/85] Add support for PHY command to store and change VIDPID and LED no. dynamically on reboot. Signed-off-by: Pol Henarejos --- src/hsm/cmd_extras.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index a5c4499..aea3fca 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -195,6 +195,40 @@ int cmd_extras() { } } } +#ifndef ENABLE_EMULATION + else if (P1(apdu) == 0x1B) { // Set PHY + if (apdu.nc == 0) { + if (file_has_data(ef_phy)) { + res_APDU_size = file_get_size(ef_phy); + memcpy(res_APDU, file_get_data(ef_phy), res_APDU_size); + } + } + else { + uint8_t tmp[PHY_MAX_SIZE]; + memset(tmp, 0, sizeof(tmp)); + if (file_has_data(ef_phy)) { + memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy))); + } + if (P2(apdu) == PHY_VID) { // VIDPID + if (apdu.nc != 4) { + return SW_WRONG_LENGTH(); + } + memcpy(tmp + PHY_VID, apdu.data, 4); + } + else if (P2(apdu) == PHY_LED_GPIO || P2(apdu) == PHY_LED_MODE) { + if (apdu.nc != 1) { + return SW_WRONG_LENGTH(); + } + tmp[P2(apdu)] = apdu.data[0]; + } + else { + return SW_INCORRECT_P1P2(); + } + flash_write_data_to_file(ef_phy, tmp, sizeof(tmp)); + low_flash_available(); + } + } +#endif else { return SW_INCORRECT_P1P2(); } From 623cf10dbad2607962253d9c713e3d4c2baac515 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 11:51:25 +0200 Subject: [PATCH 48/85] Add phy command to pico-hsm-tool to change VIDPID dynamically. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 00d9ee6..7d7813f 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -87,10 +87,17 @@ def parse_args(): parser_opts = subparser.add_parser('options', help='Manage extra options.', formatter_class=RawTextHelpFormatter) subparser_opts = parser_opts.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_set = subparser_opts.add_parser('set', help='Sets option OPT.') - parser_opts_get = subparser_opts.add_parser('get', help='Gets optiont OPT.') + parser_opts_get = subparser_opts.add_parser('get', help='Gets option OPT.') parser_opts.add_argument('opt', choices=['button', 'counter'], help='button: press-to-confirm button.\ncounter: every generated key has an internal counter.', metavar='OPT') parser_opts_set.add_argument('onoff', choices=['on', 'off'], help='Toggles state ON or OFF', metavar='ON/OFF', nargs='?') + parser_phy = subparser.add_parser('phy', help='Set PHY options.') + subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True) + parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)') + parser_phy_ledn = subparser_phy.add_parser('led', help='Sets LED GPIO number.') + parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_phy_ledn.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_secure = subparser.add_parser('secure', help='Manages security of Pico HSM.') subparser_secure = parser_secure.add_subparsers(title='commands', dest='subcommand', required=True) parser_opts_enable = subparser_secure.add_parser('enable', help='Enables secure lock.') @@ -444,8 +451,22 @@ def keygen(picohsm, args): print('Key generated successfully.') print(f'Key ID: {ret}') +def phy(picohsm, args): + val = args.value if 'value' in args else None + if (val): + if (args.subcommand == 'vidpid'): + sp = val.split(':') + if (len(sp) != 2): + print('ERROR: VID/PID have wrong format. Use VID:PID format (e.g. 1234:5678)') + val = int(sp[0],16).to_bytes(2, 'big') + int(sp[1],16).to_bytes(2, 'big') + elif (args.subcommand == 'led'): + val = [int(val)] + ret = picohsm.phy(args.subcommand, val) + if (ret): + print(f'Current value: {hexlify(ret)}') + def main(args): - sys.stderr.buffer.write(b'Pico HSM Tool v1.10\n') + sys.stderr.buffer.write(b'Pico HSM Tool v1.12\n') sys.stderr.buffer.write(b'Author: Pol Henarejos\n') sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n') sys.stderr.buffer.write(b'\n\n') @@ -470,6 +491,8 @@ def main(args): cipher(picohsm, args) elif (args.command == 'keygen'): keygen(picohsm, args) + elif (args.command == 'phy'): + phy(picohsm, args) def run(): From b0343031931175f9720b621c2a8dcbcdf8142720 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 16:36:34 +0200 Subject: [PATCH 49/85] Use new methods search_file() and file_put_data(). Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_bip_slip.c | 2 +- src/hsm/cmd_change_pin.c | 4 +-- src/hsm/cmd_external_authenticate.c | 2 +- src/hsm/cmd_extras.c | 14 ++++---- src/hsm/cmd_general_authenticate.c | 2 +- src/hsm/cmd_initialize.c | 48 ++++++++++++------------- src/hsm/cmd_key_domain.c | 10 +++--- src/hsm/cmd_key_unwrap.c | 2 +- src/hsm/cmd_key_wrap.c | 2 +- src/hsm/cmd_keypair_gen.c | 2 +- src/hsm/cmd_list_keys.c | 4 +-- src/hsm/cmd_pso.c | 4 +-- src/hsm/cmd_puk_auth.c | 6 ++-- src/hsm/cmd_read_binary.c | 8 ++--- src/hsm/cmd_reset_retry.c | 6 ++-- src/hsm/cmd_select.c | 3 +- src/hsm/cmd_signature.c | 5 +-- src/hsm/cmd_update_ef.c | 9 ++--- src/hsm/cmd_verify.c | 10 +++--- src/hsm/cvc.c | 2 +- src/hsm/kek.c | 16 ++++----- src/hsm/sc_hsm.c | 56 ++++++++++++++--------------- 23 files changed, 105 insertions(+), 114 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 6f2721a..ef196bf 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 6f2721aba343adab1aa0a336e4b15e41fbb77569 +Subproject commit ef196bf10ba29410df712b54beef8a2c4876300a diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 41d27d6..15cce9b 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -256,7 +256,7 @@ int cmd_bip_slip() { if (r != CCID_OK) { return SW_EXEC_ERROR(); } - r = flash_write_data_to_file(ef, mkey, sizeof(mkey)); + r = file_put_data(ef, mkey, sizeof(mkey)); if (r != CCID_OK) { return SW_EXEC_ERROR(); } diff --git a/src/hsm/cmd_change_pin.c b/src/hsm/cmd_change_pin.c index 7a2ba98..3af69e0 100644 --- a/src/hsm/cmd_change_pin.c +++ b/src/hsm/cmd_change_pin.c @@ -35,7 +35,7 @@ int cmd_change_pin() { if (!file_has_data(file_pin)) { return SW_REFERENCE_NOT_FOUND(); } - uint8_t pin_len = file_read_uint8(file_get_data(file_pin)); + uint8_t pin_len = file_read_uint8(file_pin); int r = check_pin(file_pin, apdu.data, pin_len); if (r != 0x9000) { return r; @@ -63,7 +63,7 @@ int cmd_change_pin() { uint8_t dhash[33]; dhash[0] = (uint8_t)apdu.nc - pin_len; double_hash_pin(apdu.data + pin_len, (uint16_t)(apdu.nc - pin_len), dhash + 1); - flash_write_data_to_file(file_pin, dhash, sizeof(dhash)); + file_put_data(file_pin, dhash, sizeof(dhash)); low_flash_available(); return SW_OK(); } diff --git a/src/hsm/cmd_external_authenticate.c b/src/hsm/cmd_external_authenticate.c index 8d5ae4d..a40dc96 100644 --- a/src/hsm/cmd_external_authenticate.c +++ b/src/hsm/cmd_external_authenticate.c @@ -34,7 +34,7 @@ int cmd_external_authenticate() { if (apdu.nc == 0) { return SW_WRONG_LENGTH(); } - file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); + file_t *ef_puk = search_file(EF_PUKAUT); if (!file_has_data(ef_puk)) { return SW_FILE_NOT_FOUND(); } diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index aea3fca..f801852 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -81,8 +81,8 @@ int cmd_extras() { } else { uint8_t newopts[] = { apdu.data[0], (opts & 0xff) }; - file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); - flash_write_data_to_file(tf, newopts, sizeof(newopts)); + file_t *tf = search_file(EF_DEVOPS); + file_put_data(tf, newopts, sizeof(newopts)); low_flash_available(); } } @@ -167,14 +167,14 @@ int cmd_extras() { (P2(apdu) == 0x04 && (opts & HSM_OPT_SECURE_LOCK))) { uint16_t tfids[] = { EF_MKEK, EF_MKEK_SO }; for (int t = 0; t < sizeof(tfids) / sizeof(uint16_t); t++) { - file_t *tf = search_by_fid(tfids[t], NULL, SPECIFY_EF); + file_t *tf = search_file(tfids[t]); if (tf) { uint8_t *tmp = (uint8_t *) calloc(1, file_get_size(tf)); memcpy(tmp, file_get_data(tf), file_get_size(tf)); for (int i = 0; i < MKEK_KEY_SIZE; i++) { MKEK_KEY(tmp)[i] ^= apdu.data[i]; } - flash_write_data_to_file(tf, tmp, file_get_size(tf)); + file_put_data(tf, tmp, file_get_size(tf)); free(tmp); } } @@ -185,8 +185,8 @@ int cmd_extras() { else if (P2(apdu) == 0x04) { newopts[0] &= ~HSM_OPT_SECURE_LOCK >> 8; } - file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); - flash_write_data_to_file(tf, newopts, sizeof(newopts)); + file_t *tf = search_file(EF_DEVOPS); + file_put_data(tf, newopts, sizeof(newopts)); low_flash_available(); } else if (P2(apdu) == 0x03) { @@ -224,7 +224,7 @@ int cmd_extras() { else { return SW_INCORRECT_P1P2(); } - flash_write_data_to_file(ef_phy, tmp, sizeof(tmp)); + file_put_data(ef_phy, tmp, sizeof(tmp)); low_flash_available(); } } diff --git a/src/hsm/cmd_general_authenticate.c b/src/hsm/cmd_general_authenticate.c index 64c5860..a7ca816 100644 --- a/src/hsm/cmd_general_authenticate.c +++ b/src/hsm/cmd_general_authenticate.c @@ -41,7 +41,7 @@ int cmd_general_authenticate() { pubkey_len = tag_len + 1; } } - file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); + file_t *fkey = search_file(EF_KEY_DEV); if (!fkey) { return SW_EXEC_ERROR(); } diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index cf19cb3..083d60a 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -53,15 +53,15 @@ int cmd_initialize() { asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi); while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) { if (tag == 0x80) { //options - file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); - flash_write_data_to_file(tf, tag_data, tag_len); + file_t *tf = search_file(EF_DEVOPS); + file_put_data(tf, tag_data, tag_len); } else if (tag == 0x81) { //user pin if (file_pin1 && file_pin1->data) { uint8_t dhash[33]; dhash[0] = (uint8_t)tag_len; double_hash_pin(tag_data, tag_len, dhash + 1); - flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); + file_put_data(file_pin1, dhash, sizeof(dhash)); hash_multi(tag_data, tag_len, session_pin); has_session_pin = true; } @@ -71,18 +71,18 @@ int cmd_initialize() { uint8_t dhash[33]; dhash[0] = (uint8_t)tag_len; double_hash_pin(tag_data, tag_len, dhash + 1); - flash_write_data_to_file(file_sopin, dhash, sizeof(dhash)); + file_put_data(file_sopin, dhash, sizeof(dhash)); hash_multi(tag_data, tag_len, session_sopin); has_session_sopin = true; } } else if (tag == 0x91) { //retries user pin - file_t *tf = search_by_fid(0x1082, NULL, SPECIFY_EF); + file_t *tf = search_file(0x1082); if (tf && tf->data) { - flash_write_data_to_file(tf, tag_data, tag_len); + file_put_data(tf, tag_data, tag_len); } if (file_retries_pin1 && file_retries_pin1->data) { - flash_write_data_to_file(file_retries_pin1, tag_data, tag_len); + file_put_data(file_retries_pin1, tag_data, tag_len); } } else if (tag == 0x92) { @@ -92,10 +92,10 @@ int cmd_initialize() { release_mkek(mkek); return SW_MEMORY_FAILURE(); } - flash_write_data_to_file(tf, NULL, 0); + file_put_data(tf, NULL, 0); } else if (tag == 0x93) { - file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); + file_t *ef_puk = search_file(EF_PUKAUT); if (!ef_puk) { release_mkek(mkek); return SW_MEMORY_FAILURE(); @@ -105,14 +105,14 @@ int cmd_initialize() { pk_status[0] = puks; pk_status[1] = puks; pk_status[2] = tag_data[1]; - flash_write_data_to_file(ef_puk, pk_status, sizeof(pk_status)); + file_put_data(ef_puk, pk_status, sizeof(pk_status)); for (uint8_t i = 0; i < puks; i++) { file_t *tf = file_new(EF_PUK + i); if (!tf) { release_mkek(mkek); return SW_MEMORY_FAILURE(); } - flash_write_data_to_file(tf, NULL, 0); + file_put_data(tf, NULL, 0); } } else if (tag == 0x97) { @@ -122,12 +122,12 @@ int cmd_initialize() { file_t *tf = file_new(EF_DKEK+i); if (!tf) return SW_MEMORY_FAILURE(); - flash_write_data_to_file(tf, NULL, 0); + file_put_data(tf, NULL, 0); } */ } } - file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF); + file_t *tf_kd = search_file(EF_KEY_DOMAIN); if (!tf_kd) { release_mkek(mkek); return SW_EXEC_ERROR(); @@ -143,7 +143,7 @@ int cmd_initialize() { if (dkeks) { if (*dkeks > 0) { uint16_t d = *dkeks; - if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { + if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); } } @@ -153,28 +153,28 @@ int cmd_initialize() { return SW_EXEC_ERROR(); } uint16_t d = 0x0101; - if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { + if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); } } } else { uint16_t d = 0x0000; - if (flash_write_data_to_file(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { + if (file_put_data(tf_kd, (const uint8_t *) &d, sizeof(d)) != CCID_OK) { return SW_EXEC_ERROR(); } } if (kds) { uint8_t t[MAX_KEY_DOMAINS * 2], k = MIN(*kds, MAX_KEY_DOMAINS); memset(t, 0xff, 2 * k); - if (flash_write_data_to_file(tf_kd, t, 2 * k) != CCID_OK) { + if (file_put_data(tf_kd, t, 2 * k) != CCID_OK) { return SW_EXEC_ERROR(); } } /* When initialized, it has all credentials */ isUserAuthenticated = true; /* Create terminal private key */ - file_t *fdkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); + file_t *fdkey = search_file(EF_KEY_DEV); if (!fdkey) { return SW_EXEC_ERROR(); } @@ -200,8 +200,8 @@ int cmd_initialize() { return SW_EXEC_ERROR(); } - file_t *fpk = search_by_fid(EF_EE_DEV, NULL, SPECIFY_EF); - ret = flash_write_data_to_file(fpk, res_APDU, (uint16_t)cvc_len); + file_t *fpk = search_file(EF_EE_DEV); + ret = file_put_data(fpk, res_APDU, (uint16_t)cvc_len); if (ret != 0) { mbedtls_ecdsa_free(&ecdsa); return SW_EXEC_ERROR(); @@ -213,8 +213,8 @@ int cmd_initialize() { } memcpy(res_APDU + cvc_len, res_APDU, cvc_len); mbedtls_ecdsa_free(&ecdsa); - fpk = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); - ret = flash_write_data_to_file(fpk, res_APDU, (uint16_t)(2 * cvc_len)); + fpk = search_file(EF_TERMCA); + ret = file_put_data(fpk, res_APDU, (uint16_t)(2 * cvc_len)); if (ret != 0) { return SW_EXEC_ERROR(); } @@ -229,8 +229,8 @@ int cmd_initialize() { 256, res_APDU, 4096); - fpk = search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF); - ret = flash_write_data_to_file(fpk, res_APDU, prkd_len); + fpk = search_file(EF_PRKD_DEV); + ret = file_put_data(fpk, res_APDU, prkd_len); } if (ret != 0) { diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index 487a7c5..a73cf47 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -44,7 +44,7 @@ int cmd_key_domain() { if (p2 >= MAX_KEY_DOMAINS) { return SW_WRONG_P1P2(); } - file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF); + file_t *tf_kd = search_file(EF_KEY_DOMAIN); if (!tf_kd) { return SW_EXEC_ERROR(); } @@ -83,7 +83,7 @@ int cmd_key_domain() { uint8_t t[MAX_KEY_DOMAINS * 2]; memcpy(t, kdata, tf_kd_size); t[2 * p2 + 1] = current_dkeks; - if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) { + if (file_put_data(tf_kd, t, tf_kd_size) != CCID_OK) { return SW_EXEC_ERROR(); } low_flash_available(); @@ -129,7 +129,7 @@ int cmd_key_domain() { else if (p1 == 0x4) { t[2 * p2 + 1] = current_dkeks = 0; } - if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK) { + if (file_put_data(tf_kd, t, tf_kd_size) != CCID_OK) { return SW_EXEC_ERROR(); } file_t *tf = NULL; @@ -151,7 +151,7 @@ int cmd_key_domain() { else if (p1 == 0x2) { //XKEK Key Domain creation if (apdu.nc > 0) { uint16_t pub_len = 0; - file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); + file_t *fterm = search_file(EF_TERMCA); if (!fterm) { return SW_EXEC_ERROR(); } @@ -189,7 +189,7 @@ int cmd_key_domain() { t86_len = 0; t86 = cvc_get_field(pub, pub_len, &t86_len, 0x86); if (t86) { - flash_write_data_to_file(tf, t86 + 1, (uint16_t)t86_len - 1); + file_put_data(tf, t86 + 1, (uint16_t)t86_len - 1); low_flash_available(); } } diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index 1eb0ecb..83205ac 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -133,7 +133,7 @@ int cmd_key_unwrap() { } if (res_APDU_size > 0) { file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id); - r = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); + r = file_put_data(fpk, res_APDU, res_APDU_size); if (r != 0) { return SW_EXEC_ERROR(); } diff --git a/src/hsm/cmd_key_wrap.c b/src/hsm/cmd_key_wrap.c index d303ddc..75529e1 100644 --- a/src/hsm/cmd_key_wrap.c +++ b/src/hsm/cmd_key_wrap.c @@ -40,7 +40,7 @@ int cmd_key_wrap() { if (kdom == 0xff) { return SW_REFERENCE_NOT_FOUND(); } - file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF); + file_t *tf_kd = search_file(EF_KEY_DOMAIN); uint8_t *kdata = file_get_data(tf_kd), dkeks = kdata ? kdata[2 * kdom] : 0, current_dkeks = kdata ? kdata[2 * kdom + 1] : 0; if (dkeks != current_dkeks || dkeks == 0 || dkeks == 0xff) { diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index 22c1e05..fe266ba 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -145,7 +145,7 @@ int cmd_keypair_gen() { return SW_EXEC_ERROR(); } file_t *fpk = file_new((EE_CERTIFICATE_PREFIX << 8) | key_id); - ret = flash_write_data_to_file(fpk, res_APDU, res_APDU_size); + ret = file_put_data(fpk, res_APDU, res_APDU_size); if (ret != 0) { return SW_EXEC_ERROR(); } diff --git a/src/hsm/cmd_list_keys.c b/src/hsm/cmd_list_keys.c index ef92c6f..a7c9fce 100644 --- a/src/hsm/cmd_list_keys.c +++ b/src/hsm/cmd_list_keys.c @@ -21,11 +21,11 @@ int cmd_list_keys() { /* First we send DEV private key */ /* Both below conditions should be always TRUE */ - if (search_by_fid(EF_PRKD_DEV, NULL, SPECIFY_EF)) { + if (search_file(EF_PRKD_DEV)) { res_APDU[res_APDU_size++] = EF_PRKD_DEV >> 8; res_APDU[res_APDU_size++] = EF_PRKD_DEV & 0xff; } - if (search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF)) { + if (search_file(EF_KEY_DEV)) { res_APDU[res_APDU_size++] = EF_KEY_DEV >> 8; res_APDU[res_APDU_size++] = EF_KEY_DEV & 0xff; } diff --git a/src/hsm/cmd_pso.c b/src/hsm/cmd_pso.c index f2ee8e7..70757a1 100644 --- a/src/hsm/cmd_pso.c +++ b/src/hsm/cmd_pso.c @@ -54,7 +54,7 @@ int cmd_pso() { file_t *ca_ef = search_dynamic_file(fid); if (!ca_ef) { ca_ef = file_new(fid); - flash_write_data_to_file(ca_ef, apdu.data, (uint16_t)apdu.nc); + file_put_data(ca_ef, apdu.data, (uint16_t)apdu.nc); if (add_cert_puk_store(file_get_data(ca_ef), file_get_size(ca_ef), false) != CCID_OK) { return SW_FILE_FULL(); @@ -144,7 +144,7 @@ int cmd_pso() { fid, buf, cd_len); - flash_write_data_to_file(cd_ef, buf, cd_len); + file_put_data(cd_ef, buf, cd_len); free(buf); if (r == 0) { return SW_EXEC_ERROR(); diff --git a/src/hsm/cmd_puk_auth.c b/src/hsm/cmd_puk_auth.c index a6ff158..ac4b102 100644 --- a/src/hsm/cmd_puk_auth.c +++ b/src/hsm/cmd_puk_auth.c @@ -21,7 +21,7 @@ int cmd_puk_auth() { 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_file(EF_PUKAUT); if (!file_has_data(ef_puk)) { if (apdu.nc > 0) { return SW_FILE_NOT_FOUND(); @@ -48,7 +48,7 @@ int cmd_puk_auth() { uint8_t *tmp = (uint8_t *) calloc(file_get_size(ef_puk), sizeof(uint8_t)); memcpy(tmp, puk_data, file_get_size(ef_puk)); tmp[1] = puk_data[1] - 1; - flash_write_data_to_file(ef_puk, tmp, file_get_size(ef_puk)); + file_put_data(ef_puk, tmp, file_get_size(ef_puk)); puk_data = file_get_data(ef_puk); free(tmp); } @@ -61,7 +61,7 @@ int cmd_puk_auth() { return SW_MEMORY_FAILURE(); } } - flash_write_data_to_file(ef, apdu.data, (uint16_t)apdu.nc); + file_put_data(ef, apdu.data, (uint16_t)apdu.nc); low_flash_available(); } else { diff --git a/src/hsm/cmd_read_binary.c b/src/hsm/cmd_read_binary.c index 7c4a6df..ee8d636 100644 --- a/src/hsm/cmd_read_binary.c +++ b/src/hsm/cmd_read_binary.c @@ -25,7 +25,7 @@ int cmd_read_binary() { if ((ins & 0x1) == 0) { if ((p1 & 0x80) != 0) { - if (!(ef = search_by_fid(p1 & 0x1f, NULL, SPECIFY_EF))) { + if (!(ef = search_file(p1 & 0x1f))) { return SW_FILE_NOT_FOUND(); } offset = p2; @@ -37,7 +37,7 @@ int cmd_read_binary() { } else { 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_file(p2 & 0x1f))) { return SW_FILE_NOT_FOUND(); } } @@ -46,9 +46,7 @@ int cmd_read_binary() { if (file_id == 0x0) { ef = currentEF; } - else if (!(ef = - search_by_fid(file_id, NULL, - SPECIFY_EF)) && !(ef = search_dynamic_file(file_id))) { + else if (!(ef = search_file(file_id))) { return SW_FILE_NOT_FOUND(); } diff --git a/src/hsm/cmd_reset_retry.c b/src/hsm/cmd_reset_retry.c index f4567d5..d17dc57 100644 --- a/src/hsm/cmd_reset_retry.c +++ b/src/hsm/cmd_reset_retry.c @@ -36,7 +36,7 @@ int cmd_reset_retry() { if (P1(apdu) == 0x0 || P1(apdu) == 0x2) { uint8_t newpin_len = 0; if (P1(apdu) == 0x0) { - uint8_t so_pin_len = file_read_uint8(file_get_data(file_sopin)); + uint8_t so_pin_len = file_read_uint8(file_sopin); if ((uint16_t)apdu.nc <= so_pin_len + 1) { return SW_WRONG_LENGTH(); } @@ -58,7 +58,7 @@ int cmd_reset_retry() { uint8_t dhash[33]; dhash[0] = newpin_len; double_hash_pin(apdu.data + (apdu.nc - newpin_len), newpin_len, dhash + 1); - flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); + file_put_data(file_pin1, dhash, sizeof(dhash)); if (pin_reset_retries(file_pin1, true) != CCID_OK) { return SW_MEMORY_FAILURE(); } @@ -82,7 +82,7 @@ int cmd_reset_retry() { return SW_COMMAND_NOT_ALLOWED(); } if (P1(apdu) == 0x1) { - uint8_t so_pin_len = file_read_uint8(file_get_data(file_sopin)); + uint8_t so_pin_len = file_read_uint8(file_sopin); if (apdu.nc != so_pin_len) { return SW_WRONG_LENGTH(); } diff --git a/src/hsm/cmd_select.c b/src/hsm/cmd_select.c index 3c8da6d..1ecf491 100644 --- a/src/hsm/cmd_select.c +++ b/src/hsm/cmd_select.c @@ -63,8 +63,7 @@ int cmd_select() { pfx == DCOD_PREFIX || pfx == DATA_PREFIX || pfx == PROT_DATA_PREFIX) {*/ - if (fid != 0x0 && !(pe = search_dynamic_file(fid)) && - !(pe = search_by_fid(fid, NULL, SPECIFY_EF))) { + if (fid != 0x0 && !(pe = search_file(fid))) { return SW_FILE_NOT_FOUND(); } /*}*/ diff --git a/src/hsm/cmd_signature.c b/src/hsm/cmd_signature.c index b75eedb..0ba2dc7 100644 --- a/src/hsm/cmd_signature.c +++ b/src/hsm/cmd_signature.c @@ -104,10 +104,7 @@ int cmd_signature() { if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if ((!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) && - !(fkey = - search_by_fid((KEY_PREFIX << 8) | key_id, NULL, - SPECIFY_EF))) || !file_has_data(fkey)) { + if (!(fkey = search_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) { return SW_FILE_NOT_FOUND(); } if (get_key_counter(fkey) == 0) { diff --git a/src/hsm/cmd_update_ef.c b/src/hsm/cmd_update_ef.c index 4b6ec18..7eba19a 100644 --- a/src/hsm/cmd_update_ef.c +++ b/src/hsm/cmd_update_ef.c @@ -72,15 +72,12 @@ int cmd_update_ef() { if (fid == 0x0 && !ef) { return SW_FILE_NOT_FOUND(); } - else if (fid != 0x0 && - !(ef = - search_by_fid(fid, NULL, - SPECIFY_EF)) && !(ef = search_dynamic_file(fid))) { //if does not exist, create it + else if (fid != 0x0 && !(ef = search_file(fid))) { //if does not exist, create it //return SW_FILE_NOT_FOUND(); ef = file_new(fid); } if (offset == 0) { - int r = flash_write_data_to_file(ef, data, data_len); + int r = file_put_data(ef, data, data_len); if (r != CCID_OK) { return SW_MEMORY_FAILURE(); } @@ -93,7 +90,7 @@ int cmd_update_ef() { uint8_t *data_merge = (uint8_t *) calloc(1, offset + data_len); memcpy(data_merge, file_get_data(ef), offset); memcpy(data_merge + offset, data, data_len); - int r = flash_write_data_to_file(ef, data_merge, offset + data_len); + int r = file_put_data(ef, data_merge, offset + data_len); free(data_merge); if (r != CCID_OK) { return SW_MEMORY_FAILURE(); diff --git a/src/hsm/cmd_verify.c b/src/hsm/cmd_verify.c index 66a725a..829cb11 100644 --- a/src/hsm/cmd_verify.c +++ b/src/hsm/cmd_verify.c @@ -39,25 +39,25 @@ int cmd_verify() { if (apdu.nc > 0) { return check_pin(file_pin1, apdu.data, (uint16_t)apdu.nc); } - if (file_read_uint8(file_get_data(file_retries_pin1)) == 0) { + if (file_read_uint8(file_retries_pin1) == 0) { 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_retries_pin1)); } else if (p2 == 0x88) { //SOPin - if (file_read_uint8(file_get_data(file_sopin)) == 0) { //not initialized + if (file_read_uint8(file_sopin) == 0) { //not initialized return SW_REFERENCE_NOT_FOUND(); } if (apdu.nc > 0) { return check_pin(file_sopin, apdu.data, (uint16_t)apdu.nc); } - if (file_read_uint8(file_get_data(file_retries_sopin)) == 0) { + if (file_read_uint8(file_retries_sopin) == 0) { return SW_PIN_BLOCKED(); } if (has_session_sopin) { 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_retries_sopin)); } else if (p2 == 0x85) { return SW_OK(); diff --git a/src/hsm/cvc.c b/src/hsm/cvc.c index fcc722c..1f9b8f0 100644 --- a/src/hsm/cvc.c +++ b/src/hsm/cvc.c @@ -323,7 +323,7 @@ uint16_t asn1_cvc_aut(void *rsa_ecdsa, uint16_t outcar_len = dev_name_len; const uint8_t *outcar = dev_name; uint16_t outcar_size = asn1_len_tag(0x42, outcar_len); - file_t *fkey = search_by_fid(EF_KEY_DEV, NULL, SPECIFY_EF); + file_t *fkey = search_file(EF_KEY_DEV); if (!fkey) { return 0; } diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 4d317b8..e6c023e 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -57,14 +57,14 @@ int load_mkek(uint8_t *mkek) { } const uint8_t *pin = NULL; if (pin == NULL && has_session_pin == true) { - file_t *tf = search_by_fid(EF_MKEK, NULL, SPECIFY_EF); + file_t *tf = search_file(EF_MKEK); if (file_has_data(tf)) { memcpy(mkek, file_get_data(tf), MKEK_SIZE); pin = session_pin; } } if (pin == NULL && has_session_sopin == true) { - file_t *tf = search_by_fid(EF_MKEK_SO, NULL, SPECIFY_EF); + file_t *tf = search_file(EF_MKEK_SO); if (file_has_data(tf)) { memcpy(mkek, file_get_data(tf), MKEK_SIZE); pin = session_sopin; @@ -137,7 +137,7 @@ int store_mkek(const uint8_t *mkek) { if (has_session_pin) { uint8_t tmp_mkek_pin[MKEK_SIZE]; memcpy(tmp_mkek_pin, tmp_mkek, MKEK_SIZE); - file_t *tf = search_by_fid(EF_MKEK, NULL, SPECIFY_EF); + file_t *tf = search_file(EF_MKEK); if (!tf) { release_mkek(tmp_mkek); release_mkek(tmp_mkek_pin); @@ -147,13 +147,13 @@ int store_mkek(const uint8_t *mkek) { MKEK_IV(tmp_mkek_pin), MKEK_KEY(tmp_mkek_pin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE); - flash_write_data_to_file(tf, tmp_mkek_pin, MKEK_SIZE); + file_put_data(tf, tmp_mkek_pin, MKEK_SIZE); release_mkek(tmp_mkek_pin); } if (has_session_sopin) { uint8_t tmp_mkek_sopin[MKEK_SIZE]; memcpy(tmp_mkek_sopin, tmp_mkek, MKEK_SIZE); - file_t *tf = search_by_fid(EF_MKEK_SO, NULL, SPECIFY_EF); + file_t *tf = search_file(EF_MKEK_SO); if (!tf) { release_mkek(tmp_mkek); release_mkek(tmp_mkek_sopin); @@ -163,7 +163,7 @@ int store_mkek(const uint8_t *mkek) { MKEK_IV(tmp_mkek_sopin), MKEK_KEY(tmp_mkek_sopin), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE); - flash_write_data_to_file(tf, tmp_mkek_sopin, MKEK_SIZE); + file_put_data(tf, tmp_mkek_sopin, MKEK_SIZE); release_mkek(tmp_mkek_sopin); } low_flash_available(); @@ -180,7 +180,7 @@ int store_dkek_key(uint8_t id, uint8_t *dkek) { if (r != CCID_OK) { return r; } - flash_write_data_to_file(tf, dkek, DKEK_KEY_SIZE); + file_put_data(tf, dkek, DKEK_KEY_SIZE); low_flash_available(); return CCID_OK; } @@ -213,7 +213,7 @@ int import_dkek_share(uint8_t id, const uint8_t *share) { for (int i = 0; i < DKEK_KEY_SIZE; i++) { tmp_dkek[i] ^= share[i]; } - flash_write_data_to_file(tf, tmp_dkek, DKEK_KEY_SIZE); + file_put_data(tf, tmp_dkek, DKEK_KEY_SIZE); low_flash_available(); return CCID_OK; } diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 03252ba..8a426dd 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -94,45 +94,45 @@ INITIALIZER( sc_hsm_ctor ) { } void scan_files() { - file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF); + file_pin1 = search_file(0x1081); if (file_pin1) { if (!file_pin1->data) { printf("PIN1 is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; - flash_write_data_to_file(file_pin1, empty, sizeof(empty)); + file_put_data(file_pin1, empty, sizeof(empty)); } } else { printf("FATAL ERROR: PIN1 not found in memory!\n"); } - file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF); + file_sopin = search_file(0x1088); if (file_sopin) { if (!file_sopin->data) { printf("SOPIN is empty. Initializing with default password\n"); const uint8_t empty[33] = { 0 }; - flash_write_data_to_file(file_sopin, empty, sizeof(empty)); + file_put_data(file_sopin, empty, sizeof(empty)); } } else { printf("FATAL ERROR: SOPIN not found in memory!\n"); } - file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF); + file_retries_pin1 = search_file(0x1083); if (file_retries_pin1) { if (!file_retries_pin1->data) { printf("Retries PIN1 is empty. Initializing with default retriesr\n"); const uint8_t retries = 3; - flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t)); + file_put_data(file_retries_pin1, &retries, sizeof(uint8_t)); } } else { printf("FATAL ERROR: Retries PIN1 not found in memory!\n"); } - file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF); + file_retries_sopin = search_file(0x108A); if (file_retries_sopin) { if (!file_retries_sopin->data) { printf("Retries SOPIN is empty. Initializing with default retries\n"); const uint8_t retries = 15; - flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t)); + file_put_data(file_retries_sopin, &retries, sizeof(uint8_t)); } } else { @@ -140,23 +140,23 @@ void scan_files() { } file_t *tf = NULL; - tf = search_by_fid(0x1082, NULL, SPECIFY_EF); + tf = search_file(0x1082); if (tf) { if (!tf->data) { printf("Max retries PIN1 is empty. Initializing with default max retriesr\n"); const uint8_t retries = 3; - flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); + file_put_data(tf, &retries, sizeof(uint8_t)); } } else { printf("FATAL ERROR: Max Retries PIN1 not found in memory!\n"); } - tf = search_by_fid(0x1089, NULL, SPECIFY_EF); + tf = search_file(0x1089); if (tf) { if (!tf->data) { printf("Max Retries SOPIN is empty. Initializing with default max retries\n"); const uint8_t retries = 15; - flash_write_data_to_file(tf, &retries, sizeof(uint8_t)); + file_put_data(tf, &retries, sizeof(uint8_t)); } } else { @@ -227,7 +227,7 @@ void reset_puk_store() { } memset(puk_store, 0, sizeof(puk_store)); puk_store_entries = 0; - file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF); + file_t *fterm = search_file(EF_TERMCA); if (fterm) { uint8_t *p = NULL, *fterm_data = file_get_data(fterm), *pq = fterm_data; uint16_t fterm_data_len = file_get_size(fterm); @@ -239,7 +239,7 @@ void reset_puk_store() { } } for (int i = 0; i < 0xfe; i++) { - file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | (uint8_t)i); + file_t *ef = search_file((CA_CERTIFICATE_PREFIX << 8) | (uint8_t)i); if (ef && file_get_size(ef) > 0) { add_cert_puk_store(file_get_data(ef), file_get_size(ef), false); } @@ -264,9 +264,9 @@ int sc_hsm_unload() { } uint16_t get_device_options() { - file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF); + file_t *ef = search_file(EF_DEVOPS); 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(ef) << 8) | file_read_uint8_offset(ef, 1); } return 0x0; } @@ -318,17 +318,17 @@ int pin_reset_retries(const file_t *pin, bool force) { if (!pin) { return CCID_ERR_NULL_PARAM; } - const file_t *max = search_by_fid(pin->fid + 1, NULL, SPECIFY_EF); - const file_t *act = search_by_fid(pin->fid + 2, NULL, SPECIFY_EF); + const file_t *max = search_file(pin->fid + 1); + const file_t *act = search_file(pin->fid + 2); if (!max || !act) { return CCID_ERR_FILE_NOT_FOUND; } - uint8_t retries = file_read_uint8(file_get_data(act)); + uint8_t retries = file_read_uint8(act); if (retries == 0 && force == false) { // blocked return CCID_ERR_BLOCKED; } - retries = file_read_uint8(file_get_data(max)); - int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries)); + retries = file_read_uint8(max); + int r = file_put_data((file_t *) act, &retries, sizeof(retries)); low_flash_available(); return r; } @@ -337,14 +337,14 @@ int pin_wrong_retry(const file_t *pin) { if (!pin) { return CCID_ERR_NULL_PARAM; } - const file_t *act = search_by_fid(pin->fid + 2, NULL, SPECIFY_EF); + const file_t *act = search_file(pin->fid + 2); if (!act) { return CCID_ERR_FILE_NOT_FOUND; } - uint8_t retries = file_read_uint8(file_get_data(act)); + uint8_t retries = file_read_uint8(act); if (retries > 0) { retries -= 1; - int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries)); + int r = file_put_data((file_t *) act, &retries, sizeof(retries)); if (r != CCID_OK) { return r; } @@ -358,8 +358,8 @@ int pin_wrong_retry(const file_t *pin) { } bool pka_enabled() { - file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF); - return file_has_data(ef_puk) && file_read_uint8(file_get_data(ef_puk)) > 0; + file_t *ef_puk = search_file(EF_PUKAUT); + return file_has_data(ef_puk) && file_read_uint8(ef_puk) > 0; } uint16_t check_pin(const file_t *pin, const uint8_t *data, uint16_t len) { @@ -544,7 +544,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { if (r != CCID_OK) { return r; } - r = flash_write_data_to_file(fpk, kdata, (uint16_t)key_size); + r = file_put_data(fpk, kdata, (uint16_t)key_size); if (r != CCID_OK) { return r; } @@ -556,7 +556,7 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { uint16_t prkd_len = asn1_build_prkd_generic(NULL, 0, (uint8_t *)key_id_str, (uint16_t)strlen(key_id_str), key_size * 8, type, kdata, sizeof(kdata)); if (prkd_len > 0) { fpk = file_new((PRKD_PREFIX << 8) | key_id); - r = flash_write_data_to_file(fpk, kdata, prkd_len); + r = file_put_data(fpk, kdata, prkd_len); if (r != 0) { return SW_EXEC_ERROR(); } From 35d5d5e94ee9091a665d742cba71d95a96dbf743 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 19:19:45 +0200 Subject: [PATCH 50/85] Use search_file() method. Signed-off-by: Pol Henarejos --- src/hsm/cmd_bip_slip.c | 2 +- src/hsm/cmd_cipher_sym.c | 2 +- src/hsm/cmd_decrypt_asym.c | 4 ++-- src/hsm/cmd_delete_file.c | 4 ++-- src/hsm/cmd_derive_asym.c | 2 +- src/hsm/cmd_key_domain.c | 10 +++++----- src/hsm/cmd_key_wrap.c | 4 ++-- src/hsm/cmd_keypair_gen.c | 2 +- src/hsm/cmd_mse.c | 2 +- src/hsm/cmd_pso.c | 2 +- src/hsm/cmd_puk_auth.c | 6 +++--- src/hsm/kek.c | 8 ++++---- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/hsm/cmd_bip_slip.c b/src/hsm/cmd_bip_slip.c index 15cce9b..20f271c 100644 --- a/src/hsm/cmd_bip_slip.c +++ b/src/hsm/cmd_bip_slip.c @@ -113,7 +113,7 @@ int load_master_bip(uint16_t mid, mbedtls_ecp_keypair *ctx, uint8_t chain[32], uint8_t key_type[1]) { uint8_t mkey[65]; mbedtls_ecp_keypair_init(ctx); - file_t *ef = search_dynamic_file(EF_MASTER_SEED | mid); + file_t *ef = search_file(EF_MASTER_SEED | mid); if (!file_has_data(ef)) { return CCID_ERR_FILE_NOT_FOUND; } diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index 6de1409..a99d465 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -170,7 +170,7 @@ int cmd_cipher_sym() { if (wait_button_pressed() == true) { // timeout return SW_SECURE_MESSAGE_EXEC_ERROR(); } - file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); + file_t *ef = search_file((KEY_PREFIX << 8) | key_id); if (hd_keytype == 0) { if (!ef) { return SW_FILE_NOT_FOUND(); diff --git a/src/hsm/cmd_decrypt_asym.c b/src/hsm/cmd_decrypt_asym.c index e68853e..fc9777e 100644 --- a/src/hsm/cmd_decrypt_asym.c +++ b/src/hsm/cmd_decrypt_asym.c @@ -32,7 +32,7 @@ int cmd_decrypt_asym() { if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); + file_t *ef = search_file((KEY_PREFIX << 8) | key_id); if (!ef) { return SW_FILE_NOT_FOUND(); } @@ -174,7 +174,7 @@ int cmd_decrypt_asym() { return SW_WRONG_DATA(); } for (uint8_t n = 0; n < MAX_KEY_DOMAINS; n++) { - file_t *tf = search_dynamic_file(EF_XKEK + n); + file_t *tf = search_file(EF_XKEK + n); if (tf) { if (file_get_size(tf) == kdom_uid.len && memcmp(file_get_data(tf), kdom_uid.data, kdom_uid.len) == 0) { diff --git a/src/hsm/cmd_delete_file.c b/src/hsm/cmd_delete_file.c index 90a9616..0919293 100644 --- a/src/hsm/cmd_delete_file.c +++ b/src/hsm/cmd_delete_file.c @@ -25,13 +25,13 @@ int cmd_delete_file() { if (apdu.nc == 0) { ef = currentEF; - if (!(ef = search_dynamic_file(ef->fid))) { + if (!(ef = search_file(ef->fid))) { return SW_FILE_NOT_FOUND(); } } else { uint16_t fid = (apdu.data[0] << 8) | apdu.data[1]; - if (!(ef = search_dynamic_file(fid))) { + if (!(ef = search_file(fid))) { return SW_FILE_NOT_FOUND(); } } diff --git a/src/hsm/cmd_derive_asym.c b/src/hsm/cmd_derive_asym.c index ff59009..47e26ed 100644 --- a/src/hsm/cmd_derive_asym.c +++ b/src/hsm/cmd_derive_asym.c @@ -43,7 +43,7 @@ int cmd_derive_asym() { if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - if (!(fkey = search_dynamic_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) { + if (!(fkey = search_file((KEY_PREFIX << 8) | key_id)) || !file_has_data(fkey)) { return SW_FILE_NOT_FOUND(); } if (key_has_purpose(fkey, ALGO_EC_DERIVE) == false) { diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index a73cf47..6566996 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -89,7 +89,7 @@ int cmd_key_domain() { low_flash_available(); } else { - file_t *tf = search_dynamic_file(EF_XKEK + p2); + file_t *tf = search_file(EF_XKEK + p2); if (2 * p2 >= tf_kd_size) { return SW_INCORRECT_P1P2(); } @@ -104,7 +104,7 @@ int cmd_key_domain() { } if (p1 == 0x3) { //if key domain is not empty, command is denied for (uint16_t i = 1; i < 256; i++) { - file_t *fkey = search_dynamic_file(KEY_PREFIX << 8 | (uint8_t)i); + file_t *fkey = search_file(KEY_PREFIX << 8 | (uint8_t)i); if (get_key_domain(fkey) == p2) { return SW_FILE_EXISTS(); } @@ -133,12 +133,12 @@ int cmd_key_domain() { return SW_EXEC_ERROR(); } file_t *tf = NULL; - if ((tf = search_dynamic_file(EF_DKEK + p2))) { + if ((tf = search_file(EF_DKEK + p2))) { if (delete_file(tf) != CCID_OK) { return SW_EXEC_ERROR(); } } - if (p1 == 0x3 && (tf = search_dynamic_file(EF_XKEK + p2))) { + if (p1 == 0x3 && (tf = search_file(EF_XKEK + p2))) { if (delete_file(tf) != CCID_OK) { return SW_EXEC_ERROR(); } @@ -203,7 +203,7 @@ int cmd_key_domain() { res_APDU[1] = dkeks > current_dkeks ? dkeks - current_dkeks : 0; dkek_kcv(p2, res_APDU + 2); res_APDU_size = 2 + 8; - file_t *tf = search_dynamic_file(EF_XKEK + p2); + file_t *tf = search_file(EF_XKEK + p2); if (tf) { memcpy(res_APDU + 10, file_get_data(tf), file_get_size(tf)); res_APDU_size += file_get_size(tf); diff --git a/src/hsm/cmd_key_wrap.c b/src/hsm/cmd_key_wrap.c index 75529e1..1244ed9 100644 --- a/src/hsm/cmd_key_wrap.c +++ b/src/hsm/cmd_key_wrap.c @@ -32,7 +32,7 @@ int cmd_key_wrap() { if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - file_t *ef = search_dynamic_file((KEY_PREFIX << 8) | key_id); + file_t *ef = search_file((KEY_PREFIX << 8) | key_id); if (!ef) { return SW_FILE_NOT_FOUND(); } @@ -49,7 +49,7 @@ int cmd_key_wrap() { if (key_has_purpose(ef, ALGO_WRAP) == false) { return SW_CONDITIONS_NOT_SATISFIED(); } - file_t *prkd = search_dynamic_file((PRKD_PREFIX << 8) | key_id); + file_t *prkd = search_file((PRKD_PREFIX << 8) | key_id); if (!prkd) { return SW_FILE_NOT_FOUND(); } diff --git a/src/hsm/cmd_keypair_gen.c b/src/hsm/cmd_keypair_gen.c index fe266ba..c0639c4 100644 --- a/src/hsm/cmd_keypair_gen.c +++ b/src/hsm/cmd_keypair_gen.c @@ -98,7 +98,7 @@ int cmd_keypair_gen() { if (a92.data[0] > MAX_KEY_DOMAINS) { return SW_WRONG_DATA(); } - file_t *tf_xkek = search_dynamic_file(EF_XKEK + a92.data[0]); + file_t *tf_xkek = search_file(EF_XKEK + a92.data[0]); if (!tf_xkek) { return SW_WRONG_DATA(); } diff --git a/src/hsm/cmd_mse.c b/src/hsm/cmd_mse.c index f930494..1e6a5a4 100644 --- a/src/hsm/cmd_mse.c +++ b/src/hsm/cmd_mse.c @@ -57,7 +57,7 @@ int cmd_mse() { } else if (p2 == 0xA4) { /* Aut */ for (uint8_t i = 0; i < MAX_PUK; i++) { - file_t *ef = search_dynamic_file(EF_PUK + i); + file_t *ef = search_file(EF_PUK + i); if (!ef) { break; } diff --git a/src/hsm/cmd_pso.c b/src/hsm/cmd_pso.c index 70757a1..cbaec4d 100644 --- a/src/hsm/cmd_pso.c +++ b/src/hsm/cmd_pso.c @@ -51,7 +51,7 @@ int cmd_pso() { } for (uint8_t i = 0; i < 0xfe; i++) { uint16_t fid = (CA_CERTIFICATE_PREFIX << 8) | i; - file_t *ca_ef = search_dynamic_file(fid); + file_t *ca_ef = search_file(fid); if (!ca_ef) { ca_ef = file_new(fid); file_put_data(ca_ef, apdu.data, (uint16_t)apdu.nc); diff --git a/src/hsm/cmd_puk_auth.c b/src/hsm/cmd_puk_auth.c index ac4b102..aaf835d 100644 --- a/src/hsm/cmd_puk_auth.c +++ b/src/hsm/cmd_puk_auth.c @@ -37,7 +37,7 @@ int cmd_puk_auth() { return SW_INCORRECT_P1P2(); } for (uint8_t i = 0; i < puk_data[0]; i++) { - ef = search_dynamic_file(EF_PUK + i); + ef = search_file(EF_PUK + i); if (!ef) { /* Never should not happen */ return SW_MEMORY_FAILURE(); } @@ -56,7 +56,7 @@ int cmd_puk_auth() { if (p2 >= puk_data[0]) { return SW_INCORRECT_P1P2(); } - ef = search_dynamic_file(EF_PUK + p2); + ef = search_file(EF_PUK + p2); if (!ef) { /* Never should not happen */ return SW_MEMORY_FAILURE(); } @@ -72,7 +72,7 @@ int cmd_puk_auth() { if (p2 >= puk_data[0]) { return SW_INCORRECT_P1P2(); } - file_t *ef = search_dynamic_file(EF_PUK + p2); + file_t *ef = search_file(EF_PUK + p2); if (!ef) { return SW_INCORRECT_P1P2(); } diff --git a/src/hsm/kek.c b/src/hsm/kek.c index e6c023e..945341e 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -109,7 +109,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len) { } int load_dkek(uint8_t id, uint8_t *dkek) { - file_t *tf = search_dynamic_file(EF_DKEK + id); + file_t *tf = search_file(EF_DKEK + id); if (!tf) { return CCID_ERR_FILE_NOT_FOUND; } @@ -172,7 +172,7 @@ int store_mkek(const uint8_t *mkek) { } int store_dkek_key(uint8_t id, uint8_t *dkek) { - file_t *tf = search_dynamic_file(EF_DKEK + id); + file_t *tf = search_file(EF_DKEK + id); if (!tf) { return CCID_ERR_FILE_NOT_FOUND; } @@ -188,7 +188,7 @@ int store_dkek_key(uint8_t id, uint8_t *dkek) { int save_dkek_key(uint8_t id, const uint8_t *key) { uint8_t dkek[DKEK_KEY_SIZE]; if (!key) { - file_t *tf = search_dynamic_file(EF_DKEK + id); + file_t *tf = search_file(EF_DKEK + id); if (!tf) { return CCID_ERR_FILE_NOT_FOUND; } @@ -202,7 +202,7 @@ int save_dkek_key(uint8_t id, const uint8_t *key) { int import_dkek_share(uint8_t id, const uint8_t *share) { uint8_t tmp_dkek[DKEK_KEY_SIZE]; - file_t *tf = search_dynamic_file(EF_DKEK + id); + file_t *tf = search_file(EF_DKEK + id); if (!tf) { return CCID_ERR_FILE_NOT_FOUND; } From 001d076fdf96987710c4e544c09fa12bd6ac6394 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 19:42:23 +0200 Subject: [PATCH 51/85] Better check for XKEK content. Signed-off-by: Pol Henarejos --- src/hsm/cmd_key_domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hsm/cmd_key_domain.c b/src/hsm/cmd_key_domain.c index 6566996..43c9a54 100644 --- a/src/hsm/cmd_key_domain.c +++ b/src/hsm/cmd_key_domain.c @@ -93,7 +93,7 @@ int cmd_key_domain() { if (2 * p2 >= tf_kd_size) { return SW_INCORRECT_P1P2(); } - if (current_dkeks == 0xff && !tf) { //XKEK have always 0xff + if (current_dkeks == 0xff && !file_has_data(tf)) { //XKEK have always 0xff return SW_REFERENCE_NOT_FOUND(); } } @@ -204,7 +204,7 @@ int cmd_key_domain() { dkek_kcv(p2, res_APDU + 2); res_APDU_size = 2 + 8; file_t *tf = search_file(EF_XKEK + p2); - if (tf) { + if (file_has_data(tf)) { memcpy(res_APDU + 10, file_get_data(tf), file_get_size(tf)); res_APDU_size += file_get_size(tf); } From 25c93c279fcf871c4a345044509f1f6364a4e24c Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 19:42:47 +0200 Subject: [PATCH 52/85] Fix potential crash on loading dkek. Signed-off-by: Pol Henarejos --- src/hsm/kek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hsm/kek.c b/src/hsm/kek.c index 945341e..688fdbb 100644 --- a/src/hsm/kek.c +++ b/src/hsm/kek.c @@ -110,7 +110,7 @@ int mse_decrypt_ct(uint8_t *data, size_t len) { int load_dkek(uint8_t id, uint8_t *dkek) { file_t *tf = search_file(EF_DKEK + id); - if (!tf) { + if (!file_has_data(tf)) { return CCID_ERR_FILE_NOT_FOUND; } memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE); From 8e8192362c2c583976fafaa9d28e5d71064ccaf3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 17 Apr 2024 19:43:10 +0200 Subject: [PATCH 53/85] Use macros for referring system fids. Signed-off-by: Pol Henarejos --- src/hsm/cmd_initialize.c | 2 +- src/hsm/files.c | 12 ++++++------ src/hsm/files.h | 8 +++++++- src/hsm/sc_hsm.c | 12 ++++++------ 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/hsm/cmd_initialize.c b/src/hsm/cmd_initialize.c index 083d60a..6906481 100644 --- a/src/hsm/cmd_initialize.c +++ b/src/hsm/cmd_initialize.c @@ -77,7 +77,7 @@ int cmd_initialize() { } } else if (tag == 0x91) { //retries user pin - file_t *tf = search_file(0x1082); + file_t *tf = search_file(EF_PIN1_MAX_RETRIES); if (tf && tf->data) { file_put_data(tf, tag_data, tag_len); } diff --git a/src/hsm/files.c b/src/hsm/files.c index 8a5fb4b..dba2367 100644 --- a/src/hsm/files.c +++ b/src/hsm/files.c @@ -41,22 +41,22 @@ file_t file_entries[] = { .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.TokenInfo /* 8 */ { .fid = 0x5033, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.UnusedSpace - /* 9 */ { .fid = 0x1081, .parent = 5, .name = NULL, + /* 9 */ { .fid = EF_PIN1, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //PIN (PIN1) - /* 10 */ { .fid = 0x1082, .parent = 5, .name = NULL, + /* 10 */ { .fid = EF_PIN1_MAX_RETRIES, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //max retries PIN (PIN1) - /* 11 */ { .fid = 0x1083, .parent = 5, .name = NULL, + /* 11 */ { .fid = EF_PIN1_RETRIES, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (PIN1) - /* 12 */ { .fid = 0x1088, .parent = 5, .name = NULL, + /* 12 */ { .fid = EF_SOPIN, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //PIN (SOPIN) - /* 13 */ { .fid = 0x1089, .parent = 5, .name = NULL, + /* 13 */ { .fid = EF_SOPIN_MAX_RETRIES, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //max retries PIN (SOPIN) - /* 14 */ { .fid = 0x108A, .parent = 5, .name = NULL, + /* 14 */ { .fid = EF_SOPIN_RETRIES, .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0xff } }, //retries PIN (SOPIN) /* 15 */ { .fid = EF_DEVOPS, .parent = 5, .name = NULL, diff --git a/src/hsm/files.h b/src/hsm/files.h index 8637fc8..e436c92 100644 --- a/src/hsm/files.h +++ b/src/hsm/files.h @@ -24,7 +24,13 @@ #define EF_DEVOPS 0x100E #define EF_MKEK 0x100A #define EF_MKEK_SO 0x100B -#define EF_XKEK 0x1080 +#define EF_XKEK 0x1070 +#define EF_PIN1 0x1081 +#define EF_PIN1_MAX_RETRIES 0x1082 +#define EF_PIN1_RETRIES 0x1083 +#define EF_SOPIN 0x1088 +#define EF_SOPIN_MAX_RETRIES 0x1089 +#define EF_SOPIN_RETRIES 0x108A #define EF_DKEK 0x1090 #define EF_KEY_DOMAIN 0x10A0 #define EF_PUKAUT 0x10C0 diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 8a426dd..b0498e1 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -94,7 +94,7 @@ INITIALIZER( sc_hsm_ctor ) { } void scan_files() { - file_pin1 = search_file(0x1081); + file_pin1 = search_file(EF_PIN1); if (file_pin1) { if (!file_pin1->data) { printf("PIN1 is empty. Initializing with default password\n"); @@ -105,7 +105,7 @@ void scan_files() { else { printf("FATAL ERROR: PIN1 not found in memory!\n"); } - file_sopin = search_file(0x1088); + file_sopin = search_file(EF_SOPIN); if (file_sopin) { if (!file_sopin->data) { printf("SOPIN is empty. Initializing with default password\n"); @@ -116,7 +116,7 @@ void scan_files() { else { printf("FATAL ERROR: SOPIN not found in memory!\n"); } - file_retries_pin1 = search_file(0x1083); + file_retries_pin1 = search_file(EF_PIN1_RETRIES); if (file_retries_pin1) { if (!file_retries_pin1->data) { printf("Retries PIN1 is empty. Initializing with default retriesr\n"); @@ -127,7 +127,7 @@ void scan_files() { else { printf("FATAL ERROR: Retries PIN1 not found in memory!\n"); } - file_retries_sopin = search_file(0x108A); + file_retries_sopin = search_file(EF_SOPIN_RETRIES); if (file_retries_sopin) { if (!file_retries_sopin->data) { printf("Retries SOPIN is empty. Initializing with default retries\n"); @@ -140,7 +140,7 @@ void scan_files() { } file_t *tf = NULL; - tf = search_file(0x1082); + tf = search_file(EF_PIN1_MAX_RETRIES); if (tf) { if (!tf->data) { printf("Max retries PIN1 is empty. Initializing with default max retriesr\n"); @@ -151,7 +151,7 @@ void scan_files() { else { printf("FATAL ERROR: Max Retries PIN1 not found in memory!\n"); } - tf = search_file(0x1089); + tf = search_file(EF_SOPIN_MAX_RETRIES); if (tf) { if (!tf->data) { printf("Max Retries SOPIN is empty. Initializing with default max retries\n"); From de89d61359c865751ea098d182959fab4849387d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 22 Apr 2024 23:44:00 +0200 Subject: [PATCH 54/85] Use new file methods. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index ef196bf..a5f19a1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit ef196bf10ba29410df712b54beef8a2c4876300a +Subproject commit a5f19a135673d5bd4edb9f10cea65758a3e7e7d5 From 218660e6946b06dcbea37215356f71bc4dce4b61 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 22 Apr 2024 23:47:08 +0200 Subject: [PATCH 55/85] Only allow change PHY without PIN. PIN is required for other extra options. Signed-off-by: Pol Henarejos --- src/hsm/cmd_extras.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index f801852..02736ee 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -28,6 +28,12 @@ #include "mbedtls/chachapoly.h" int cmd_extras() { +#ifndef ENABLE_EMULATION + // Only allow change PHY without PIN + if (!isUserAuthenticated && P1(apdu) != 0x1B) { + return SW_SECURITY_STATUS_NOT_SATISFIED(); + } +#endif if (P1(apdu) == 0xA) { //datetime operations if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); From 294ca81d7d26356ecfe6f9a2dd66f4216ce6e35b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 30 May 2024 19:18:37 +0200 Subject: [PATCH 56/85] Upgrade patch_vidpid with newer Pico Keys SDK. Signed-off-by: Pol Henarejos --- tools/pico-hsm-patch-vidpid.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pico-hsm-patch-vidpid.sh b/tools/pico-hsm-patch-vidpid.sh index c2881db..6eacdc4 100755 --- a/tools/pico-hsm-patch-vidpid.sh +++ b/tools/pico-hsm-patch-vidpid.sh @@ -17,7 +17,7 @@ # along with this program. If not, see . # -VERSION_MAJOR="4" #Version of Pico CCID Core +VERSION_MAJOR="5" #Version of Pico Keys SDK VERSION_MINOR="0" echo "----------------------------" From 07079b6ba1de4ea095f0c15d21f636e4e9e5cc30 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 30 May 2024 19:19:02 +0200 Subject: [PATCH 57/85] Add descriptive message. Signed-off-by: Pol Henarejos --- tools/pico-hsm-tool.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 7d7813f..91840be 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -464,6 +464,8 @@ def phy(picohsm, args): ret = picohsm.phy(args.subcommand, val) if (ret): print(f'Current value: {hexlify(ret)}') + else: + print('Command executed successfully. Please, restart your Pico Key.') def main(args): sys.stderr.buffer.write(b'Pico HSM Tool v1.12\n') From 87ffd21543ba4df1e8b52e25e32f5e1cecff35f7 Mon Sep 17 00:00:00 2001 From: fastchain Date: Thu, 13 Jun 2024 16:09:54 +0900 Subject: [PATCH 58/85] Update cmd_extras.c This security fix ensures that the extra settings, cannot be silently disabled, if button control enabled. So the button control setting cannot be silently (without button push) disabled, even if the user's PC is fully compromised. --- src/hsm/cmd_extras.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index e0f26ba..d484b17 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -28,6 +28,10 @@ #include "mbedtls/chachapoly.h" int cmd_extras() { + //check button (if enabled) + if (wait_button_pressed() == true) { + return SW_SECURE_MESSAGE_EXEC_ERROR(); + } if (P1(apdu) == 0xA) { //datetime operations if (P2(apdu) != 0x0) { return SW_INCORRECT_P1P2(); From 54cdbfc22c3306fb56da9f621962d785ad1095db Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 22:01:15 +0200 Subject: [PATCH 59/85] Add PHY OPTS. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_extras.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index a5f19a1..d458250 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit a5f19a135673d5bd4edb9f10cea65758a3e7e7d5 +Subproject commit d4582508879bb7d6022bcf0dd03f823e29c5db30 diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index 02736ee..cbbde54 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -227,6 +227,12 @@ int cmd_extras() { } tmp[P2(apdu)] = apdu.data[0]; } + else if (P2(apdu) == PHY_OPTS) { + if (apdu.nc != 2) { + return SW_WRONG_LENGTH(); + } + memcpy(tmp + PHY_OPTS, apdu.data, 2); + } else { return SW_INCORRECT_P1P2(); } From 50a29519bdc7f3e4a92884fddc1846f660db040d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 22:03:39 +0200 Subject: [PATCH 60/85] First release to support ESP32. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index d458250..59597a0 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit d4582508879bb7d6022bcf0dd03f823e29c5db30 +Subproject commit 59597a0a683ac7d0cf4be78b2a2000b5615ea125 From e7d4a5dd3df822dc79020e44b515caec11544dff Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 22:35:04 +0200 Subject: [PATCH 61/85] Fix tusb initialization. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 59597a0..a0e55eb 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 59597a0a683ac7d0cf4be78b2a2000b5615ea125 +Subproject commit a0e55ebfaed615a7627c63282d57fdfa3b7e106c From f20fdc9bda8a99aca46d016f4710f8ee8be15ec5 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 22:42:19 +0200 Subject: [PATCH 62/85] Add missing header. Signed-off-by: Pol Henarejos --- src/hsm/cmd_extras.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index c9f2792..211c796 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -19,6 +19,7 @@ #include "mbedtls/ecdh.h" #if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "hardware/rtc.h" +#include #else #include #endif From dd68554782da971925ac105d25a2ae465cbc2dc9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 23:29:05 +0200 Subject: [PATCH 63/85] Added support for enable/disable Web CCID on the fly. Signed-off-by: Pol Henarejos --- CMakeLists.txt | 1 + pico-keys-sdk | 2 +- tools/pico-hsm-tool.py | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e926f6..a9d5871 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ set(SOURCES ${SOURCES} ) set(USB_ITF_CCID 1) +set(USB_ITF_WCID 1) include(pico-keys-sdk/pico_keys_sdk_import.cmake) if(ESP_PLATFORM) project(pico_hsm) diff --git a/pico-keys-sdk b/pico-keys-sdk index a0e55eb..218441a 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit a0e55ebfaed615a7627c63282d57fdfa3b7e106c +Subproject commit 218441a45a50993c585ad74b3d0a632d2cf1124e diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index 91840be..c06e1ba 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -95,8 +95,10 @@ def parse_args(): subparser_phy = parser_phy.add_subparsers(title='commands', dest='subcommand', required=True) parser_phy_vp = subparser_phy.add_parser('vidpid', help='Sets VID/PID. Use VID:PID format (e.g. 1234:5678)') parser_phy_ledn = subparser_phy.add_parser('led', help='Sets LED GPIO number.') + parser_phy_optwcid = subparser_phy.add_parser('wcid', help='Enable/Disable Web CCID interface.') parser_phy_vp.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') parser_phy_ledn.add_argument('value', help='Value of the PHY option.', metavar='VAL', nargs='?') + parser_phy_optwcid.add_argument('value', choices=['enable', 'disable'], help='Enable/Disable Web CCID interface.', nargs='?') parser_secure = subparser.add_parser('secure', help='Manages security of Pico HSM.') subparser_secure = parser_secure.add_subparsers(title='commands', dest='subcommand', required=True) @@ -461,6 +463,8 @@ def phy(picohsm, args): val = int(sp[0],16).to_bytes(2, 'big') + int(sp[1],16).to_bytes(2, 'big') elif (args.subcommand == 'led'): val = [int(val)] + elif (args.subcommand == 'wcid'): + val = val == 'enable' ret = picohsm.phy(args.subcommand, val) if (ret): print(f'Current value: {hexlify(ret)}') @@ -468,7 +472,7 @@ def phy(picohsm, args): print('Command executed successfully. Please, restart your Pico Key.') def main(args): - sys.stderr.buffer.write(b'Pico HSM Tool v1.12\n') + sys.stderr.buffer.write(b'Pico HSM Tool v1.14\n') sys.stderr.buffer.write(b'Author: Pol Henarejos\n') sys.stderr.buffer.write(b'Report bugs to https://github.com/polhenarejos/pico-hsm/issues\n') sys.stderr.buffer.write(b'\n\n') From 79f76a176daed7289b1e7454353bc0418f38f7e3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Wed, 19 Jun 2024 23:36:41 +0200 Subject: [PATCH 64/85] Fix time.h header. Signed-off-by: Pol Henarejos --- src/hsm/cmd_extras.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index 211c796..eaea88e 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -19,9 +19,9 @@ #include "mbedtls/ecdh.h" #if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) #include "hardware/rtc.h" -#include #else #include +#include #endif #include "files.h" #include "random.h" From 99c777c780278086e6ae6ea1d3468b7283dc73c7 Mon Sep 17 00:00:00 2001 From: al heisner Date: Fri, 21 Jun 2024 11:35:05 -0500 Subject: [PATCH 65/85] Fix for multiples of 64 bytes on cmd_list_keys --- src/hsm/cmd_list_keys.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hsm/cmd_list_keys.c b/src/hsm/cmd_list_keys.c index ef92c6f..d3bc6af 100644 --- a/src/hsm/cmd_list_keys.c +++ b/src/hsm/cmd_list_keys.c @@ -60,5 +60,9 @@ int cmd_list_keys() { res_APDU[res_APDU_size++] = f->fid & 0xff; } } + if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64 + res_APDU[res_APDU_size++] = 0; + res_APDU[res_APDU_size++] = 0; + } return SW_OK(); } From 47acef71c86b1545cab818dc8110035818845532 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 21 Jun 2024 21:11:18 +0200 Subject: [PATCH 66/85] Only when not emulation. Signed-off-by: Pol Henarejos --- src/hsm/cmd_list_keys.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hsm/cmd_list_keys.c b/src/hsm/cmd_list_keys.c index d3bc6af..da09a08 100644 --- a/src/hsm/cmd_list_keys.c +++ b/src/hsm/cmd_list_keys.c @@ -60,9 +60,11 @@ int cmd_list_keys() { res_APDU[res_APDU_size++] = f->fid & 0xff; } } - if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64 +#if !defined(ENABLE_EMULATION) + if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64 + res_APDU[res_APDU_size++] = 0; res_APDU[res_APDU_size++] = 0; - res_APDU[res_APDU_size++] = 0; } +#endif return SW_OK(); } From 223fc117dd92643075e6919fa393e48018a259fb Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 21 Jun 2024 21:15:29 +0200 Subject: [PATCH 67/85] Enable patch only for RPI Signed-off-by: Pol Henarejos --- src/hsm/cmd_list_keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hsm/cmd_list_keys.c b/src/hsm/cmd_list_keys.c index 566fd93..2dcca8a 100644 --- a/src/hsm/cmd_list_keys.c +++ b/src/hsm/cmd_list_keys.c @@ -60,7 +60,7 @@ int cmd_list_keys() { res_APDU[res_APDU_size++] = f->fid & 0xff; } } -#if !defined(ENABLE_EMULATION) +#if !defined(ENABLE_EMULATION) && !defined(ESP_PLATFORM) if ((apdu.rlen + 2 + 10) % 64 == 0) { // FIX for strange behaviour with PSCS and multiple of 64 res_APDU[res_APDU_size++] = 0; res_APDU[res_APDU_size++] = 0; From c4a08aff0f3c94d30c32137dfe51f8f66161db50 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 21 Jun 2024 21:29:32 +0200 Subject: [PATCH 68/85] Upgrade to Mbedtls 3.6 Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/sc_hsm.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 218441a..f848029 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 218441a45a50993c585ad74b3d0a632d2cf1124e +Subproject commit f8480291fe2325b6658ee94320aa028eeec98b23 diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 5b76499..69d7a3e 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -513,9 +513,8 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { } else if (type & PICO_KEYS_KEY_EC) { mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; - key_size = (uint16_t)mbedtls_mpi_size(&ecdsa->d); kdata[0] = ecdsa->grp.id & 0xff; - mbedtls_ecp_write_key(ecdsa, kdata + 1, key_size); + mbedtls_ecp_write_key_ext(ecdsa, (size_t *)&key_size, kdata + 1, sizeof(kdata) - 1); key_size++; } else if (type & PICO_KEYS_KEY_AES) { From 9a7be98e6e2927a323ff83d9b28e41f1172fbd83 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 21 Jun 2024 22:08:36 +0200 Subject: [PATCH 69/85] Settings proper phy options Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_extras.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index f848029..2700163 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit f8480291fe2325b6658ee94320aa028eeec98b23 +Subproject commit 2700163e1f861d75cc31d188bc9426b01e6dac75 diff --git a/src/hsm/cmd_extras.c b/src/hsm/cmd_extras.c index 5e1748a..e304f08 100644 --- a/src/hsm/cmd_extras.c +++ b/src/hsm/cmd_extras.c @@ -37,7 +37,7 @@ int cmd_extras() { } #endif //check button (if enabled) - if (wait_button_pressed() == true) { + if (wait_button_pressed() == true) { return SW_SECURE_MESSAGE_EXEC_ERROR(); } if (P1(apdu) == 0xA) { //datetime operations @@ -243,30 +243,44 @@ int cmd_extras() { else { uint8_t tmp[PHY_MAX_SIZE]; memset(tmp, 0, sizeof(tmp)); + uint16_t opts = 0; if (file_has_data(ef_phy)) { memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy))); + if (file_get_size(ef_phy) >= 8) { + opts = (tmp[PHY_OPTS] << 8) | tmp[PHY_OPTS + 1]; + } } if (P2(apdu) == PHY_VID) { // VIDPID if (apdu.nc != 4) { return SW_WRONG_LENGTH(); } memcpy(tmp + PHY_VID, apdu.data, 4); + opts |= PHY_OPT_VPID; } else if (P2(apdu) == PHY_LED_GPIO || P2(apdu) == PHY_LED_MODE) { if (apdu.nc != 1) { return SW_WRONG_LENGTH(); } tmp[P2(apdu)] = apdu.data[0]; + if (P2(apdu) == PHY_LED_GPIO) { + opts |= PHY_OPT_GPIO; + } + else if (P2(apdu) == PHY_LED_MODE) { + opts |= PHY_OPT_LED; + } } else if (P2(apdu) == PHY_OPTS) { if (apdu.nc != 2) { return SW_WRONG_LENGTH(); } - memcpy(tmp + PHY_OPTS, apdu.data, 2); + uint16_t opt = (apdu.data[0] << 8) | apdu.data[1]; + opts = (opts & ~PHY_OPT_MASK) | (opt & PHY_OPT_MASK); } else { return SW_INCORRECT_P1P2(); } + tmp[PHY_OPTS] = opts >> 8; + tmp[PHY_OPTS + 1] = opts & 0xff; file_put_data(ef_phy, tmp, sizeof(tmp)); low_flash_available(); } From ed89175edc57c2c9a1d7f327f481d0011b9a2a6a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 22 Jun 2024 19:03:58 +0200 Subject: [PATCH 70/85] Fix rare overflow (never happens). Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 2700163..447c68f 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 2700163e1f861d75cc31d188bc9426b01e6dac75 +Subproject commit 447c68febd3f5586790d7c6155d02bf244814b4e From 237e687c3ba7c216b2ecd34bfe7613fc7f17e967 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sat, 22 Jun 2024 20:57:28 +0200 Subject: [PATCH 71/85] Upgrade to Pico Keys SDK v6.0 Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- tools/pico-hsm-patch-vidpid.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 447c68f..01d1de6 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 447c68febd3f5586790d7c6155d02bf244814b4e +Subproject commit 01d1de6074ab8be93319e469f1f706a7dc444a24 diff --git a/tools/pico-hsm-patch-vidpid.sh b/tools/pico-hsm-patch-vidpid.sh index 6eacdc4..3ca4414 100755 --- a/tools/pico-hsm-patch-vidpid.sh +++ b/tools/pico-hsm-patch-vidpid.sh @@ -17,7 +17,7 @@ # along with this program. If not, see . # -VERSION_MAJOR="5" #Version of Pico Keys SDK +VERSION_MAJOR="6" #Version of Pico Keys SDK VERSION_MINOR="0" echo "----------------------------" From dc979194fa863863bb3090649beeaf7faca77f0d Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 23 Jun 2024 01:00:14 +0200 Subject: [PATCH 72/85] Fix crash in mbedtls 3.6 Signed-off-by: Pol Henarejos --- src/hsm/sc_hsm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 69d7a3e..66daccb 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -513,9 +513,10 @@ int store_keys(void *key_ctx, int type, uint8_t key_id) { } else if (type & PICO_KEYS_KEY_EC) { mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx; + size_t olen = 0; kdata[0] = ecdsa->grp.id & 0xff; - mbedtls_ecp_write_key_ext(ecdsa, (size_t *)&key_size, kdata + 1, sizeof(kdata) - 1); - key_size++; + mbedtls_ecp_write_key_ext(ecdsa, &olen, kdata + 1, sizeof(kdata) - 1); + key_size = olen + 1; } else if (type & PICO_KEYS_KEY_AES) { if (type == PICO_KEYS_KEY_AES_128) { From d708158feae4fe072368e3e733c134b385b82663 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 23 Jun 2024 01:17:01 +0200 Subject: [PATCH 73/85] Fix key unwrap with latest OpenSC. Fixes #41. SC-HSM driver in OpenSC has changed the procedure for unwraping. It stores the wrap into a temporary file (0x2F10) and then it calls unwrap cmd. Signed-off-by: Pol Henarejos --- src/hsm/cmd_key_unwrap.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/hsm/cmd_key_unwrap.c b/src/hsm/cmd_key_unwrap.c index c2905c8..3c2f5a5 100644 --- a/src/hsm/cmd_key_unwrap.c +++ b/src/hsm/cmd_key_unwrap.c @@ -29,7 +29,17 @@ int cmd_key_unwrap() { if (!isUserAuthenticated) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } - int key_type = dkek_type_key(apdu.data); + uint8_t *data = apdu.data; + uint16_t data_len = apdu.nc; + if (data_len == 0) { // New style + file_t *tef = search_file(0x2F10); + if (!file_has_data(tef)) { + return SW_FILE_NOT_FOUND(); + } + data = file_get_data(tef); + data_len = file_get_size(tef); + } + int key_type = dkek_type_key(data); uint8_t *allowed = NULL; int16_t kdom = -1; uint16_t allowed_len = 0; @@ -40,7 +50,7 @@ int cmd_key_unwrap() { mbedtls_rsa_context ctx; mbedtls_rsa_init(&ctx); do { - r = dkek_decode_key((uint8_t)++kdom, &ctx, apdu.data, (uint16_t)apdu.nc, NULL, &allowed, &allowed_len); + r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len); } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { mbedtls_rsa_free(&ctx); @@ -60,7 +70,7 @@ int cmd_key_unwrap() { mbedtls_ecdsa_context ctx; mbedtls_ecdsa_init(&ctx); do { - r = dkek_decode_key((uint8_t)++kdom, &ctx, apdu.data, (uint16_t)apdu.nc, NULL, &allowed, &allowed_len); + r = dkek_decode_key((uint8_t)++kdom, &ctx, data, data_len, NULL, &allowed, &allowed_len); } while ((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS); if (r != CCID_OK) { mbedtls_ecdsa_free(&ctx); @@ -82,8 +92,8 @@ int cmd_key_unwrap() { do { r = dkek_decode_key((uint8_t)++kdom, aes_key, - apdu.data, - (uint16_t)apdu.nc, + data, + data_len, &key_size, &allowed, &allowed_len); From d3751e391895a92d8a54b1455bb45a56dbb9c305 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 23 Jun 2024 01:18:19 +0200 Subject: [PATCH 74/85] Upgrade opensc version in workflows. Signed-off-by: Pol Henarejos --- tests/docker/bullseye/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/docker/bullseye/Dockerfile b/tests/docker/bullseye/Dockerfile index 032ba5c..f185ecc 100644 --- a/tests/docker/bullseye/Dockerfile +++ b/tests/docker/bullseye/Dockerfile @@ -28,7 +28,7 @@ RUN pip3 install pytest pycvc cryptography pyscard base58 WORKDIR / RUN git clone https://github.com/OpenSC/OpenSC WORKDIR /OpenSC -RUN git checkout tags/0.23.0 +RUN git checkout tags/0.25.1 RUN ./bootstrap RUN ./configure --enable-openssl RUN make -j `nproc` From db5c7adef465e7a8df15af1dce63d035ca341a08 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 23 Jun 2024 01:59:32 +0200 Subject: [PATCH 75/85] Update tests for OpenSC 0.25.1 Signed-off-by: Pol Henarejos --- tests/scripts/sign_and_verify.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/sign_and_verify.sh b/tests/scripts/sign_and_verify.sh index 02f856e..de2bbff 100755 --- a/tests/scripts/sign_and_verify.sh +++ b/tests/scripts/sign_and_verify.sh @@ -12,7 +12,7 @@ create_dgst() { test $? -eq 0 && echo -n "." || exit $? } -dgsts=("sha1" "sha224" "sha256" "sha384" "sha512") +dgsts=("sha256" "sha384" "sha512") for dgst in ${dgsts[*]}; do echo -n " Create digest ${dgst}..." create_dgst ${dgst} @@ -104,7 +104,7 @@ dd if=/dev/zero bs=1 count=$((256-$tlen)) >> data_pad > /dev/null 2>&1 test $? -eq 0 && echo -n "." || exit $? pkcs11-tool --id 1 --sign --pin 648219 --mechanism RSA-X-509 -i data_pad -o data.sig > /dev/null 2>&1 test $? -eq 0 && echo -n "." || exit $? -TDATA=$(tr -d '\0' < <(openssl rsautl -verify -inkey 1.pub -in data.sig -pubin -raw)) +TDATA=$(tr -d '\0' < <(openssl rsautl -verify -inkey 1.pub -in data.sig -pubin -raw 2>/dev/null)) if [[ ${TEST_DATA} != "$TDATA" ]]; then exit 1 fi From 55cf9292d28103ff2948318b78b9214297945052 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 23 Jun 2024 02:09:38 +0200 Subject: [PATCH 76/85] Update ESP32 CMake Signed-off-by: Pol Henarejos --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9d5871..2a8cd4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,9 +20,6 @@ cmake_minimum_required(VERSION 3.13) if(ESP_PLATFORM) set(EXTRA_COMPONENT_DIRS src pico-keys-sdk/src) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -set(USB_VID 0x20a0) -set(USB_PID 0x4230) -set(DEBUG_APDU 1) set(USB_ITF_CCID 1) set(USB_ITF_WCID 1) else() From c65f92118865c343de0a4e52ea601140d0ec1970 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 24 Jun 2024 19:44:46 +0200 Subject: [PATCH 77/85] Update README. Signed-off-by: Pol Henarejos --- README.md | 268 +++++++++++++++++++++++++++++------------------------- 1 file changed, 145 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index f89f79e..66f1d7a 100644 --- a/README.md +++ b/README.md @@ -1,172 +1,177 @@ # Raspberry Pico HSM -This is a project to create a Hardware Security Module (HSM) with a Raspberry Pico. It converts your Pico board into a HSM which is able to generate and store private keys, encrypt or decrypt with AES or signing data without to disclose the private key. In detail, the private key never leaves the board and it cannot be retrieved as it is encrypted in the flash memory. +This project aims to transform a Raspberry Pi Pico or ESP32 microcontroller into a Hardware Security Module (HSM). The modified Pico or ESP32 board will be capable of generating and storing private keys, performing AES encryption or decryption, and signing data without exposing the private key. Specifically, the private key remains securely on the board and cannot be retrieved since it is encrypted within the flash memory. ## Capabilities ### > Key generation and encrypted storage -Private and secret keys are stored with a master AES 256 key (MKEK). The MKEK is, at the same time, encrypted with a hashed and salted version of the PIN. +Private and secret keys are secured using a master AES 256 key (MKEK). The MKEK is encrypted with a hashed and salted version of the PIN. **No private/secret keys, DKEK or PIN are stored in plain text ever. Never.** -### > RSA key generation from 1024 to 4096 bits -RSA key generation in place for 1024, 2048, 3072 and 4096 bits. Private keys never leave the device. +### > RSA Key Generation (1024 to 4096 Bits) +RSA key generation is supported for 1024, 2048, 3072, and 4096 bits. Private keys never leave the device. -### > ECDSA key generation from 192 to 521 bits -ECDSA key generation in place for different curves, from 192 to 521 bits. +### > ECDSA Key Generation (192 to 521 Bits) +ECDSA key generation supports various curves from 192 to 521 bits. -### > ECC curves -It supports secp192r1, secp256r1, secp384r1, secp521r1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, secp192k1 (insecure), secp256k1 curves. Also Curve25519 and Curve448. +### > ECC Curves +Supported ECC curves include secp192r1, secp256r1, secp384r1, secp521r1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, secp192k1 (insecure), secp256k1, Curve25519, and Curve448. -### > SHA1, SHA224, SHA256, SHA384, SHA512 digests -ECDSA and RSA signature can be combined with SHA digest in place. +### > SHA Digests +ECDSA and RSA signatures can be combined with SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 digests. -### > Multiple RSA signature algorithms -It supports RSA-PSS, RSA-PKCS and raw RSA signatures. +### > Multiple RSA Signature Algorithms +Supported RSA signature algorithms include RSA-PSS, RSA-PKCS, and raw RSA signatures. -### > ECDSA raw and hash signature -ECDSA signatures can be in raw or pre-hashed formats. +### > ECDSA Signatures +ECDSA signatures can be raw or pre-hashed. -### > ECDH key derivation -It supports the calculation of shared secrets with ECDH algorithm. +### > ECDH Key Derivation +Supports the ECDH algorithm for calculating shared secrets. -### > EC private key derivation -It allows ECDSA key derivation.[^1] +### > EC Private Key Derivation +Allows ECDSA key derivation. -### > RSA-OEP and RSA-X-509 decryption -It allows private decryption in place with RSA-OEP and RSA-X-509 algorithms. +### > RSA Decryption +Supports RSA-OEP and RSA-X.509 decryption. -### > AES key generation -It supports AES key generation in place with keys of 128, 192 and 256 bits. +### > AES Key Generation +Supports AES key generation with keys of 128, 192, and 256 bits. -### > AES-CBC encryption/decryption -Legacy AES encryption and decryption is performed in place. +### > AES-CBC Encryption/Decryption +Performs AES-CBC encryption and decryption. -### > AES ECB, CBC, CFB, OFB, XTS, CTR, GCM and CCM -Advanced AES encryption and decryption with multiples modes and customized IV/nonce and additional authenticated data (AAD).[^4] +### > Advanced AES Modes +Supports AES encryption and decryption in ECB, CBC, CFB, OFB, XTS, CTR, GCM, and CCM modes, with customizable IV/nonce and additional authenticated data (AAD).[^4] -### > AES key generation of 128, 192, 256 and 512 bits. -Besides 128, 192 and 256 bits, Pico HSM also supports key generation of 512 bits (64 bytes). These keys are specially indicated for running AES XTS, where two keys of 256 bits are concatenated. +### > AES Key Generation (128, 192, 256, 512 Bits) +Supports AES key generation up to 512 bits, useful for AES XTS where two 256-bit keys are concatenated. ### > CMAC -It supports AES-CMAC authentication.[^1] +Supports AES-CMAC authentication.[^1] -### > AES derivation -It supports AES secret key derivation.[^1] +### > AES Secret Key Derivation +Supports AES secret key derivation.[^1] -### > PIN authorization -Private and secret keys cannot be used without prior PIN authentication. It supports alphanumeric PIN. +### > PIN Authorization +Private and secret keys require prior PIN authentication. Supports alphanumeric PINs. -### > PKCS11 compliant interface -The module can be interfaced with PKCS11 standard. +### > PKCS11 Compliant Interface +Interfacing with the PKCS11 standard is supported. -### > HRNG (hardware random number generator) -It contains a harware random number generator properly modeled to guarantee maximum entropy. +### > Hardware Random Number Generator (HRNG) +Contains an HRNG designed for maximum entropy. -### > Device Key Encryption Key (DKEK) shares -It supports DKEK share imports. DKEK are used to wrap, unwrap and encrypt private and secret keys in the device. +### > Device Key Encryption Key (DKEK) Shares +Supports importing DKEK shares to wrap, unwrap, and encrypt keys. -### > DKEK n-of-m threshold scheme -It supports a n-of-m threshold scheme to minimize outage when a DKEK custodian is not available during the import process. +### > DKEK n-of-m Threshold Scheme +Supports an n-of-m threshold scheme to prevent outages when a DKEK custodian is unavailable. -### > USB/CCID support with OpenSC, openssl, etc. -Pico HSM has a full USB CCID stack to communicate with the host via OpenSC and PCSC. It allows the use of frontend applications such as OpenSSL via PKCS11 module. +### > USB/CCID Support +Full USB CCID stack for communication with the host via OpenSC and PCSC, allowing the use of frontend applications like OpenSSL via the PKCS11 module. -### > Extended APDU support -It supports extended APDU packets, which allows up to 65535 bytes. +### > Extended APDU Support +Supports extended APDU packets, allowing up to 65535 bytes. ### > CV Certificates -Pico HSM manipulates CVC certificates and requests to minimize the storage of internal certificates. +Handles CVC certificates and requests to minimize internal certificate storage. ### > Attestation -Every generated key is attached to a certificate, signed by an external PKI to ensure that a particular key is effectively generated by this specific device. +Each generated key is attached to a certificate signed by an external PKI, ensuring the key was generated by the specific device. -### > Import external private keys and certificates -It allows private key and certificates import via WKY or PKCS#12 files.[^2][^3] +### > Import External Keys and Certificates +Allows importing private keys and certificates via WKY or PKCS#12 files.[^2][^3] -### > Tranport PIN -It allows transport PIN for provisioning and forcing to set a new PIN.[^2] It is a tampered mechanism that ensures the device has not been unsealed during the transportation from the issuer to the legitimate user. +### > Transport PIN +Allows a transport PIN for provisioning, ensuring the device has not been tampered with during transportation.[^2] -### > Press-to-confirm button -It allows the use of BOOTSEL button to confirm operations with private/secret keys, such as signatures and decryption. When a private/secret key is loaded, the user has 15 seconds to press the button to confirm the operation. -This feature protects the user from unwanted uses from background applications that may sign data without user notice. +### > Press-to-Confirm Button +Uses the BOOTSEL button to confirm operations with private/secret keys, providing a 15-second window to confirm the operation to protect against unauthorized use. -### > Store and retrieve binary data -It allows the storage of arbitrary files with binary data. +### > Store and Retrieve Binary Data +Allows the storage of arbitrary binary data files. -### > Real time clock (RTC) -Pico HSM has a RTC with external datetime setting and getting. +### > Real-Time Clock (RTC) +Includes an RTC with external date and time setting and retrieval. -### > Secure Messaging (secure channel) -Pico HSM supports secure channel, where the data packets between the host and device are encrypted to avoid man-in-the-middle attacks. +### > Secure Messaging +Supports secure channels to encrypt data packets between the host and device, preventing man-in-the-middle attacks. ### > Session PIN -A specific session PIN can be set during the session opening to avoid the systemmatic use of PIN. +A specific session PIN can be set during session opening to avoid systematic PIN usage. -### > PKI CVCert remote issuing for Secure Message +### > PKI CVCert Remote Issuing for Secure Messaging Secure channel messages are secured with a certificate issued by an external PKI. -### > Multiple key domains -Key domains are domains to store separate private/secret keys. Each domain is protected by a DKEK, independent from the other domains. Private/secret keys can be generated in different key domains to be used with separated DKEK. -Therefore, a single device may contain different domains with independent keys. +### > Multiple Key Domains +Supports separate key domains protected by independent DKEKs, allowing different keys in different domains. -### > Key usage counter -A key usage counter is a counter that is reduced by 1 everytime that the private/secret key is used for signing, decrypting, derivation, etc. When it reaches 0, the key is disabled and cannot be used anymore. +### > Key Usage Counter +Tracks and limits the usage of private/secret keys, disabling keys once their usage counter reaches zero. -Key usage can also be used to perform and auditory and track the usage of a particular key. - -### > Public Key Authentication -Public Key Authentication (PKA) allows to authenticate by using a secondary device with a private key and a registered public key in the primary device. A challenge is generated by the primary Pico HSM and given to the secondary for signature. The secondary device signs the challenge and returns the signature. Then, the primary device verifies the signature with the registered public key and if it is valid, it grants full access, as normal PIN authentication. - -In PKA, the PIN is used for protecting the MKEK, as classic method with only PIN, and PKA is used for adding an extra security layer. Therefore, this mechanism provides a higher degree of security, since it needs a secondary Pico HSM to authenticate the primary one. +### > Public Key Authentication (PKA) +Supports PKA for enhanced security, requiring a secondary device for authentication using a challenge-response mechanism. ### > Secure Lock -An extra layer can be added to the device by adding a private key stored on the computer to lock that Pico HSM to the specific computer. The content will be completely encrypted with a private key only available from a specific computer. +Adds an extra layer of security by locking the Pico HSM to a specific computer using a private key. ### > ChaCha20-Poly1305 -This is a novel fast and efficient symmetric encryption algorithm. Similarly to AES, it can be used to cipher your private data.[^4] +Supports the ChaCha20-Poly1305 encryption algorithm for secure data encryption.[^4] ### > X25519 and X448 -Both cruves Curve25519 and Curve448 are supported for doing DH X25519 and X448. Remember that cannot be used for signing. +Supports DH X25519 and X448 for key agreement, though these cannot be used for signing. -### > Key Derivation Functions: HKDF, PBKDF2 and X963-KDF -It supports symmetric key derivations from different standards and RFC. +### > Key Derivation Functions +Supports HKDF, PBKDF2, and X963-KDF for symmetric key derivation. ### > HMAC -It supports performing HMAC from a secret key on an arbitrary data with SHA digest algorithm. +Supports HMAC generation with SHA digest algorithms. ### > CMAC -Similarly to HMAC, Pico HSM also supports CMAC with AES algorithm for keys of 128, 192 and 256 bits. +Supports CMAC with AES for keys of 128, 192, and 256 bits. ### > XKEK -Besides DKEK, it supports a more advanced scheme to share keys. Based on private key domains, it is possible to wrap and unwrap private and secret keys inside the domain to only authorized devices. If a device outside the domain tries to unwrap a key, it will fail. +Supports an advanced key sharing scheme (XKEK) for securely wrapping and unwrapping keys within authorized domains. -### > MKEK -A Master Key Encryption Key is used to store safely all the keys. This key is also ciphered with an ephemereal key derived from the hashed PIN. Therefore, we can ensure all the keys are encrypted and stored. +### > Master Key Encryption Key (MKEK) +Uses an MKEK to securely store all keys, encrypted with an ephemeral key derived from the hashed PIN. -### > Hierarchical Deterministic key generation -It supports **BIP32** for asymmetric deterministic key derivation and **SLIP10** for symmetric key derivation. With it, crypto wallets can be deployed with Pico HSM, as infinite keys can be derived for signature and symmetric encryption. Curves NIST 256 and Koblitz 256 are supported for master key generation.[^4] +### > Hierarchical Deterministic Key Generation +Supports BIP32 for asymmetric key derivation and SLIP10 for symmetric key derivation, enabling crypto wallet deployment with infinite key generation. Supports NIST 256 and Koblitz 256 curves for master key generation.[^4] [^1]: PKCS11 modules (`pkcs11-tool` and `sc-tool`) do not support CMAC and key derivation. It must be processed through raw APDU command (`opensc-tool -s`). [^2]: Available via SCS3 tool. See [SCS3](/doc/scs3.md "SCS3") for more information. [^3]: Imports are available only if the Pico HSM is previously initialized with a DKEK and DKEK shares are available during the import process. [^4]: Available by using PicoHSM python tool. +### > ESP32-S3 support +Pico HSM also supports ESP32-S3 boards, which add secure storage, flash encryption and secure boot. + +### > Dynamic VID/PID +Supports setting VID & PID on-the-fly. Use `pico-hsm-tool.py` for specify VID/PID values and reboot the device. + +### > Rescue Pico HSM Tool +Pico HSM Tool implements a new CCID stack to rescue the Pico HSM in case it has wrong VID/PID values and it is not recognized by the OS. + ## Security considerations -All secret keys (asymmetric and symmetric) are stored encrypted in the flash memory of the Raspberry Pico. DKEK is used as a 256 bit AES key to protect private and secret keys. Keys are never stored in RAM except for signature and decryption operations and only during the process. All keys (including DKEK) are loaded and cleared every time to avoid potential security flaws. +All secret keys (both asymmetric and symmetric) are encrypted and stored in the flash memory of the Raspberry Pico. The DKEK, a 256-bit AES key, is used to protect these private and secret keys. Keys are only held in RAM during signature and decryption operations, and are loaded and cleared each time to avoid potential security vulnerabilities. -At the same time, DKEK is encrypted with doubled salted and hashed PIN. Also, the PIN is hashed in memory during the session. Hence, PIN is never stored in plain text neither in flash nor in memory. Note that PIN is conveyed from the host to the HSM in plain text if no secure channel is provided. +The DKEK itself is encrypted using a doubly salted and hashed PIN, and the PIN is hashed in memory during sessions. This ensures that the PIN is never stored in plain text, either in flash memory or in RAM. However, if no secure channel is used, the PIN is transmitted in plain text from the host to the HSM. -If the Pico is stolen the contents of private and secret keys cannot be read without the PIN, even if the flash memory is dumped. +In the event that the Pico is stolen, the private and secret key contents cannot be accessed without the PIN, even if the flash memory is dumped. ## Download +**If you own an ESP32-S3 board, go to [ESP32 support](https://www.picokeys.com/esp32-support/) for further information.** + Please, go to the Release page and download the UF2 file for your board. -Note that UF2 files are shiped with a dummy VID/PID to avoid license issues (FEFF:FCFD). If you are planning to use it with OpenSC or similar, you should modify Info.plist of CCID driver to add these VID/PID or use the [Pico Patcher tool](https://www.picokeys.com/pico-patcher/). +Note that UF2 files are shiped with a dummy VID/PID to avoid license issues (FEFF:FCFD). If you plan to use it with OpenSC or similar tools, you should modify Info.plist of CCID driver to add these VID/PID or use the [Pico Patcher tool](https://www.picokeys.com/pico-patcher/). Alternatively you can use the legacy VID/PID patcher as follows: `./patch_vidpid.sh VID:PID input_hsm_file.uf2 output_hsm_file.uf2` You can use whatever VID/PID (i.e., 234b:0000 from FISJ), but remember that you are not authorized to distribute the binary with a VID/PID that you do not own. -Note that the pure-browser option [Pico Patcher tool](https://www.picokeys.com/pico-patcher/) is the most recommended. +Note that the pure-browser option [Pico Patcher tool](https://www.picokeys.com/pico-patcher/) is the most recommended. ## Build Before building, ensure you have installed the toolchain for the Pico and the Pico SDK is properly located in your drive. @@ -182,12 +187,29 @@ make ``` Note that `PICO_BOARD`, `USB_VID` and `USB_PID` are optional. If not provided, `pico` board and VID/PID `FEFF:FCFD` will be used. -After `make` ends, the binary file `pico_hsm.uf2` will be generated. Put your pico board into loading mode, by pushing `BOOTSEL` button while pluging on, and copy the UF2 to the new fresh usb mass storage Pico device. Once copied, the pico mass storage will be disconnected automatically and the pico board will reset with the new firmware. A blinking led will indicate the device is ready to work. +Additionally, you can pass the `VIDPID=value` parameter to build the firmware with a known VID/PID. The supported values are: + +- `NitroHSM` +- `NitroFIDO2` +- `NitroStart` +- `NitroPro` +- `Nitro3` +- `Yubikey5` +- `YubikeyNeo` +- `YubiHSM` +- `Gnuk` +- `GnuPG` + +After running `make`, the binary file `pico_hsm.uf2` will be generated. To load this onto your Pico board: + +1. Put the Pico board into loading mode by holding the `BOOTSEL` button while plugging it in. +2. Copy the `pico_hsm.uf2` file to the new USB mass storage device that appears. +3. Once the file is copied, the Pico mass storage device will automatically disconnect, and the Pico board will reset with the new firmware. +4. A blinking LED will indicate that the device is ready to work. ### Docker Independent from your Linux distribution or when using another OS that supports Docker, you could build a specific pico-hsm version in a Linux container. - ``` sudo docker build \ --build-arg VERSION_PICO_SDK=1.5.0 \ @@ -209,36 +231,31 @@ sudo docker rm mybuild ``` ## Usage -The firmware uploaded to the Pico contains a reader and a virtual smart card. It is like having a physical reader with an inserted SIM card. -We recommend the use of [OpenSC](http://github.com/opensc/opensc/ "OpenSC") to communicate with the reader. If it is not installed, you can download and build it or install the binaries for your system. The first command is to ensure that the Pico is detected as a HSM: -``` +The firmware uploaded to the Pico contains a reader and a virtual smart card, similar to having a physical reader with an inserted SIM card. We recommend using [OpenSC](http://github.com/opensc/opensc/ "OpenSC") to communicate with the reader. If OpenSC is not installed, you can download and build it or install the binaries for your system. + +To ensure that the Pico is detected as an HSM, use the following command: +```sh opensc-tool -an ``` -It should return a text like the following: -``` +It should return a text similar to: +```sh Using reader with a card: Free Software Initiative of Japan Gnuk 3b:fe:18:00:00:81:31:fe:45:80:31:81:54:48:53:4d:31:73:80:21:40:81:07:fa SmartCard-HSM ``` The name of the reader may vary if you modified the VID/PID. -For initialization and asymmetric operations, check [doc/usage.md](/doc/usage.md). +For further details and operations, refer to the following documentation: -For signing and verification operations, check [doc/sign-verify.md](/doc/sign-verify.md). - -For asymmetric encryption and decryption, check [doc/asymmetric-ciphering.md](/doc/asymmetric-ciphering.md). - -For backup, restore and DKEK share management, check [doc/backup-and-restore.md](/doc/backup-and-restore.md). - -For AES key generation, encryption and decryption, check [doc/aes.md](/doc/aes.md). - -For 4096 bits RSA support, check [doc/scs3.md](/doc/scs3.md). - -For storing and retrieving arbitrary data, check [doc/store_data.md](/doc/store_data.md). - -For extra options, such as set/get real datetime or enable/disable press-to-confirm button, check [doc/extra_command.md](/doc/extra_command.md). - -For Public Key Authentication, check [doc/public_key_authentication.md](/doc/public_key_authentication.md). +- Initialization and Asymmetric Operations [doc/usage.md](/doc/usage.md) +- Signing and Verification Operations [doc/sign-verify.md](/doc/sign-verify.md) +- Asymmetric Encryption and Decryption [doc/asymmetric-ciphering.md](/doc/asymmetric-ciphering.md) +- Backup, Restore, and DKEK Share Management [doc/backup-and-restore.md](/doc/backup-and-restore.md) +- AES Key Generation, Encryption, and Decryption [doc/aes.md](/doc/aes.md) +- 4096 Bits RSA Support [doc/scs3.md](/doc/scs3.md) +- Storing and Retrieving Arbitrary Data [doc/store_data.md](/doc/store_data.md) +- Extra Options (e.g., set/get real datetime, enable/disable press-to-confirm button [doc/extra_command.md](/doc/extra_command.md) +- Public Key Authentication [doc/public_key_authentication.md](/doc/public_key_authentication.md) ## Operation time ### Keypair generation @@ -260,14 +277,17 @@ Generating EC keys is almost instant. RSA keypair generation takes some time, sp | 4096 | 15 | ## Press-to-confirm button -Raspberry Pico comes with the BOOTSEL button to load the firmware. When this firmware is running, the button can be used for other purposes. Pico HSM uses this button to confirm private/secret operations. This feature is optional and it shall be enabled. For more information, see [doc/extra_command.md](/doc/extra_command.md). +The Raspberry Pico includes a BOOTSEL button used for loading firmware initially. Once the Pico HSM firmware is running, this button can be repurposed for additional functionalities. Specifically, the Pico HSM utilizes this button to confirm private and secret operations, a feature that is optional but highly recommended for enhanced security. -With this feature enabled, everytime that a private/secret key is loaded, the Pico HSM awaits for the user confirmation by pressing the BOOTSEL button. The Led of the Pico HSM will remain almost illuminated, turning off quickly once a second, indicating that the user must press the button to confirm the operation. Otherwise, the Pico HSM waits indefinitely. See [Led blink](#press-to-confirm) for a picture of the blinking sequence. When in this mode, the Pico HSM sends periodic timeout commands to the host to do not trigger the timeout operation. +When enabled, each time a private or secret key operation is initiated, the Pico HSM enters a waiting state where it awaits user confirmation by pressing the BOOTSEL button. During this waiting period, the Pico HSM's LED remains mostly illuminated but blinks off briefly every second, signaling to the user to press the button for confirmation. If no action is taken, the Pico HSM will continue to wait indefinitely. This operation mode includes periodic timeout commands sent to the host to prevent the session from timing out prematurely. -This feature is an extra layer of security, as it requires the user intervention to sign or decrypt and it ensures that any application will use the Pico HSM without user awareness. However, it is not recommended for servers or other environments where operations are authomatized, since it requires a physical access to the Pico HSM to push the button. +This feature adds an additional layer of security by requiring physical user intervention for sensitive operations such as signing or decrypting data. It mitigates risks associated with unauthorized applications or scripts using the Pico HSM without user awareness. However, it is not recommended for server environments or other automated settings where physical access to press the button may not be practical. + +For more details on configuring and using this feature, refer to the [doc/extra_command.md](/doc/extra_command.md) document. ## Led blink Pico HSM uses the led to indicate the current status. Four states are available: + ### Press to confirm The Led is almost on all the time. It goes off for 100 miliseconds every second. @@ -290,18 +310,20 @@ While processing, the Pico HSM is busy and cannot receive additional commands un ## Driver -Pico HSM uses the `sc-hsm` driver provided by [OpenSC](https://github.com/OpenSC/OpenSC/ "OpenSC") or the `sc-hsm-embedded` driver provided by [CardContact](https://github.com/CardContact/sc-hsm-embedded "CardContact"). This driver utilizes the standardized PKCS#11 interface to communicate with the user and it can be used with many engines that accept PKCS#11 interface, such as OpenSSL, P11 library or pkcs11-tool. +The Pico HSM uses either the `sc-hsm` driver from [OpenSC](https://github.com/OpenSC/OpenSC/) or the `sc-hsm-embedded` driver from [CardContact](https://github.com/CardContact/sc-hsm-embedded/) to interface with external applications. These drivers employ the standardized PKCS#11 interface, making it compatible with various cryptographic engines that support PKCS#11, such as OpenSSL, P11 library, or pkcs11-tool. -Pico HSM relies on PKCS#15 structure to store and manipulate the internal files (PINs, private keys, certificates, etc.) and directories. Therefore, it accepts the commands from `pkcs15-tool`. For instance, `pkcs15-tool -D` will list all elements stored in the Pico HSM. +Internally, the Pico HSM organizes and manages its data using the PKCS#15 structure, which includes elements like PINs, private keys, and certificates. Commands can be issued to interact with these stored elements using tools such as `pkcs15-tool`. For example, `pkcs15-tool -D` lists all elements stored within the Pico HSM. -The way to communicate is exactly the same as with other cards, such as OpenPGP or similar. +Communication with the Pico HSM follows the same protocols and methods used with other smart cards, such as OpenPGP cards or similar devices. -For an advanced usage, see the docs and examples. - -Pico HSM also supports SCS3 tool for advanced use and multiple key domain. See [SCS3](/doc/scs3.md) for more information. +For advanced usage scenarios, refer to the documentation and examples provided. Additionally, the Pico HSM supports the SCS3 tool for more sophisticated operations and includes features like multiple key domains. For detailed information on SCS3 usage, refer to [SCS3 documentation](/doc/scs3.md). ### Important -OpenSC relies on PCSC driver, which reads a list (`Info.plist`) that contains a pair of VID/PID of supported readers. In order to be detectable, you must patch the UF2 binary (if you just downloaded from the [Release section](https://github.com/polhenarejos/pico-hsm/releases "Release section")) or configure the project with the proper VID/PID with `USB_VID` and `USB_PID` parameters in `CMake` (see [Build section](#build "Build section")). Note that you cannot distribute the patched/compiled binary if you do not own the VID/PID or have an explicit authorization. +OpenSC relies on PCSC driver, which reads a list (`Info.plist`) that contains a pair of VID/PID of supported readers. In order to be detectable, you have several options: +- Use `pico-hsm-tool.py` to modify VID/PID on-the-fly. +- Use the online [Pico Patcher tool](https://www.picokeys.com/pico-patcher/). +- Patch the UF2 binary (if you just downloaded from the [Release section](https://github.com/polhenarejos/pico-hsm/releases "Release section")) +- Build and configure the project with the proper VID/PID with `USB_VID` and `USB_PID` parameters in `CMake` (see [Build section](#build "Build section")). Note that you cannot distribute the patched/compiled binary if you do not own the VID/PID or have an explicit authorization. ## Credits Pico HSM uses the following libraries or portion of code: From fd12758551d2d689306e69e87214858e417a9f37 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 24 Jun 2024 19:44:58 +0200 Subject: [PATCH 78/85] Upgrade to version 4.0 Signed-off-by: Pol Henarejos --- build_pico_hsm.sh | 4 ++-- src/hsm/version.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build_pico_hsm.sh b/build_pico_hsm.sh index aa6a112..b190c3e 100755 --- a/build_pico_hsm.sh +++ b/build_pico_hsm.sh @@ -1,7 +1,7 @@ #!/bin/bash -VERSION_MAJOR="3" -VERSION_MINOR="6" +VERSION_MAJOR="4" +VERSION_MINOR="0" rm -rf release/* cd build_release diff --git a/src/hsm/version.h b/src/hsm/version.h index 43be6a3..201d3d4 100644 --- a/src/hsm/version.h +++ b/src/hsm/version.h @@ -18,7 +18,7 @@ #ifndef __VERSION_H_ #define __VERSION_H_ -#define HSM_VERSION 0x0306 +#define HSM_VERSION 0x0400 #define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff) #define HSM_VERSION_MINOR (HSM_VERSION & 0xff) From 0811b8022e6700087a47ac4bafcdbbd081d94ef6 Mon Sep 17 00:00:00 2001 From: Pol Henarejos <55573252+polhenarejos@users.noreply.github.com> Date: Mon, 24 Jun 2024 20:37:03 +0200 Subject: [PATCH 79/85] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66f1d7a..83530d9 100644 --- a/README.md +++ b/README.md @@ -146,10 +146,10 @@ Supports BIP32 for asymmetric key derivation and SLIP10 for symmetric key deriva ### > ESP32-S3 support Pico HSM also supports ESP32-S3 boards, which add secure storage, flash encryption and secure boot. -### > Dynamic VID/PID +### > Dynamic VID/PID Supports setting VID & PID on-the-fly. Use `pico-hsm-tool.py` for specify VID/PID values and reboot the device. -### > Rescue Pico HSM Tool +### > Rescue Pico HSM Tool Pico HSM Tool implements a new CCID stack to rescue the Pico HSM in case it has wrong VID/PID values and it is not recognized by the OS. ## Security considerations From bf2f961b8511eb103e5858a3f960f8d2004b1f5a Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Thu, 27 Jun 2024 21:02:04 +0200 Subject: [PATCH 80/85] Fix windows compatibility. Fixes #44. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 01d1de6..5c11db5 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 01d1de6074ab8be93319e469f1f706a7dc444a24 +Subproject commit 5c11db54aebb729c64995efdf7170f5aecbca95f From c1a47ed0238b7df5a733f77bf95d77412d96651b Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 28 Jun 2024 22:05:10 +0200 Subject: [PATCH 81/85] Fix EF.DIR selection. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/hsm/cmd_select.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 5c11db5..eca200d 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 5c11db54aebb729c64995efdf7170f5aecbca95f +Subproject commit eca200d2f13d2846d1c6e6373d6276aa25e6ae4b diff --git a/src/hsm/cmd_select.c b/src/hsm/cmd_select.c index 1ecf491..05bd4d1 100644 --- a/src/hsm/cmd_select.c +++ b/src/hsm/cmd_select.c @@ -23,7 +23,7 @@ void select_file(file_t *pe) { currentDF = (file_t *) MF; currentEF = NULL; } - else if (pe->type & FILE_TYPE_INTERNAL_EF) { + else if (pe->type & (FILE_TYPE_INTERNAL_EF|FILE_TYPE_WORKING_EF)) { currentEF = pe; currentDF = &file_entries[pe->parent]; } From 5630043a4d530cae68ff660391ddd27c83dfc5e9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 28 Jun 2024 22:59:16 +0200 Subject: [PATCH 82/85] Fix binary read permission. Signed-off-by: Pol Henarejos --- src/hsm/cmd_read_binary.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hsm/cmd_read_binary.c b/src/hsm/cmd_read_binary.c index ee8d636..513f348 100644 --- a/src/hsm/cmd_read_binary.c +++ b/src/hsm/cmd_read_binary.c @@ -18,7 +18,6 @@ #include "sc_hsm.h" int cmd_read_binary() { - uint16_t fid = 0x0; uint16_t offset = 0; uint8_t ins = INS(apdu), p1 = P1(apdu), p2 = P2(apdu); const file_t *ef = NULL; @@ -61,7 +60,7 @@ int cmd_read_binary() { } } - if ((fid >> 8) == KEY_PREFIX || !authenticate_action(ef, ACL_OP_READ_SEARCH)) { + if ((ef->fid >> 8) == KEY_PREFIX || !authenticate_action(ef, ACL_OP_READ_SEARCH)) { return SW_SECURITY_STATUS_NOT_SATISFIED(); } if (ef->data) { From 0c2e728c35e1cab9065e0c1f6db922a148799833 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Fri, 28 Jun 2024 22:59:52 +0200 Subject: [PATCH 83/85] Add EF.DIR list aid. Signed-off-by: Pol Henarejos --- src/hsm/files.c | 3 ++- src/hsm/sc_hsm.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/hsm/files.c b/src/hsm/files.c index dba2367..cefc844 100644 --- a/src/hsm/files.c +++ b/src/hsm/files.c @@ -19,11 +19,12 @@ extern const uint8_t sc_hsm_aid[]; extern int parse_token_info(const file_t *f, int mode); +extern int parse_ef_dir(const file_t *f, int mode); file_t file_entries[] = { /* 0 */ { .fid = 0x3f00, .parent = 0xff, .name = NULL, .type = FILE_TYPE_DF, .data = NULL, .ef_structure = 0, .acl = { 0 } }, // MF - /* 1 */ { .fid = 0x2f00, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, + /* 1 */ { .fid = 0x2f00, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_ef_dir, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.DIR /* 2 */ { .fid = 0x2f01, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = { 0 } }, //EF.ATR diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 66daccb..e53858e 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -314,6 +314,25 @@ int parse_token_info(const file_t *f, int mode) { return (int)(2 + (2 + 1) + (2 + 8) + (2 + strlen(manu)) + (2 + strlen(label)) + (2 + 2)); } +int parse_ef_dir(const file_t *f, int mode) { + (void)f; +#ifdef __FOR_CI + char *label = "SmartCard-HSM"; +#else + char *label = "Pico-HSM"; +#endif + if (mode == 1) { + uint8_t *p = res_APDU; + *p++ = 0x61; + *p++ = 0; //set later + *p++ = 0x4F; *p++ = sc_hsm_aid[0]; memcpy(p, sc_hsm_aid + 1, sc_hsm_aid[0]); p += sc_hsm_aid[0]; + *p++ = 0x50; *p++ = (uint8_t)strlen(label); strcpy((char *) p, label); p += strlen(label); + res_APDU_size = (uint16_t)(p - res_APDU); + res_APDU[1] = (uint8_t)res_APDU_size - 2; + } + return (int)(2 + (2 + sc_hsm_aid[0]) + (2 + strlen(label))); +} + int pin_reset_retries(const file_t *pin, bool force) { if (!pin) { return CCID_ERR_NULL_PARAM; From b429616895e774b40ef0104ae71a7f70fea620bc Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 8 Jul 2024 10:53:25 +0200 Subject: [PATCH 84/85] Fix potential infinite loop when bad ASN1 is processed. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index eca200d..7e8807e 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit eca200d2f13d2846d1c6e6373d6276aa25e6ae4b +Subproject commit 7e8807e054ba45545705d08401b1033dce27b364 From 3cae928de85cf152dcfc82115aaeefaf6c99b1c9 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 15 Jul 2024 14:41:28 +0200 Subject: [PATCH 85/85] Fix for Pico Patcher. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 7e8807e..f4ad8e1 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 7e8807e054ba45545705d08401b1033dce27b364 +Subproject commit f4ad8e1af2e2657f3900f1e01db031d7d73d623b