From 8c7e95d9e011d9de58de26fb4cc4584f1395195f Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 12:03:35 +0000 Subject: [PATCH 1/8] tests: Remove unused key policy objects persistent_key_import() and persistent_key_destroy() don't need to and don't use key policy objects. Remove unused key policy objects. --- tests/suites/test_suite_psa_crypto_persistent_key.function | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 425dabbd9..753e3d237 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -117,7 +117,6 @@ void persistent_key_destroy( int key_id_arg, int should_store, int first_type_arg, data_t *first_data, int second_type_arg, data_t *second_data ) { - psa_key_policy_t policy; psa_key_id_t key_id = key_id_arg; psa_key_handle_t handle = 0; psa_key_type_t first_type = (psa_key_type_t) first_type_arg; @@ -125,8 +124,6 @@ void persistent_key_destroy( int key_id_arg, int should_store, PSA_ASSERT( psa_crypto_init() ); - psa_key_policy_init( &policy ); - PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, first_type, PSA_BYTES_TO_BITS( first_data->len ), @@ -171,7 +168,6 @@ exit: void persistent_key_import( int key_id_arg, int type_arg, data_t *data, int expected_status ) { - psa_key_policy_t policy; psa_key_lifetime_t lifetime; psa_key_id_t key_id = (psa_key_id_t) key_id_arg; psa_key_type_t type = (psa_key_type_t) type_arg; @@ -183,7 +179,6 @@ void persistent_key_import( int key_id_arg, int type_arg, data_t *data, type, PSA_BYTES_TO_BITS( data->len ), &handle ) ); - psa_key_policy_init( &policy ); TEST_EQUAL( psa_import_key( handle, type, data->x, data->len ), expected_status ); From 70261c513a9b584757a956dc3750409c08af3b06 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 11:47:20 +0000 Subject: [PATCH 2/8] psa: Add initializers for key policies Add new initializers for key policies and use them in our docs, example programs, tests, and library code. Prefer using the macro initializers due to their straightforwardness. --- docs/getting_started.md | 13 +- include/psa/crypto.h | 48 ++++- include/psa/crypto_struct.h | 7 + library/psa_crypto.c | 5 - programs/psa/crypto_examples.c | 3 +- programs/psa/key_ladder_demo.c | 12 +- tests/suites/test_suite_psa_crypto.data | 3 + tests/suites/test_suite_psa_crypto.function | 177 ++++++++---------- ...t_suite_psa_crypto_persistent_key.function | 3 +- ..._suite_psa_crypto_slot_management.function | 16 +- 10 files changed, 145 insertions(+), 142 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index eac831546..3008a19ce 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -116,14 +116,13 @@ This allows the key in the key slot to be used for RSA signing. int key_slot = 1; unsigned char key[] = "RSA_KEY"; unsigned char payload[] = "ASYMMETRIC_INPUT_FOR_SIGN"; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0}; size_t signature_length; status = psa_crypto_init(); /* Import the key */ - psa_key_policy_init(&policy); psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_SIGN, PSA_ALG_RSA_PKCS1V15_SIGN_RAW); status = psa_set_key_policy(key_slot, &policy); @@ -343,7 +342,7 @@ At this point the derived key slot holds a new 128-bit AES-CTR encryption key de ```C psa_key_slot_t base_key = 1; psa_key_slot_t derived_key = 2; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; unsigned char key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, @@ -358,6 +357,7 @@ At this point the derived key slot holds a new 128-bit AES-CTR encryption key de 0xf7, 0xf8, 0xf9 }; psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256); + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; size_t derived_bits = 128; size_t capacity = PSA_BITS_TO_BYTES(derived_bits); @@ -365,7 +365,6 @@ At this point the derived key slot holds a new 128-bit AES-CTR encryption key de status = psa_crypto_init(); /* Import a key for use in key derivation, if such a key has already been imported you can skip this part */ - psa_key_policy_init(&policy); psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DERIVE, alg); status = psa_set_key_policy(base_key, &policy); @@ -416,12 +415,12 @@ To authenticate and encrypt a message: size_t output_size = 0; size_t output_length = 0; size_t tag_length = 16; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = sizeof(input_data) + tag_length; output_data = malloc(output_size); status = psa_crypto_init(); - psa_key_policy_init(&policy); psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_ENCRYPT, PSA_ALG_CCM); status = psa_set_key_policy(slot, &policy); @@ -463,12 +462,12 @@ To authenticate and decrypt a message: unsigned char *output_data = NULL; size_t output_size = 0; size_t output_length = 0; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = sizeof(input_data); output_data = malloc(output_size); status = psa_crypto_init(); - psa_key_policy_init(&policy); psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_DECRYPT, PSA_ALG_CCM); status = psa_set_key_policy(slot, &policy); @@ -503,10 +502,10 @@ Generate a piece of random 128-bit AES data: size_t exported_size = bits; size_t exported_length = 0; uint8_t *exported = malloc(exported_size); + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_crypto_init(); - psa_key_policy_init(&policy); psa_key_policy_set_usage(&policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_GCM); psa_set_key_policy(slot, &policy); diff --git a/include/psa/crypto.h b/include/psa/crypto.h index fa8045cf4..2bc6807b2 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -571,18 +571,50 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, */ /** The type of the key policy data structure. + * + * Before calling any function on a key policy, the application must initialize + * it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_key_policy_t policy; + * memset(&policy, 0, sizeof(policy)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_key_policy_t policy = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_KEY_POLICY_INIT, + * for example: + * \code + * psa_key_policy_t policy = PSA_KEY_POLICY_INIT; + * \endcode + * - Assign the result of the function psa_key_policy_init() + * to the structure, for example: + * \code + * psa_key_policy_t policy; + * policy = psa_key_policy_init(); + * \endcode * * This is an implementation-defined \c struct. Applications should not * make any assumptions about the content of this structure except * as directed by the documentation of a specific implementation. */ typedef struct psa_key_policy_s psa_key_policy_t; -/** \brief Initialize a key policy structure to a default that forbids all - * usage of the key. +/** \def PSA_KEY_POLICY_INIT * - * \param[out] policy The policy object to initialize. + * This macro returns a suitable initializer for a key policy object of type + * #psa_key_policy_t. */ -void psa_key_policy_init(psa_key_policy_t *policy); +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_KEY_POLICY_INIT {0} +#endif + +/** Return an initial value for a key policy that forbids all usage of the key. + */ +static psa_key_policy_t psa_key_policy_init(void); /** \brief Set the standard fields of a policy structure. * @@ -590,9 +622,11 @@ void psa_key_policy_init(psa_key_policy_t *policy); * parameters. The values are only checked when applying the policy to * a key slot with psa_set_key_policy(). * - * \param[out] policy The policy object to modify. - * \param usage The permitted uses for the key. - * \param alg The algorithm that the key may be used for. + * \param[in,out] policy The key policy to modify. It must have been + * initialized as per the documentation for + * #psa_key_policy_t. + * \param usage The permitted uses for the key. + * \param alg The algorithm that the key may be used for. */ void psa_key_policy_set_usage(psa_key_policy_t *policy, psa_key_usage_t usage, diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 44a1a6057..320466f8f 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -208,4 +208,11 @@ struct psa_key_policy_s psa_algorithm_t alg; }; +#define PSA_KEY_POLICY_INIT {0, 0} +static inline struct psa_key_policy_s psa_key_policy_init( void ) +{ + const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT; + return( v ); +} + #endif /* PSA_CRYPTO_STRUCT_H */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0a47fae44..fd76b27b4 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2938,11 +2938,6 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) /****************************************************************/ #if !defined(MBEDTLS_PSA_CRYPTO_SPM) -void psa_key_policy_init( psa_key_policy_t *policy ) -{ - memset( policy, 0, sizeof( *policy ) ); -} - void psa_key_policy_set_usage( psa_key_policy_t *policy, psa_key_usage_t usage, psa_algorithm_t alg ) diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index 53b6b2ae7..db8546863 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -49,9 +49,8 @@ static psa_status_t set_key_policy( psa_key_handle_t key_handle, psa_algorithm_t alg ) { psa_status_t status; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, key_usage, alg ); status = psa_set_key_policy( key_handle, &policy ); ASSERT_STATUS( status, PSA_SUCCESS ); diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c index 4acf6b150..66f66fc2e 100644 --- a/programs/psa/key_ladder_demo.c +++ b/programs/psa/key_ladder_demo.c @@ -209,12 +209,11 @@ static psa_status_t generate( const char *key_file_name ) { psa_status_t status = PSA_SUCCESS; psa_key_handle_t key_handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ), &key_handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT, KDF_ALG ); @@ -243,7 +242,7 @@ static psa_status_t import_key_from_file( psa_key_usage_t usage, psa_key_handle_t *master_key_handle ) { psa_status_t status = PSA_SUCCESS; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; uint8_t key_data[KEY_SIZE_BYTES]; size_t key_size; FILE *key_file = NULL; @@ -267,7 +266,6 @@ static psa_status_t import_key_from_file( psa_key_usage_t usage, PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( key_size ), master_key_handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); PSA_CHECK( psa_set_key_policy( *master_key_handle, &policy ) ); PSA_CHECK( psa_import_key( *master_key_handle, @@ -297,10 +295,9 @@ static psa_status_t derive_key_ladder( const char *ladder[], psa_key_handle_t *key_handle ) { psa_status_t status = PSA_SUCCESS; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; size_t i; - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT, KDF_ALG ); @@ -351,13 +348,12 @@ static psa_status_t derive_wrapping_key( psa_key_usage_t usage, psa_key_handle_t *wrapping_key_handle ) { psa_status_t status = PSA_SUCCESS; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; *wrapping_key_handle = 0; PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_AES, WRAPPING_KEY_BITS, wrapping_key_handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, WRAPPING_ALG ); PSA_CHECK( psa_set_key_policy( *wrapping_key_handle, &policy ) ); diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 848e8edfd..09029ffde 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -332,6 +332,9 @@ import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:0:PSA_ERROR_NOT_SUPPORTED PSA key policy set and get key_policy:PSA_KEY_USAGE_ENCRYPT:PSA_ALG_CBC_NO_PADDING +Key policy initializers zero properly +key_policy_init: + PSA key policy: MAC, sign | verify depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C mac_key_policy:PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_256) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index c1339c015..535879964 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -902,7 +902,7 @@ void import_twice( int alg_arg, int usage_arg, psa_status_t expected_import1_status = expected_import1_status_arg; psa_key_type_t type2 = type2_arg; psa_status_t expected_import2_status = expected_import2_status_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; PSA_ASSERT( psa_crypto_init( ) ); @@ -911,7 +911,6 @@ void import_twice( int alg_arg, int usage_arg, MAX( KEY_BITS_FROM_DATA( type1, data1 ), KEY_BITS_FROM_DATA( type2, data2 ) ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -989,7 +988,7 @@ void import_export( data_t *data, size_t reexported_length; psa_key_type_t got_type; size_t got_bits; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; export_size = (ptrdiff_t) data->len + export_size_delta; ASSERT_ALLOC( exported, export_size ); @@ -998,7 +997,6 @@ void import_export( data_t *data, PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( type, expected_bits, &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage_arg, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1126,7 +1124,7 @@ void export_with_no_key_activity( ) psa_key_handle_t handle = 0; psa_algorithm_t alg = PSA_ALG_CTR; psa_status_t status; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; unsigned char *exported = NULL; size_t export_size = 0; size_t exported_length = INVALID_EXPORT_LENGTH; @@ -1135,7 +1133,6 @@ void export_with_no_key_activity( ) PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0, &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1155,7 +1152,7 @@ void cipher_with_no_key_activity( ) { psa_key_handle_t handle = 0; psa_status_t status; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_cipher_operation_t operation; int exercise_alg = PSA_ALG_CTR; @@ -1163,7 +1160,6 @@ void cipher_with_no_key_activity( ) PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0, &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, exercise_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1245,7 +1241,7 @@ void export_after_destroy_key( data_t *data, int type_arg ) psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_status_t status; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_algorithm_t alg = PSA_ALG_CTR; unsigned char *exported = NULL; size_t export_size = 0; @@ -1255,7 +1251,6 @@ void export_after_destroy_key( data_t *data, int type_arg ) PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); export_size = (ptrdiff_t) data->len; @@ -1298,13 +1293,12 @@ void import_export_public_key( data_t *data, unsigned char *exported = NULL; size_t export_size = expected_public_key->len + export_size_delta; size_t exported_length = INVALID_EXPORT_LENGTH; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1347,7 +1341,7 @@ void import_and_exercise_key( data_t *data, size_t bits = bits_arg; psa_algorithm_t alg = alg_arg; psa_key_usage_t usage = usage_to_exercise( type, alg ); - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_key_type_t got_type; size_t got_bits; psa_status_t status; @@ -1356,7 +1350,6 @@ void import_and_exercise_key( data_t *data, PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1389,8 +1382,8 @@ void key_policy( int usage_arg, int alg_arg ) psa_key_usage_t usage = usage_arg; psa_key_type_t key_type = PSA_KEY_TYPE_AES; unsigned char key[32] = {0}; - psa_key_policy_t policy_set; - psa_key_policy_t policy_get; + psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT; + psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT; memset( key, 0x2a, sizeof( key ) ); @@ -1398,8 +1391,6 @@ void key_policy( int usage_arg, int alg_arg ) PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( sizeof( key ) ), &handle ) ); - psa_key_policy_init( &policy_set ); - psa_key_policy_init( &policy_get ); psa_key_policy_set_usage( &policy_set, usage, alg ); TEST_EQUAL( psa_key_policy_get_usage( &policy_set ), usage ); @@ -1420,6 +1411,31 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void key_policy_init( ) +{ + /* Test each valid way of initializing the object, except for `= {0}`, as + * Clang 5 complains when `-Wmissing-field-initializers` is used, even + * though it's OK by the C standard. We could test for this, but we'd need + * to supress the Clang warning for the test. */ + psa_key_policy_t func = psa_key_policy_init( ); + psa_key_policy_t init = PSA_KEY_POLICY_INIT; + psa_key_policy_t zero; + + memset( &zero, 0, sizeof( zero ) ); + + /* Although not technically guaranteed by the C standard nor the PSA Crypto + * specification, we test that all valid ways of initializing the object + * have the same bit pattern. This is a stronger requirement that may not + * be valid on all platforms or PSA Crypto implementations, but implies the + * weaker actual requirement is met: that a freshly initialized object, no + * matter how it was initialized, acts the same as any other valid + * initialization. */ + TEST_EQUAL( memcmp( &func, &zero, sizeof( zero ) ), 0 ); + TEST_EQUAL( memcmp( &init, &zero, sizeof( zero ) ), 0 ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mac_key_policy( int policy_usage, int policy_alg, @@ -1428,7 +1444,7 @@ void mac_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_mac_operation_t operation; psa_status_t status; unsigned char mac[PSA_MAC_MAX_SIZE]; @@ -1438,7 +1454,6 @@ void mac_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1476,7 +1491,7 @@ void cipher_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_cipher_operation_t operation; psa_status_t status; @@ -1485,7 +1500,6 @@ void cipher_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1524,7 +1538,7 @@ void aead_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; unsigned char nonce[16] = {0}; size_t nonce_length = nonce_length_arg; @@ -1540,7 +1554,6 @@ void aead_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1586,7 +1599,7 @@ void asymmetric_encryption_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; size_t key_bits; size_t buffer_length; @@ -1598,7 +1611,6 @@ void asymmetric_encryption_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1651,7 +1663,7 @@ void asymmetric_signature_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; unsigned char payload[16] = {1}; size_t payload_length = sizeof( payload ); @@ -1663,7 +1675,6 @@ void asymmetric_signature_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1704,7 +1715,7 @@ void derive_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; psa_status_t status; @@ -1713,7 +1724,6 @@ void derive_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1746,7 +1756,7 @@ void agreement_key_policy( int policy_usage, int exercise_alg ) { psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_key_type_t key_type = key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; psa_status_t status; @@ -1756,7 +1766,6 @@ void agreement_key_policy( int policy_usage, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1901,14 +1910,13 @@ void mac_setup( int key_type_arg, psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; psa_mac_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY, alg ); @@ -1938,7 +1946,7 @@ void mac_sign( int key_type_arg, psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_mac_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; /* Leave a little extra room in the output buffer. At the end of the * test, we'll check that the implementation didn't overwrite onto * this extra room. */ @@ -1955,7 +1963,6 @@ void mac_sign( int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -1996,7 +2003,7 @@ void mac_verify( int key_type_arg, psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_mac_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE ); @@ -2004,7 +2011,6 @@ void mac_verify( int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2037,14 +2043,13 @@ void cipher_setup( int key_type_arg, psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; psa_cipher_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2079,7 +2084,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); memset( iv, 0x2a, iv_size ); @@ -2088,7 +2093,6 @@ void cipher_encrypt( int alg_arg, int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2147,7 +2151,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); memset( iv, 0x2a, iv_size ); @@ -2156,7 +2160,6 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2218,7 +2221,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); memset( iv, 0x2a, iv_size ); @@ -2227,7 +2230,6 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2291,7 +2293,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, size_t function_output_length = 0; size_t total_output_length = 0; psa_cipher_operation_t operation; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); memset( iv, 0x2a, iv_size ); @@ -2300,7 +2302,6 @@ void cipher_decrypt( int alg_arg, int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2363,13 +2364,12 @@ void cipher_verify_output( int alg_arg, int key_type_arg, size_t function_output_length = 0; psa_cipher_operation_t operation1; psa_cipher_operation_t operation2; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2449,13 +2449,12 @@ void cipher_verify_output_multipart( int alg_arg, size_t function_output_length; psa_cipher_operation_t operation1; psa_cipher_operation_t operation2; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2550,7 +2549,7 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, size_t output_length2 = 0; size_t tag_length = 16; psa_status_t expected_result = expected_result_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = input_data->len + tag_length; ASSERT_ALLOC( output_data, output_size ); @@ -2559,7 +2558,6 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); @@ -2617,7 +2615,7 @@ void aead_encrypt( int key_type_arg, data_t *key_data, size_t output_size = 0; size_t output_length = 0; size_t tag_length = 16; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = input_data->len + tag_length; ASSERT_ALLOC( output_data, output_size ); @@ -2626,7 +2624,6 @@ void aead_encrypt( int key_type_arg, data_t *key_data, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2667,7 +2664,7 @@ void aead_decrypt( int key_type_arg, data_t *key_data, size_t output_size = 0; size_t output_length = 0; size_t tag_length = 16; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t expected_result = expected_result_arg; output_size = input_data->len + tag_length; @@ -2677,7 +2674,6 @@ void aead_decrypt( int key_type_arg, data_t *key_data, PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2732,14 +2728,13 @@ void sign_deterministic( int key_type_arg, data_t *key_data, unsigned char *signature = NULL; size_t signature_size; size_t signature_length = 0xdeadbeef; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2787,7 +2782,7 @@ void sign_fail( int key_type_arg, data_t *key_data, psa_status_t expected_status = expected_status_arg; unsigned char *signature = NULL; size_t signature_length = 0xdeadbeef; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; ASSERT_ALLOC( signature, signature_size ); @@ -2796,7 +2791,6 @@ void sign_fail( int key_type_arg, data_t *key_data, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2833,14 +2827,13 @@ void sign_verify( int key_type_arg, data_t *key_data, unsigned char *signature = NULL; size_t signature_size; size_t signature_length = 0xdeadbeef; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY, alg ); @@ -2903,7 +2896,7 @@ void asymmetric_verify( int key_type_arg, data_t *key_data, psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE ); @@ -2912,7 +2905,6 @@ void asymmetric_verify( int key_type_arg, data_t *key_data, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2941,14 +2933,13 @@ void asymmetric_verify_fail( int key_type_arg, data_t *key_data, psa_algorithm_t alg = alg_arg; psa_status_t actual_status; psa_status_t expected_status = expected_status_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -2988,7 +2979,7 @@ void asymmetric_encrypt( int key_type_arg, size_t output_length = ~0; psa_status_t actual_status; psa_status_t expected_status = expected_status_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -2996,7 +2987,6 @@ void asymmetric_encrypt( int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); PSA_ASSERT( psa_import_key( handle, key_type, @@ -3059,14 +3049,13 @@ void asymmetric_encrypt_decrypt( int key_type_arg, unsigned char *output2 = NULL; size_t output2_size; size_t output2_length = ~0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); @@ -3127,7 +3116,7 @@ void asymmetric_decrypt( int key_type_arg, unsigned char *output = NULL; size_t output_size = 0; size_t output_length = ~0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = key_data->len; ASSERT_ALLOC( output, output_size ); @@ -3137,7 +3126,6 @@ void asymmetric_decrypt( int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3194,7 +3182,7 @@ void asymmetric_decrypt_fail( int key_type_arg, size_t output_length = ~0; psa_status_t actual_status; psa_status_t expected_status = expected_status_arg; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; output_size = key_data->len; ASSERT_ALLOC( output, output_size ); @@ -3204,7 +3192,6 @@ void asymmetric_decrypt_fail( int key_type_arg, PSA_ASSERT( psa_allocate_key( key_type, KEY_BITS_FROM_DATA( key_type, key_data ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3258,13 +3245,12 @@ void derive_setup( int key_type_arg, size_t requested_capacity = requested_capacity_arg; psa_status_t expected_status = expected_status_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3297,14 +3283,13 @@ void test_derive_invalid_generator_state( ) const uint8_t key_data[22] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( sizeof( key_data ) ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3385,7 +3370,7 @@ void derive_output( int alg_arg, uint8_t *output_buffer = NULL; size_t expected_capacity; size_t current_capacity; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; unsigned i; @@ -3402,7 +3387,6 @@ void derive_output( int alg_arg, PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3476,14 +3460,13 @@ void derive_full( int alg_arg, unsigned char output_buffer[16]; size_t expected_capacity = requested_capacity; size_t current_capacity; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( key_data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3547,7 +3530,7 @@ void derive_key_exercise( int alg_arg, psa_algorithm_t derived_alg = derived_alg_arg; size_t capacity = PSA_BITS_TO_BYTES( derived_bits ); psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_key_type_t got_type; size_t got_bits; @@ -3556,7 +3539,6 @@ void derive_key_exercise( int alg_arg, PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( key_data->len ), &base_handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) ); PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE, @@ -3614,7 +3596,7 @@ void derive_key_export( int alg_arg, psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; uint8_t *output_buffer = NULL; uint8_t *export_buffer = NULL; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; size_t length; ASSERT_ALLOC( output_buffer, capacity ); @@ -3624,7 +3606,6 @@ void derive_key_export( int alg_arg, PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( key_data->len ), &base_handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) ); PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE, @@ -3696,7 +3677,7 @@ void key_agreement_setup( int alg_arg, psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -3704,7 +3685,6 @@ void key_agreement_setup( int alg_arg, KEY_BITS_FROM_DATA( our_key_type, our_key_data ), &our_key ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( our_key, &policy ) ); PSA_ASSERT( psa_import_key( our_key, our_key_type, @@ -3734,7 +3714,7 @@ void key_agreement_capacity( int alg_arg, psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; size_t actual_capacity; unsigned char output[16]; @@ -3744,7 +3724,6 @@ void key_agreement_capacity( int alg_arg, KEY_BITS_FROM_DATA( our_key_type, our_key_data ), &our_key ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( our_key, &policy ) ); PSA_ASSERT( psa_import_key( our_key, our_key_type, @@ -3790,7 +3769,7 @@ void key_agreement_output( int alg_arg, psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; uint8_t *actual_output = NULL; ASSERT_ALLOC( actual_output, MAX( expected_output1->len, @@ -3802,7 +3781,6 @@ void key_agreement_output( int alg_arg, KEY_BITS_FROM_DATA( our_key_type, our_key_data ), &our_key ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); PSA_ASSERT( psa_set_key_policy( our_key, &policy ) ); PSA_ASSERT( psa_import_key( our_key, our_key_type, @@ -3904,12 +3882,11 @@ void generate_key( int type_arg, size_t got_bits; psa_status_t expected_info_status = expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); PSA_ASSERT( psa_allocate_key( type, bits, &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); @@ -3946,11 +3923,11 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, psa_key_type_t type = (psa_key_type_t) type_arg; psa_key_type_t type_get; size_t bits_get; - psa_key_policy_t policy_set; - psa_key_policy_t policy_get; + psa_key_policy_t policy_set = PSA_KEY_POLICY_INIT; + psa_key_policy_t policy_get = PSA_KEY_POLICY_INIT; psa_key_usage_t policy_usage = (psa_key_usage_t) usage_arg; psa_algorithm_t policy_alg = (psa_algorithm_t) alg_arg; - psa_key_policy_t base_policy_set; + psa_key_policy_t base_policy_set = PSA_KEY_POLICY_INIT; psa_algorithm_t base_policy_alg = PSA_ALG_HKDF(PSA_ALG_SHA_256); psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; unsigned char *first_export = NULL; @@ -3967,7 +3944,6 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1, type, bits, &handle ) ); - psa_key_policy_init( &policy_set ); psa_key_policy_set_usage( &policy_set, policy_usage, policy_alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) ); @@ -3991,7 +3967,6 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( data->len ), &base_key ) ); - psa_key_policy_init( &base_policy_set ); psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE, base_policy_alg ); PSA_ASSERT( psa_set_key_policy( diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 753e3d237..939a37b56 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -209,7 +209,7 @@ void import_export_persistent_key( data_t *data, int type_arg, size_t exported_length; psa_key_type_t got_type; size_t got_bits; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_key_lifetime_t lifetime_get; ASSERT_ALLOC( exported, export_size ); @@ -221,7 +221,6 @@ void import_export_persistent_key( data_t *data, int type_arg, PSA_BYTES_TO_BITS( data->len ), &handle ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_VENDOR_FLAG ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function index 3df0887a6..670c7404a 100644 --- a/tests/suites/test_suite_psa_crypto_slot_management.function +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -77,14 +77,13 @@ void transient_slot_lifecycle( int type_arg, int max_bits_arg, close_method_t close_method = close_method_arg; psa_key_type_t read_type; psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); /* Get a handle and import a key. */ PSA_ASSERT( psa_allocate_key( type, max_bits, &handle ) ); TEST_ASSERT( handle != 0 ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage_flags, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) ); @@ -131,7 +130,7 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg, close_method_t close_method = close_method_arg; psa_key_type_t read_type; psa_key_handle_t handle = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; TEST_MAX_KEY_ID( id ); @@ -140,7 +139,6 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg, /* Get a handle and import a key. */ PSA_ASSERT( psa_create_key( lifetime, id, type, max_bits, &handle ) ); TEST_ASSERT( handle != 0 ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage_flags, alg ); PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) ); @@ -202,7 +200,8 @@ void create_existent( int lifetime_arg, int id_arg, psa_key_lifetime_t lifetime = lifetime_arg; psa_key_id_t id = id_arg; psa_key_handle_t handle1 = 0, handle2 = 0; - psa_key_policy_t policy1, read_policy; + psa_key_policy_t policy1 = PSA_KEY_POLICY_INIT; + psa_key_policy_t read_policy = PSA_KEY_POLICY_INIT; psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA; psa_key_type_t type2 = new_type_arg; psa_key_type_t read_type; @@ -220,7 +219,6 @@ void create_existent( int lifetime_arg, int id_arg, /* Create a key. */ PSA_ASSERT( psa_create_key( lifetime, id, type1, bits1, &handle1 ) ); TEST_ASSERT( handle1 != 0 ); - psa_key_policy_init( &policy1 ); psa_key_policy_set_usage( &policy1, PSA_KEY_USAGE_EXPORT, 0 ); PSA_ASSERT( psa_set_key_policy( handle1, &policy1 ) ); PSA_ASSERT( psa_import_key( handle1, type1, @@ -308,7 +306,7 @@ exit: void invalid_handle( ) { psa_key_handle_t handle1 = 0; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_key_type_t read_type; size_t read_bits; uint8_t material[1] = "a"; @@ -318,7 +316,6 @@ void invalid_handle( ) /* Allocate a handle and store a key in it. */ PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 1, &handle1 ) ); TEST_ASSERT( handle1 != 0 ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, 0, 0 ); PSA_ASSERT( psa_set_key_policy( handle1, &policy ) ); PSA_ASSERT( psa_import_key( handle1, PSA_KEY_TYPE_RAW_DATA, @@ -350,14 +347,13 @@ void many_transient_handles( int max_handles_arg ) size_t max_handles = max_handles_arg; size_t i, j; psa_status_t status; - psa_key_policy_t policy; + psa_key_policy_t policy = PSA_KEY_POLICY_INIT; uint8_t exported[sizeof( size_t )]; size_t exported_length; size_t max_bits = PSA_BITS_TO_BYTES( sizeof( exported ) ); ASSERT_ALLOC( handles, max_handles ); PSA_ASSERT( psa_crypto_init( ) ); - psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 ); for( i = 0; i < max_handles; i++ ) From 6a25b41ac32eb502b1bb70689c9bb05ef635967c Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 11:47:44 +0000 Subject: [PATCH 3/8] psa: Add initializers for hash operation objects Add new initializers for hash operation objects and use them in our tests and library code. Prefer using the macro initializers due to their straightforwardness. --- include/psa/crypto.h | 47 ++++++++++++++++++- include/psa/crypto_struct.h | 7 +++ tests/suites/test_suite_psa_crypto.data | 3 ++ tests/suites/test_suite_psa_crypto.function | 33 +++++++++++-- .../test_suite_psa_crypto_hash.function | 6 +-- 5 files changed, 87 insertions(+), 9 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 2bc6807b2..694fdf4d5 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -705,18 +705,59 @@ psa_status_t psa_get_key_policy(psa_key_handle_t handle, */ /** The type of the state data structure for multipart hash operations. + * + * Before calling any function on a hash operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_hash_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_hash_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_HASH_OPERATION_INIT, + * for example: + * \code + * psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_hash_operation_init() + * to the structure, for example: + * \code + * psa_hash_operation_t operation; + * operation = psa_hash_operation_init(); + * \endcode * * This is an implementation-defined \c struct. Applications should not * make any assumptions about the content of this structure except * as directed by the documentation of a specific implementation. */ typedef struct psa_hash_operation_s psa_hash_operation_t; +/** \def PSA_HASH_OPERATION_INIT + * + * This macro returns a suitable initializer for a hash operation object + * of type #psa_hash_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_HASH_OPERATION_INIT {0} +#endif + +/** Return an initial value for a hash operation object. + */ +static psa_hash_operation_t psa_hash_operation_init(void); + /** Start a multipart hash operation. * * The sequence of operations to calculate a hash (message digest) * is as follows: * -# Allocate an operation object which will be passed to all the functions * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_hash_operation_t, e.g. PSA_HASH_OPERATION_INIT. * -# Call psa_hash_setup() to specify the algorithm. * -# Call psa_hash_update() zero, one or more times, passing a fragment * of the message each time. The hash that is calculated is the hash @@ -725,7 +766,7 @@ typedef struct psa_hash_operation_s psa_hash_operation_t; * To compare the hash with an expected value, call psa_hash_verify(). * * The application may call psa_hash_abort() at any time after the operation - * has been initialized with psa_hash_setup(). + * has been initialized. * * After a successful call to psa_hash_setup(), the application must * eventually terminate the operation. The following events terminate an @@ -733,7 +774,9 @@ typedef struct psa_hash_operation_s psa_hash_operation_t; * - A failed call to psa_hash_update(). * - A call to psa_hash_finish(), psa_hash_verify() or psa_hash_abort(). * - * \param[out] operation The operation object to use. + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_hash_operation_t and not yet in use. * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_HASH(\p alg) is true). * diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 320466f8f..4a6e16857 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -85,6 +85,13 @@ struct psa_hash_operation_s } ctx; }; +#define PSA_HASH_OPERATION_INIT {0, {0}} +static inline struct psa_hash_operation_s psa_hash_operation_init( void ) +{ + const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT; + return( v ); +} + #if defined(MBEDTLS_MD_C) typedef struct { diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 09029ffde..701a9a7bd 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -471,6 +471,9 @@ PSA key policy: agreement, wrong algorithm depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW) +Hash operation object initializers zero properly +hash_operation_init: + PSA hash setup: good, SHA-1 depends_on:MBEDTLS_SHA1_C hash_setup:PSA_ALG_SHA_1:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 535879964..ea4a8e10d 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1787,13 +1787,38 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void hash_operation_init( ) +{ + /* Test each valid way of initializing the object, except for `= {0}`, as + * Clang 5 complains when `-Wmissing-field-initializers` is used, even + * though it's OK by the C standard. We could test for this, but we'd need + * to supress the Clang warning for the test. */ + psa_hash_operation_t func = psa_hash_operation_init( ); + psa_hash_operation_t init = PSA_HASH_OPERATION_INIT; + psa_hash_operation_t zero; + + memset( &zero, 0, sizeof( zero ) ); + + /* Although not technically guaranteed by the C standard nor the PSA Crypto + * specification, we test that all valid ways of initializing the object + * have the same bit pattern. This is a stronger requirement that may not + * be valid on all platforms or PSA Crypto implementations, but implies the + * weaker actual requirement is met: that a freshly initialized object, no + * matter how it was initialized, acts the same as any other valid + * initialization. */ + TEST_EQUAL( memcmp( &func, &zero, sizeof( zero ) ), 0 ); + TEST_EQUAL( memcmp( &init, &zero, sizeof( zero ) ), 0 ); +} +/* END_CASE */ + /* BEGIN_CASE */ void hash_setup( int alg_arg, int expected_status_arg ) { psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; psa_status_t status; PSA_ASSERT( psa_crypto_init( ) ); @@ -1817,7 +1842,7 @@ void hash_bad_order( ) 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55 }; size_t hash_len; - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -1853,7 +1878,7 @@ void hash_verify_bad_args( ) 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55, 0xaa, 0xbb }; size_t expected_size = PSA_HASH_SIZE( alg ); - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -1883,7 +1908,7 @@ void hash_finish_bad_args( ) psa_algorithm_t alg = PSA_ALG_SHA_256; unsigned char hash[PSA_HASH_MAX_SIZE]; size_t expected_size = PSA_HASH_SIZE( alg ); - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; size_t hash_len; PSA_ASSERT( psa_crypto_init( ) ); diff --git a/tests/suites/test_suite_psa_crypto_hash.function b/tests/suites/test_suite_psa_crypto_hash.function index 5931a2338..bdb2f98f1 100644 --- a/tests/suites/test_suite_psa_crypto_hash.function +++ b/tests/suites/test_suite_psa_crypto_hash.function @@ -21,7 +21,7 @@ void hash_finish( int alg_arg, data_t *input, data_t *expected_hash ) psa_algorithm_t alg = alg_arg; unsigned char actual_hash[PSA_HASH_MAX_SIZE]; size_t actual_hash_length; - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -43,7 +43,7 @@ exit: void hash_verify( int alg_arg, data_t *input, data_t *expected_hash ) { psa_algorithm_t alg = alg_arg; - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -66,7 +66,7 @@ void hash_multi_part( int alg_arg, data_t *input, data_t *expected_hash ) psa_algorithm_t alg = alg_arg; unsigned char actual_hash[PSA_HASH_MAX_SIZE]; size_t actual_hash_length; - psa_hash_operation_t operation; + psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; uint32_t len = 0; PSA_ASSERT( psa_crypto_init( ) ); From 769ce27f1209a3dda1382f8e3f32cdf43d177aa6 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 11:48:03 +0000 Subject: [PATCH 4/8] psa: Add initializers for MAC operation objects Add new initializers for MAC operation objects and use them in our tests and library code. Prefer using the macro initializers due to their straightforwardness. --- include/psa/crypto.h | 55 +++++++++++++++++++-- include/psa/crypto_struct.h | 7 +++ tests/suites/test_suite_psa_crypto.data | 3 ++ tests/suites/test_suite_psa_crypto.function | 35 +++++++++++-- 4 files changed, 91 insertions(+), 9 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 694fdf4d5..f94830d83 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -928,12 +928,51 @@ psa_status_t psa_hash_abort(psa_hash_operation_t *operation); */ /** The type of the state data structure for multipart MAC operations. + * + * Before calling any function on a MAC operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_mac_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_mac_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT, + * for example: + * \code + * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_mac_operation_init() + * to the structure, for example: + * \code + * psa_mac_operation_t operation; + * operation = psa_mac_operation_init(); + * \endcode * * This is an implementation-defined \c struct. Applications should not * make any assumptions about the content of this structure except * as directed by the documentation of a specific implementation. */ typedef struct psa_mac_operation_s psa_mac_operation_t; +/** \def PSA_MAC_OPERATION_INIT + * + * This macro returns a suitable initializer for a MAC operation object of type + * #psa_mac_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_MAC_OPERATION_INIT {0} +#endif + +/** Return an initial value for a MAC operation object. + */ +static psa_mac_operation_t psa_mac_operation_init(void); + /** Start a multipart MAC calculation operation. * * This function sets up the calculation of the MAC @@ -944,6 +983,8 @@ typedef struct psa_mac_operation_s psa_mac_operation_t; * The sequence of operations to calculate a MAC is as follows: * -# Allocate an operation object which will be passed to all the functions * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. PSA_MAC_OPERATION_INIT. * -# Call psa_mac_sign_setup() to specify the algorithm and key. * The key remains associated with the operation even if the content * of the key slot changes. @@ -954,14 +995,16 @@ typedef struct psa_mac_operation_s psa_mac_operation_t; * calculating the MAC value and retrieve it. * * The application may call psa_mac_abort() at any time after the operation - * has been initialized with psa_mac_sign_setup(). + * has been initialized. * * After a successful call to psa_mac_sign_setup(), the application must * eventually terminate the operation through one of the following methods: * - A failed call to psa_mac_update(). * - A call to psa_mac_sign_finish() or psa_mac_abort(). * - * \param[out] operation The operation object to use. + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. * \param handle Handle to the key to use for the operation. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(alg) is true). @@ -996,6 +1039,8 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * The sequence of operations to verify a MAC is as follows: * -# Allocate an operation object which will be passed to all the functions * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. PSA_MAC_OPERATION_INIT. * -# Call psa_mac_verify_setup() to specify the algorithm and key. * The key remains associated with the operation even if the content * of the key slot changes. @@ -1007,14 +1052,16 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * the expected value. * * The application may call psa_mac_abort() at any time after the operation - * has been initialized with psa_mac_verify_setup(). + * has been initialized. * * After a successful call to psa_mac_verify_setup(), the application must * eventually terminate the operation through one of the following methods: * - A failed call to psa_mac_update(). * - A call to psa_mac_verify_finish() or psa_mac_abort(). * - * \param[out] operation The operation object to use. + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. * \param handle Handle to the key to use for the operation. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(\p alg) is true). diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 4a6e16857..efc30b804 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -123,6 +123,13 @@ struct psa_mac_operation_s } ctx; }; +#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}} +static inline struct psa_mac_operation_s psa_mac_operation_init( void ) +{ + const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; + return( v ); +} + struct psa_cipher_operation_s { psa_algorithm_t alg; diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 701a9a7bd..8275a1c3c 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -527,6 +527,9 @@ hash_verify_bad_args: PSA hash finish: bad arguments hash_finish_bad_args: +MAC operation object initializers zero properly +mac_operation_init: + PSA MAC setup: good, HMAC-SHA-256 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index ea4a8e10d..e821165c1 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -124,7 +124,7 @@ static int exercise_mac_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { - psa_mac_operation_t operation; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; const unsigned char input[] = "foo"; unsigned char mac[PSA_MAC_MAX_SIZE] = {0}; size_t mac_length = sizeof( mac ); @@ -1445,7 +1445,7 @@ void mac_key_policy( int policy_usage, { psa_key_handle_t handle = 0; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; - psa_mac_operation_t operation; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; psa_status_t status; unsigned char mac[PSA_MAC_MAX_SIZE]; @@ -1924,6 +1924,31 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mac_operation_init( ) +{ + /* Test each valid way of initializing the object, except for `= {0}`, as + * Clang 5 complains when `-Wmissing-field-initializers` is used, even + * though it's OK by the C standard. We could test for this, but we'd need + * to supress the Clang warning for the test. */ + psa_mac_operation_t func = psa_mac_operation_init( ); + psa_mac_operation_t init = PSA_MAC_OPERATION_INIT; + psa_mac_operation_t zero; + + memset( &zero, 0, sizeof( zero ) ); + + /* Although not technically guaranteed by the C standard nor the PSA Crypto + * specification, we test that all valid ways of initializing the object + * have the same bit pattern. This is a stronger requirement that may not + * be valid on all platforms or PSA Crypto implementations, but implies the + * weaker actual requirement is met: that a freshly initialized object, no + * matter how it was initialized, acts the same as any other valid + * initialization. */ + TEST_EQUAL( memcmp( &func, &zero, sizeof( zero ) ), 0 ); + TEST_EQUAL( memcmp( &init, &zero, sizeof( zero ) ), 0 ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mac_setup( int key_type_arg, data_t *key, @@ -1934,7 +1959,7 @@ void mac_setup( int key_type_arg, psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; - psa_mac_operation_t operation; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; @@ -1970,7 +1995,7 @@ void mac_sign( int key_type_arg, psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; - psa_mac_operation_t operation; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; /* Leave a little extra room in the output buffer. At the end of the * test, we'll check that the implementation didn't overwrite onto @@ -2027,7 +2052,7 @@ void mac_verify( int key_type_arg, psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; - psa_mac_operation_t operation; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE ); From 5a5dc77696cb390d7aaab540d784a3f20e1cd412 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 15:33:37 +0000 Subject: [PATCH 5/8] psa: Enable easier initialization of cipher operations The struct psa_cipher_operation_s is built with a mbedtls_cipher_context_t. The shape of mbedtls_cipher_context_t and an initializer that works with Clang 5.0 and its -Wmissing-field-initializers varies based on the configuration of the library. Instead of making multiple initializers based on a maze of ifdefs for all combinations of MBEDTLS_CIPHER_MODE_WITH_PADDING, MBEDTLS_CMAC_C, and MBEDTLS_USE_PSA_CRYPTO, add a dummy variable to psa_cipher_operation_s's union that encloses mbedtls_cipher_context_t. This allows us to initialize the dummy with a Clang-approved initializer and have it properly initialize the entire object. --- include/psa/crypto_struct.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index efc30b804..5eb262405 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -140,6 +140,7 @@ struct psa_cipher_operation_s uint8_t block_size; union { + unsigned dummy; /* Enable easier initializing of the union. */ mbedtls_cipher_context_t cipher; } ctx; }; From 5bae227da07157a45948a22290d6e5e67afde458 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 11:48:27 +0000 Subject: [PATCH 6/8] psa: Add initializers for cipher operation objects Add new initializers for cipher operation objects and use them in our tests and library code. Prefer using the macro initializers due to their straightforwardness. --- include/psa/crypto.h | 57 +++++++++++++++++++-- include/psa/crypto_struct.h | 7 +++ tests/suites/test_suite_psa_crypto.data | 3 ++ tests/suites/test_suite_psa_crypto.function | 51 +++++++++++++----- 4 files changed, 101 insertions(+), 17 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index f94830d83..c266f9fe7 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -1228,18 +1228,60 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); */ /** The type of the state data structure for multipart cipher operations. + * + * Before calling any function on a cipher operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_cipher_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_cipher_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT, + * for example: + * \code + * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_cipher_operation_init() + * to the structure, for example: + * \code + * psa_cipher_operation_t operation; + * operation = psa_cipher_operation_init(); + * \endcode * * This is an implementation-defined \c struct. Applications should not * make any assumptions about the content of this structure except * as directed by the documentation of a specific implementation. */ typedef struct psa_cipher_operation_s psa_cipher_operation_t; +/** \def PSA_CIPHER_OPERATION_INIT + * + * This macro returns a suitable initializer for a cipher operation object of + * type #psa_cipher_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_CIPHER_OPERATION_INIT {0} +#endif + +/** Return an initial value for a cipher operation object. + */ +static psa_cipher_operation_t psa_cipher_operation_init(void); + /** Set the key for a multipart symmetric encryption operation. * * The sequence of operations to encrypt a message with a symmetric cipher * is as follows: * -# Allocate an operation object which will be passed to all the functions * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * PSA_CIPHER_OPERATION_INIT. * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. * The key remains associated with the operation even if the content * of the key slot changes. @@ -1252,7 +1294,7 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t; * -# Call psa_cipher_finish(). * * The application may call psa_cipher_abort() at any time after the operation - * has been initialized with psa_cipher_encrypt_setup(). + * has been initialized. * * After a successful call to psa_cipher_encrypt_setup(), the application must * eventually terminate the operation. The following events terminate an @@ -1261,7 +1303,9 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t; * or psa_cipher_update(). * - A call to psa_cipher_finish() or psa_cipher_abort(). * - * \param[out] operation The operation object to use. + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. * \param handle Handle to the key to use for the operation. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that @@ -1295,6 +1339,9 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * is as follows: * -# Allocate an operation object which will be passed to all the functions * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * PSA_CIPHER_OPERATION_INIT. * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. * The key remains associated with the operation even if the content * of the key slot changes. @@ -1307,7 +1354,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * -# Call psa_cipher_finish(). * * The application may call psa_cipher_abort() at any time after the operation - * has been initialized with psa_cipher_decrypt_setup(). + * has been initialized. * * After a successful call to psa_cipher_decrypt_setup(), the application must * eventually terminate the operation. The following events terminate an @@ -1315,7 +1362,9 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * - A failed call to psa_cipher_update(). * - A call to psa_cipher_finish() or psa_cipher_abort(). * - * \param[out] operation The operation object to use. + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. * \param handle Handle to the key to use for the operation. * \param alg The cipher algorithm to compute * (\c PSA_ALG_XXX value such that diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 5eb262405..ee3ecd776 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -145,6 +145,13 @@ struct psa_cipher_operation_s } ctx; }; +#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, {0}} +static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) +{ + const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; + return( v ); +} + #if defined(MBEDTLS_MD_C) typedef struct { diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 8275a1c3c..6ba61baa4 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -755,6 +755,9 @@ PSA MAC verify: CMAC-AES-128, truncated to 4 bytes depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 4):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747" +Cipher operation object initializers zero properly +cipher_operation_init: + PSA cipher setup: good, AES-CTR depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e821165c1..0ed374918 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -165,7 +165,7 @@ static int exercise_cipher_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; unsigned char iv[16] = {0}; size_t iv_length = sizeof( iv ); const unsigned char plaintext[16] = "Hello, world..."; @@ -1153,7 +1153,7 @@ void cipher_with_no_key_activity( ) psa_key_handle_t handle = 0; psa_status_t status; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; int exercise_alg = PSA_ALG_CTR; PSA_ASSERT( psa_crypto_init( ) ); @@ -1210,7 +1210,7 @@ void cipher_after_import_failure( data_t *data, int type_arg, int expected_import_status_arg ) { psa_key_handle_t handle = 0; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_type_t type = type_arg; psa_status_t status; psa_status_t expected_import_status = expected_import_status_arg; @@ -1492,7 +1492,7 @@ void cipher_key_policy( int policy_usage, { psa_key_handle_t handle = 0; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_status_t status; PSA_ASSERT( psa_crypto_init( ) ); @@ -2082,6 +2082,31 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void cipher_operation_init( ) +{ + /* Test each valid way of initializing the object, except for `= {0}`, as + * Clang 5 complains when `-Wmissing-field-initializers` is used, even + * though it's OK by the C standard. We could test for this, but we'd need + * to supress the Clang warning for the test. */ + psa_cipher_operation_t func = psa_cipher_operation_init( ); + psa_cipher_operation_t init = PSA_CIPHER_OPERATION_INIT; + psa_cipher_operation_t zero; + + memset( &zero, 0, sizeof( zero ) ); + + /* Although not technically guaranteed by the C standard nor the PSA Crypto + * specification, we test that all valid ways of initializing the object + * have the same bit pattern. This is a stronger requirement that may not + * be valid on all platforms or PSA Crypto implementations, but implies the + * weaker actual requirement is met: that a freshly initialized object, no + * matter how it was initialized, acts the same as any other valid + * initialization. */ + TEST_EQUAL( memcmp( &func, &zero, sizeof( zero ) ), 0 ); + TEST_EQUAL( memcmp( &init, &zero, sizeof( zero ) ), 0 ); +} +/* END_CASE */ + /* BEGIN_CASE */ void cipher_setup( int key_type_arg, data_t *key, @@ -2092,7 +2117,7 @@ void cipher_setup( int key_type_arg, psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; psa_status_t status; @@ -2133,7 +2158,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); @@ -2200,7 +2225,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); @@ -2270,7 +2295,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); @@ -2342,7 +2367,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, size_t output_buffer_size = 0; size_t function_output_length = 0; size_t total_output_length = 0; - psa_cipher_operation_t operation; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ); @@ -2412,8 +2437,8 @@ void cipher_verify_output( int alg_arg, int key_type_arg, size_t output2_size = 0; size_t output2_length = 0; size_t function_output_length = 0; - psa_cipher_operation_t operation1; - psa_cipher_operation_t operation2; + psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT; + psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); @@ -2497,8 +2522,8 @@ void cipher_verify_output_multipart( int alg_arg, size_t output2_buffer_size = 0; size_t output2_length = 0; size_t function_output_length; - psa_cipher_operation_t operation1; - psa_cipher_operation_t operation2; + psa_cipher_operation_t operation1 = PSA_CIPHER_OPERATION_INIT; + psa_cipher_operation_t operation2 = PSA_CIPHER_OPERATION_INIT; psa_key_policy_t policy = PSA_KEY_POLICY_INIT; PSA_ASSERT( psa_crypto_init( ) ); From d94d671f14592ea966911b03595cc552ed74daba Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Fri, 4 Jan 2019 14:11:48 +0000 Subject: [PATCH 7/8] psa: Test that generator initializers work --- tests/suites/test_suite_psa_crypto.data | 3 +++ tests/suites/test_suite_psa_crypto.function | 25 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 6ba61baa4..aa0a89052 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1402,6 +1402,9 @@ PSA decrypt: RSA OAEP-SHA-256, input too large depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V21:MBEDTLS_SHA256_C asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_OAEP(PSA_ALG_SHA_256):"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":"":PSA_ERROR_INVALID_ARGUMENT +Crypto generator initializers zero properly +crypto_generator_init: + PSA key derivation: HKDF-SHA-256, good case depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C derive_setup:PSA_KEY_TYPE_DERIVE:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HKDF(PSA_ALG_SHA_256):"":"":42:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 0ed374918..6916bf42e 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -3305,6 +3305,31 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void crypto_generator_init( ) +{ + /* Test each valid way of initializing the object, except for `= {0}`, as + * Clang 5 complains when `-Wmissing-field-initializers` is used, even + * though it's OK by the C standard. We could test for this, but we'd need + * to supress the Clang warning for the test. */ + psa_crypto_generator_t func = psa_crypto_generator_init( ); + psa_crypto_generator_t init = PSA_CRYPTO_GENERATOR_INIT; + psa_crypto_generator_t zero; + + memset( &zero, 0, sizeof( zero ) ); + + /* Although not technically guaranteed by the C standard nor the PSA Crypto + * specification, we test that all valid ways of initializing the object + * have the same bit pattern. This is a stronger requirement that may not + * be valid on all platforms or PSA Crypto implementations, but implies the + * weaker actual requirement is met: that a freshly initialized object, no + * matter how it was initialized, acts the same as any other valid + * initialization. */ + TEST_EQUAL( memcmp( &func, &zero, sizeof( zero ) ), 0 ); + TEST_EQUAL( memcmp( &init, &zero, sizeof( zero ) ), 0 ); +} +/* END_CASE */ + /* BEGIN_CASE */ void derive_setup( int key_type_arg, data_t *key_data, From 9e919c636fe170c656429003258d8e25e4288606 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 7 Jan 2019 15:41:50 +0000 Subject: [PATCH 8/8] psa: Document generator requirements consistently We've added documentation for how context objects for multi-part operations must be initialized consistently for key policy, hash, cipher, and MAC. Update the generator documentation to be consistent with how we've documented the other operations. --- include/psa/crypto.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index c266f9fe7..683feb83f 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -2099,11 +2099,9 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); * - For HKDF (#PSA_ALG_HKDF), \p salt is the salt used in the "extract" step * and \p label is the info string used in the "expand" step. * - * \param[in,out] generator The generator object to set up. It must - * have been initialized to all-bits-zero, - * a logical zero (`{0}`), - * \c PSA_CRYPTO_GENERATOR_INIT or - * psa_crypto_generator_init(). + * \param[in,out] generator The generator object to set up. It must have + * been initialized as per the documentation for + * #psa_crypto_generator_t and not yet in use. * \param handle Handle to the secret key. * \param alg The key derivation algorithm to compute * (\c PSA_ALG_XXX value such that @@ -2153,11 +2151,9 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, * The resulting generator always has the maximum capacity permitted by * the algorithm. * - * \param[in,out] generator The generator object to set up. It must - * have been initialized to all-bits-zero, - * a logical zero (`{0}`), - * \c PSA_CRYPTO_GENERATOR_INIT or - * psa_crypto_generator_init(). + * \param[in,out] generator The generator object to set up. It must have + * been initialized as per the documentation for + * #psa_crypto_generator_t and not yet in use. * \param private_key Handle to the private key to use. * \param[in] peer_key Public key of the peer. It must be * in the same format that psa_import_key()