Skip to content

Commit b151d9a

Browse files
committed
otp_crypto: address review feedback for mbedtls 4 support
- Use psa_hash_algorithm_table instead of atom_to_psa_hash_alg() if-chain - Use psa_cipher_table instead of atom_to_psa_cipher_alg() if-chain - Cast to const uint8_t* in psa_hash_fold_fun - Remove unnecessary void* cast - Widen preprocessor guards for PSA table definitions Signed-off-by: Peter M <petermm@gmail.com>
1 parent 5b484c9 commit b151d9a

1 file changed

Lines changed: 77 additions & 165 deletions

File tree

src/libAtomVM/otp_crypto.c

Lines changed: 77 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#ifdef HAVE_PSA_CRYPTO
5656
#include <mbedtls/psa_util.h>
5757
#endif
58-
#if defined(HAVE_PSA_CRYPTO) || defined(MBEDTLS_PSA_CRYPTO_C) || MBEDTLS_VERSION_NUMBER >= 0x04000000
58+
#if defined(HAVE_PSA_CRYPTO) || MBEDTLS_VERSION_NUMBER >= 0x04000000
5959
#include <psa/crypto.h>
6060
#endif
6161

@@ -98,7 +98,7 @@
9898

9999
#define MAX_MD_SIZE 64
100100

