Merge remote-tracking branch 'psa/pr/63' into feature-psa
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 28103c7..4a46eb8 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -366,9 +366,6 @@
 /** Whether a key type is vendor-defined. */
 #define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
     (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
-#define PSA_KEY_TYPE_IS_RAW_BYTES(type)                                 \
-    (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_RAW_DATA ||  \
-     ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC)
 
 /** Whether a key type is asymmetric: either a key pair or a public key. */
 #define PSA_KEY_TYPE_IS_ASYMMETRIC(type)                                \
@@ -1846,14 +1843,17 @@
 /**
  * \brief Generate a key or key pair.
  *
- * \param key         Slot where the key will be stored. This must be a
- *                    valid slot for a key of the chosen type. It must
- *                    be unoccupied.
- * \param type        Key type (a \c PSA_KEY_TYPE_XXX value).
- * \param bits        Key size in bits.
- * \param parameters  Extra parameters for key generation. The interpretation
- *                    of this parameter depends on \c type. All types support
- *                    \c NULL to use default parameters specified below.
+ * \param key               Slot where the key will be stored. This must be a
+ *                          valid slot for a key of the chosen type. It must
+ *                          be unoccupied.
+ * \param type              Key type (a \c PSA_KEY_TYPE_XXX value).
+ * \param bits              Key size in bits.
+ * \param parameters        Extra parameters for key generation. The
+ *                          interpretation of this parameter depends on
+ *                          \c type. All types support \c NULL to use
+ *                          the default parameters specified below.
+ * \param parameters_size   Size of the buffer that \param parameters
+ *                          points to, in bytes.
  *
  * For any symmetric key type (type such that
  * `PSA_KEY_TYPE_IS_ASYMMETRIC(type)` is false), \c parameters must be
@@ -1878,7 +1878,8 @@
 psa_status_t psa_generate_key(psa_key_slot_t key,
                               psa_key_type_t type,
                               size_t bits,
-                              const void *parameters);
+                              const void *parameters,
+                              size_t parameters_size);
 
 /**@}*/
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index e41e512..2670e41 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -39,6 +39,7 @@
 #endif
 
 #include "mbedtls/arc4.h"
+#include "mbedtls/asn1.h"
 #include "mbedtls/blowfish.h"
 #include "mbedtls/camellia.h"
 #include "mbedtls/cipher.h"
@@ -115,6 +116,13 @@
     } data;
 } key_slot_t;
 
+static int key_type_is_raw_bytes( psa_key_type_t type )
+{
+    psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
+    return( category == PSA_KEY_TYPE_RAW_DATA ||
+            category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
+}
+
 typedef struct
 {
     int initialized;
@@ -144,6 +152,17 @@
         case MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED:
             return( PSA_ERROR_HARDWARE_FAILURE );
 
+        case MBEDTLS_ERR_ASN1_OUT_OF_DATA:
+        case MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:
+        case MBEDTLS_ERR_ASN1_INVALID_LENGTH:
+        case MBEDTLS_ERR_ASN1_LENGTH_MISMATCH:
+        case MBEDTLS_ERR_ASN1_INVALID_DATA:
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        case MBEDTLS_ERR_ASN1_ALLOC_FAILED:
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+        case MBEDTLS_ERR_ASN1_BUF_TOO_SMALL:
+            return( PSA_ERROR_BUFFER_TOO_SMALL );
+
         case MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH:
         case MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH:
             return( PSA_ERROR_NOT_SUPPORTED );
@@ -346,6 +365,94 @@
     }
 }
 
