Merge pull request #333 from gilles-peskine-arm/psa-streamline_encodings-prepare_for_types

Streamline PSA key type encodings: prepare
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index a87ca81..2e7393b 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -378,24 +378,6 @@
     }
 }
 
-
-#define MBEDTLS_PSA_ECC_KEY_BITS_OF_CURVE( curve )                \
-    ( curve == PSA_ECC_CURVE_SECP192R1        ? 192 :             \
-      curve == PSA_ECC_CURVE_SECP224R1        ? 224 :             \
-      curve == PSA_ECC_CURVE_SECP256R1        ? 256 :             \
-      curve == PSA_ECC_CURVE_SECP384R1        ? 384 :             \
-      curve == PSA_ECC_CURVE_SECP521R1        ? 521 :             \
-      curve == PSA_ECC_CURVE_SECP192K1        ? 192 :             \
-      curve == PSA_ECC_CURVE_SECP224K1        ? 224 :             \
-      curve == PSA_ECC_CURVE_SECP256K1        ? 256 :             \
-      curve == PSA_ECC_CURVE_BRAINPOOL_P256R1 ? 256 :             \
-      curve == PSA_ECC_CURVE_BRAINPOOL_P384R1 ? 384 :             \
-      curve == PSA_ECC_CURVE_BRAINPOOL_P512R1 ? 512 :             \
-      0 )
-
-#define MBEDTLS_PSA_ECC_KEY_BYTES_OF_CURVE( curve )                \
-    ( ( MBEDTLS_PSA_ECC_KEY_BITS_OF_CURVE( curve ) + 7 ) / 8 )
-
 /* Translations for PK layer */
 
 static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index d0008a9..dbe75ad 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -604,6 +604,7 @@
         (type) == PSA_KEY_TYPE_DES ? 8 :             \
         (type) == PSA_KEY_TYPE_CAMELLIA ? 16 :       \
         (type) == PSA_KEY_TYPE_ARC4 ? 1 :            \
+        (type) == PSA_KEY_TYPE_CHACHA20 ? 1 :            \
         0)
 
 /** Vendor-defined algorithm flag.
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 25aff01..59edae1 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -584,6 +584,20 @@
 #endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) */
 
 #if defined(MBEDTLS_ECP_C)
+static psa_status_t psa_prepare_import_ec_key( psa_ecc_curve_t curve,
+                                               mbedtls_ecp_keypair **p_ecp )
+{
+    mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
+    *p_ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
+    if( *p_ecp == NULL )
+        return( PSA_ERROR_INSUFFICIENT_MEMORY );
+    mbedtls_ecp_keypair_init( *p_ecp );
+
+    /* Load the group. */
+    grp_id = mbedtls_ecc_group_of_psa( curve );
+    return( mbedtls_to_psa_error(
+                mbedtls_ecp_group_load( &( *p_ecp )->grp, grp_id ) ) );
+}
 
 /* Import a public key given as the uncompressed representation defined by SEC1
  * 2.3.3 as the content of an ECPoint. */
@@ -594,19 +608,11 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_keypair *ecp = NULL;
-    mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
 
-    *p_ecp = NULL;
-    ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
-    if( ecp == NULL )
-        return( PSA_ERROR_INSUFFICIENT_MEMORY );
-    mbedtls_ecp_keypair_init( ecp );
-
-    /* Load the group. */
-    status = mbedtls_to_psa_error(
-        mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
+    status = psa_prepare_import_ec_key( curve, &ecp );
     if( status != PSA_SUCCESS )
         goto exit;
+
     /* Load the public value. */
     status = mbedtls_to_psa_error(
         mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
@@ -631,9 +637,7 @@
     }
     return( status );
 }
-#endif /* defined(MBEDTLS_ECP_C) */
 
