Skip to content

Commit bb3c1f7

Browse files
committed
Extend crypto:mac support to CMAC too
Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent d5ed500 commit bb3c1f7

File tree

1 file changed

+58
-18
lines changed

1 file changed

+58
-18
lines changed

src/libAtomVM/otp_crypto.c

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -895,11 +895,38 @@ static term nif_crypto_compute_key(Context *ctx, int argc, term argv[])
895895
return result;
896896
}
897897

898-
#define INVALID_HMAC_ALGO 0
899-
900898
static const AtomStringIntPair hmac_algorithm_table[] = {
899+
{ ATOM_STR("\x3", "sha"), PSA_ALG_SHA_1 },
900+
{ ATOM_STR("\x6", "sha224"), PSA_ALG_SHA_224 },
901901
{ ATOM_STR("\x6", "sha256"), PSA_ALG_SHA_256 },
902-
SELECT_INT_DEFAULT(INVALID_HMAC_ALGO)
902+
{ ATOM_STR("\x6", "sha384"), PSA_ALG_SHA_384 },
903+
{ ATOM_STR("\x6", "sha512"), PSA_ALG_SHA_512 },
904+
{ ATOM_STR("\x6", "sha3_224"), PSA_ALG_SHA_224 },
905+
{ ATOM_STR("\x6", "sha3_256"), PSA_ALG_SHA_256 },
906+
{ ATOM_STR("\x6", "sha3_384"), PSA_ALG_SHA_384 },
907+
{ ATOM_STR("\x6", "sha3_512"), PSA_ALG_SHA_512 },
908+
{ ATOM_STR("\x3", "md5"), PSA_ALG_MD5 },
909+
{ ATOM_STR("\x6", "ripemd160"), PSA_ALG_RIPEMD160 },
910+
911+
SELECT_INT_DEFAULT(PSA_ALG_NONE)
912+
};
913+
914+
static const AtomStringIntPair cmac_algorithm_bits_table[] = {
915+
{ ATOM_STR("\xB", "aes_128_cbc"), 128 },
916+
{ ATOM_STR("\xB", "aes_128_ecb"), 128 },
917+
{ ATOM_STR("\xB", "aes_192_cbc"), 192 },
918+
{ ATOM_STR("\xB", "aes_192_ecb"), 192 },
919+
{ ATOM_STR("\xB", "aes_256_cbc"), 256 },
920+
{ ATOM_STR("\xB", "aes_256_ecb"), 256 },
921+
922+
SELECT_INT_DEFAULT(0)
923+
};
924+
925+
static const AtomStringIntPair mac_key_table[] = {
926+
{ ATOM_STR("\x4", "cmac"), PSA_KEY_TYPE_AES },
927+
{ ATOM_STR("\x4", "hmac"), PSA_KEY_TYPE_HMAC },
928+
929+
SELECT_INT_DEFAULT(PSA_KEY_TYPE_NONE)
903930
};
904931

905932
static term nif_crypto_mac(Context *ctx, int argc, term argv[])
@@ -911,25 +938,38 @@ static term nif_crypto_mac(Context *ctx, int argc, term argv[])
911938
GlobalContext *glb = ctx->global;
912939

913940
term mac_type_term = argv[0];
914-
bool is_hmac
915-
= globalcontext_is_term_equal_to_atom_string(glb, mac_type_term, ATOM_STR("\x4", "hmac"));
916-
if (UNLIKELY(!is_hmac)) {
917-
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Unknown mac algorithm", ctx));
918-
}
919-
920941
term sub_type_term = argv[1];
921-
psa_algorithm_t sub_type_algo
922-
= interop_atom_term_select_int(hmac_algorithm_table, sub_type_term, glb);
923-
if (UNLIKELY(sub_type_algo == INVALID_HMAC_ALGO)) {
924-
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Bad digest algorithm for HMAC", ctx));
925-
}
926-
psa_algorithm_t psa_key_algo = PSA_ALG_HMAC(sub_type_algo);
927942

928943
term key_term = argv[2];
929944
VALIDATE_VALUE(key_term, term_is_binary);
930945
const void *key = term_binary_data(key_term);
931946
size_t key_len = term_binary_size(key_term);
932-
psa_key_bits_t key_bit_size = key_len * 8;
947+
948+
psa_key_type_t psa_key_type = interop_atom_term_select_int(mac_key_table, mac_type_term, glb);
949+
psa_algorithm_t psa_key_algo;
950+
psa_key_bits_t key_bit_size;
951+
switch (psa_key_type) {
952+
case PSA_KEY_TYPE_AES:
953+
psa_key_algo = PSA_ALG_CMAC;
954+
key_bit_size
955+
= interop_atom_term_select_int(cmac_algorithm_bits_table, sub_type_term, glb);
956+
if (UNLIKELY(key_bit_size != key_len * 8)) {
957+
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Bad key size", ctx));
958+
}
959+
break;
960+
case PSA_KEY_TYPE_HMAC: {
961+
psa_algorithm_t sub_type_algo
962+
= interop_atom_term_select_int(hmac_algorithm_table, sub_type_term, glb);
963+
if (UNLIKELY(sub_type_algo == PSA_ALG_NONE)) {
964+
RAISE_ERROR(
965+
make_crypto_error(__FILE__, __LINE__, "Bad digest algorithm for HMAC", ctx));
966+
}
967+
psa_key_algo = PSA_ALG_HMAC(sub_type_algo);
968+
key_bit_size = key_len * 8;
969+
} break;
970+
default:
971+
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Unknown mac algorithm", ctx));
972+
}
933973

934974
term data_term = argv[3];
935975
VALIDATE_VALUE(data_term, term_is_binary);
@@ -942,7 +982,7 @@ static term nif_crypto_mac(Context *ctx, int argc, term argv[])
942982
psa_key_id_t key_id = 0;
943983

944984
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
945-
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
985+
psa_set_key_type(&attr, psa_key_type);
946986
psa_set_key_bits(&attr, key_bit_size);
947987
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
948988
psa_set_key_algorithm(&attr, psa_key_algo);
@@ -958,7 +998,7 @@ static term nif_crypto_mac(Context *ctx, int argc, term argv[])
958998
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Unexpected error", ctx));
959999
}
9601000

961-
size_t mac_out_size = PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, key_bit_size, psa_key_algo);
1001+
size_t mac_out_size = PSA_MAC_LENGTH(psa_key_type, key_bit_size, psa_key_algo);
9621002
void *mac_out = malloc(mac_out_size);
9631003
if (IS_NULL_PTR(mac_out)) {
9641004
result = OUT_OF_MEMORY_ATOM;

0 commit comments

Comments
 (0)