+static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve )
+{
+    switch( curve )
+    {
+        case PSA_ECC_CURVE_SECP192R1:
+            return( MBEDTLS_ECP_DP_SECP192R1 );
+        case PSA_ECC_CURVE_SECP224R1:
+            return( MBEDTLS_ECP_DP_SECP224R1 );
+        case PSA_ECC_CURVE_SECP256R1:
+            return( MBEDTLS_ECP_DP_SECP256R1 );
+        case PSA_ECC_CURVE_SECP384R1:
+            return( MBEDTLS_ECP_DP_SECP384R1 );
+        case PSA_ECC_CURVE_SECP521R1:
+            return( MBEDTLS_ECP_DP_SECP521R1 );
+        case PSA_ECC_CURVE_BRAINPOOL_P256R1:
+            return( MBEDTLS_ECP_DP_BP256R1 );
+        case PSA_ECC_CURVE_BRAINPOOL_P384R1:
+            return( MBEDTLS_ECP_DP_BP384R1 );
+        case PSA_ECC_CURVE_BRAINPOOL_P512R1:
+            return( MBEDTLS_ECP_DP_BP512R1 );
+        case PSA_ECC_CURVE_CURVE25519:
+            return( MBEDTLS_ECP_DP_CURVE25519 );
+        case PSA_ECC_CURVE_SECP192K1:
+            return( MBEDTLS_ECP_DP_SECP192K1 );
+        case PSA_ECC_CURVE_SECP224K1:
+            return( MBEDTLS_ECP_DP_SECP224K1 );
+        case PSA_ECC_CURVE_SECP256K1:
+            return( MBEDTLS_ECP_DP_SECP256K1 );
+        case PSA_ECC_CURVE_CURVE448:
+            return( MBEDTLS_ECP_DP_CURVE448 );
+        default:
+            return( MBEDTLS_ECP_DP_NONE );
+    }
+}
+
+static psa_status_t prepare_raw_data_slot( psa_key_type_t type,
+                                           size_t bits,
+                                           struct raw_data *raw )
+{
+    /* Check that the bit size is acceptable for the key type */
+    switch( type )
+    {
+        case PSA_KEY_TYPE_RAW_DATA:
+#if defined(MBEDTLS_MD_C)
+        case PSA_KEY_TYPE_HMAC:
+#endif
+            break;
+#if defined(MBEDTLS_AES_C)
+        case PSA_KEY_TYPE_AES:
+            if( bits != 128 && bits != 192 && bits != 256 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
+#if defined(MBEDTLS_CAMELLIA_C)
+        case PSA_KEY_TYPE_CAMELLIA:
+            if( bits != 128 && bits != 192 && bits != 256 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
+#if defined(MBEDTLS_DES_C)
+        case PSA_KEY_TYPE_DES:
+            if( bits != 64 && bits != 128 && bits != 192 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
+#if defined(MBEDTLS_ARC4_C)
+        case PSA_KEY_TYPE_ARC4:
+            if( bits < 8 || bits > 2048 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            break;
+#endif
+        default:
+            return( PSA_ERROR_NOT_SUPPORTED );
+    }
+    if( bits % 8 != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    /* Allocate memory for the key */
+    raw->bytes = PSA_BITS_TO_BYTES( bits );
+    raw->data = mbedtls_calloc( 1, raw->bytes );
+    if( raw->data == NULL )
+    {
+        raw->bytes = 0;
+        return( PSA_ERROR_INSUFFICIENT_MEMORY );
+    }
+    return( PSA_SUCCESS );
+}
+
 psa_status_t psa_import_key( psa_key_slot_t key,
                              psa_key_type_t type,
                              const uint8_t *data,
@@ -359,16 +466,18 @@
     if( slot->type != PSA_KEY_TYPE_NONE )
         return( PSA_ERROR_OCCUPIED_SLOT );
 
-    if( PSA_KEY_TYPE_IS_RAW_BYTES( type ) )
+    if( key_type_is_raw_bytes( type ) )
     {
+        psa_status_t status;
         /* Ensure that a bytes-to-bit conversion won't overflow. */
         if( data_length > SIZE_MAX / 8 )
             return( PSA_ERROR_NOT_SUPPORTED );
-        slot->data.raw.data = mbedtls_calloc( 1, data_length );
-        if( slot->data.raw.data == NULL )
-            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+        status = prepare_raw_data_slot( type,
+                                        PSA_BYTES_TO_BITS( data_length ),
+                                        &slot->data.raw );
+        if( status != PSA_SUCCESS )
+            return( status );
         memcpy( slot->data.raw.data, data, data_length );
-        slot->data.raw.bytes = data_length;
     }
     else
 #if defined(MBEDTLS_PK_PARSE_C)
@@ -439,7 +548,7 @@
         /* No key material to clean, but do zeroize the slot below to wipe
          * metadata such as policies. */
     }
-    else if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
+    else if( key_type_is_raw_bytes( slot->type ) )
     {
         mbedtls_free( slot->data.raw.data );
     }
@@ -487,7 +596,7 @@
     if( slot->type == PSA_KEY_TYPE_NONE )
         return( PSA_ERROR_EMPTY_SLOT );
 
-    if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
+    if( key_type_is_raw_bytes( slot->type ) )
     {
         if( bits != NULL )
             *bits = slot->data.raw.bytes * 8;
@@ -541,7 +650,7 @@
         ( slot->policy.usage & PSA_KEY_USAGE_EXPORT ) == 0 )
         return( PSA_ERROR_NOT_PERMITTED );
 
-    if( PSA_KEY_TYPE_IS_RAW_BYTES( slot->type ) )
+    if( key_type_is_raw_bytes( slot->type ) )
     {
         if( slot->data.raw.bytes > data_size )
             return( PSA_ERROR_BUFFER_TOO_SMALL );
@@ -575,7 +684,23 @@
             else
                 ret = mbedtls_pk_write_key_der( &pk, data, data_size );
             if( ret < 0 )
+            {
+                memset( data, 0, data_size );
                 return( mbedtls_to_psa_error( ret ) );
+            }
+            /* The mbedtls_pk_xxx functions write to the end of the buffer.
+             * Move the data to the beginning and erase remaining data
+             * at the original location. */
+            if( 2 * (size_t) ret <= data_size )
+            {
+                memcpy( data, data + data_size - ret, ret );
+                memset( data + data_size - ret, 0, ret );
+            }
+            else if( (size_t) ret < data_size )
+            {
+                memmove( data, data + data_size - ret, ret );
+                memset( data + ret, 0, data_size - ret );
+            }
             *data_length = ret;
             return( PSA_SUCCESS );
         }
@@ -659,6 +784,11 @@
 {
     switch( operation->alg )
     {
+        case 0:
+            /* The object has (apparently) been initialized but it is not
+             * in use. It's ok to call abort on such an object, and there's
+             * nothing to do. */
+            break;
 #if defined(MBEDTLS_MD2_C)
         case PSA_ALG_MD2:
             mbedtls_md2_free( &operation->ctx.md2 );
@@ -697,7 +827,7 @@
             break;
 #endif
         default:
-            return( PSA_ERROR_NOT_SUPPORTED );
+            return( PSA_ERROR_BAD_STATE );
     }
     operation->alg = 0;
     return( PSA_SUCCESS );
@@ -761,7 +891,9 @@
             break;
 #endif
         default:
-            return( PSA_ERROR_NOT_SUPPORTED );
+            return( PSA_ALG_IS_HASH( alg ) ?
+                    PSA_ERROR_NOT_SUPPORTED :
+                    PSA_ERROR_INVALID_ARGUMENT );
     }
     if( ret == 0 )
         operation->alg = alg;
@@ -982,10 +1114,17 @@
             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
             break;
         case PSA_KEY_TYPE_DES:
+            /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
+             * and 192 for three-key Triple-DES. */
             if( key_bits == 64 )
                 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
             else
                 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
+            /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
+             * but two-key Triple-DES is functionally three-key Triple-DES
+             * with K1=K3, so that's how we present it to mbedtls. */
+            if( key_bits == 128 )
+                key_bits = 192;
             break;
         case PSA_KEY_TYPE_CAMELLIA:
             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
@@ -1029,10 +1168,57 @@
     }
 }
 
+/* Initialize the MAC operation structure. Once this function has been
+ * called, psa_mac_abort can run and will do the right thing. */
+static psa_status_t psa_mac_init( psa_mac_operation_t *operation,
+                                  psa_algorithm_t alg )
+{
+    psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
+
+    operation->alg = alg;
+    operation->key_set = 0;
+    operation->iv_set = 0;
+    operation->iv_required = 0;
+    operation->has_input = 0;
+    operation->key_usage_sign = 0;
+    operation->key_usage_verify = 0;
+
+#if defined(MBEDTLS_CMAC_C)
+    if( alg == PSA_ALG_CMAC )
+    {
+        operation->iv_required = 0;
+        mbedtls_cipher_init( &operation->ctx.cmac );
+        status = PSA_SUCCESS;
+    }
+    else
+#endif /* MBEDTLS_CMAC_C */
+#if defined(MBEDTLS_MD_C)
+    if( PSA_ALG_IS_HMAC( operation->alg ) )
+    {
+        status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
+                                 PSA_ALG_HMAC_HASH( alg ) );
+    }
+    else
+#endif /* MBEDTLS_MD_C */
+    {
+        if( ! PSA_ALG_IS_MAC( alg ) )
+            status = PSA_ERROR_INVALID_ARGUMENT;
+    }
+
+    if( status != PSA_SUCCESS )
+        memset( operation, 0, sizeof( *operation ) );
+    return( status );
+}
+
 psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
 {
     switch( operation->alg )
     {
+        case 0:
+            /* The object has (apparently) been initialized but it is not
+             * in use. It's ok to call abort on such an object, and there's
+             * nothing to do. */
+            return( PSA_SUCCESS );
 #if defined(MBEDTLS_CMAC_C)
         case PSA_ALG_CMAC:
             mbedtls_cipher_free( &operation->ctx.cmac );
@@ -1053,7 +1239,11 @@
             }
             else
 #endif /* MBEDTLS_MD_C */
-                return( PSA_ERROR_NOT_SUPPORTED );
+            {
+                /* Sanity check (shouldn't happen: operation->alg should
+                 * always have been initialized to a valid value). */
+                return( PSA_ERROR_BAD_STATE );
+            }
     }
 
     operation->alg = 0;
@@ -1061,6 +1251,8 @@
     operation->iv_set = 0;
     operation->iv_required = 0;
     operation->has_input = 0;
+    operation->key_usage_sign = 0;
+    operation->key_usage_verify = 0;
 
     return( PSA_SUCCESS );
 }
@@ -1074,8 +1266,6 @@
     int ret;
 
     operation->mac_size = cipher_info->block_size;
-    operation->iv_required = 0;
-    mbedtls_cipher_init( &operation->ctx.cmac );
 
     ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info );
     if( ret != 0 )
