psa_export_key: Always set a valid data length
Make psa_export_key() always set a valid data_length when exporting,
even when there are errors. This makes the API easier to use for buggy
programs (like our test code).
Our test code previously used exported_length uninitialized when
checking to see that the buffer returned was all zero in import_export()
in the case where an error was returned from psa_export_key().
Initialize exported_length to an invalid length, and check that it gets
set properly by psa_export_key(), to avoid this using export_length
uninitialized. Note that the mem_is_zero() check is still valid when
psa_export_key() returns an error, e.g. where exported_length is 0, as
we want to check that nothing was written to the buffer on error.
Out test code also previous passed NULL for the data_length parameter of
psa_export_key() when it expected a failure (in key_policy_fail()).
However, data_length is not allowed to be NULL, especially now that we
write to data_length from psa_export_key() even when there are errors.
Update the test code to not pass in a NULL data_length.
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 2d279fc..c67725d 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -8,6 +8,9 @@
#define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) 1
#endif
+/** An invalid export length that will never be set by psa_export_key(). */
+static const size_t INVALID_EXPORT_LENGTH = ~0U;
+
/** Test if a buffer is not all-bits zero.
*
* \param buffer Pointer to the beginning of the buffer.
@@ -320,7 +323,7 @@
unsigned char *exported = NULL;
unsigned char *reexported = NULL;
size_t export_size;
- size_t exported_length;
+ size_t exported_length = INVALID_EXPORT_LENGTH;
size_t reexported_length;
psa_key_type_t got_type;
size_t got_bits;
@@ -358,6 +361,13 @@
exported, export_size,
&exported_length );
TEST_ASSERT( status == expected_export_status );
+
+ /* The exported length must be set by psa_export_key() to a value between 0
+ * and export_size. On errors, the exported length must be 0. */
+ TEST_ASSERT( exported_length != INVALID_EXPORT_LENGTH );
+ TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
+ TEST_ASSERT( exported_length <= export_size );
+
TEST_ASSERT( mem_is_zero( exported + exported_length,
export_size - exported_length ) );
if( status != PSA_SUCCESS )
@@ -536,13 +546,14 @@
if( usage & PSA_KEY_USAGE_SIGN )
{
+ size_t data_length;
TEST_ASSERT( keypair != NULL );
TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( keypair->len ) );
TEST_ASSERT( psa_import_key( key_slot,
PSA_KEY_TYPE_RSA_KEYPAIR,
keypair->x,
keypair->len ) == PSA_SUCCESS );
- actual_status = psa_export_key( key_slot, NULL, 0, NULL );
+ actual_status = psa_export_key( key_slot, NULL, 0, &data_length );
}
TEST_ASSERT( actual_status == expected_status );