mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-12-11 13:24:21 +01:00
adcfdbf2c6
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
714 lines
31 KiB
Plaintext
714 lines
31 KiB
Plaintext
/* BEGIN_HEADER */
|
|
/* Test macros that provide metadata about algorithms and key types.
|
|
* This test suite only contains tests that don't require executing
|
|
* code. Other test suites validate macros that require creating a key
|
|
* and using it. */
|
|
|
|
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
|
#include "spm/psa_defs.h"
|
|
#endif
|
|
|
|
#include "psa/crypto.h"
|
|
#include "psa_crypto_invasive.h"
|
|
|
|
/* Flags for algorithm classification macros. There is a flag for every
|
|
* algorithm classification macro PSA_ALG_IS_xxx except for the
|
|
* category test macros, which are hard-coded in each
|
|
* category-specific function. The name of the flag is the name of the
|
|
* classification macro without the PSA_ prefix. */
|
|
#define ALG_IS_VENDOR_DEFINED ( 1u << 0 )
|
|
#define ALG_IS_HMAC ( 1u << 1 )
|
|
#define ALG_IS_BLOCK_CIPHER_MAC ( 1u << 2 )
|
|
#define ALG_IS_STREAM_CIPHER ( 1u << 3 )
|
|
#define ALG_IS_RSA_PKCS1V15_SIGN ( 1u << 4 )
|
|
#define ALG_IS_RSA_PSS ( 1u << 5 )
|
|
#define ALG_IS_RSA_PSS_ANY_SALT ( 1u << 6 )
|
|
#define ALG_IS_RSA_PSS_STANDARD_SALT ( 1u << 7 )
|
|
#define ALG_IS_DSA ( 1u << 8 )
|
|
#define ALG_DSA_IS_DETERMINISTIC ( 1u << 9 )
|
|
#define ALG_IS_DETERMINISTIC_DSA ( 1u << 10 )
|
|
#define ALG_IS_RANDOMIZED_DSA ( 1u << 11 )
|
|
#define ALG_IS_ECDSA ( 1u << 12 )
|
|
#define ALG_ECDSA_IS_DETERMINISTIC ( 1u << 13 )
|
|
#define ALG_IS_DETERMINISTIC_ECDSA ( 1u << 14 )
|
|
#define ALG_IS_RANDOMIZED_ECDSA ( 1u << 15 )
|
|
#define ALG_IS_HASH_EDDSA ( 1u << 16 )
|
|
#define ALG_IS_SIGN_HASH ( 1u << 17 )
|
|
#define ALG_IS_HASH_AND_SIGN ( 1u << 18 )
|
|
#define ALG_IS_RSA_OAEP ( 1u << 19 )
|
|
#define ALG_IS_HKDF ( 1u << 20 )
|
|
#define ALG_IS_FFDH ( 1u << 21 )
|
|
#define ALG_IS_ECDH ( 1u << 22 )
|
|
#define ALG_IS_WILDCARD ( 1u << 23 )
|
|
#define ALG_IS_RAW_KEY_AGREEMENT ( 1u << 24 )
|
|
#define ALG_IS_AEAD_ON_BLOCK_CIPHER ( 1u << 25 )
|
|
#define ALG_IS_TLS12_PRF ( 1u << 26 )
|
|
#define ALG_IS_TLS12_PSK_TO_MS ( 1u << 27 )
|
|
#define ALG_FLAG_MASK_PLUS_ONE ( 1u << 28 ) /* must be last! */
|
|
|
|
/* Flags for key type classification macros. There is a flag for every
|
|
* key type classification macro PSA_KEY_TYPE_IS_xxx except for some that
|
|
* are tested as derived from other macros. The name of the flag is
|
|
* the name of the classification macro without the PSA_ prefix. */
|
|
#define KEY_TYPE_IS_VENDOR_DEFINED ( 1u << 0 )
|
|
#define KEY_TYPE_IS_UNSTRUCTURED ( 1u << 1 )
|
|
#define KEY_TYPE_IS_PUBLIC_KEY ( 1u << 2 )
|
|
#define KEY_TYPE_IS_KEY_PAIR ( 1u << 3 )
|
|
#define KEY_TYPE_IS_RSA ( 1u << 4 )
|
|
#define KEY_TYPE_IS_DSA ( 1u << 5 )
|
|
#define KEY_TYPE_IS_ECC ( 1u << 6 )
|
|
#define KEY_TYPE_IS_DH ( 1u << 7 )
|
|
#define KEY_TYPE_FLAG_MASK_PLUS_ONE ( 1u << 8 ) /* must be last! */
|
|
|
|
/* Flags for lifetime classification macros. There is a flag for every
|
|
* lifetime classification macro PSA_KEY_LIFETIME_IS_xxx. The name of the
|
|
* flag is the name of the classification macro without the PSA_ prefix. */
|
|
#define KEY_LIFETIME_IS_VOLATILE ( 1u << 0 )
|
|
#define KEY_LIFETIME_IS_READ_ONLY ( 1u << 1 )
|
|
#define KEY_LIFETIME_FLAG_MASK_PLUS_ONE ( 1u << 2 ) /* must be last! */
|
|
|
|
/* Check that in the value of flags, the bit flag (which should be a macro
|
|
* expanding to a number of the form 1 << k) is set if and only if
|
|
* PSA_##flag(alg) is true.
|
|
*
|
|
* Only perform this check if cond is true. Typically cond is 1, but it can
|
|
* be different if the value of the flag bit is only specified under specific
|
|
* conditions.
|
|
*
|
|
* Unconditionally mask flag into the ambient variable
|
|
* classification_flags_tested.
|
|
*/
|
|
#define TEST_CLASSIFICATION_MACRO( cond, flag, alg, flags ) \
|
|
do \
|
|
{ \
|
|
if( cond ) \
|
|
{ \
|
|
if( ( flags ) & ( flag ) ) \
|
|
TEST_ASSERT( PSA_##flag( alg ) ); \
|
|
else \
|
|
TEST_ASSERT( ! PSA_##flag( alg ) ); \
|
|
} \
|
|
classification_flags_tested |= ( flag ); \
|
|
} \
|
|
while( 0 )
|
|
|
|
/* Check the parity of value.
|
|
*
|
|
* There are several numerical encodings for which the PSA Cryptography API
|
|
* specification deliberately defines encodings that all have the same
|
|
* parity. This way, a data glitch that flips one bit in the data cannot
|
|
* possibly turn a valid encoding into another valid encoding. Here in
|
|
* the tests, we check that the values (including Mbed TLS vendor-specific
|
|
* values) have the expected parity.
|
|
*
|
|
* The expected parity is even so that 0 is considered a valid encoding.
|
|
*
|
|
* Return a nonzero value if value has even parity and 0 otherwise. */
|
|
int has_even_parity( uint32_t value )
|
|
{
|
|
value ^= value >> 16;
|
|
value ^= value >> 8;
|
|
value ^= value >> 4;
|
|
return( 0x9669 & 1 << ( value & 0xf ) );
|
|
}
|
|
#define TEST_PARITY( value ) \
|
|
TEST_ASSERT( has_even_parity( value ) )
|
|
|
|
void algorithm_classification( psa_algorithm_t alg, unsigned flags )
|
|
{
|
|
unsigned classification_flags_tested = 0;
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_VENDOR_DEFINED, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HMAC, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_BLOCK_CIPHER_MAC, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_STREAM_CIPHER, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PKCS1V15_SIGN, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_ANY_SALT, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_PSS_STANDARD_SALT, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_DSA( alg ),
|
|
ALG_DSA_IS_DETERMINISTIC, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_DSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_DSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( PSA_ALG_IS_ECDSA( alg ),
|
|
ALG_ECDSA_IS_DETERMINISTIC, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_DETERMINISTIC_ECDSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RANDOMIZED_ECDSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_EDDSA, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_SIGN_HASH, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HASH_AND_SIGN, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RSA_OAEP, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_HKDF, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_WILDCARD, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_ECDH, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_FFDH, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_RAW_KEY_AGREEMENT, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PRF, alg, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, ALG_IS_TLS12_PSK_TO_MS, alg, flags );
|
|
TEST_EQUAL( classification_flags_tested, ALG_FLAG_MASK_PLUS_ONE - 1 );
|
|
exit: ;
|
|
}
|
|
|
|
void key_type_classification( psa_key_type_t type, unsigned flags )
|
|
{
|
|
unsigned classification_flags_tested = 0;
|
|
|
|
/* Macros tested based on the test case parameter */
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_VENDOR_DEFINED, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_UNSTRUCTURED, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_PUBLIC_KEY, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_KEY_PAIR, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_RSA, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DSA, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_ECC, type, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_TYPE_IS_DH, type, flags );
|
|
TEST_EQUAL( classification_flags_tested, KEY_TYPE_FLAG_MASK_PLUS_ONE - 1 );
|
|
|
|
/* Macros with derived semantics */
|
|
TEST_EQUAL( PSA_KEY_TYPE_IS_ASYMMETRIC( type ),
|
|
( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ||
|
|
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
|
TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ),
|
|
( PSA_KEY_TYPE_IS_ECC( type ) &&
|
|
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
|
TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ),
|
|
( PSA_KEY_TYPE_IS_ECC( type ) &&
|
|
PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
|
|
TEST_EQUAL( PSA_KEY_TYPE_IS_DH_KEY_PAIR( type ),
|
|
( PSA_KEY_TYPE_IS_DH( type ) &&
|
|
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
|
TEST_EQUAL( PSA_KEY_TYPE_IS_DH_PUBLIC_KEY( type ),
|
|
( PSA_KEY_TYPE_IS_DH( type ) &&
|
|
PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
|
|
|
|
TEST_PARITY( type );
|
|
|
|
exit: ;
|
|
}
|
|
|
|
void mac_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|
psa_key_type_t key_type, size_t key_bits,
|
|
size_t length )
|
|
{
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
|
|
/* Length */
|
|
TEST_EQUAL( length, PSA_MAC_LENGTH( key_type, key_bits, alg ) );
|
|
|
|
#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C)
|
|
PSA_ASSERT( psa_mac_key_can_do( alg, key_type ) );
|
|
#endif
|
|
|
|
exit: ;
|
|
}
|
|
|
|
void aead_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|
psa_key_type_t key_type, size_t key_bits,
|
|
size_t tag_length )
|
|
{
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
|
|
/* Tag length */
|
|
TEST_EQUAL( tag_length, PSA_AEAD_TAG_LENGTH( key_type, key_bits, alg ) );
|
|
|
|
exit: ;
|
|
}
|
|
|
|
/* END_HEADER */
|
|
|
|
/* BEGIN_DEPENDENCIES
|
|
* depends_on:MBEDTLS_PSA_CRYPTO_CLIENT
|
|
* END_DEPENDENCIES
|
|
*/
|
|
|
|
/* BEGIN_CASE */
|
|
void hash_algorithm( int alg_arg, int length_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
size_t length = length_arg;
|
|
psa_algorithm_t hmac_alg = PSA_ALG_HMAC( alg );
|
|
psa_algorithm_t rsa_pkcs1v15_sign_alg = PSA_ALG_RSA_PKCS1V15_SIGN( alg );
|
|
psa_algorithm_t rsa_pss_alg = PSA_ALG_RSA_PSS( alg );
|
|
psa_algorithm_t dsa_alg = PSA_ALG_DSA( alg );
|
|
psa_algorithm_t deterministic_dsa_alg = PSA_ALG_DETERMINISTIC_DSA( alg );
|
|
psa_algorithm_t ecdsa_alg = PSA_ALG_ECDSA( alg );
|
|
psa_algorithm_t deterministic_ecdsa_alg = PSA_ALG_DETERMINISTIC_ECDSA( alg );
|
|
psa_algorithm_t rsa_oaep_alg = PSA_ALG_RSA_OAEP( alg );
|
|
psa_algorithm_t hkdf_alg = PSA_ALG_HKDF( alg );
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, 0 );
|
|
|
|
/* Dependent algorithms */
|
|
TEST_EQUAL( PSA_ALG_HMAC_GET_HASH( hmac_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( rsa_pkcs1v15_sign_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( rsa_pss_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( dsa_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( deterministic_dsa_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( ecdsa_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( deterministic_ecdsa_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_RSA_OAEP_GET_HASH( rsa_oaep_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_HKDF_GET_HASH( hkdf_alg ), alg );
|
|
|
|
/* Hash length */
|
|
TEST_EQUAL( length, PSA_HASH_LENGTH( alg ) );
|
|
TEST_ASSERT( length <= PSA_HASH_MAX_SIZE );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void mac_algorithm( int alg_arg, int classification_flags,
|
|
int length_arg,
|
|
int key_type_arg, int key_bits_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
size_t length = length_arg;
|
|
size_t n;
|
|
size_t key_type = key_type_arg;
|
|
size_t key_bits = key_bits_arg;
|
|
|
|
mac_algorithm_core( alg, classification_flags,
|
|
key_type, key_bits, length );
|
|
TEST_EQUAL( PSA_ALG_FULL_LENGTH_MAC( alg ), alg );
|
|
TEST_ASSERT( length <= PSA_MAC_MAX_SIZE );
|
|
|
|
/* Truncated versions */
|
|
for( n = 1; n <= length; n++ )
|
|
{
|
|
psa_algorithm_t truncated_alg = PSA_ALG_TRUNCATED_MAC( alg, n );
|
|
mac_algorithm_core( truncated_alg, classification_flags,
|
|
key_type, key_bits, n );
|
|
TEST_EQUAL( PSA_ALG_FULL_LENGTH_MAC( truncated_alg ), alg );
|
|
/* Check that calling PSA_ALG_TRUNCATED_MAC twice gives the length
|
|
* of the outer truncation (even if the outer length is smaller than
|
|
* the inner length). */
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, 1 ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, length - 1 ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, length - 1) );
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, length ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, length ) );
|
|
|
|
/* Check that calling PSA_ALG_TRUNCATED_MAC on an algorithm
|
|
* earlier constructed with PSA_ALG_AT_LEAST_THIS_LENGTH_MAC gives the
|
|
* length of the outer truncation (even if the outer length is smaller
|
|
* than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC(
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( truncated_alg, n ), 1 ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC(
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( truncated_alg, n ), length - 1 ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, length - 1) );
|
|
TEST_EQUAL( PSA_ALG_TRUNCATED_MAC(
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( truncated_alg, n ), length ),
|
|
PSA_ALG_TRUNCATED_MAC( alg, length ) );
|
|
}
|
|
|
|
/* At-leat-this-length versions */
|
|
for( n = 1; n <= length; n++ )
|
|
{
|
|
psa_algorithm_t policy_alg = PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, n );
|
|
mac_algorithm_core( policy_alg, classification_flags | ALG_IS_WILDCARD,
|
|
key_type, key_bits, n );
|
|
TEST_EQUAL( PSA_ALG_FULL_LENGTH_MAC( policy_alg ), alg );
|
|
/* Check that calling PSA_ALG_AT_LEAST_THIS_LENGTH_MAC twice gives the
|
|
* length of the outer truncation (even if the outer length is smaller
|
|
* than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( policy_alg, 1 ),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( policy_alg, length - 1 ),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( policy_alg, length ),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, length ) );
|
|
|
|
/* Check that calling PSA_ALG_AT_LEAST_THIS_LENGTH_MAC on an algorithm
|
|
* earlier constructed with PSA_ALG_TRUNCATED_MAC gives the length of
|
|
* the outer truncation (even if the outer length is smaller than the
|
|
* inner length). */
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(
|
|
PSA_ALG_TRUNCATED_MAC( policy_alg, n ), 1),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(
|
|
PSA_ALG_TRUNCATED_MAC( policy_alg, n ), length - 1 ),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(
|
|
PSA_ALG_TRUNCATED_MAC( policy_alg, n ), length ),
|
|
PSA_ALG_AT_LEAST_THIS_LENGTH_MAC( alg, length ) );
|
|
}
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void hmac_algorithm( int alg_arg,
|
|
int length_arg,
|
|
int block_size_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
|
|
size_t block_size = block_size_arg;
|
|
size_t length = length_arg;
|
|
size_t n;
|
|
|
|
TEST_ASSERT( PSA_ALG_IS_HASH( hash_alg ) );
|
|
TEST_EQUAL( PSA_ALG_HMAC( hash_alg ), alg );
|
|
|
|
TEST_ASSERT( block_size == PSA_HASH_BLOCK_LENGTH( alg ) );
|
|
TEST_ASSERT( block_size <= PSA_HMAC_MAX_HASH_BLOCK_SIZE );
|
|
|
|
test_mac_algorithm( alg_arg, ALG_IS_HMAC, length,
|
|
PSA_KEY_TYPE_HMAC, PSA_BYTES_TO_BITS( length ) );
|
|
|
|
for( n = 1; n <= length; n++ )
|
|
{
|
|
psa_algorithm_t truncated_alg = PSA_ALG_TRUNCATED_MAC( alg, n );
|
|
TEST_EQUAL( PSA_ALG_HMAC_GET_HASH( truncated_alg ), hash_alg );
|
|
}
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void cipher_algorithm( int alg_arg, int classification_flags )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void aead_algorithm( int alg_arg, int classification_flags,
|
|
int tag_length_arg,
|
|
int key_type_arg, int key_bits_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
size_t tag_length = tag_length_arg;
|
|
size_t n;
|
|
psa_key_type_t key_type = key_type_arg;
|
|
size_t key_bits = key_bits_arg;
|
|
|
|
aead_algorithm_core( alg, classification_flags,
|
|
key_type, key_bits, tag_length );
|
|
|
|
/* Truncated versions */
|
|
for( n = 1; n <= tag_length; n++ )
|
|
{
|
|
psa_algorithm_t truncated_alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, n );
|
|
aead_algorithm_core( truncated_alg, classification_flags,
|
|
key_type, key_bits, n );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( truncated_alg ),
|
|
alg );
|
|
/* Check that calling PSA_ALG_AEAD_WITH_SHORTENED_TAG twice gives
|
|
* the length of the outer truncation (even if the outer length is
|
|
* smaller than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG( truncated_alg, 1 ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG( truncated_alg, tag_length - 1 ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, tag_length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG( truncated_alg, tag_length ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, tag_length ) );
|
|
|
|
/* Check that calling PSA_ALG_AEAD_WITH_SHORTENED_TAG on an algorithm
|
|
* earlier constructed with PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG
|
|
* gives the length of the outer truncation (even if the outer length is
|
|
* smaller than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG(
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( truncated_alg, n ), 1 ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG(
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( truncated_alg, n ), tag_length - 1 ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, tag_length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_SHORTENED_TAG(
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( truncated_alg, n ), tag_length ),
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, tag_length ) );
|
|
}
|
|
|
|
/* At-leat-this-length versions */
|
|
for( n = 1; n <= tag_length; n++ )
|
|
{
|
|
psa_algorithm_t policy_alg = PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, n );
|
|
aead_algorithm_core( policy_alg, classification_flags | ALG_IS_WILDCARD,
|
|
key_type, key_bits, n );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( policy_alg ),
|
|
alg );
|
|
/* Check that calling PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG twice
|
|
* gives the length of the outer truncation (even if the outer length is
|
|
* smaller than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( policy_alg, 1 ),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( policy_alg, tag_length - 1 ),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, tag_length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( policy_alg, tag_length ),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, tag_length ) );
|
|
|
|
/* Check that calling PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG on an
|
|
* algorithm earlier constructed with PSA_ALG_AEAD_WITH_SHORTENED_TAG
|
|
* gives the length of the outer truncation (even if the outer length is
|
|
* smaller than the inner length). */
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, n ), 1),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, 1 ) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, n ), tag_length - 1 ),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, tag_length - 1) );
|
|
TEST_EQUAL( PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(
|
|
PSA_ALG_AEAD_WITH_SHORTENED_TAG( policy_alg, n ), tag_length ),
|
|
PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG( alg, tag_length ) );
|
|
}
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void asymmetric_signature_algorithm( int alg_arg, int classification_flags )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void asymmetric_signature_wildcard( int alg_arg, int classification_flags )
|
|
{
|
|
classification_flags |= ALG_IS_WILDCARD;
|
|
classification_flags |= ALG_IS_SIGN_HASH;
|
|
classification_flags |= ALG_IS_HASH_AND_SIGN;
|
|
test_asymmetric_signature_algorithm( alg_arg, classification_flags );
|
|
/* Any failure of this test function comes from
|
|
* asymmetric_signature_algorithm. Pacify -Werror=unused-label. */
|
|
goto exit;
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void asymmetric_encryption_algorithm( int alg_arg, int classification_flags )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void key_derivation_algorithm( int alg_arg, int classification_flags )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_algorithm_t ecdh_alg = PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, alg );
|
|
psa_algorithm_t ffdh_alg = PSA_ALG_KEY_AGREEMENT( PSA_ALG_FFDH, alg );
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
|
|
/* Check combinations with key agreements */
|
|
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( ecdh_alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( ffdh_alg ) );
|
|
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( ecdh_alg ), alg );
|
|
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( ffdh_alg ), alg );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void key_agreement_algorithm( int alg_arg, int classification_flags,
|
|
int ka_alg_arg, int kdf_alg_arg )
|
|
{
|
|
psa_algorithm_t alg = alg_arg;
|
|
psa_algorithm_t actual_ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( alg );
|
|
psa_algorithm_t expected_ka_alg = ka_alg_arg;
|
|
psa_algorithm_t actual_kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
|
|
psa_algorithm_t expected_kdf_alg = kdf_alg_arg;
|
|
|
|
/* Algorithm classification */
|
|
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
|
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
|
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
|
algorithm_classification( alg, classification_flags );
|
|
|
|
/* Shared secret derivation properties */
|
|
TEST_EQUAL( actual_ka_alg, expected_ka_alg );
|
|
TEST_EQUAL( actual_kdf_alg, expected_kdf_alg );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void key_type( int type_arg, int classification_flags )
|
|
{
|
|
psa_key_type_t type = type_arg;
|
|
|
|
key_type_classification( type, classification_flags );
|
|
|
|
/* For asymmetric types, check the corresponding pair/public type */
|
|
if( classification_flags & KEY_TYPE_IS_PUBLIC_KEY )
|
|
{
|
|
psa_key_type_t pair_type = PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( type );
|
|
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( pair_type ), type );
|
|
key_type_classification( pair_type,
|
|
( classification_flags
|
|
& ~KEY_TYPE_IS_PUBLIC_KEY )
|
|
| KEY_TYPE_IS_KEY_PAIR );
|
|
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type ), type );
|
|
}
|
|
if( classification_flags & KEY_TYPE_IS_KEY_PAIR )
|
|
{
|
|
psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
|
|
TEST_EQUAL( PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( public_type ), type );
|
|
key_type_classification( public_type,
|
|
( classification_flags
|
|
& ~KEY_TYPE_IS_KEY_PAIR )
|
|
| KEY_TYPE_IS_PUBLIC_KEY );
|
|
TEST_EQUAL( PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( type ), type );
|
|
}
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void block_cipher_key_type( int type_arg, int block_size_arg )
|
|
{
|
|
psa_key_type_t type = type_arg;
|
|
size_t block_size = block_size_arg;
|
|
|
|
test_key_type( type_arg, KEY_TYPE_IS_UNSTRUCTURED );
|
|
|
|
TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
|
|
PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
|
|
TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ), block_size );
|
|
|
|
/* Check that the block size is a power of 2. This is required, at least,
|
|
for PSA_ROUND_UP_TO_MULTIPLE(block_size, length) in crypto_sizes.h. */
|
|
TEST_ASSERT( ( ( block_size - 1 ) & block_size ) == 0 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void stream_cipher_key_type( int type_arg )
|
|
{
|
|
psa_key_type_t type = type_arg;
|
|
|
|
test_key_type( type_arg, KEY_TYPE_IS_UNSTRUCTURED );
|
|
|
|
TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
|
|
PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
|
|
TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ), 1 );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:PSA_KEY_TYPE_ECC_PUBLIC_KEY:PSA_KEY_TYPE_ECC_KEY_PAIR */
|
|
void ecc_key_family( int curve_arg )
|
|
{
|
|
psa_ecc_family_t curve = curve_arg;
|
|
psa_key_type_t public_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
|
|
psa_key_type_t pair_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve );
|
|
|
|
TEST_PARITY( curve );
|
|
|
|
test_key_type( public_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_PUBLIC_KEY );
|
|
test_key_type( pair_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_KEY_PAIR );
|
|
|
|
TEST_EQUAL( PSA_KEY_TYPE_ECC_GET_FAMILY( public_type ), curve );
|
|
TEST_EQUAL( PSA_KEY_TYPE_ECC_GET_FAMILY( pair_type ), curve );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE depends_on:MBEDTLS_DHM_C */
|
|
void dh_key_family( int group_arg )
|
|
{
|
|
psa_dh_family_t group = group_arg;
|
|
psa_key_type_t public_type = PSA_KEY_TYPE_DH_PUBLIC_KEY( group );
|
|
psa_key_type_t pair_type = PSA_KEY_TYPE_DH_KEY_PAIR( group );
|
|
|
|
TEST_PARITY( group );
|
|
|
|
test_key_type( public_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_PUBLIC_KEY );
|
|
test_key_type( pair_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_KEY_PAIR );
|
|
|
|
TEST_EQUAL( PSA_KEY_TYPE_DH_GET_FAMILY( public_type ), group );
|
|
TEST_EQUAL( PSA_KEY_TYPE_DH_GET_FAMILY( pair_type ), group );
|
|
}
|
|
/* END_CASE */
|
|
|
|
/* BEGIN_CASE */
|
|
void lifetime( int lifetime_arg, int classification_flags,
|
|
int persistence_arg, int location_arg )
|
|
{
|
|
psa_key_lifetime_t lifetime = lifetime_arg;
|
|
psa_key_persistence_t persistence = persistence_arg;
|
|
psa_key_location_t location = location_arg;
|
|
unsigned flags = classification_flags;
|
|
unsigned classification_flags_tested = 0;
|
|
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_VOLATILE, lifetime, flags );
|
|
TEST_CLASSIFICATION_MACRO( 1, KEY_LIFETIME_IS_READ_ONLY, lifetime, flags );
|
|
TEST_EQUAL( classification_flags_tested,
|
|
KEY_LIFETIME_FLAG_MASK_PLUS_ONE - 1 );
|
|
|
|
TEST_EQUAL( PSA_KEY_LIFETIME_GET_PERSISTENCE( lifetime ), persistence );
|
|
TEST_EQUAL( PSA_KEY_LIFETIME_GET_LOCATION( lifetime ), location );
|
|
}
|
|
/* END_CASE */
|