@@ -1088,6 +1278,7 @@
 }
 #endif /* MBEDTLS_CMAC_C */
 
+#if defined(MBEDTLS_MD_C)
 static int psa_hmac_start( psa_mac_operation_t *operation,
                            psa_key_type_t key_type,
                            key_slot_t *slot,
@@ -1109,14 +1300,9 @@
     if( key_type != PSA_KEY_TYPE_HMAC )
         return( PSA_ERROR_INVALID_ARGUMENT );
 
-    operation->iv_required = 0;
     operation->mac_size = digest_size;
 
-    status = psa_hash_start( &operation->ctx.hmac.hash_ctx,
-                             PSA_ALG_HMAC_HASH( alg ) );
-    if( status != PSA_SUCCESS )
-        return( status );
-
+    /* The hash was started earlier in psa_mac_init. */
     if( key_length > block_size )
     {
         status = psa_hash_update( &operation->ctx.hmac.hash_ctx,
@@ -1159,6 +1345,7 @@
 
     return( status );
 }
+#endif /* MBEDTLS_MD_C */
 
 psa_status_t psa_mac_start( psa_mac_operation_t *operation,
                             psa_key_slot_t key,
@@ -1170,13 +1357,9 @@
     size_t key_bits;
     const mbedtls_cipher_info_t *cipher_info = NULL;
 
-    operation->alg = 0;
-    operation->key_set = 0;
-    operation->iv_set = 0;
-    operation->iv_required = 1;
-    operation->has_input = 0;
-    operation->key_usage_sign = 0;
-    operation->key_usage_verify = 0;
+    status = psa_mac_init( operation, alg );
+    if( status != PSA_SUCCESS )
+        return( status );
 
     status = psa_get_key_information( key, &key_type, &key_bits );
     if( status != PSA_SUCCESS )
@@ -1219,16 +1402,13 @@
     }
 
     /* If we reach this point, then the algorithm-specific part of the
-
      * context may contain data that needs to be wiped on error. */
     if( status != PSA_SUCCESS )
     {
         psa_mac_abort( operation );
     }
-
     else
     {
-        operation->alg = alg;
         operation->key_set = 1;
     }
     return( status );
@@ -1768,6 +1948,27 @@
 /* Symmetric cryptography */
 /****************************************************************/
 
+/* Initialize the cipher operation structure. Once this function has been
+ * called, psa_cipher_abort can run and will do the right thing. */
+static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
+                                     psa_algorithm_t alg )
+{
+    if( ! PSA_ALG_IS_CIPHER( alg ) )
+    {
+        memset( operation, 0, sizeof( *operation ) );
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    }
+
+    operation->alg = alg;
+    operation->key_set = 0;
+    operation->iv_set = 0;
+    operation->iv_required = 1;
+    operation->iv_size = 0;
+    operation->block_size = 0;
+    mbedtls_cipher_init( &operation->ctx.cipher );
+    return( PSA_SUCCESS );
+}
+
 static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
                                       psa_key_slot_t key,
                                       psa_algorithm_t alg,
@@ -1780,12 +1981,9 @@
     size_t key_bits;
     const mbedtls_cipher_info_t *cipher_info = NULL;
 
-    operation->alg = alg;
-    operation->key_set = 0;
-    operation->iv_set = 0;
-    operation->iv_required = 1;
-    operation->iv_size = 0;
-    operation->block_size = 0;
+    status = psa_cipher_init( operation, alg );
+    if( status != PSA_SUCCESS )
+        return( status );
 
     status = psa_get_key_information( key, &key_type, &key_bits );
     if( status != PSA_SUCCESS )
@@ -1796,7 +1994,6 @@
     if( cipher_info == NULL )
         return( PSA_ERROR_NOT_SUPPORTED );
 
-    mbedtls_cipher_init( &operation->ctx.cipher );
     ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
     if( ret != 0 )
     {
@@ -1804,8 +2001,24 @@
         return( mbedtls_to_psa_error( ret ) );
     }
 
-    ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
-                                 key_bits, cipher_operation );
+#if defined(MBEDTLS_DES_C)
+    if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
+    {
+        /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
+        unsigned char keys[24];
+        memcpy( keys, slot->data.raw.data, 16 );
+        memcpy( keys + 16, slot->data.raw.data, 8 );
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
+                                     keys,
+                                     192, cipher_operation );
+    }
+    else
+#endif
+    {
+        ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
+                                     slot->data.raw.data,
+                                     key_bits, cipher_operation );
+    }
     if( ret != 0 )
     {
         psa_cipher_abort( operation );
@@ -1840,7 +2053,6 @@
 #endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
 
     operation->key_set = 1;
-    operation->alg = alg;
     operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
                               PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
                               1 );
