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
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
102102static 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
325315static 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
578503static 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+
593566static 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
16231581static 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