From 6bf72e5a5954d9d229a5914f5c3429fcd58c86ab Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 8 Nov 2022 17:26:32 +0100 Subject: [PATCH] Added support for HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512. Signed-off-by: Pol Henarejos --- src/hsm/cmd_cipher_sym.c | 24 ++++++++++++++++++++++-- src/hsm/oid.h | 9 +++++++++ tools/pico-hsm-tool.py | 21 +++++++++++++++++---- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/hsm/cmd_cipher_sym.c b/src/hsm/cmd_cipher_sym.c index e65553f..73e8122 100644 --- a/src/hsm/cmd_cipher_sym.c +++ b/src/hsm/cmd_cipher_sym.c @@ -20,6 +20,8 @@ #include "mbedtls/cmac.h" #include "mbedtls/hkdf.h" #include "mbedtls/chachapoly.h" +#include "md_wrap.h" +#include "mbedtls/md.h" #include "crypto_utils.h" #include "sc_hsm.h" #include "kek.h" @@ -120,8 +122,7 @@ int cmd_cipher_sym() { asn1_find_tag(apdu.data, 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) - { + if (memcmp(oid, 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(); @@ -144,6 +145,25 @@ int cmd_cipher_sym() { else if (algo == ALGO_EXT_CIPHER_DECRYPT) res_APDU_size = enc_len - 16; } + else if (memcmp(oid, OID_HMAC, 7) == 0) { + const mbedtls_md_info_t *md_info = NULL; + if (memcmp(oid, OID_HMAC_SHA1, oid_len) == 0) + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + else if (memcmp(oid, OID_HMAC_SHA224, oid_len) == 0) + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); + else if (memcmp(oid, OID_HMAC_SHA256, oid_len) == 0) + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); + else if (memcmp(oid, OID_HMAC_SHA384, oid_len) == 0) + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); + else if (memcmp(oid, 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, apdu.data, apdu.nc, res_APDU); + if (r != 0) + return SW_EXEC_ERROR(); + res_APDU_size = md_info->size; + } } else { mbedtls_platform_zeroize(kdata, sizeof(kdata)); diff --git a/src/hsm/oid.h b/src/hsm/oid.h index fd97f57..b055407 100644 --- a/src/hsm/oid.h +++ b/src/hsm/oid.h @@ -106,4 +106,13 @@ #define OID_CHACHA20_POLY1305 "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x12" +#define OID_HMAC "\x2A\x86\x48\x86\xF7\x0D\x02" + +#define OID_HMAC_SHA1 OID_HMAC "\x07" +#define OID_HMAC_SHA224 OID_HMAC "\x08" +#define OID_HMAC_SHA256 OID_HMAC "\x09" +#define OID_HMAC_SHA384 OID_HMAC "\x0A" +#define OID_HMAC_SHA512 OID_HMAC "\x0B" + + #endif diff --git a/tools/pico-hsm-tool.py b/tools/pico-hsm-tool.py index ea488d1..6d89254 100644 --- a/tools/pico-hsm-tool.py +++ b/tools/pico-hsm-tool.py @@ -134,8 +134,8 @@ def parse_args(): parser_secure.add_argument('subcommand', choices=['enable', 'disable', 'unlock'], help='Enables, disables or unlocks the security.') 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.add_argument('subcommand', choices=['encrypt','decrypt','e','d','keygen'], help='Encrypts, decrypts or generates a new key.') - parser_cipher.add_argument('--alg', choices=['CHACHAPOLY'], help='Selects the algorithm.', required='keygen' not in sys.argv) + parser_cipher.add_argument('subcommand', choices=['encrypt','decrypt','keygen','mac'], help='Encrypts, decrypts or generates a new key.') + parser_cipher.add_argument('--alg', choices=['CHACHAPOLY','HMAC-SHA1','HMAC-SHA224','HMAC-SHA256','HMAC-SHA384','HMAC-SHA512'], help='Selects the algorithm.', required='keygen' not in sys.argv) parser_cipher.add_argument('--iv', help='Sets the IV/nonce (hex string).') parser_cipher.add_argument('--file-in', help='File to encrypt or decrypt.') parser_cipher.add_argument('--file-out', help='File to write the result.') @@ -405,8 +405,18 @@ def cipher(card, args): else: if (args.alg == 'CHACHAPOLY'): oid = b'\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x12' + elif (args.alg == 'HMAC-SHA1'): + oid = b'\x2A\x86\x48\x86\xF7\x0D\x02\x07' + elif (args.alg == 'HMAC-SHA224'): + oid = b'\x2A\x86\x48\x86\xF7\x0D\x02\x08' + elif (args.alg == 'HMAC-SHA256'): + oid = b'\x2A\x86\x48\x86\xF7\x0D\x02\x09' + elif (args.alg == 'HMAC-SHA384'): + oid = b'\x2A\x86\x48\x86\xF7\x0D\x02\x0A' + elif (args.alg == 'HMAC-SHA512'): + oid = b'\x2A\x86\x48\x86\xF7\x0D\x02\x0B' - if (args.subcommand[0] == 'e'): + if (args.subcommand[0] == 'e' or args.subcommand == 'mac'): alg = 0x51 elif (args.subcommand[0] == 'd'): alg = 0x52 @@ -432,7 +442,10 @@ def cipher(card, args): fout = open(args.file_out, 'wb') else: fout = sys.stdout.buffer - fout.write(bytes(ret)) + if (args.hex): + fout.write(hexlify(bytes(ret))) + else: + fout.write(bytes(ret)) if (args.file_out): fout.close()