@@ -2015,6 +2227,19 @@
 
 psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
 {
+    if( operation->alg == 0 )
+    {
+        /* The object has (apparently) been initialized but it is not
+         * in use. It's ok to call abort on such an object, and there's
+         * nothing to do. */
+        return( PSA_SUCCESS );
+    }
+
+    /* Sanity check (shouldn't happen: operation->alg should
+     * always have been initialized to a valid value). */
+    if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
+        return( PSA_ERROR_BAD_STATE );
+
     mbedtls_cipher_free( &operation->ctx.cipher );
 
     operation->alg = 0;
@@ -2409,6 +2634,135 @@
 
 
 /****************************************************************/
+/* Key generation */
+/****************************************************************/
+
+psa_status_t psa_generate_random( uint8_t *output,
+                                  size_t output_size )
+{
+    int ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
+                                       output, output_size );
+    return( mbedtls_to_psa_error( ret ) );
+}
+
+psa_status_t psa_generate_key( psa_key_slot_t key,
+                               psa_key_type_t type,
+                               size_t bits,
+                               const void *parameters,
+                               size_t parameters_size )
+{
+    key_slot_t *slot;
+
+    if( key == 0 || key > PSA_KEY_SLOT_COUNT )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    slot = &global_data.key_slots[key];
+    if( slot->type != PSA_KEY_TYPE_NONE )
+        return( PSA_ERROR_OCCUPIED_SLOT );
+    if( parameters == NULL && parameters_size != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+
+    if( key_type_is_raw_bytes( type ) )
+    {
+        psa_status_t status = prepare_raw_data_slot( type, bits,
+                                                     &slot->data.raw );
+        if( status != PSA_SUCCESS )
+            return( status );
+        status = psa_generate_random( slot->data.raw.data,
+                                      slot->data.raw.bytes );
+        if( status != PSA_SUCCESS )
+        {
+            mbedtls_free( slot->data.raw.data );
+            return( status );
+        }
+#if defined(MBEDTLS_DES_C)
+        if( type == PSA_KEY_TYPE_DES )
+        {
+            mbedtls_des_key_set_parity( slot->data.raw.data );
+            if( slot->data.raw.bytes >= 16 )
+                mbedtls_des_key_set_parity( slot->data.raw.data + 8 );
+            if( slot->data.raw.bytes == 24 )
+                mbedtls_des_key_set_parity( slot->data.raw.data + 16 );
+        }
+#endif /* MBEDTLS_DES_C */
+    }
+    else
+
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME)
+    if ( type == PSA_KEY_TYPE_RSA_KEYPAIR )
+    {
+        mbedtls_rsa_context *rsa;
+        int ret;
+        int exponent = 65537;
+        if( parameters != NULL )
+        {
+            const unsigned *p = parameters;
+            if( parameters_size != sizeof( *p ) )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            if( *p > INT_MAX )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            exponent = *p;
+        }
+        rsa = mbedtls_calloc( 1, sizeof( *rsa ) );
+        if( rsa == NULL )
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+        mbedtls_rsa_init( rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE );
+        ret = mbedtls_rsa_gen_key( rsa,
+                                   mbedtls_ctr_drbg_random,
+                                   &global_data.ctr_drbg,
+                                   bits,
+                                   exponent );
+        if( ret != 0 )
+        {
+            mbedtls_rsa_free( rsa );
+            mbedtls_free( rsa );
+            return( mbedtls_to_psa_error( ret ) );
+        }
+        slot->data.rsa = rsa;
+    }
+    else
+#endif /* MBEDTLS_RSA_C && MBEDTLS_GENPRIME */
+
+#if defined(MBEDTLS_ECP_C)
+    if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEYPAIR( type ) )
+    {
+        psa_ecc_curve_t curve = PSA_KEY_TYPE_GET_CURVE( type );
+        mbedtls_ecp_group_id grp_id = mbedtls_ecc_group_of_psa( curve );
+        const mbedtls_ecp_curve_info *curve_info =
+            mbedtls_ecp_curve_info_from_grp_id( grp_id );
+        mbedtls_ecp_keypair *ecp;
+        int ret;
+        if( parameters != NULL )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
+            return( PSA_ERROR_NOT_SUPPORTED );
+        if( curve_info->bit_size != bits )
+            return( PSA_ERROR_INVALID_ARGUMENT );
+        ecp = mbedtls_calloc( 1, sizeof( *ecp ) );
+        if( ecp == NULL )
+            return( PSA_ERROR_INSUFFICIENT_MEMORY );
+        mbedtls_ecp_keypair_init( ecp );
+        ret = mbedtls_ecp_gen_key( grp_id, ecp,
+                                   mbedtls_ctr_drbg_random,
+                                   &global_data.ctr_drbg );
+        if( ret != 0 )
+        {
+            mbedtls_ecp_keypair_free( ecp );
+            mbedtls_free( ecp );
+            return( mbedtls_to_psa_error( ret ) );
+        }
+        slot->data.ecp = ecp;
+    }
+    else
+#endif /* MBEDTLS_ECP_C */
+
+        return( PSA_ERROR_NOT_SUPPORTED );
+
+    slot->type = type;
+    return( PSA_SUCCESS );
+}
+
+
+/****************************************************************/
 /* Module setup */
 /****************************************************************/
 
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 0d7a31b..265a6d5 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -13,21 +13,77 @@
 PSA import/export raw: 2 bytes, buffer too small
 import_export:"2a2b":PSA_KEY_TYPE_RAW_DATA:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:16:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
 
+PSA import/export AES-128
+depends_on:MBEDTLS_AES_C
+import_export:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:128:0:PSA_SUCCESS:1
+
+PSA import/export AES-192
+depends_on:MBEDTLS_AES_C
+import_export:"0123456789abcdef0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:192:0:PSA_SUCCESS:1
+
+PSA import/export AES-256
+depends_on:MBEDTLS_AES_C
+import_export:"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ALG_CTR:PSA_KEY_USAGE_EXPORT:256:0:PSA_SUCCESS:1
+
+PSA import AES: bad key size
+depends_on:MBEDTLS_AES_C
+import:"0123456789abcdef":PSA_KEY_TYPE_AES:PSA_ERROR_INVALID_ARGUMENT
+
 PSA import/export RSA public key: good, 1024-bit
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (+1 byte)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:1:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2-1)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:161:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:162:PSA_SUCCESS:1
+
+PSA import/export RSA public key: good, larger buffer (*2+1)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:163:PSA_SUCCESS:1
+
+PSA import/export RSA public key: export buffer too small
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
 
 PSA import/export RSA keypair: policy forbids export
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_ENCRYPT:1024:0:PSA_ERROR_NOT_PERMITTED:1
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_ENCRYPT:1024:0:PSA_ERROR_NOT_PERMITTED:1
 
 PSA import/export RSA keypair: good, 1024-bit
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:0:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (+1 byte)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:1:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2-1)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:609:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:610:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: good, larger buffer (*2+1)
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:611:PSA_SUCCESS:1
+
+PSA import/export RSA keypair: export buffer too small
+depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_ERROR_BUFFER_TOO_SMALL:1
 
 PSA import/export RSA keypair: trailing garbage ignored
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b2400":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_SUCCESS:0
+import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b2400":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1024:-1:PSA_SUCCESS:0
 
 PSA import RSA keypair: truncated
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
@@ -35,15 +91,15 @@
 
 PSA import/export RSA keypair: good, 1023-bit
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_USAGE_EXPORT:1023:0:PSA_SUCCESS:1
+import_export:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_EXPORT:1023:0:PSA_SUCCESS:1
 
 PSA import/export-public RSA public key: good, 1024-bit
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export_public_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:1024:162:PSA_SUCCESS
+import_export_public_key:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
 
 PSA import/export-public PSA keypair: good, 1024-bit
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
-import_export_public_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:1024:162:PSA_SUCCESS
+import_export_public_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:1024:162:PSA_SUCCESS
 
 PSA import/export-public: cannot export-public a symmetric key
 depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
@@ -82,6 +138,18 @@
 PSA key lifetime set: invalid key lifetime value
 key_lifetime_set_fail:1:PSA_KEY_LIFETIME_PERSISTENT+1:PSA_ERROR_INVALID_ARGUMENT
 
+PSA hash setup: good, SHA-256
+depends_on:MBEDTLS_SHA256_C
+hash_setup:PSA_ALG_SHA_256:PSA_SUCCESS
+
+PSA hash setup: bad (unknown hash algorithm)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+hash_setup:0x80000000 | PSA_ALG_SHA_256:PSA_ERROR_NOT_SUPPORTED
+
+PSA hash setup: bad (not a hash algorithm)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+hash_setup:PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_INVALID_ARGUMENT
+
 PSA hash finish: SHA-256
 depends_on:MBEDTLS_SHA256_C
 hash_finish:PSA_ALG_SHA_256:"bd":"68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b"
@@ -90,6 +158,31 @@
 depends_on:MBEDTLS_SHA256_C
 hash_verify:PSA_ALG_SHA_256:"bd":"68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b"
 
+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
+
+PSA MAC setup: good, AES-CMAC
+depends_on:MBEDTLS_AES_C:MBEDTLS_CMAC_C
+mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_SUCCESS
+
+PSA MAC setup: bad algorithm (unknown MAC algorithm)
+depends_on:MBEDTLS_MD_C
+mac_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(0):PSA_ERROR_NOT_SUPPORTED
+
+PSA MAC setup: bad algorithm (not a MAC algorithm)
+depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
+mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_ERROR_INVALID_ARGUMENT
+
+PSA MAC setup: invalid key type, HMAC-SHA-256
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):PSA_ERROR_INVALID_ARGUMENT
+
+PSA MAC setup: incompatible key HMAC for CMAC
+depends_on:MBEDTLS_CMAC_C
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED
+
 PSA MAC verify: HMAC-SHA-256
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
 mac_verify:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):"53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e":"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62"