101-
#if defined(HAVE_PSA_CRYPTO) || defined(MBEDTLS_PSA_CRYPTO_C) || MBEDTLS_VERSION_NUMBER >= 0x04000000
101+
#if defined(HAVE_PSA_CRYPTO) || MBEDTLS_VERSION_NUMBER >= 0x04000000
102102
static void do_psa_init(void)
103103
{
104104
if (UNLIKELY(psa_crypto_init() != PSA_SUCCESS)) {
@@ -293,38 +293,28 @@ DEFINE_DO_HASH_NORET_IS_OTHER(sha512, , false)
293293
#endif
294294
#endif
295295

296-
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
297-
static psa_algorithm_t atom_to_psa_hash_alg(term type, GlobalContext *global)
298-
{
299-
if (type == globalcontext_make_atom(global, ATOM_STR("\x3", "md5"))) {
300-
return PSA_ALG_MD5;
301-
}
302-
if (type == globalcontext_make_atom(global, ATOM_STR("\x3", "sha"))) {
303-
return PSA_ALG_SHA_1;
304-
}
305-
if (type == globalcontext_make_atom(global, ATOM_STR("\x6", "sha224"))) {
306-
return PSA_ALG_SHA_224;
307-
}
308-
if (type == globalcontext_make_atom(global, ATOM_STR("\x6", "sha256"))) {
309-
return PSA_ALG_SHA_256;
310-
}
311-
if (type == globalcontext_make_atom(global, ATOM_STR("\x6", "sha384"))) {
312-
return PSA_ALG_SHA_384;
313-
}
314-
if (type == globalcontext_make_atom(global, ATOM_STR("\x6", "sha512"))) {
315-
return PSA_ALG_SHA_512;
316-
}
317-
#ifdef PSA_ALG_RIPEMD160
318-
if (type == globalcontext_make_atom(global, ATOM_STR("\x9", "ripemd160"))) {
319-
return PSA_ALG_RIPEMD160;
320-
}
296+
#if defined(HAVE_PSA_CRYPTO) || MBEDTLS_VERSION_NUMBER >= 0x04000000
297+
static const AtomStringIntPair psa_hash_algorithm_table[] = {
298+
{ ATOM_STR("\x3", "sha"), PSA_ALG_SHA_1 },
299+
{ ATOM_STR("\x6", "sha224"), PSA_ALG_SHA_224 },
300+
{ ATOM_STR("\x6", "sha256"), PSA_ALG_SHA_256 },
301+
{ ATOM_STR("\x6", "sha384"), PSA_ALG_SHA_384 },
302+
{ ATOM_STR("\x6", "sha512"), PSA_ALG_SHA_512 },
303+
{ ATOM_STR("\x8", "sha3_224"), PSA_ALG_SHA3_224 },
304+
{ ATOM_STR("\x8", "sha3_256"), PSA_ALG_SHA3_256 },
305+
{ ATOM_STR("\x8", "sha3_384"), PSA_ALG_SHA3_384 },
306+
{ ATOM_STR("\x8", "sha3_512"), PSA_ALG_SHA3_512 },
307+
{ ATOM_STR("\x3", "md5"), PSA_ALG_MD5 },
308+
{ ATOM_STR("\x9", "ripemd160"), PSA_ALG_RIPEMD160 },
309+
310+
SELECT_INT_DEFAULT(PSA_ALG_NONE)
311+
};
321312
#endif
322-
return PSA_ALG_NONE;
323-
}
324313

314+
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
325315
static InteropFunctionResult psa_hash_fold_fun(term t, void *accum)
326316
{
327-
psa_hash_operation_t *operation = (psa_hash_operation_t *) accum;
317+
psa_hash_operation_t *operation = accum;
328318
if (term_is_integer(t)) {
329319
avm_int64_t tmp = term_maybe_unbox_int64(t);
330320
if (tmp < 0 || tmp > 255) {
@@ -335,7 +325,7 @@ static InteropFunctionResult psa_hash_fold_fun(term t, void *accum)
335325
return InteropBadArg;
336326
}
337327
} else /* term_is_binary(t) */ {
338-
if (UNLIKELY(psa_hash_update(operation, (uint8_t *) term_binary_data(t), term_binary_size(t)) != PSA_SUCCESS)) {
328+
if (UNLIKELY(psa_hash_update(operation, (const uint8_t *) term_binary_data(t), term_binary_size(t)) != PSA_SUCCESS)) {
339329
return InteropBadArg;
340330
}
341331
}
@@ -355,7 +345,7 @@ static term nif_crypto_hash(Context *ctx, int argc, term argv[])
355345

356346
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
357347
do_psa_init();
358-
psa_algorithm_t alg = atom_to_psa_hash_alg(type, ctx->global);
348+
psa_algorithm_t alg = interop_atom_term_select_int(psa_hash_algorithm_table, type, ctx->global);
359349
if (alg == PSA_ALG_NONE) {
360350
TRACE("crypto:hash unknown algorithm\n");
361351
RAISE_ERROR(BADARG_ATOM);
@@ -509,72 +499,7 @@ static term handle_iodata(term iodata, const void **data, size_t *len, void **al
509499
}
510500
}
511501

512-
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
513-
static psa_algorithm_t atom_to_psa_cipher_alg(term type, GlobalContext *global, psa_key_type_t *key_type, size_t *key_bits)
514-
{
515-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_128_ecb"))) {
516-
*key_type = PSA_KEY_TYPE_AES;
517-
*key_bits = 128;
518-
return PSA_ALG_ECB_NO_PADDING;
519-
}
520-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_192_ecb"))) {
521-
*key_type = PSA_KEY_TYPE_AES;
522-
*key_bits = 192;
523-
return PSA_ALG_ECB_NO_PADDING;
524-
}
525-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_256_ecb"))) {
526-
*key_type = PSA_KEY_TYPE_AES;
527-
*key_bits = 256;
528-
return PSA_ALG_ECB_NO_PADDING;
529-
}
530-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_128_cbc"))) {
531-
*key_type = PSA_KEY_TYPE_AES;
532-
*key_bits = 128;
533-
return PSA_ALG_CBC_NO_PADDING;
534-
}
535-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_192_cbc"))) {
536-
*key_type = PSA_KEY_TYPE_AES;
537-
*key_bits = 192;
538-
return PSA_ALG_CBC_NO_PADDING;
539-
}
540-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_256_cbc"))) {
541-
*key_type = PSA_KEY_TYPE_AES;
542-
*key_bits = 256;
543-
return PSA_ALG_CBC_NO_PADDING;
544-
}
545-
if (type == globalcontext_make_atom(global, ATOM_STR("\xE", "aes_128_cfb128"))) {
546-
*key_type = PSA_KEY_TYPE_AES;
547-
*key_bits = 128;
548-
return PSA_ALG_CFB;
549-
}
550-
if (type == globalcontext_make_atom(global, ATOM_STR("\xE", "aes_192_cfb128"))) {
551-
*key_type = PSA_KEY_TYPE_AES;
552-
*key_bits = 192;
553-
return PSA_ALG_CFB;
554-
}
555-
if (type == globalcontext_make_atom(global, ATOM_STR("\xE", "aes_256_cfb128"))) {
556-
*key_type = PSA_KEY_TYPE_AES;
557-
*key_bits = 256;
558-
return PSA_ALG_CFB;
559-
}
560-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_128_ctr"))) {
561-
*key_type = PSA_KEY_TYPE_AES;
562-
*key_bits = 128;
563-
return PSA_ALG_CTR;
564-
}
565-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_192_ctr"))) {
566-
*key_type = PSA_KEY_TYPE_AES;
567-
*key_bits = 192;
568-
return PSA_ALG_CTR;
569-
}
570-
if (type == globalcontext_make_atom(global, ATOM_STR("\xB", "aes_256_ctr"))) {
571-
*key_type = PSA_KEY_TYPE_AES;
572-
*key_bits = 256;
573-
return PSA_ALG_CTR;
574-
}
575-
return PSA_ALG_NONE;
576-
}
577-
#else
502+
#if MBEDTLS_VERSION_NUMBER < 0x04000000
578503
static bool bool_to_mbedtls_operation(term encrypt_flag, mbedtls_operation_t *operation)
579504
{
580505
switch (encrypt_flag) {
@@ -590,6 +515,54 @@ static bool bool_to_mbedtls_operation(term encrypt_flag, mbedtls_operation_t *op
590515
}
591516
#endif
592517

518+
#if defined(HAVE_PSA_CRYPTO) || MBEDTLS_VERSION_NUMBER >= 0x04000000
519+
struct PsaCipherParams
520+
{
521+
const char *atom_str;
522+
psa_key_type_t key_type;
523+
psa_algorithm_t algorithm;
524+
uint16_t key_bits;
525+
uint8_t block_size;
526+
uint8_t iv_len;
527+
};
528+
529+
static const struct PsaCipherParams psa_cipher_table[] = {
530+
// ECB modes - block cipher, no IV
531+
{ ATOM_STR("\xB", "aes_128_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 128, 16, 0 },
532+
{ ATOM_STR("\xB", "aes_192_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 192, 16, 0 },
533+
{ ATOM_STR("\xB", "aes_256_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 256, 16, 0 },
534+
// CBC modes - block cipher, with IV
535+
{ ATOM_STR("\xB", "aes_128_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 128, 16, 16 },
536+
{ ATOM_STR("\xB", "aes_192_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 192, 16, 16 },
537+
{ ATOM_STR("\xB", "aes_256_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 256, 16, 16 },
538+
// CFB128 modes - stream-like, with IV
539+
{ ATOM_STR("\xE", "aes_128_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 128, 0, 16 },
540+
{ ATOM_STR("\xE", "aes_192_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 192, 0, 16 },
541+
{ ATOM_STR("\xE", "aes_256_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 256, 0, 16 },
542+
// CTR modes - stream cipher, with IV
543+
{ ATOM_STR("\xB", "aes_128_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 128, 0, 16 },
544+
{ ATOM_STR("\xB", "aes_192_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 192, 0, 16 },
545+
{ ATOM_STR("\xB", "aes_256_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 256, 0, 16 },
546+
// OFB modes - stream-like, with IV
547+
{ ATOM_STR("\xB", "aes_128_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 128, 0, 16 },
548+
{ ATOM_STR("\xB", "aes_192_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 192, 0, 16 },
549+
{ ATOM_STR("\xB", "aes_256_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 256, 0, 16 },
550+
};
551+
552+
#define PSA_CIPHER_TABLE_LEN (sizeof(psa_cipher_table) / sizeof(psa_cipher_table[0]))
553+
554+
static const struct PsaCipherParams *psa_cipher_table_lookup(GlobalContext *glb, term cipher_atom)
555+
{
556+
for (size_t i = 0; i < PSA_CIPHER_TABLE_LEN; i++) {
557+
AtomString atom_str = (AtomString) psa_cipher_table[i].atom_str;
558+
if (globalcontext_is_term_equal_to_atom_string(glb, cipher_atom, atom_str)) {
559+
return &psa_cipher_table[i];
560+
}
561+
}
562+
return NULL;
563+
}
564+
#endif
565+
593566
static term make_crypto_error_tag(
594567
const char *file, int line, const char *message, term tag, Context *ctx)
595568
{
@@ -642,12 +615,13 @@ static term nif_crypto_crypto_one_time(Context *ctx, int argc, term argv[])
642615

643616
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
644617
do_psa_init();
645-
psa_key_type_t key_type;
646-
size_t key_bits;
647-
psa_algorithm_t alg = atom_to_psa_cipher_alg(cipher_term, ctx->global, &key_type, &key_bits);
648-
if (UNLIKELY(alg == PSA_ALG_NONE)) {
618+
const struct PsaCipherParams *cipher_params = psa_cipher_table_lookup(ctx->global, cipher_term);
619+
if (IS_NULL_PTR(cipher_params)) {
649620
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Unknown cipher", ctx));
650621
}
622+
psa_key_type_t key_type = cipher_params->key_type;
623+
size_t key_bits = cipher_params->key_bits;
624+
psa_algorithm_t alg = cipher_params->algorithm;
651625
#else
652626
mbedtls_cipher_type_t cipher
653627
= interop_atom_term_select_int(cipher_table, cipher_term, ctx->global);
@@ -1602,22 +1576,6 @@ static term nif_crypto_compute_key(Context *ctx, int argc, term argv[])
16021576
return result;
16031577
}
16041578

1605-
static const AtomStringIntPair psa_hash_algorithm_table[] = {
1606-
{ ATOM_STR("\x3", "sha"), PSA_ALG_SHA_1 },
1607-
{ ATOM_STR("\x6", "sha224"), PSA_ALG_SHA_224 },
1608-
{ ATOM_STR("\x6", "sha256"), PSA_ALG_SHA_256 },
1609-
{ ATOM_STR("\x6", "sha384"), PSA_ALG_SHA_384 },
1610-
{ ATOM_STR("\x6", "sha512"), PSA_ALG_SHA_512 },
1611-
{ ATOM_STR("\x8", "sha3_224"), PSA_ALG_SHA3_224 },
1612-
{ ATOM_STR("\x8", "sha3_256"), PSA_ALG_SHA3_256 },
1613-
{ ATOM_STR("\x8", "sha3_384"), PSA_ALG_SHA3_384 },
1614-
{ ATOM_STR("\x8", "sha3_512"), PSA_ALG_SHA3_512 },
1615-
{ ATOM_STR("\x3", "md5"), PSA_ALG_MD5 },
1616-
{ ATOM_STR("\x9", "ripemd160"), PSA_ALG_RIPEMD160 },
1617-
1618-
SELECT_INT_DEFAULT(PSA_ALG_NONE)
1619-
};
1620-
16211579
#ifdef CRYPTO_SIGN_AVAILABLE
16221580

16231581
static term nif_crypto_sign(Context *ctx, int argc, term argv[])
@@ -2699,52 +2657,6 @@ const ErlNifResourceTypeInit psa_cipher_op_resource_type_init = {
26992657
.dtor = psa_cipher_op_dtor
27002658
};
27012659

2702-
struct PsaCipherParams
2703-
{
2704-
const char *atom_str;
2705-
psa_key_type_t key_type;
2706-
psa_algorithm_t algorithm;
2707-
uint16_t key_bits;
2708-
uint8_t block_size;
2709-
uint8_t iv_len;
2710-
};
2711-
2712-
static const struct PsaCipherParams psa_cipher_table[] = {
2713-
// ECB modes - block cipher, no IV
2714-
{ ATOM_STR("\xB", "aes_128_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 128, 16, 0 },
2715-
{ ATOM_STR("\xB", "aes_192_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 192, 16, 0 },
2716-
{ ATOM_STR("\xB", "aes_256_ecb"), PSA_KEY_TYPE_AES, PSA_ALG_ECB_NO_PADDING, 256, 16, 0 },
2717-
// CBC modes - block cipher, with IV
2718-
{ ATOM_STR("\xB", "aes_128_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 128, 16, 16 },
2719-
{ ATOM_STR("\xB", "aes_192_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 192, 16, 16 },
2720-
{ ATOM_STR("\xB", "aes_256_cbc"), PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, 256, 16, 16 },
2721-
// CFB128 modes - stream-like, with IV
2722-
{ ATOM_STR("\xE", "aes_128_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 128, 0, 16 },
2723-
{ ATOM_STR("\xE", "aes_192_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 192, 0, 16 },
2724-
{ ATOM_STR("\xE", "aes_256_cfb128"), PSA_KEY_TYPE_AES, PSA_ALG_CFB, 256, 0, 16 },
2725-
// CTR modes - stream cipher, with IV
2726-
{ ATOM_STR("\xB", "aes_128_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 128, 0, 16 },
2727-
{ ATOM_STR("\xB", "aes_192_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 192, 0, 16 },
2728-
{ ATOM_STR("\xB", "aes_256_ctr"), PSA_KEY_TYPE_AES, PSA_ALG_CTR, 256, 0, 16 },
2729-
// OFB modes - stream-like, with IV
2730-
{ ATOM_STR("\xB", "aes_128_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 128, 0, 16 },
2731-
{ ATOM_STR("\xB", "aes_192_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 192, 0, 16 },
2732-
{ ATOM_STR("\xB", "aes_256_ofb"), PSA_KEY_TYPE_AES, PSA_ALG_OFB, 256, 0, 16 },
2733-
};
2734-
2735-
#define PSA_CIPHER_TABLE_LEN (sizeof(psa_cipher_table) / sizeof(psa_cipher_table[0]))
2736-
2737-
static const struct PsaCipherParams *psa_cipher_table_lookup(GlobalContext *glb, term cipher_atom)
2738-
{
2739-
for (size_t i = 0; i < PSA_CIPHER_TABLE_LEN; i++) {
2740-
AtomString atom_str = (AtomString) psa_cipher_table[i].atom_str;
2741-
if (globalcontext_is_term_equal_to_atom_string(glb, cipher_atom, atom_str)) {
2742-
return &psa_cipher_table[i];
2743-
}
2744-
}
2745-
return NULL;
2746-
}
2747-
27482660
/*
27492661
* Accepts:
27502662
* - true / false (boolean shorthand for {encrypt, true/false})
@@ -3520,7 +3432,7 @@ static term nif_crypto_pbkdf2_hmac(Context *ctx, int argc, term argv[])
35203432
avm_int_t derived_key_len = 0;
35213433

35223434
#if MBEDTLS_VERSION_NUMBER >= 0x04000000
3523-
psa_algorithm_t hash_alg = atom_to_psa_hash_alg(digest_type_term, glb);
3435+
psa_algorithm_t hash_alg = interop_atom_term_select_int(psa_hash_algorithm_table, digest_type_term, glb);
35243436
if (UNLIKELY(hash_alg == PSA_ALG_NONE)) {
35253437
RAISE_ERROR(make_crypto_error(__FILE__, __LINE__, "Unknown digest type", ctx));
35263438
}

0 commit comments

Comments
 (0)