Merge remote-tracking branch 'psa/pr/75' into feature-psa
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 2670e41..de2bf40 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -636,6 +636,12 @@
 {
     key_slot_t *slot;
 
+    /* Set the key to empty now, so that even when there are errors, we always
+     * set data_length to a value between 0 and data_size. On error, setting
+     * the key to empty is a good choice because an empty key representation is
+     * unlikely to be accepted anywhere. */
+    *data_length = 0;
+
     if( key == 0 || key > PSA_KEY_SLOT_COUNT )
         return( PSA_ERROR_EMPTY_SLOT );
     slot = &global_data.key_slots[key];
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 265a6d5..612a152 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -103,7 +103,7 @@
 
 PSA import/export-public: cannot export-public a symmetric key
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export_public_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:128:162:PSA_ERROR_INVALID_ARGUMENT
+import_export_public_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:128:0:PSA_ERROR_INVALID_ARGUMENT
 
 PSA import/export EC secp256r1: good
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 2d279fc..0d056db 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 )
@@ -415,7 +425,7 @@
     psa_status_t status;
     unsigned char *exported = NULL;
     size_t export_size;
-    size_t exported_length;
+    size_t exported_length = INVALID_EXPORT_LENGTH;
     psa_key_type_t got_type;
     size_t got_bits;
     psa_key_policy_t policy;
@@ -448,11 +458,12 @@
                                     exported, export_size,
                                     &exported_length );
     TEST_ASSERT( status == expected_export_status );
+    TEST_ASSERT( exported_length == (size_t) public_key_expected_length );
+    TEST_ASSERT( mem_is_zero( exported + exported_length,
+                              export_size - exported_length ) );
     if( status != PSA_SUCCESS )
         goto destroy;
 
-    TEST_ASSERT( exported_length == (size_t) public_key_expected_length );
-
 destroy:
     /* Destroy the key */
     TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
@@ -536,13 +547,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 );