@@ -194,6 +287,28 @@
 depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
 mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
 
+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
+
+PSA cipher setup: bad algorithm (unknown cipher algorithm)
+depends_on:MBEDTLS_AES_C
+cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CATEGORY_CIPHER:PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher setup: bad algorithm (not a cipher algorithm)
+depends_on:MBEDTLS_AES_C
+cipher_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CMAC:PSA_ERROR_INVALID_ARGUMENT
+
+PSA cipher setup: invalid key type, CTR
+depends_on:MBEDTLS_CIPHER_MODE_CTR
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_setup:PSA_KEY_TYPE_RAW_DATA:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
+
+PSA cipher setup: incompatible key ARC4 for CTR
+depends_on:MBEDTLS_ARC4_C:MBEDTLS_CIPHER_MODE_CTR
+# Either INVALID_ARGUMENT or NOT_SUPPORTED would be reasonable here
+cipher_setup:PSA_KEY_TYPE_ARC4:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CTR:PSA_ERROR_NOT_SUPPORTED
+
 PSA symmetric encrypt: AES-CBC-nopad, 16 bytes, good
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":"a076ec9dfbe47d52afc357336f20743b":PSA_SUCCESS
@@ -218,6 +333,18 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_MODE_CTR
 cipher_encrypt:PSA_ALG_CTR | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":PSA_SUCCESS
 
+PSA symmetric encrypt: DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0e":"eda4011239bc3ac9":"64f917b0152f8f05":PSA_SUCCESS
+
+PSA symmetric encrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"eda4011239bc3ac9":"5d0652429c5b0ac7":PSA_SUCCESS
+
+PSA symmetric encrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_encrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"eda4011239bc3ac9":"817ca7d69b80d86a":PSA_SUCCESS
+
 PSA symmetric decrypt: AES-CBC-nopad, 16 bytes, good
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"396ee84fb75fdbb5c2b13c7fe5a654aa":"49e4e66c89a86b67758df89db9ad6955":PSA_SUCCESS
@@ -242,6 +369,18 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee223":"6bc1bee223":PSA_ERROR_BAD_STATE
 
+PSA symmetric decrypt: DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0e":"64f917b0152f8f05":"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt: 2-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce":"5d0652429c5b0ac7":"eda4011239bc3ac9":PSA_SUCCESS
+
+PSA symmetric decrypt: 3-key 3DES-CBC-nopad, 8 bytes, good
+depends_on:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
+cipher_decrypt:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_DES:"01020407080b0d0ec1c2c4c7c8cbcdce31323437383b3d3e":"817ca7d69b80d86a":"eda4011239bc3ac9":PSA_SUCCESS
+
 PSA symmetric encrypt/decrypt: AES-CBC-nopad, 16 bytes, good
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 cipher_verify_output:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a"
@@ -415,7 +554,7 @@
 
 PSA encrypt: RSA PKCS#1 v1.5: invalid key type
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_encrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_encrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
 
 PSA decrypt: RSA PKCS#1 v1.5: good #1
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
@@ -429,9 +568,9 @@
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
 asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_SHA_256:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
 
-PSA decrypt: RSA PKCS#1 v1.5: incorrect key type
+PSA decrypt: RSA PKCS#1 v1.5: invalid key type
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
-asymmetric_decrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
+asymmetric_decrypt_fail:PSA_KEY_TYPE_AES:"3082025e02010002818100af057d396e":PSA_ALG_RSA_PKCS1V15_CRYPT:"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":PSA_ERROR_INVALID_ARGUMENT
 
 PSA decrypt: RSA PKCS#1 v1.5, input too small
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
@@ -440,3 +579,80 @@
 PSA decrypt: RSA PKCS#1 v1.5, input too large
 depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
 asymmetric_decrypt_fail:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_CRYPT:"0099ffde2fcc00c9cc01972ebfa7779b298dbbaf7f50707a7405296dd2783456fc792002f462e760500e02afa25a859ace8701cb5d3b0262116431c43af8eb08f5a88301057cf1c156a2a5193c143e7a5b03fac132b7e89e6dcd8f4c82c9b28452329c260d30bc39b3816b7c46b41b37b4850d2ae74e729f99c6621fbbe2e46872":PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate random: 0 bytes
+generate_random:0
+
+PSA generate random: 1 byte
+generate_random:1
+
+PSA generate random: 4 bytes
+generate_random:4
+
+PSA generate random: 16 bytes
+generate_random:16
+
+PSA generate random: 19 bytes
+generate_random:19
+
+PSA generate random: 260 bytes
+generate_random:260
+
+PSA generate key: bad type (0xffffffff)
+generate_key:0xffffffff:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key: bad type (RSA public key)
+generate_key:PSA_KEY_TYPE_RSA_PUBLIC_KEY:512:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED
+
+PSA generate key: raw data, 0 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:128:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: raw data, 7 bits: invalid argument
+generate_key:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key: raw data, 8 bits
+generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS
+
+PSA generate key: AES, 128 bits, CTR
+depends_on:MBEDTLS_AES_C
+generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS
+
+PSA generate key: AES, 128 bits, GCM
+depends_on:MBEDTLS_AES_C
+generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_GCM:PSA_SUCCESS
+
+PSA generate key: DES, 64 bits, CBC-nopad
+depends_on:MBEDTLS_DES_C
+generate_key:PSA_KEY_TYPE_DES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: DES, 128 bits, CBC-nopad
+depends_on:MBEDTLS_DES_C
+generate_key:PSA_KEY_TYPE_DES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: DES, 192 bits, CBC-nopad
+depends_on:MBEDTLS_DES_C
+generate_key:PSA_KEY_TYPE_DES:192:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CBC_BASE | PSA_ALG_BLOCK_CIPHER_PAD_NONE:PSA_SUCCESS
+
+PSA generate key: invalid key size: AES, 64 bits
+depends_on:MBEDTLS_AES_C
+generate_key:PSA_KEY_TYPE_AES:64:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_ERROR_INVALID_ARGUMENT
+
+PSA generate key: RSA, 512 bits, good, sign
+depends_on:MBEDTLS_RSA_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS
+
+PSA generate key: RSA, 1024 bits, good, sign
+depends_on:MBEDTLS_RSA_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_SUCCESS
+
+PSA generate key: RSA, 512 bits, good, encrypt
+depends_on:MBEDTLS_RSA_C
+generate_key:PSA_KEY_TYPE_RSA_KEYPAIR:512:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:PSA_SUCCESS
+
+PSA generate key: ECC, SECP256R1, good
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):256:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_RAW | PSA_ALG_SHA_256:PSA_SUCCESS
+
+PSA generate key: ECC, SECP256R1, incorrect bit size
+depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_RAW:PSA_ERROR_INVALID_ARGUMENT
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 9dbf034..2d279fc 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -7,6 +7,256 @@
 #else
 #define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) 1
 #endif