-#if defined(MBEDTLS_ECP_C)
 /* Import a private key given as a byte string which is the private value
  * in big-endian order. */
 static psa_status_t psa_import_ec_private_key( psa_ecc_curve_t curve,
@@ -643,22 +647,14 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     mbedtls_ecp_keypair *ecp = NULL;
-    mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
 
     if( PSA_BITS_TO_BYTES( PSA_ECC_CURVE_BITS( curve ) ) != data_length )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
-    *p_ecp = NULL;
-    ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
-    if( ecp == NULL )
-        return( PSA_ERROR_INSUFFICIENT_MEMORY );
-    mbedtls_ecp_keypair_init( ecp );
-
-    /* Load the group. */
-    status = mbedtls_to_psa_error(
-        mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
+    status = psa_prepare_import_ec_key( curve, &ecp );
     if( status != PSA_SUCCESS )
         goto exit;
+
     /* Load the secret value. */
     status = mbedtls_to_psa_error(
         mbedtls_mpi_read_binary( &ecp->d, data, data_length ) );
diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py
index c2d2558..a9de148 100755
--- a/scripts/generate_psa_constants.py
+++ b/scripts/generate_psa_constants.py
@@ -270,11 +270,16 @@
             # Other macro without parameter
             return
 
+    _nonascii_re = re.compile(rb'[^\x00-\x7f]+')
+    _continued_line_re = re.compile(rb'\\\r?\n\Z')
     def read_file(self, header_file):
         for line in header_file:
-            while line.endswith('\\\n'):
+            m = re.search(self._continued_line_re, line)
+            while m:
                 cont = next(header_file)
-                line = line[:-2] + cont
+                line = line[:m.start(0)] + cont
+                m = re.search(self._continued_line_re, line)
+            line = re.sub(self._nonascii_re, rb'', line).decode('ascii')
             self.read_line(line)
 
     @staticmethod
@@ -380,7 +385,7 @@
 def generate_psa_constants(header_file_names, output_file_name):
     collector = MacroCollector()
     for header_file_name in header_file_names:
-        with open(header_file_name) as header_file:
+        with open(header_file_name, 'rb') as header_file:
             collector.read_file(header_file)
     temp_file_name = output_file_name + '.tmp'
     with open(temp_file_name, 'w') as output_file:
diff --git a/tests/scripts/test_psa_constant_names.py b/tests/scripts/test_psa_constant_names.py
index 7553394..717d0db 100755
--- a/tests/scripts/test_psa_constant_names.py
+++ b/tests/scripts/test_psa_constant_names.py
@@ -43,12 +43,14 @@
     except that if process(line) raises an exception, then the read_file_lines
     snippet annotates the exception with the file name and line number.
     """
-    def __init__(self, filename):
+    def __init__(self, filename, binary=False):
         self.filename = filename
         self.line_number = 'entry'
         self.generator = None
+        self.binary = binary
     def __enter__(self):
-        self.generator = enumerate(open(self.filename, 'r'))
+        self.generator = enumerate(open(self.filename,
+                                        'rb' if self.binary else 'r'))
         return self
     def __iter__(self):
         for line_number, content in self.generator:
@@ -100,6 +102,8 @@
             # Any function ending in _algorithm also gets added to
             # self.algorithms.
             'key_type': [self.key_types],
+            'block_cipher_key_type': [self.key_types],
+            'stream_cipher_key_type': [self.key_types],
             'ecc_key_types': [self.ecc_curves],
             'dh_key_types': [self.dh_groups],
             'hash_algorithm': [self.hash_algorithms],
@@ -224,13 +228,15 @@
         if m.group(3):
             self.argspecs[name] = self._argument_split(m.group(3))
 
+    _nonascii_re = re.compile(rb'[^\x00-\x7f]+')
     def parse_header(self, filename):
         """Parse a C header file, looking for "#define PSA_xxx"."""
-        with read_file_lines(filename) as lines:
+        with read_file_lines(filename, binary=True) as lines:
             for line in lines:
+                line = re.sub(self._nonascii_re, rb'', line).decode('ascii')
                 self.parse_header_line(line)
 
-    _macro_identifier_re = r'[A-Z]\w+'
+    _macro_identifier_re = re.compile(r'[A-Z]\w+')
     def generate_undeclared_names(self, expr):
         for name in re.findall(self._macro_identifier_re, expr):
             if name not in self.all_declared:
@@ -385,6 +391,8 @@
         outputs = output.decode('ascii').strip().split('\n')
         self.count += len(expressions)
         for expr, value, output in zip(expressions, values, outputs):
+            if self.options.show:
+                sys.stdout.write('{} {}\t{}\n'.format(type_word, value, output))
             if normalize(expr) != normalize(output):
                 self.errors.append(self.Error(type=type_word,
                                               expression=expr,
@@ -430,6 +438,12 @@
     parser.add_argument('--program',
                         default='programs/psa/psa_constant_names',
                         help='Program to test')
+    parser.add_argument('--show',
+                        action='store_true',
+                        help='Keep the intermediate C file')
+    parser.add_argument('--no-show',
+                        action='store_false', dest='show',
+                        help='Don\'t show tested values (default)')
     options = parser.parse_args()
     headers = [os.path.join(options.include[0], h) for h in HEADERS]
     inputs = gather_inputs(headers, TEST_SUITES)
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 436ed7c..fa2f6ec 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -228,6 +228,14 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 import_export:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA_ANY:256:0:PSA_SUCCESS:1
 
+PSA import/export EC secp521r1 public key: good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP521R1_ENABLED
+import_export:"04001de142d54f69eb038ee4b7af9d3ca07736fd9cf719eb354d69879ee7f3c136fb0fbf9f08f86be5fa128ec1a051d3e6c643e85ada8ffacf3663c260bd2c844b6f5600cee8e48a9e65d09cadd89f235dee05f3b8a646be715f1f67d5b434e0ff23a1fc07ef7740193e40eeff6f3bcdfd765aa9155033524fe4f205f5444e292c4c2f6ac1":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP521R1):PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA_ANY:521:0:PSA_SUCCESS:1
+
+PSA import/export EC brainpoolP256r1 public key: good
+depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP256R1_ENABLED
+import_export:"04768c8cae4abca6306db0ed81b0c4a6215c378066ec6d616c146e13f1c7df809b96ab6911c27d8a02339f0926840e55236d3d1efbe2669d090e4c4c660fada91d":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_BRAINPOOL_P256R1):PSA_KEY_USAGE_EXPORT:PSA_ALG_ECDSA_ANY:256:0:PSA_SUCCESS:1
+
 PSA import/export AES key: policy forbids export
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
 import_export:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:128:0:PSA_ERROR_NOT_PERMITTED:1
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 83b0c95..ba7c192 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -106,6 +106,22 @@
 #undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE
 #endif
 
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+int lifetime_is_secure_element( psa_key_lifetime_t lifetime )
+{
+    /* At the moment, anything that isn't a built-in lifetime is either
+     * a secure element or unassigned. */
+    return( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
+            lifetime != PSA_KEY_LIFETIME_PERSISTENT );
+}
+#else
+int lifetime_is_secure_element( psa_key_lifetime_t lifetime )
+{
+    (void) lifetime;
+    return( 0 );
+}
+#endif
+
 /** Test if a buffer contains a constant byte value.
  *
  * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
@@ -212,6 +228,69 @@
     return( len );
 }
 
+int check_key_attributes_sanity( psa_key_handle_t key )
+{
+    int ok = 0;
+    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+    psa_key_lifetime_t lifetime;
+    psa_key_id_t id;
+    psa_key_type_t type;
+    psa_key_type_t bits;
+
+    PSA_ASSERT( psa_get_key_attributes( key, &attributes ) );
+    lifetime = psa_get_key_lifetime( &attributes );
+    id = psa_get_key_id( &attributes );
+    type = psa_get_key_type( &attributes );
+    bits = psa_get_key_bits( &attributes );
+
+    /* Persistence */
+    if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
+        TEST_ASSERT( id == 0 );
+    else
+    {
+        TEST_ASSERT(
+            ( PSA_KEY_ID_USER_MIN <= id && id <= PSA_KEY_ID_USER_MAX ) ||
+            ( PSA_KEY_ID_USER_MIN <= id && id <= PSA_KEY_ID_USER_MAX ) );
+    }
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+    /* randomly-generated 64-bit constant, should never appear in test data */
+    psa_key_slot_number_t slot_number = 0xec94d4a5058a1a21;
+    psa_status_t status = psa_get_key_slot_number( &attributes, &slot_number );
+    if( lifetime_is_secure_element( lifetime ) )
+    {
+        /* Mbed Crypto currently always exposes the slot number to
+         * applications. This is not mandated by the PSA specification
+         * and may change in future versions. */
+        TEST_EQUAL( status, 0 );
+        TEST_ASSERT( slot_number != 0xec94d4a5058a1a21 );
+    }
+    else
+    {
+        TEST_EQUAL( status, PSA_ERROR_INVALID_ARGUMENT );
+    }
+#endif
+
+    /* Type and size */
+    TEST_ASSERT( type != 0 );
+    TEST_ASSERT( bits != 0 );
+    TEST_ASSERT( bits <= PSA_MAX_KEY_BITS );
+    if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
+        TEST_ASSERT( bits % 8 == 0 );
+
+    /* MAX macros concerning specific key types */
+    if( PSA_KEY_TYPE_IS_ECC( type ) )
+        TEST_ASSERT( bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS );
+    else if( PSA_KEY_TYPE_IS_RSA( type ) )
+        TEST_ASSERT( bits <= PSA_VENDOR_RSA_MAX_KEY_BITS );
+    TEST_ASSERT( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) <= PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE );
+
+    ok = 1;
+
+exit:
+    psa_reset_key_attributes( &attributes );
+    return( ok );
+}
+
 int exercise_mac_setup( psa_key_type_t key_type,
                         const unsigned char *key_bytes,
                         size_t key_length,
@@ -1021,6 +1100,10 @@
                          psa_algorithm_t alg )
 {
     int ok;
+
+    if( ! check_key_attributes_sanity( handle ) )
+        return( 0 );
+
     if( alg == 0 )
         ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */
     else if( PSA_ALG_IS_MAC( alg ) )
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index 9cdee03..d0cc799 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -315,25 +315,25 @@
 Key type: secret for key derivation
 key_type:PSA_KEY_TYPE_DERIVE:KEY_TYPE_IS_UNSTRUCTURED
 
-Key type: AES
+Block cipher key type: AES
 depends_on:MBEDTLS_AES_C
-key_type:PSA_KEY_TYPE_AES:KEY_TYPE_IS_UNSTRUCTURED
+block_cipher_key_type:PSA_KEY_TYPE_AES:16
 
-Key type: DES
+Block cipher key type: DES
 depends_on:MBEDTLS_DES_C
-key_type:PSA_KEY_TYPE_DES:KEY_TYPE_IS_UNSTRUCTURED
+block_cipher_key_type:PSA_KEY_TYPE_DES:8
 
-Key type: Camellia
+Block cipher key type: Camellia
 depends_on:MBEDTLS_CAMELLIA_C
-key_type:PSA_KEY_TYPE_CAMELLIA:KEY_TYPE_IS_UNSTRUCTURED
+block_cipher_key_type:PSA_KEY_TYPE_CAMELLIA:16
 
-Key type: ARC4
+Stream cipher key type: ARC4
 depends_on:MBEDTLS_ARC4_C
-key_type:PSA_KEY_TYPE_ARC4:KEY_TYPE_IS_UNSTRUCTURED
+stream_cipher_key_type:PSA_KEY_TYPE_ARC4
 
-Key type: ChaCha20
+Stream cipher key type: ChaCha20
 depends_on:MBEDTLS_CHACHA20_C
-key_type:PSA_KEY_TYPE_CHACHA20:KEY_TYPE_IS_UNSTRUCTURED
+stream_cipher_key_type:PSA_KEY_TYPE_CHACHA20
 
 Key type: RSA public key
 depends_on:MBEDTLS_RSA_C
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index 3a9347e..9282641 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -450,6 +450,33 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void block_cipher_key_type( int type_arg, int block_size_arg )
+{
+    psa_key_type_t type = type_arg;
+    size_t block_size = block_size_arg;
+
+    test_key_type( type_arg, KEY_TYPE_IS_UNSTRUCTURED );
+
+    TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
+                PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
+    TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ), block_size );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void stream_cipher_key_type( int type_arg )
+{
+    psa_key_type_t type = type_arg;
+
+    test_key_type( type_arg, KEY_TYPE_IS_UNSTRUCTURED );
+
+    TEST_EQUAL( type & PSA_KEY_TYPE_CATEGORY_MASK,
+                PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
+    TEST_EQUAL( PSA_BLOCK_CIPHER_BLOCK_SIZE( type ), 1 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void ecc_key_types( int curve_arg, int curve_bits_arg )
 {
     psa_ecc_curve_t curve = curve_arg;
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data
index 8765dfc..9e5d45a 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.data
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.data
@@ -1,27 +1,27 @@
-PSA Storage format data for storage
+Format for storage: RSA private key
 format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
 
-PSA Storage parse stored data
+Parse storage: RSA private key
 parse_storage_data_check:"505341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_SUCCESS
 
-PSA Storage parse stored data wrong version, should fail
+Parse storage: wrong version
 parse_storage_data_check:"505341004b455900ffffffff0100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
-PSA Storage parse too big data, should fail
+Parse storage: data too big
 parse_storage_data_check:"505341004b455900000000000100000000000170010000000000001200000010ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
-PSA Storage parse bad magic, should fail
+Parse storage: bad magic
 parse_storage_data_check:"645341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
-PSA Storage parse not enough magic, should fail
+Parse storage: truncated magic
 parse_storage_data_check:"505341004b4559":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
 
 # Not specific to files, but only run this test in an environment where the maximum size could be reached.
-Save maximum size persistent raw key
+Save maximum-size persistent raw key
 depends_on:MBEDTLS_PSA_ITS_FILE_C
 save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE:PSA_SUCCESS
 
-Save larger than maximum size persistent raw key, should fail
+Save larger than maximum-size persistent raw key
 save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE + 1:PSA_ERROR_NOT_SUPPORTED
 
 Persistent key destroy
@@ -66,7 +66,7 @@
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:0:1
 
-PSA import/export-persistent symmetric key: 16 bytes [#1]
+import/export-persistent symmetric key: 16 bytes
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:0:0
 
@@ -92,6 +92,6 @@
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:1:1
 
-PSA import/export-persistent symmetric key: 16 bytes [#2]
+import/export-persistent symmetric key with restart: 16 bytes
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
 import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:1:0
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index 115bfea..d4163cd 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -32,8 +32,9 @@
                                 int key_lifetime, int key_type,
                                 int key_usage, int key_alg, int key_alg2 )
 {
-    uint8_t *file_data;
-    size_t file_data_length;
+    uint8_t *file_data = NULL;
+    size_t file_data_length =
+        key_data->len + sizeof( psa_persistent_key_storage_format );
     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
     psa_set_key_lifetime( &attributes, key_lifetime );
@@ -42,14 +43,15 @@
     psa_set_key_algorithm( &attributes, key_alg );
     psa_set_key_enrollment_algorithm( &attributes, key_alg2 );
 
-    file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format );
-    file_data = mbedtls_calloc( 1, file_data_length );
+    ASSERT_ALLOC( file_data, file_data_length );
     psa_format_key_data_for_storage( key_data->x, key_data->len,
                                      &attributes.core,
                                      file_data );
 
     ASSERT_COMPARE( expected_file_data->x, expected_file_data->len,
                     file_data, file_data_length );
+
+exit:
     mbedtls_free( file_data );
 }
 /* END_CASE */