+
+/** Test if a buffer is not all-bits zero.
+ *
+ * \param buffer    Pointer to the beginning of the buffer.
+ * \param size      Size of the buffer in bytes.
+ *
+ * \return          1 if the buffer is all-bits-zero.
+ * \return          0 if there is at least one nonzero byte.
+ */
+static int mem_is_zero( void *buffer, size_t size )
+{
+    size_t i;
+    for( i = 0; i < size; i++ )
+    {
+        if( ( (unsigned char *) buffer )[i] != 0 )
+            return( 0 );
+    }
+    return( 1 );
+}
+
+static int key_type_is_raw_bytes( psa_key_type_t type )
+{
+    psa_key_type_t category = type & PSA_KEY_TYPE_CATEGORY_MASK;
+    return( category == PSA_KEY_TYPE_RAW_DATA ||
+            category == PSA_KEY_TYPE_CATEGORY_SYMMETRIC );
+}
+
+static int exercise_mac_key( psa_key_slot_t key,
+                             psa_key_usage_t usage,
+                             psa_algorithm_t alg )
+{
+    psa_mac_operation_t operation;
+    const unsigned char input[] = "foo";
+    unsigned char mac[64] = {0};
+    size_t mac_length = sizeof( mac );
+
+    if( usage & PSA_KEY_USAGE_SIGN )
+    {
+        TEST_ASSERT( psa_mac_start( &operation, key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_update( &operation,
+                                     input, sizeof( input ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_finish( &operation,
+                                     mac, sizeof( input ),
+                                     &mac_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_VERIFY )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_SIGN ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_mac_start( &operation, key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_update( &operation,
+                                     input, sizeof( input ) ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_mac_verify( &operation, mac, mac_length ) == verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    psa_mac_abort( &operation );
+    return( 0 );
+}
+
+static int exercise_cipher_key( psa_key_slot_t key,
+                                psa_key_usage_t usage,
+                                psa_algorithm_t alg )
+{
+    psa_cipher_operation_t operation;
+    unsigned char iv[16] = {0};
+    size_t iv_length = sizeof( iv );
+    const unsigned char plaintext[16] = "Hello, world...";
+    unsigned char ciphertext[32] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    unsigned char decrypted[sizeof( ciphertext )];
+    size_t part_length;
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT( psa_encrypt_setup( &operation, key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_encrypt_generate_iv( &operation,
+                                              iv, sizeof( iv ),
+                                              &iv_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_update( &operation,
+                                        plaintext, sizeof( plaintext ),
+                                        ciphertext, sizeof( ciphertext ),
+                                        &ciphertext_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_finish( &operation,
+                                        ciphertext + ciphertext_length,
+                                        sizeof( ciphertext ) - ciphertext_length,
+                                        &part_length ) == PSA_SUCCESS );
+        ciphertext_length += part_length;
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t status;
+        if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) )
+        {
+            psa_key_type_t type;
+            size_t bits;
+            TEST_ASSERT( psa_get_key_information( key, &type, &bits ) );
+            iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE( type );
+        }
+        TEST_ASSERT( psa_decrypt_setup( &operation, key, alg ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_encrypt_set_iv( &operation,
+                                         iv, iv_length ) == PSA_SUCCESS );
+        TEST_ASSERT( psa_cipher_update( &operation,
+                                        ciphertext, ciphertext_length,
+                                        decrypted, sizeof( decrypted ),
+                                        &part_length ) == PSA_SUCCESS );
+        status = psa_cipher_finish( &operation,
+                                    decrypted + part_length,
+                                    sizeof( decrypted ) - part_length,
+                                    &part_length );
+        /* For a stream cipher, all inputs are valid. For a block cipher,
+         * if the input is some aribtrary data rather than an actual
+         ciphertext, a padding error is likely.  */
+        if( ( usage & PSA_KEY_USAGE_DECRYPT ) ||
+            PSA_BLOCK_CIPHER_BLOCK_SIZE( alg ) == 1 )
+            TEST_ASSERT( status == PSA_SUCCESS );
+        else
+            TEST_ASSERT( status == PSA_SUCCESS ||
+                         status == PSA_ERROR_INVALID_PADDING );
+    }
+
+    return( 1 );
+
+exit:
+    psa_cipher_abort( &operation );
+    return( 0 );
+}
+
+static int exercise_aead_key( psa_key_slot_t key,
+                              psa_key_usage_t usage,
+                              psa_algorithm_t alg )
+{
+    unsigned char nonce[16] = {0};
+    size_t nonce_length = sizeof( nonce );
+    unsigned char plaintext[16] = "Hello, world...";
+    unsigned char ciphertext[48] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    size_t plaintext_length = sizeof( ciphertext );
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT( psa_aead_encrypt( key, alg,
+                                       nonce, nonce_length,
+                                       NULL, 0,
+                                       plaintext, sizeof( plaintext ),
+                                       ciphertext, sizeof( ciphertext ),
+                                       &ciphertext_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_ENCRYPT ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_aead_decrypt( key, alg,
+                                       nonce, nonce_length,
+                                       NULL, 0,
+                                       ciphertext, ciphertext_length,
+                                       plaintext, sizeof( plaintext ),
+                                       &plaintext_length ) == verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_signature_key( psa_key_slot_t key,
+                                   psa_key_usage_t usage,
+                                   psa_algorithm_t alg )
+{
+    unsigned char payload[16] = {0};
+    size_t payload_length = sizeof( payload );
+    unsigned char signature[256] = {0};
+    size_t signature_length = sizeof( signature );
+
+    if( usage & PSA_KEY_USAGE_SIGN )
+    {
+        TEST_ASSERT( psa_asymmetric_sign( key, alg,
+                                          payload, payload_length,
+                                          NULL, 0,
+                                          signature, sizeof( signature ),
+                                          &signature_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_VERIFY )
+    {
+        psa_status_t verify_status =
+            ( usage & PSA_KEY_USAGE_SIGN ?
+              PSA_SUCCESS :
+              PSA_ERROR_INVALID_SIGNATURE );
+        TEST_ASSERT( psa_asymmetric_verify( key, alg,
+                                            payload, payload_length,
+                                            NULL, 0,
+                                            signature, signature_length ) ==
+                     verify_status );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
+
+static int exercise_asymmetric_encryption_key( psa_key_slot_t key,
+                                               psa_key_usage_t usage,
+                                               psa_algorithm_t alg )
+{
+    unsigned char plaintext[256] = "Hello, world...";
+    unsigned char ciphertext[256] = "(wabblewebblewibblewobblewubble)";
+    size_t ciphertext_length = sizeof( ciphertext );
+    size_t plaintext_length = 16;
+
+    if( usage & PSA_KEY_USAGE_ENCRYPT )
+    {
+        TEST_ASSERT(
+            psa_asymmetric_encrypt( key, alg,
+                                    plaintext, plaintext_length,
+                                    NULL, 0,
+                                    ciphertext, sizeof( ciphertext ),
+                                    &ciphertext_length ) == PSA_SUCCESS );
+    }
+
+    if( usage & PSA_KEY_USAGE_DECRYPT )
+    {
+        psa_status_t status =
+            psa_asymmetric_decrypt( key, alg,
+                                    ciphertext, ciphertext_length,
+                                    NULL, 0,
+                                    plaintext, sizeof( plaintext ),
+                                    &plaintext_length );
+        TEST_ASSERT( status == PSA_SUCCESS ||
+                     ( ( usage & PSA_KEY_USAGE_ENCRYPT ) == 0 &&
+                       ( status == PSA_ERROR_INVALID_ARGUMENT ||
+                         status == PSA_ERROR_INVALID_PADDING ) ) );
+    }
+
+    return( 1 );
+
+exit:
+    return( 0 );
+}
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -31,9 +281,10 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void import( data_t *data, int type, int expected_status )
+void import( data_t *data, int type, int expected_status_arg )
 {
     int slot = 1;
+    psa_status_t expected_status = expected_status_arg;
     psa_status_t status;
 
     TEST_ASSERT( data != NULL );
@@ -41,7 +292,7 @@
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
     status = psa_import_key( slot, type, data->x, data->len );
-    TEST_ASSERT( status == (psa_status_t) expected_status );
+    TEST_ASSERT( status == expected_status );
     if( status == PSA_SUCCESS )
         TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS );
 
@@ -57,13 +308,14 @@
                     int usage_arg,
                     int expected_bits,
                     int export_size_delta,
-                    int expected_export_status,
+                    int expected_export_status_arg,
                     int canonical_input )
 {
     int slot = 1;
     int slot2 = slot + 1;
     psa_key_type_t type = type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_export_status = expected_export_status_arg;
     psa_status_t status;
     unsigned char *exported = NULL;
     unsigned char *reexported = NULL;
@@ -105,9 +357,14 @@
     status = psa_export_key( slot,
                              exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == (psa_status_t) expected_export_status );
+    TEST_ASSERT( status == expected_export_status );
+    TEST_ASSERT( mem_is_zero( exported + exported_length,
+                              export_size - exported_length ) );
     if( status != PSA_SUCCESS )
+    {
+        TEST_ASSERT( exported_length == 0 );
         goto destroy;
+    }
 
     if( canonical_input )
     {
@@ -149,11 +406,12 @@
                                int alg_arg,
                                int expected_bits,
                                int public_key_expected_length,
-                               int expected_export_status )
+                               int expected_export_status_arg )
 {
     int slot = 1;
     psa_key_type_t type = type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_export_status = expected_export_status_arg;
     psa_status_t status;
     unsigned char *exported = NULL;
     size_t export_size;
@@ -189,7 +447,7 @@
     status = psa_export_public_key( slot,
                                     exported, export_size,
                                     &exported_length );
-    TEST_ASSERT( status == (psa_status_t) expected_export_status );
+    TEST_ASSERT( status == expected_export_status );
     if( status != PSA_SUCCESS )
         goto destroy;
 
@@ -351,6 +609,26 @@
 /* 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_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    status = psa_hash_start( &operation, alg );
+    psa_hash_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void hash_finish( int alg_arg, data_t *input, data_t *expected_hash )
 {
     psa_algorithm_t alg = alg_arg;
@@ -407,6 +685,41 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mac_setup( int key_type_arg,
+                data_t *key,
+                int alg_arg,
+                int expected_status_arg )
+{
+    int key_slot = 1;
+    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_key_policy_t policy;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy,
+                              PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
+                              alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    status = psa_mac_start( &operation, key_slot, alg );
+    psa_mac_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mac_verify( int key_type_arg,
                  data_t *key,
                  int alg_arg,
@@ -450,16 +763,51 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void cipher_setup( int key_type_arg,
+                   data_t *key,
+                   int alg_arg,
+                   int expected_status_arg )
+{
+    int key_slot = 1;
+    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_key_policy_t policy;
+    psa_status_t status;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
+    TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS );
+
+    TEST_ASSERT( psa_import_key( key_slot, key_type,
+                                 key->x, key->len ) == PSA_SUCCESS );
+
+    status = psa_encrypt_setup( &operation, key_slot, alg );
+    psa_cipher_abort( &operation );
+    TEST_ASSERT( status == expected_status );
+
+exit:
+    psa_destroy_key( key_slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void cipher_encrypt( int alg_arg, int key_type_arg,
                      data_t *key,
                      data_t *input, data_t *expected_output,
-                     int expected_status )
+                     int expected_status_arg )
 {
     int key_slot = 1;
     psa_status_t status;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
     unsigned char iv[16] = {0};
+    size_t iv_size;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
@@ -473,7 +821,8 @@
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
 
-    memset( iv, 0x2a, sizeof( iv ) );
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
 
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
@@ -484,7 +833,7 @@
                                     key_slot, alg ) == PSA_SUCCESS );
 
     TEST_ASSERT( psa_encrypt_set_iv( &operation,
-                                     iv, sizeof( iv ) ) == PSA_SUCCESS );
+                                     iv, iv_size ) == PSA_SUCCESS );
     output_buffer_size = input->len + operation.block_size;
     output = mbedtls_calloc( 1, output_buffer_size );
     TEST_ASSERT( output != NULL );
@@ -500,7 +849,7 @@
                                 &function_output_length );
     total_output_length += function_output_length;
 
-    TEST_ASSERT( status == (psa_status_t) expected_status );
+    TEST_ASSERT( status == expected_status );
     if( expected_status == PSA_SUCCESS )
     {
         TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
@@ -527,6 +876,7 @@
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
     unsigned char iv[16] = {0};
+    size_t iv_size;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
@@ -540,7 +890,8 @@
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
 
-    memset( iv, 0x2a, sizeof( iv ) );
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
 
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
@@ -597,6 +948,7 @@
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
     unsigned char iv[16] = {0};
+    size_t iv_size;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
@@ -610,7 +962,8 @@
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
 
-    memset( iv, 0x2a, sizeof( iv ) );
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
 
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
@@ -661,13 +1014,15 @@
 void cipher_decrypt( int alg_arg, int key_type_arg,
                      data_t *key,
                      data_t *input, data_t *expected_output,
-                     int expected_status )
+                     int expected_status_arg )
 {
     int key_slot = 1;
     psa_status_t status;
     psa_key_type_t key_type = key_type_arg;
     psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
     unsigned char iv[16] = {0};
+    size_t iv_size;
     unsigned char *output = NULL;
     size_t output_buffer_size = 0;
     size_t function_output_length = 0;
@@ -681,7 +1036,8 @@
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
     TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
 
-    memset( iv, 0x2a, sizeof( iv ) );
+    iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    memset( iv, 0x2a, iv_size );
 
     TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
 
@@ -692,7 +1048,7 @@
                                     key_slot, alg ) == PSA_SUCCESS );
 
     TEST_ASSERT( psa_encrypt_set_iv( &operation,
-                                     iv, sizeof( iv ) ) == PSA_SUCCESS );
+                                     iv, iv_size ) == PSA_SUCCESS );
 
     output_buffer_size = input->len + operation.block_size;
     output = mbedtls_calloc( 1, output_buffer_size );
@@ -708,7 +1064,7 @@
                                 output_buffer_size,
                                 &function_output_length );
     total_output_length += function_output_length;
-    TEST_ASSERT( status == (psa_status_t) expected_status );
+    TEST_ASSERT( status == expected_status );
 
     if( expected_status == PSA_SUCCESS )
     {
@@ -1520,3 +1876,190 @@
     mbedtls_psa_crypto_free( );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void generate_random( int bytes_arg )
+{
+    size_t bytes = bytes_arg;
+    const unsigned char trail[] = "don't overwrite me";
+    unsigned char *output = mbedtls_calloc( 1, bytes + sizeof( trail ) );
+    unsigned char *changed = mbedtls_calloc( 1, bytes );
+    size_t i;
+    unsigned run;
+
+    TEST_ASSERT( output != NULL );
+    TEST_ASSERT( changed != NULL );
+    memcpy( output + bytes, trail, sizeof( trail ) );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    /* Run several times, to ensure that every output byte will be
+     * nonzero at least once with overwhelming probability
+     * (2^(-8*number_of_runs)). */
+    for( run = 0; run < 10; run++ )
+    {
+        memset( output, 0, bytes );
+        TEST_ASSERT( psa_generate_random( output, bytes ) == PSA_SUCCESS );
+
+        /* Check that no more than bytes have been overwritten */
+        TEST_ASSERT( memcmp( output + bytes, trail, sizeof( trail ) ) == 0 );
+
+        for( i = 0; i < bytes; i++ )
+        {
+            if( output[i] != 0 )
+                ++changed[i];
+        }
+    }
+
+    /* Check that every byte was changed to nonzero at least once. This
+     * validates that psa_generate_random is overwriting every byte of
+     * the output buffer. */
+    for( i = 0; i < bytes; i++ )
+    {
+        TEST_ASSERT( changed[i] != 0 );
+    }
+
+exit:
+    mbedtls_psa_crypto_free( );
+    mbedtls_free( output );
+    mbedtls_free( changed );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void generate_key( int type_arg,
+                   int bits_arg,
+                   int usage_arg,
+                   int alg_arg,
+                   int expected_status_arg )
+{
+    int slot = 1;
+    psa_key_type_t type = type_arg;
+    psa_key_usage_t usage = usage_arg;
+    size_t bits = bits_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_status_t expected_status = expected_status_arg;
+    psa_key_type_t got_type;
+    size_t got_bits;
+    unsigned char exported[616] = {0}; /* enough for a 1024-bit RSA key */
+    size_t exported_length;
+    psa_status_t expected_export_status =
+        usage & PSA_KEY_USAGE_EXPORT ? PSA_SUCCESS : PSA_ERROR_NOT_PERMITTED;
+    psa_status_t expected_info_status =
+        expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
+    psa_key_policy_t policy;
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, usage, alg );
+    TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS );
+
+    /* Generate a key */
+    TEST_ASSERT( psa_generate_key( slot, type, bits,
+                                   NULL, 0 ) == expected_status );
+
+    /* Test the key information */
+    TEST_ASSERT( psa_get_key_information( slot,
+                                          &got_type,
+                                          &got_bits ) == expected_info_status );
+    if( expected_info_status != PSA_SUCCESS )
+        goto exit;
+    TEST_ASSERT( got_type == type );
+    TEST_ASSERT( got_bits == bits );
+
+    /* Export the key */
+    TEST_ASSERT( psa_export_key( slot,
+                                 exported, sizeof( exported ),
+                                 &exported_length ) == expected_export_status );
+    if( expected_export_status == PSA_SUCCESS )
+    {
+        if( key_type_is_raw_bytes( type ) )
+            TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
+#if defined(MBEDTLS_DES_C)
+        if( type == PSA_KEY_TYPE_DES )
+        {
+            /* Check the parity bits. */
+            unsigned i;
+            for( i = 0; i < bits / 8; i++ )
+            {
+                unsigned bit_count = 0;
+                unsigned m;
+                for( m = 1; m <= 0x100; m <<= 1 )
+                {
+                    if( exported[i] & m )
+                        ++bit_count;
+                }
+                TEST_ASSERT( bit_count % 2 != 0 );
+            }
+        }
+#endif
+#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C)
+        if( type == PSA_KEY_TYPE_RSA_KEYPAIR )
+        {
+            /* Sanity check: does this look like the beginning of a PKCS#8
+             * RSA key pair? Assumes bits is a multiple of 8. */
+            size_t n_bytes = bits / 8 + 1;
+            size_t n_encoded_bytes;
+            unsigned char *n_end;
+            TEST_ASSERT( exported_length >= 7 + ( n_bytes + 3 ) * 9 / 2 );
+            TEST_ASSERT( exported[0] == 0x30 );
+            TEST_ASSERT( exported[1] == 0x82 ); // assumes >=416-bit key
+            TEST_ASSERT( exported[4] == 0x02 );
+            TEST_ASSERT( exported[5] == 0x01 );
+            TEST_ASSERT( exported[6] == 0x00 );
+            TEST_ASSERT( exported[7] == 0x02 );
+            n_encoded_bytes = exported[8];
+            n_end = exported + 9 + n_encoded_bytes;
+            if( n_encoded_bytes & 0x80 )
+            {
+                n_encoded_bytes = ( n_encoded_bytes & 0x7f ) << 7;
+                n_encoded_bytes |= exported[9] & 0x7f;
+                n_end += 1;
+            }
+            /* The encoding of n should start with a 0 byte since it should
+             * have its high bit set. However Mbed TLS is not compliant and
+             * generates an invalid, but widely tolerated, encoding of
+             * positive INTEGERs with a bit size that is a multiple of 8
+             * with no leading 0 byte. Accept this here. */
+            TEST_ASSERT( n_bytes == n_encoded_bytes ||
+                         n_bytes == n_encoded_bytes + 1 );
+            if( n_bytes == n_encoded_bytes )
+                TEST_ASSERT( exported[n_encoded_bytes <= 127 ? 9 : 10] == 0x00 );
+            /* Sanity check: e must be 3 */
+            TEST_ASSERT( n_end[0] == 0x02 );
+            TEST_ASSERT( n_end[1] == 0x03 );
+            TEST_ASSERT( n_end[2] == 0x01 );
+            TEST_ASSERT( n_end[3] == 0x00 );
+            TEST_ASSERT( n_end[4] == 0x01 );
+            TEST_ASSERT( n_end[5] == 0x02 );
+        }
+#endif /* MBEDTLS_RSA_C */
+#if defined(MBEDTLS_ECP_C)
+        if( PSA_KEY_TYPE_IS_ECC( type ) )
+        {
+            /* Sanity check: does this look like the beginning of a PKCS#8
+             * elliptic curve key pair? */
+            TEST_ASSERT( exported_length >= bits * 3 / 8 + 10 );
+            TEST_ASSERT( exported[0] == 0x30 );
+        }
+#endif /* MBEDTLS_ECP_C */
+    }
+
+    /* Do something with the key according to its type and permitted usage. */
+    if( PSA_ALG_IS_MAC( alg ) )
+        exercise_mac_key( slot, usage, alg );
+    else if( PSA_ALG_IS_CIPHER( alg ) )
+        exercise_cipher_key( slot, usage, alg );
+    else if( PSA_ALG_IS_AEAD( alg ) )
+        exercise_aead_key( slot, usage, alg );
+    else if( PSA_ALG_IS_SIGN( alg ) )
+        exercise_signature_key( slot, usage, alg );
+    else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) )
+        exercise_asymmetric_encryption_key( slot, usage, alg );
+
+exit:
+    psa_destroy_key( slot );
+    mbedtls_psa_crypto_free( );
+}
+/* END_CASE */