Merge pull request #161 from ARMmbed/driver_api

Added the crypto driver API header file
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 62d3920..99c4b52 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -756,6 +756,82 @@
     (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
      PSA_ALG_HMAC_BASE)
 
+/* In the encoding of a MAC algorithm, the bits corresponding to
+ * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is
+ * truncated. As an exception, the value 0 means the untruncated algorithm,
+ * whatever its length is. The length is encoded in 6 bits, so it can
+ * reach up to 63; the largest MAC is 64 bytes so its trivial truncation
+ * to full length is correctly encoded as 0 and any non-trivial truncation
+ * is correctly encoded as a value between 1 and 63. */
+#define PSA_ALG_MAC_TRUNCATION_MASK             ((psa_algorithm_t)0x00003f00)
+#define PSA_MAC_TRUNCATION_OFFSET 8
+
+/** Macro to build a truncated MAC algorithm.
+ *
+ * A truncated MAC algorithm is identical to the corresponding MAC
+ * algorithm except that the MAC value for the truncated algorithm
+ * consists of only the first \p mac_length bytes of the MAC value
+ * for the untruncated algorithm.
+ *
+ * \note    This macro may allow constructing algorithm identifiers that
+ *          are not valid, either because the specified length is larger
+ *          than the untruncated MAC or because the specified length is
+ *          smaller than permitted by the implementation.
+ *
+ * \note    It is implementation-defined whether a truncated MAC that
+ *          is truncated to the same length as the MAC of the untruncated
+ *          algorithm is considered identical to the untruncated algorithm
+ *          for policy comparison purposes.
+ *
+ * \param alg           A MAC algorithm identifier (value of type
+ *                      #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
+ *                      is true). This may be a truncated or untruncated
+ *                      MAC algorithm.
+ * \param mac_length    Desired length of the truncated MAC in bytes.
+ *                      This must be at most the full length of the MAC
+ *                      and must be at least an implementation-specified
+ *                      minimum. The implementation-specified minimum
+ *                      shall not be zero.
+ *
+ * \return              The corresponding MAC algorithm with the specified
+ *                      length.
+ * \return              Unspecified if \p alg is not a supported
+ *                      MAC algorithm or if \p mac_length is too small or
+ *                      too large for the specified MAC algorithm.
+ */
+#define PSA_ALG_TRUNCATED_MAC(alg, mac_length)                          \
+    (((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) |                           \
+     ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK))
+
+/** Macro to build the base MAC algorithm corresponding to a truncated
+ * MAC algorithm.
+ *
+ * \param alg           A MAC algorithm identifier (value of type
+ *                      #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
+ *                      is true). This may be a truncated or untruncated
+ *                      MAC algorithm.
+ *
+ * \return              The corresponding base MAC algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      MAC algorithm.
+ */
+#define PSA_ALG_FULL_LENGTH_MAC(alg)            \
+    ((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK)
+
+/** Length to which a MAC algorithm is truncated.
+ *
+ * \param alg           A MAC algorithm identifier (value of type
+ *                      #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg)
+ *                      is true).
+ *
+ * \return              Length of the truncated MAC in bytes.
+ * \return              0 if \p alg is a non-truncated MAC algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      MAC algorithm.
+ */
+#define PSA_MAC_TRUNCATED_LENGTH(alg)           \
+    (((alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
+
 #define PSA_ALG_CIPHER_MAC_BASE                 ((psa_algorithm_t)0x02c00000)
 #define PSA_ALG_CBC_MAC                         ((psa_algorithm_t)0x02c00001)
 #define PSA_ALG_CMAC                            ((psa_algorithm_t)0x02c00002)
@@ -834,8 +910,56 @@
  */
 #define PSA_ALG_CBC_PKCS7                       ((psa_algorithm_t)0x04600101)
 
-#define PSA_ALG_CCM                             ((psa_algorithm_t)0x06000001)
-#define PSA_ALG_GCM                             ((psa_algorithm_t)0x06000002)
+#define PSA_ALG_CCM                             ((psa_algorithm_t)0x06001001)
+#define PSA_ALG_GCM                             ((psa_algorithm_t)0x06001002)
+
+/* In the encoding of a AEAD algorithm, the bits corresponding to
+ * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
+ * The constants for default lengths follow this encoding.
+ */
+#define PSA_ALG_AEAD_TAG_LENGTH_MASK            ((psa_algorithm_t)0x00003f00)
+#define PSA_AEAD_TAG_LENGTH_OFFSET 8
+
+/** Macro to build a shortened AEAD algorithm.
+ *
+ * A shortened AEAD algorithm is similar to the corresponding AEAD
+ * algorithm, but has an authentication tag that consists of fewer bytes.
+ * Depending on the algorithm, the tag length may affect the calculation
+ * of the ciphertext.
+ *
+ * \param alg           A AEAD algorithm identifier (value of type
+ *                      #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg)
+ *                      is true).
+ * \param tag_length    Desired length of the authentication tag in bytes.
+ *
+ * \return              The corresponding AEAD algorithm with the specified
+ *                      length.
+ * \return              Unspecified if \p alg is not a supported
+ *                      AEAD algorithm or if \p tag_length is not valid
+ *                      for the specified AEAD algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, tag_length)                   \
+    (((alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) |                          \
+     ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET &                      \
+      PSA_ALG_AEAD_TAG_LENGTH_MASK))
+
+/** Calculate the corresponding AEAD algorithm with the default tag length.
+ *
+ * \param alg   An AEAD algorithm (\c PSA_ALG_XXX value such that
+ *              #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return      The corresponding AEAD algorithm with the default tag length
+ *              for that algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg)                       \
+    (                                                                   \
+        PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_CCM)   \
+        PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_GCM)   \
+        0)
+#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, ref) \
+    PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, 0) == \
+    PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ?  \
+    ref :
 
 #define PSA_ALG_RSA_PKCS1V15_SIGN_BASE          ((psa_algorithm_t)0x10020000)
 /** RSA PKCS#1 v1.5 signature with hashing.
@@ -2382,9 +2506,9 @@
  *                            correct size for an AEAD algorithm that it
  *                            recognizes, but does not support.
  */
-#define PSA_AEAD_TAG_SIZE(alg)             \
-    ((alg) == PSA_ALG_GCM ? 16 :           \
-     (alg) == PSA_ALG_CCM ? 16 :           \
+#define PSA_AEAD_TAG_LENGTH(alg)                                        \
+    (PSA_ALG_IS_AEAD(alg) ?                                             \
+     (((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \
      0)
 
 /** Process an authenticated encryption operation.
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index edb240b..b5ff2aa 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -79,6 +79,9 @@
  */
 /* All non-HMAC MACs have a maximum size that's smaller than the
  * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
+/* Note that the encoding of truncated MAC algorithms limits this value
+ * to 64 bytes.
+ */
 #define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
 
 /* The maximum size of an RSA key on this implementation, in bits.
@@ -143,7 +146,8 @@
         PSA_VENDOR_ECC_MAX_CURVE_BITS                                   \
         )
 
-
+/** The maximum size of a block cipher supported by the implementation. */
+#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE 16
 
 /** The size of the output of psa_mac_sign_finish(), in bytes.
  *
@@ -163,7 +167,8 @@
  *                      with the algorithm.
  */
 #define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg)                     \
-    (PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \
+    ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
+     PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \
      PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
      ((void)(key_type), (void)(key_bits), 0))
 
@@ -186,9 +191,9 @@
  *                            correct size for an AEAD algorithm that it
  *                            recognizes, but does not support.
  */
-#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length)     \
-    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
-     (plaintext_length) + PSA_AEAD_TAG_SIZE(alg) :              \
+#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length)       \
+    (PSA_AEAD_TAG_LENGTH(alg) != 0 ?                              \
+     (plaintext_length) + PSA_AEAD_TAG_LENGTH(alg) :              \
      0)
 
 /** The maximum size of the output of psa_aead_decrypt(), in bytes.
@@ -210,9 +215,9 @@
  *                            correct size for an AEAD algorithm that it
  *                            recognizes, but does not support.
  */
-#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length)    \
-    (PSA_AEAD_TAG_SIZE(alg) != 0 ?                              \
-     (plaintext_length) - PSA_AEAD_TAG_SIZE(alg) :              \
+#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length)      \
+    (PSA_AEAD_TAG_LENGTH(alg) != 0 ?                              \
+     (plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) :              \
      0)
 
 /** Safe signature buffer size for psa_asymmetric_sign().
diff --git a/library/Makefile b/library/Makefile
index f4b39bd..cf6750d 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -200,5 +200,6 @@
 ifndef WINDOWS
 	rm -f *.o libmbed*
 else
-	del /Q /F *.o libmbed*
+	if exist *.o del /Q /F *.o
+	if exist libmbed* del /Q /F libmbed*
 endif
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 6fd905c..6b01c13 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -242,7 +242,7 @@
         case MBEDTLS_ERR_GCM_AUTH_FAILED:
             return( PSA_ERROR_INVALID_SIGNATURE );
         case MBEDTLS_ERR_GCM_BAD_INPUT:
-            return( PSA_ERROR_NOT_SUPPORTED );
+            return( PSA_ERROR_INVALID_ARGUMENT );
         case MBEDTLS_ERR_GCM_HW_ACCEL_FAILED:
             return( PSA_ERROR_HARDWARE_FAILURE );
 
@@ -1224,6 +1224,9 @@
     mbedtls_cipher_mode_t mode;
     mbedtls_cipher_id_t cipher_id_tmp;
 
+    if( PSA_ALG_IS_AEAD( alg ) )
+        alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 );
+
     if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
     {
         switch( alg )
@@ -1246,10 +1249,10 @@
             case PSA_ALG_CBC_PKCS7:
                 mode = MBEDTLS_MODE_CBC;
                 break;
-            case PSA_ALG_CCM:
+            case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
                 mode = MBEDTLS_MODE_CCM;
                 break;
-            case PSA_ALG_GCM:
+            case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
                 mode = MBEDTLS_MODE_GCM;
                 break;
             default:
@@ -1523,8 +1526,10 @@
     size_t key_bits;
     psa_key_usage_t usage =
         is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY;
+    unsigned char truncated = PSA_MAC_TRUNCATED_LENGTH( alg );
+    psa_algorithm_t full_length_alg = PSA_ALG_FULL_LENGTH_MAC( alg );
 
-    status = psa_mac_init( operation, alg );
+    status = psa_mac_init( operation, full_length_alg );
     if( status != PSA_SUCCESS )
         return( status );
     if( is_sign )
@@ -1536,10 +1541,11 @@
     key_bits = psa_get_key_bits( slot );
 
 #if defined(MBEDTLS_CMAC_C)
-    if( alg == PSA_ALG_CMAC )
+    if( full_length_alg == PSA_ALG_CMAC )
     {
         const mbedtls_cipher_info_t *cipher_info =
-            mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL );
+            mbedtls_cipher_info_from_psa( full_length_alg,
+                                          slot->type, key_bits, NULL );
         int ret;
         if( cipher_info == NULL )
         {
@@ -1553,7 +1559,7 @@
     else
 #endif /* MBEDTLS_CMAC_C */
 #if defined(MBEDTLS_MD_C)
-    if( PSA_ALG_IS_HMAC( alg ) )
+    if( PSA_ALG_IS_HMAC( full_length_alg ) )
     {
         psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
         if( hash_alg == 0 )
@@ -1588,6 +1594,26 @@
         status = PSA_ERROR_NOT_SUPPORTED;
     }
 
+    if( truncated == 0 )
+    {
+        /* The "normal" case: untruncated algorithm. Nothing to do. */
+    }
+    else if( truncated < 4 )
+    {
+        /* A very short MAC is too short for security since it can be
+         * brute-forced. Ancient protocols with 32-bit MACs do exist,
+         * so we make this our minimum, even though 32 bits is still
+         * too small for security. */
+        status = PSA_ERROR_NOT_SUPPORTED;
+    }
+    else if( truncated > operation->mac_size )
+    {
+        /* It's impossible to "truncate" to a larger length. */
+        status = PSA_ERROR_INVALID_ARGUMENT;
+    }
+    else
+        operation->mac_size = truncated;
+
 exit:
     if( status != PSA_SUCCESS )
     {
@@ -1682,7 +1708,11 @@
     if( status != PSA_SUCCESS )
         goto exit;
 
-    status = psa_hash_finish( &hmac->hash_ctx, mac, mac_size, &hash_size );
+    status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size );
+    if( status != PSA_SUCCESS )
+        goto exit;
+
+    memcpy( mac, tmp, mac_size );
 
 exit:
     mbedtls_zeroize( tmp, hash_size );
@@ -1705,7 +1735,11 @@
 #if defined(MBEDTLS_CMAC_C)
     if( operation->alg == PSA_ALG_CMAC )
     {
-        int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, mac );
+        uint8_t tmp[PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE];
+        int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp );
+        if( ret == 0 )
+            memcpy( mac, tmp, operation->mac_size );
+        mbedtls_zeroize( tmp, sizeof( tmp ) );
         return( mbedtls_to_psa_error( ret ) );
     }
     else
@@ -1714,7 +1748,7 @@
     if( PSA_ALG_IS_HMAC( operation->alg ) )
     {
         return( psa_hmac_finish_internal( &operation->ctx.hmac,
-                                          mac, mac_size ) );
+                                          mac, operation->mac_size ) );
     }
     else
 #endif /* MBEDTLS_MD_C */
@@ -1793,6 +1827,8 @@
     else
         psa_mac_abort( operation );
 
+    mbedtls_zeroize( actual_mac, sizeof( actual_mac ) );
+
     return( status );
 }
 
@@ -2790,6 +2826,115 @@
 /* AEAD */
 /****************************************************************/
 
+typedef struct
+{
+    key_slot_t *slot;
+    const mbedtls_cipher_info_t *cipher_info;
+    union
+    {
+#if defined(MBEDTLS_CCM_C)
+        mbedtls_ccm_context ccm;
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_GCM_C)
+        mbedtls_gcm_context gcm;
+#endif /* MBEDTLS_GCM_C */
+    } ctx;
+    psa_algorithm_t core_alg;
+    uint8_t full_tag_length;
+    uint8_t tag_length;
+} aead_operation_t;
+
+static void psa_aead_abort( aead_operation_t *operation )
+{
+    switch( operation->core_alg )
+    {
+#if defined(MBEDTLS_CCM_C)
+        case PSA_ALG_CCM:
+            mbedtls_ccm_free( &operation->ctx.ccm );
+            break;
+#endif /* MBEDTLS_CCM_C */
+#if defined(MBEDTLS_CCM_C)
+        case PSA_ALG_GCM:
+            mbedtls_gcm_free( &operation->ctx.gcm );
+            break;
+#endif /* MBEDTLS_GCM_C */
+    }
+}
+
+static psa_status_t psa_aead_setup( aead_operation_t *operation,
+                                    psa_key_slot_t key,
+                                    psa_key_usage_t usage,
+                                    psa_algorithm_t alg )
+{
+    psa_status_t status;
+    size_t key_bits;
+    mbedtls_cipher_id_t cipher_id;
+
+    status = psa_get_key_from_slot( key, &operation->slot, usage, alg );
+    if( status != PSA_SUCCESS )
+        return( status );
+
+    key_bits = psa_get_key_bits( operation->slot );
+
+    operation->cipher_info =
+        mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits,
+                                      &cipher_id );
+    if( operation->cipher_info == NULL )
+        return( PSA_ERROR_NOT_SUPPORTED );
+
+    switch( PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 0 ) )
+    {
+#if defined(MBEDTLS_CCM_C)
+        case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):
+            operation->core_alg = PSA_ALG_CCM;
+            operation->full_tag_length = 16;
+            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            mbedtls_ccm_init( &operation->ctx.ccm );
+            status = mbedtls_to_psa_error(
+                mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
+                                    operation->slot->data.raw.data,
+                                    (unsigned int) key_bits ) );
+            if( status != 0 )
+                goto cleanup;
+            break;
+#endif /* MBEDTLS_CCM_C */
+
+#if defined(MBEDTLS_GCM_C)
+        case PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):
+            operation->core_alg = PSA_ALG_GCM;
+            operation->full_tag_length = 16;
+            if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 )
+                return( PSA_ERROR_INVALID_ARGUMENT );
+            mbedtls_gcm_init( &operation->ctx.gcm );
+            status = mbedtls_to_psa_error(
+                mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
+                                    operation->slot->data.raw.data,
+                                    (unsigned int) key_bits ) );
+            break;
+#endif /* MBEDTLS_GCM_C */
+
+        default:
+            return( PSA_ERROR_NOT_SUPPORTED );
+    }
+
+    if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length )
+    {
+        status = PSA_ERROR_INVALID_ARGUMENT;
+        goto cleanup;
+    }
+    operation->tag_length = PSA_AEAD_TAG_LENGTH( alg );
+    /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
+     * GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
+     * In both cases, mbedtls_xxx will validate the tag length below. */
+
+    return( PSA_SUCCESS );
+
+cleanup:
+    psa_aead_abort( operation );
+    return( status );
+}
+
 psa_status_t psa_aead_encrypt( psa_key_slot_t key,
                                psa_algorithm_t alg,
                                const uint8_t *nonce,
@@ -2802,113 +2947,60 @@
                                size_t ciphertext_size,
                                size_t *ciphertext_length )
 {
-    int ret;
     psa_status_t status;
-    key_slot_t *slot;
-    size_t key_bits;
+    aead_operation_t operation;
     uint8_t *tag;
-    size_t tag_length;
-    mbedtls_cipher_id_t cipher_id;
-    const mbedtls_cipher_info_t *cipher_info = NULL;
 
     *ciphertext_length = 0;
 
-    status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg );
+    status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
-    key_bits = psa_get_key_bits( slot );
 
-    cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
-                                                key_bits, &cipher_id );
-    if( cipher_info == NULL )
-        return( PSA_ERROR_NOT_SUPPORTED );
-
-    if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
-        PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
-        return( PSA_ERROR_INVALID_ARGUMENT );
-
-    if( alg == PSA_ALG_GCM )
+    /* For all currently supported modes, the tag is at the end of the
+     * ciphertext. */
+    if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
     {
-        mbedtls_gcm_context gcm;
-        tag_length = 16;
-
-        if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-
-        //make sure we have place to hold the tag in the ciphertext buffer
-        if( ciphertext_size < ( plaintext_length + tag_length ) )
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-
-        //update the tag pointer to point to the end of the ciphertext_length
-        tag = ciphertext + plaintext_length;
-
-        mbedtls_gcm_init( &gcm );
-        ret = mbedtls_gcm_setkey( &gcm, cipher_id,
-                                  slot->data.raw.data,
-                                  (unsigned int) key_bits );
-        if( ret != 0 )
-        {
-            mbedtls_gcm_free( &gcm );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-        ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
-                                         plaintext_length, nonce,
-                                         nonce_length, additional_data,
-                                         additional_data_length, plaintext,
-                                         ciphertext, tag_length, tag );
-        mbedtls_gcm_free( &gcm );
+        status = PSA_ERROR_BUFFER_TOO_SMALL;
+        goto exit;
     }
-    else if( alg == PSA_ALG_CCM )
+    tag = ciphertext + plaintext_length;
+
+    if( operation.core_alg == PSA_ALG_GCM )
     {
-        mbedtls_ccm_context ccm;
-        tag_length = 16;
-
-        if( PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) != 16 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-
-        if( nonce_length < 7 || nonce_length > 13 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-
-        //make sure we have place to hold the tag in the ciphertext buffer
-        if( ciphertext_size < ( plaintext_length + tag_length ) )
-            return( PSA_ERROR_BUFFER_TOO_SMALL );
-
-        //update the tag pointer to point to the end of the ciphertext_length
-        tag = ciphertext + plaintext_length;
-
-        mbedtls_ccm_init( &ccm );
-        ret = mbedtls_ccm_setkey( &ccm, cipher_id,
-                                  slot->data.raw.data,
-                                  (unsigned int) key_bits );
-        if( ret != 0 )
-        {
-            mbedtls_ccm_free( &ccm );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-        ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
-                                           nonce, nonce_length,
-                                           additional_data,
-                                           additional_data_length,
-                                           plaintext, ciphertext,
-                                           tag, tag_length );
-        mbedtls_ccm_free( &ccm );
+        status = mbedtls_to_psa_error(
+            mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
+                                       MBEDTLS_GCM_ENCRYPT,
+                                       plaintext_length,
+                                       nonce, nonce_length,
+                                       additional_data, additional_data_length,
+                                       plaintext, ciphertext,
+                                       operation.tag_length, tag ) );
+    }
+    else if( operation.core_alg == PSA_ALG_CCM )
+    {
+        status = mbedtls_to_psa_error(
+            mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
+                                         plaintext_length,
+                                         nonce, nonce_length,
+                                         additional_data,
+                                         additional_data_length,
+                                         plaintext, ciphertext,
+                                         tag, operation.tag_length ) );
     }
     else
     {
         return( PSA_ERROR_NOT_SUPPORTED );
     }
 
-    if( ret != 0 )
-    {
-        /* If ciphertext_size is 0 then ciphertext may be NULL and then the
-         * call to memset would have undefined behavior. */
-        if( ciphertext_size != 0 )
-            memset( ciphertext, 0, ciphertext_size );
-        return( mbedtls_to_psa_error( ret ) );
-    }
+    if( status != PSA_SUCCESS && ciphertext_size != 0 )
+        memset( ciphertext, 0, ciphertext_size );
 
-    *ciphertext_length = plaintext_length + tag_length;
-    return( PSA_SUCCESS );
+exit:
+    psa_aead_abort( &operation );
+    if( status == PSA_SUCCESS )
+        *ciphertext_length = plaintext_length + operation.tag_length;
+    return( status );
 }
 
 /* Locate the tag in a ciphertext buffer containing the encrypted data
@@ -2944,108 +3036,63 @@
                                size_t plaintext_size,
                                size_t *plaintext_length )
 {
-    int ret;
     psa_status_t status;
-    key_slot_t *slot;
-    size_t key_bits;
-    const uint8_t *tag;
-    size_t tag_length;
-    mbedtls_cipher_id_t cipher_id;
-    const mbedtls_cipher_info_t *cipher_info = NULL;
+    aead_operation_t operation;
+    const uint8_t *tag = NULL;
 
     *plaintext_length = 0;
 
-    status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
+    status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg );
     if( status != PSA_SUCCESS )
         return( status );
-    key_bits = psa_get_key_bits( slot );
 
-    cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type,
-                                                key_bits, &cipher_id );
-    if( cipher_info == NULL )
-        return( PSA_ERROR_NOT_SUPPORTED );
-
-    if( ( slot->type & PSA_KEY_TYPE_CATEGORY_MASK ) !=
-        PSA_KEY_TYPE_CATEGORY_SYMMETRIC )
-        return( PSA_ERROR_INVALID_ARGUMENT );
-
-    if( alg == PSA_ALG_GCM )
+    if( operation.core_alg == PSA_ALG_GCM )
     {
-        mbedtls_gcm_context gcm;
-
-        tag_length = 16;
-        status = psa_aead_unpadded_locate_tag( tag_length,
+        status = psa_aead_unpadded_locate_tag( operation.tag_length,
                                                ciphertext, ciphertext_length,
                                                plaintext_size, &tag );
         if( status != PSA_SUCCESS )
-            return( status );
+            goto exit;
 
-        mbedtls_gcm_init( &gcm );
-        ret = mbedtls_gcm_setkey( &gcm, cipher_id,
-                                  slot->data.raw.data,
-                                  (unsigned int) key_bits );
-        if( ret != 0 )
-        {
-            mbedtls_gcm_free( &gcm );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-
-        ret = mbedtls_gcm_auth_decrypt( &gcm,
-                                        ciphertext_length - tag_length,
-                                        nonce, nonce_length,
-                                        additional_data,
-                                        additional_data_length,
-                                        tag, tag_length,
-                                        ciphertext, plaintext );
-        mbedtls_gcm_free( &gcm );
+        status = mbedtls_to_psa_error(
+            mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
+                                      ciphertext_length - operation.tag_length,
+                                      nonce, nonce_length,
+                                      additional_data,
+                                      additional_data_length,
+                                      tag, operation.tag_length,
+                                      ciphertext, plaintext ) );
     }
-    else if( alg == PSA_ALG_CCM )
+    else if( operation.core_alg == PSA_ALG_CCM )
     {
-        mbedtls_ccm_context ccm;
-
-        if( nonce_length < 7 || nonce_length > 13 )
-            return( PSA_ERROR_INVALID_ARGUMENT );
-
-        tag_length = 16;
-        status = psa_aead_unpadded_locate_tag( tag_length,
+        status = psa_aead_unpadded_locate_tag( operation.tag_length,
                                                ciphertext, ciphertext_length,
                                                plaintext_size, &tag );
         if( status != PSA_SUCCESS )
-            return( status );
+            goto exit;
 
-        mbedtls_ccm_init( &ccm );
-        ret = mbedtls_ccm_setkey( &ccm, cipher_id,
-                                  slot->data.raw.data,
-                                  (unsigned int) key_bits );
-        if( ret != 0 )
-        {
-            mbedtls_ccm_free( &ccm );
-            return( mbedtls_to_psa_error( ret ) );
-        }
-        ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length - tag_length,
-                                        nonce, nonce_length,
-                                        additional_data,
-                                        additional_data_length,
-                                        ciphertext, plaintext,
-                                        tag, tag_length );
-        mbedtls_ccm_free( &ccm );
+        status = mbedtls_to_psa_error(
+            mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
+                                      ciphertext_length - operation.tag_length,
+                                      nonce, nonce_length,
+                                      additional_data,
+                                      additional_data_length,
+                                      ciphertext, plaintext,
+                                      tag, operation.tag_length ) );
     }
     else
     {
         return( PSA_ERROR_NOT_SUPPORTED );
     }
 
-    if( ret != 0 )
-    {
-        /* If plaintext_size is 0 then plaintext may be NULL and then the
-         * call to memset has undefined behavior. */
-        if( plaintext_size != 0 )
-            memset( plaintext, 0, plaintext_size );
-    }
-    else
-        *plaintext_length = ciphertext_length - tag_length;
+    if( status != PSA_SUCCESS && plaintext_size != 0 )
+        memset( plaintext, 0, plaintext_size );
 
-    return( mbedtls_to_psa_error( ret ) );
+exit:
+    psa_aead_abort( &operation );
+    if( status == PSA_SUCCESS )
+        *plaintext_length = ciphertext_length - operation.tag_length;
+    return( status );
 }
 
 
diff --git a/programs/Makefile b/programs/Makefile
index b153407..f3627c9 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -96,7 +96,12 @@
 $(DEP):
 	$(MAKE) -C ../library
 
+ifdef WINDOWS
+EXTRA_GENERATED += psa\psa_constant_names_generated.c
+else
 EXTRA_GENERATED += psa/psa_constant_names_generated.c
+endif
+
 psa/psa_constant_names$(EXEXT): psa/psa_constant_names_generated.c
 psa/psa_constant_names_generated.c: ../scripts/generate_psa_constants.py ../include/psa/crypto.h
 	../scripts/generate_psa_constants.py
@@ -317,7 +322,9 @@
 ifndef WINDOWS
 	rm -f $(APPS) $(EXTRA_GENERATED)
 else
-	del /S /Q /F *.o *.exe $(EXTRA_GENERATED)
+	if exist *.o del /S /Q /F *.o
+	if exist *.exe del /S /Q /F *.exe
+	if exist $(EXTRA_GENERATED) del /S /Q /F $(EXTRA_GENERATED)
 endif
 
 list:
diff --git a/programs/psa/psa_constant_names.c b/programs/psa/psa_constant_names.c
index d422e14..dd19677 100644
--- a/programs/psa/psa_constant_names.c
+++ b/programs/psa/psa_constant_names.c
@@ -4,6 +4,35 @@
 
 #include "psa/crypto.h"
 
+/* This block is present to support Visual Studio builds prior to 2015 */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#include <stdarg.h>
+int snprintf( char *s, size_t n, const char *fmt, ... )
+{
+    int ret;
+    va_list argp;
+
+    /* Avoid calling the invalid parameter handler by checking ourselves */
+    if( s == NULL || n == 0 || fmt == NULL )
+        return( -1 );
+
+    va_start( argp, fmt );
+#if defined(_TRUNCATE) && !defined(__MINGW32__)
+    ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
+#else
+    ret = _vsnprintf( s, n, fmt, argp );
+    if( ret < 0 || (size_t) ret == n )
+    {
+        s[n-1] = '\0';
+        ret = -1;
+    }
+#endif
+    va_end( argp );
+
+    return( ret );
+}
+#endif
+
 /* There are different GET_HASH macros for different kinds of algorithms
  * built from hashes, but the values are all constructed on the
  * same model. */
@@ -21,6 +50,16 @@
     }
 }
 
+static void append_integer(char **buffer, size_t buffer_size,
+                           size_t *required_size,
+                           const char *format /*printf format for value*/,
+                           unsigned long value)
+{
+    size_t n = snprintf(*buffer, buffer_size - *required_size, format, value);
+    if (n < buffer_size - *required_size) *buffer += n;
+    *required_size += n;
+}
+
 /* The code of these function is automatically generated and included below. */
 static const char *psa_ecc_curve_name(psa_ecc_curve_t curve);
 static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg);
@@ -37,10 +76,8 @@
         append(buffer, buffer_size, required_size,
                curve_name, strlen(curve_name));
     } else {
-        size_t n = snprintf(*buffer, buffer_size - *required_size,
-                            "0x%04x", (unsigned) curve);
-        if (n < buffer_size - *required_size) *buffer += n;
-        *required_size += n;
+        append_integer(buffer, buffer_size, required_size,
+                       "0x%04x", curve);
     }
     append(buffer, buffer_size, required_size, ")", 1);
 }
@@ -57,10 +94,8 @@
         append(buffer, buffer_size, required_size,
                hash_name, strlen(hash_name));
     } else {
-        size_t n = snprintf(*buffer, buffer_size - *required_size,
-                            "0x%08lx", (unsigned long) hash_alg);
-        if (n < buffer_size - *required_size) *buffer += n;
-        *required_size += n;
+        append_integer(buffer, buffer_size, required_size,
+                       "0x%08lx", hash_alg);
     }
     append(buffer, buffer_size, required_size, ")", 1);
 }
@@ -77,9 +112,9 @@
         size_t length = strlen(name);
         if (length < buffer_size) {
             memcpy(buffer, name, length + 1);
-            return length;
+            return (int) length;
         } else {
-            return buffer_size;
+            return (int) buffer_size;
         }
     }
 }
@@ -94,9 +129,9 @@
         size_t length = strlen(name);
         if (length < buffer_size) {
             memcpy(buffer, name, length + 1);
-            return length;
+            return (int) length;
         } else {
-            return buffer_size;
+            return (int) buffer_size;
         }
     }
 }
@@ -107,9 +142,9 @@
            program_name == NULL ? "psa_constant_names" : program_name);
     printf("Print the symbolic name whose numerical value is VALUE in TYPE.\n");
     printf("Supported types (with = between aliases):\n");
-    printf("  alg=algorithm         Status code (psa_algorithm_t)\n");
+    printf("  alg=algorithm         Algorithm (psa_algorithm_t)\n");
     printf("  curve=ecc_curve       Elliptic curve identifier (psa_ecc_curve_t)\n");
-    printf("  type=key_type         Status code (psa_key_type_t)\n");
+    printf("  type=key_type         Key type (psa_key_type_t)\n");
     printf("  usage=key_usage       Key usage (psa_key_usage_t)\n");
     printf("  error=status          Status code (psa_status_t)\n");
 }
@@ -138,15 +173,15 @@
     }
 
     if (!strcmp(argv[1], "error") || !strcmp(argv[1], "status"))
-        psa_snprint_status(buffer, sizeof(buffer), value);
+        psa_snprint_status(buffer, sizeof(buffer), (psa_status_t) value);
     else if (!strcmp(argv[1], "alg") || !strcmp(argv[1], "algorithm"))
-        psa_snprint_algorithm(buffer, sizeof(buffer), value);
+        psa_snprint_algorithm(buffer, sizeof(buffer), (psa_algorithm_t) value);
     else if (!strcmp(argv[1], "curve") || !strcmp(argv[1], "ecc_curve"))
-        psa_snprint_ecc_curve(buffer, sizeof(buffer), value);
+        psa_snprint_ecc_curve(buffer, sizeof(buffer), (psa_ecc_curve_t) value);
     else if (!strcmp(argv[1], "type") || !strcmp(argv[1], "key_type"))
-        psa_snprint_key_type(buffer, sizeof(buffer), value);
+        psa_snprint_key_type(buffer, sizeof(buffer), (psa_key_type_t) value);
     else if (!strcmp(argv[1], "usage") || !strcmp(argv[1], "key_usage"))
-        psa_snprint_key_usage(buffer, sizeof(buffer), value);
+        psa_snprint_key_usage(buffer, sizeof(buffer), (psa_key_usage_t) value);
     else {
         printf("Unknown type: %s\n", argv[1]);
         return EXIT_FAILURE;
diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py
index 7ab1c0a..7e4420b 100755
--- a/scripts/generate_psa_constants.py
+++ b/scripts/generate_psa_constants.py
@@ -44,24 +44,47 @@
         break;
     }
     buffer[0] = 0;
-    return required_size;
+    return (int) required_size;
 }
 
 static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
                                  psa_algorithm_t alg)
 {
     size_t required_size = 0;
-    switch (alg) {
+    psa_algorithm_t core_alg = alg;
+    unsigned long length_modifier = 0;
+    if (PSA_ALG_IS_MAC(alg)) {
+        core_alg = PSA_ALG_TRUNCATED_MAC(alg, 0);
+        if (core_alg != alg) {
+            append(&buffer, buffer_size, &required_size,
+                   "PSA_ALG_TRUNCATED_MAC(", 22);
+            length_modifier = PSA_MAC_TRUNCATED_LENGTH(alg);
+        }
+    } else if (PSA_ALG_IS_AEAD(alg)) {
+        core_alg = PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg);
+        if (core_alg != alg) {
+            append(&buffer, buffer_size, &required_size,
+                   "PSA_ALG_AEAD_WITH_TAG_LENGTH(", 29);
+            length_modifier = PSA_AEAD_TAG_LENGTH(alg);
+        }
+    }
+    switch (core_alg) {
     %(algorithm_cases)s
     default:
         %(algorithm_code)s{
-            return snprintf(buffer, buffer_size,
-                            "0x%%08lx", (unsigned long) alg);
+            append_integer(&buffer, buffer_size, &required_size,
+                           "0x%%08lx", (unsigned long) alg);
         }
         break;
     }
+    if (core_alg != alg) {
+        append(&buffer, buffer_size, &required_size, ", ", 2);
+        append_integer(&buffer, buffer_size, &required_size,
+                       "%%lu", length_modifier);
+        append(&buffer, buffer_size, &required_size, ")", 1);
+    }
     buffer[0] = 0;
-    return required_size;
+    return (int) required_size;
 }
 
 static int psa_snprint_key_usage(char *buffer, size_t buffer_size,
@@ -82,12 +105,12 @@
         if (required_size != 0) {
             append(&buffer, buffer_size, &required_size, " | ", 3);
         }
-        required_size += snprintf(buffer, buffer_size - required_size,
-                                  "0x%%08x", usage);
+        append_integer(&buffer, buffer_size, &required_size,
+                       "0x%%08lx", (unsigned long) usage);
     } else {
         buffer[0] = 0;
     }
-    return required_size;
+    return (int) required_size;
 }
 
 /* End of automatically generated file. */
@@ -99,10 +122,10 @@
                               PSA_KEY_TYPE_GET_CURVE(type));
         } else '''
 
-algorithm_from_hash_template = '''if (%(tester)s(alg)) {
+algorithm_from_hash_template = '''if (%(tester)s(core_alg)) {
             append_with_hash(&buffer, buffer_size, &required_size,
                              "%(builder)s", %(builder_length)s,
-                             PSA_ALG_GET_HASH(alg));
+                             PSA_ALG_GET_HASH(core_alg));
         } else '''
 
 bit_test_template = '''\
diff --git a/tests/.jenkins/Jenkinsfile b/tests/.jenkins/Jenkinsfile
new file mode 100644
index 0000000..78a7878
--- /dev/null
+++ b/tests/.jenkins/Jenkinsfile
@@ -0,0 +1 @@
+mbedtls_psa.run_job()
diff --git a/tests/Makefile b/tests/Makefile
index b6e49bf..889d2a7 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -107,7 +107,9 @@
 ifndef WINDOWS
 	rm -rf $(BINARIES) *.c *.datax TESTS
 else
-	del /Q /F *.c *.exe *.datax
+	if exist *.c del /Q /F *.c
+	if exist *.exe del /Q /F *.exe
+	if exist *.datax del /Q /F *.datax
 ifneq ($(wildcard TESTS/.*),)
 	rmdir /Q /S TESTS
 endif
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 0319782..871a511 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -1,3 +1,6 @@
+PSA compile-time sanity checks
+static_checks:
+
 PSA init/deinit
 init_deinit:
 
@@ -345,6 +348,14 @@
 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
 mac_setup:PSA_KEY_TYPE_AES:"000102030405060708090a0b0c0d0e0f":PSA_ALG_CBC_NO_PADDING:PSA_ERROR_INVALID_ARGUMENT
 
+PSA MAC setup: truncated MAC too small (1 byte)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_TRUNCATED_MAC( PSA_ALG_HMAC( PSA_ALG_SHA_256 ), 1 ):PSA_ERROR_NOT_SUPPORTED
+
+PSA MAC setup: truncated MAC too large (33 bytes for SHA-256)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_setup:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_TRUNCATED_MAC( PSA_ALG_HMAC( PSA_ALG_SHA_256 ), 33 ):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
@@ -354,22 +365,34 @@
 # 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
+PSA MAC sign: RFC4231 Test case 1 - HMAC-SHA-224
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
-mac_verify:PSA_KEY_TYPE_HMAC:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f":PSA_ALG_HMAC(PSA_ALG_SHA_256):"53616d706c65206d65737361676520666f72206b65796c656e3d626c6f636b6c656e":"8bb9a1db9806f20df7f77b82138c7914d174d59e13dc4d0169c9057b133e1d62"
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"
 
 PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-224
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
 mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"
 
+PSA MAC sign: RFC4231 Test case 1 - HMAC-SHA-256
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"4869205468657265":"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
+
 PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-256
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
 mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_256):"4869205468657265":"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
 
+PSA MAC sign: RFC4231 Test case 1 - HMAC-SHA-384
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_384):"4869205468657265":"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"
+
 PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-384
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
 mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_384):"4869205468657265":"afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6"
 
+PSA MAC sign: RFC4231 Test case 1 - HMAC-SHA-512
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_512):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"
+
 PSA MAC verify: RFC4231 Test case 1 - HMAC-SHA-512
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
 mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_512):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"
@@ -454,10 +477,86 @@
 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
 mac_verify:PSA_KEY_TYPE_HMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_ALG_HMAC(PSA_ALG_SHA_512):"5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e":"e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58"
 
+PSA MAC sign: HMAC-SHA-224, truncated to 28 bytes (actual size)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 28):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"
+
+PSA MAC verify: HMAC-SHA-224, truncated to 28 bytes (actual size)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 28):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22"
+
+PSA MAC sign: HMAC-SHA-512, truncated to 64 bytes (actual size)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 64):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"
+
+PSA MAC verify: HMAC-SHA-512, truncated to 64 bytes (actual size)
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 64):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854"
+
+PSA MAC sign: HMAC-SHA-224, truncated to 27 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 27):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b"
+
+PSA MAC verify: HMAC-SHA-224, truncated to 27 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 27):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b"
+
+PSA MAC sign: HMAC-SHA-512, truncated to 63 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 63):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a1268"
+
+PSA MAC verify: HMAC-SHA-512, truncated to 63 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 63):"4869205468657265":"87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a1268"
+
+PSA MAC sign: HMAC-SHA-224, truncated to 4 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 4):"4869205468657265":"896fb112"
+
+PSA MAC verify: HMAC-SHA-224, truncated to 4 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_224), 4):"4869205468657265":"896fb112"
+
+PSA MAC sign: HMAC-SHA-512, truncated to 4 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 4):"4869205468657265":"87aa7cde"
+
+PSA MAC verify: HMAC-SHA-512, truncated to 4 bytes
+depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C
+mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 4):"4869205468657265":"87aa7cde"
+
+PSA MAC sign: CMAC-AES-128
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
+
 PSA MAC verify: CMAC-AES-128
 depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
 mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
 
+PSA MAC sign: CMAC-AES-128, truncated to 16 bytes (actual size)
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
+
+PSA MAC verify: CMAC-AES-128, truncated to 16 bytes (actual size)
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 16):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827"
+
+PSA MAC sign: CMAC-AES-128, truncated to 15 bytes
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 15):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c8"
+
+PSA MAC verify: CMAC-AES-128, truncated to 15 bytes
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 15):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c8"
+
+PSA MAC sign: CMAC-AES-128, truncated to 4 bytes
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 4):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747"
+
+PSA MAC verify: CMAC-AES-128, truncated to 4 bytes
+depends_on:MBEDTLS_CMAC_C:MBEDTLS_AES_C
+mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_TRUNCATED_MAC(PSA_ALG_CMAC, 4):"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747"
+
 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
@@ -606,67 +705,187 @@
 
 PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #1
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_CCM:"0C0D0E0F101112131415161718191A1B1C1D1E":"000102030405060708090A0B":"000102030405060708090A0B":PSA_SUCCESS
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_CCM:"000102030405060708090A0B":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E":PSA_SUCCESS
 
 PSA AEAD encrypt/decrypt: AES-CCM, 19 bytes #2
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":PSA_SUCCESS
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":"B96B49E21D621741632875DB7F6C9243D2D7C2":PSA_SUCCESS
 
 PSA AEAD encrypt/decrypt: DES-CCM not supported
 depends_on:MBEDTLS_DES_C:MBEDTLS_CCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_DES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":PSA_ERROR_NOT_SUPPORTED
+aead_encrypt_decrypt:PSA_KEY_TYPE_DES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"000102030405060708090A0B":"EC46BB63B02520C33C49FD70":"B96B49E21D621741632875DB7F6C9243D2D7C2":PSA_ERROR_NOT_SUPPORTED
 
 PSA AEAD encrypt: AES-CCM, 23 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_encrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":"0BE1A88BACE018B1":"00412B4EA9CDBE3C9696766CFA":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8"
+aead_encrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8"
 
 PSA AEAD encrypt: AES-CCM, 24 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9"
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 4 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6643b4f39"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=6
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 6 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b63fdffcd729bc"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=8
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b64cf2c3bf5f220776"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=10
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 10 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b69613343621327defd18e"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=12
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 12 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b69a2e5d8faee3138fa5cf9846"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=14
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 14 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6c99af01cdb6aa76df73c8646c27f"
+
+PSA AEAD encrypt: AES-CCM, 24 bytes, T=16
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 16 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9"
 
 PSA AEAD decrypt: AES-CCM, 39 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"0BE1A88BACE018B1":"00412B4EA9CDBE3C9696766CFA":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_SUCCESS
+aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_SUCCESS
 
 PSA AEAD decrypt, AES-CCM, 40 bytes
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 4 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6643b4f39":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=6
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 6 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b63fdffcd729bc":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=8
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 8 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b64cf2c3bf5f220776":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=10
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 10 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b69613343621327defd18e":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=12
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 12 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b69a2e5d8faee3138fa5cf9846":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=14
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 14 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6c99af01cdb6aa76df73c8646c27f":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
+
+PSA AEAD decrypt: AES-CCM, 24 bytes, T=16
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 16 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_SUCCESS
 
 PSA AEAD decrypt: AES-CCM, invalid signature
 depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"26d56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"48c0906930561e0ab0ef4cd972":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_SIGNATURE
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26d56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD decrypt: AES-CCM, invalid signature, T=4
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 4 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6643b4f38":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD decrypt: AES-CCM, T=4, tag is truncated tag for T=16
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 4 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD decrypt: AES-CCM, invalid tag length 0
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 0 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM, invalid tag length 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 2 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM, invalid tag length 15
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 15 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-CCM, invalid tag length 18
+depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_CCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD encrypt/decrypt, AES-GCM, 19 bytes #1
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"0C0D0E0F101112131415161718191A1B1C1D1E":"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":PSA_SUCCESS
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF":PSA_ALG_GCM:"000102030405060708090A0B0C0D0E0F":"000102030405060708090A0B":"0C0D0E0F101112131415161718191A1B1C1D1E":PSA_SUCCESS
 
 PSA AEAD encrypt/decrypt, AES GCM, 19 bytes #2
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_GCM:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":PSA_SUCCESS
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_GCM:"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":"B96B49E21D621741632875DB7F6C9243D2D7C2":PSA_SUCCESS
 
 PSA AEAD encrypt, AES-GCM, 128 bytes #1
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"00e440846db73a490573deaf3728c94f":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
+aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
 
 PSA AEAD encrypt, AES-GCM, 128 bytes #2
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_encrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56"
+aead_encrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56"
+
+PSA AEAD encrypt, AES-GCM, 128 bytes #1, T=4
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 4 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f"
+
+PSA AEAD encrypt, AES-GCM, 128 bytes #1, T=15
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 15 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a"
+
+PSA AEAD encrypt, AES-GCM, 128 bytes #1, T=16
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96"
 
 PSA AEAD decrypt, AES-GCM, 144 bytes #1
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"00e440846db73a490573deaf3728c94f":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
 
 PSA AEAD decrypt, AES-GCM, 144 bytes #2
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_SUCCESS
+aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12495120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-GCM, 144 bytes, T=4
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 4 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847f":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-GCM, 144 bytes, T=15
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 15 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
+
+PSA AEAD decrypt, AES-GCM, 144 bytes, T=16
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 16 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS
 
 PSA AEAD decrypt, AES-GCM, invalid signature
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"12195120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"97ce3f848276783599c6875de324361e":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_ERROR_INVALID_SIGNATURE
+aead_decrypt:PSA_KEY_TYPE_AES:"fe96eab10ff48c7942025422583d0377":PSA_ALG_GCM:"97ce3f848276783599c6875de324361e":"127628b6dcbce6fc8a8ef60798eb67b2088415635119697d20bb878c24d9c6f9c29e148521cb5e0feff892c7855d4f1c0bfb32ad33420976714dce87a0bbc18e4378bd1ef35197d0ca73051148f1199010f63caf122df5f71ad8d9c71df3eb2fbe3b2529d0ba657570358d3776f687bdb9c96d5e0e9e00c4b42d5d7a268d6a08":"12195120056ca3cac70d583603a476821bac6c57c9733b81cfb83538dc9e850f8bdf46065069591c23ebcbc6d1e2523375fb7efc80c09507fa25477ed07cee54fc4eb90168b3ef988f651fc40652474a644b1b311decf899660aef2347bb081af48950f06ebf799911e37120de94c55c20e5f0a77119be06e2b6e557f872fa0f6bac793bdc2190a195122c98544ccf56":"194c8bbbfae4a671386b8cd38f390f46f9df6b8661b470c310921a1c858a938045834bb10380037fbf5f5e00688554537be0fcafe8270b9b59068fa056ab1268fc166c2d729243a06650a171c929c7845c85330c04568d62977eedf3b1ba9dca13bdb8f9522817c8cb99e635e37465ec1c9f6f148d51437aa9f994a62e1bd013":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD decrypt, AES-GCM, T=15 but passing 16 bytes
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 15 ):"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INVALID_SIGNATURE
+
+PSA AEAD decrypt: AES-GCM, invalid tag length 0
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 0 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-GCM, invalid tag length 2
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 2 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
+
+PSA AEAD decrypt: AES-GCM, invalid tag length 18
+depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
+aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, 18 ):"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":PSA_ERROR_INVALID_ARGUMENT
 
 PSA AEAD encrypt/decrypt: invalid algorithm (CTR)
 depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
-aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"B96B49E21D621741632875DB7F6C9243D2D7C2":"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":PSA_ERROR_NOT_SUPPORTED
+aead_encrypt_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CTR:"000102030405060708090A0B0C0D0E0F":"EC46BB63B02520C33C49FD70":"B96B49E21D621741632875DB7F6C9243D2D7C2":PSA_ERROR_NOT_SUPPORTED
 
 PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 raw
 signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 59cc716..63d837f 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -22,20 +22,23 @@
 /** An invalid export length that will never be set by psa_export_key(). */
 static const size_t INVALID_EXPORT_LENGTH = ~0U;
 
-/** Test if a buffer is all-bits zero.
+/** Test if a buffer contains a constant byte value.
+ *
+ * `mem_is_char(buffer, c, size)` is true after `memset(buffer, c, size)`.
  *
  * \param buffer    Pointer to the beginning of the buffer.
+ * \param c         Expected value of every byte.
  * \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 )
+static int mem_is_char( void *buffer, unsigned char c, size_t size )
 {
     size_t i;
     for( i = 0; i < size; i++ )
     {
-        if( ( (unsigned char *) buffer )[i] != 0 )
+        if( ( (unsigned char *) buffer )[i] != c )
             return( 0 );
     }
     return( 1 );
@@ -791,6 +794,19 @@
  */
 
 /* BEGIN_CASE */
+void static_checks( )
+{
+    size_t max_truncated_mac_size =
+        PSA_ALG_MAC_TRUNCATION_MASK >> PSA_MAC_TRUNCATION_OFFSET;
+
+    /* Check that the length for a truncated MAC always fits in the algorithm
+     * encoding. The shifted mask is the maximum truncated value. The
+     * untruncated algorithm may be one byte larger. */
+    TEST_ASSERT( PSA_MAC_MAX_SIZE <= 1 + max_truncated_mac_size );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void init_deinit( )
 {
     psa_status_t status;
@@ -978,7 +994,7 @@
     TEST_ASSERT( status == PSA_SUCCESS || exported_length == 0 );
     TEST_ASSERT( exported_length <= export_size );
 
-    TEST_ASSERT( mem_is_zero( exported + exported_length,
+    TEST_ASSERT( mem_is_char( exported + exported_length, 0,
                               export_size - exported_length ) );
     if( status != PSA_SUCCESS )
     {
@@ -1067,7 +1083,7 @@
                                     &exported_length );
     TEST_ASSERT( status == expected_export_status );
     TEST_ASSERT( exported_length == (size_t) public_key_expected_length );
-    TEST_ASSERT( mem_is_zero( exported + exported_length,
+    TEST_ASSERT( mem_is_char( exported + exported_length, 0,
                               export_size - exported_length ) );
     if( status != PSA_SUCCESS )
         goto destroy;
@@ -1648,6 +1664,62 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mac_sign( int key_type_arg,
+               data_t *key,
+               int alg_arg,
+               data_t *input,
+               data_t *expected_mac )
+{
+    int key_slot = 1;
+    psa_key_type_t key_type = key_type_arg;
+    psa_algorithm_t alg = alg_arg;
+    psa_mac_operation_t operation;
+    psa_key_policy_t policy;
+    /* Leave a little extra room in the output buffer. At the end of the
+     * test, we'll check that the implementation didn't overwrite onto
+     * this extra room. */
+    uint8_t actual_mac[PSA_MAC_MAX_SIZE + 10];
+    size_t mac_buffer_size =
+        PSA_MAC_FINAL_SIZE( key_type, PSA_BYTES_TO_BITS( key->len ), alg );
+    size_t mac_length = 0;
+
+    memset( actual_mac, '+', sizeof( actual_mac ) );
+    TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE );
+    TEST_ASSERT( expected_mac->len <= mac_buffer_size );
+
+    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+
+    psa_key_policy_init( &policy );
+    psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, 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 );
+
+    /* Calculate the MAC. */
+    TEST_ASSERT( psa_mac_sign_setup( &operation,
+                                     key_slot, alg ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_mac_update( &operation,
+                                 input->x, input->len ) == PSA_SUCCESS );
+    TEST_ASSERT( psa_mac_sign_finish( &operation,
+                                      actual_mac, mac_buffer_size,
+                                      &mac_length ) == PSA_SUCCESS );
+
+    /* Compare with the expected value. */
+    TEST_ASSERT( mac_length == expected_mac->len );
+    TEST_ASSERT( memcmp( actual_mac, expected_mac->x, mac_length ) == 0 );
+
+    /* Verify that the end of the buffer is untouched. */
+    TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
+                              sizeof( actual_mac ) - mac_length ) );
+
+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,
@@ -2224,12 +2296,11 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void aead_encrypt_decrypt( int key_type_arg,
-                           data_t * key_data,
+void aead_encrypt_decrypt( int key_type_arg, data_t *key_data,
                            int alg_arg,
-                           data_t * input_data,
-                           data_t * nonce,
-                           data_t * additional_data,
+                           data_t *nonce,
+                           data_t *additional_data,
+                           data_t *input_data,
                            int expected_result_arg )
 {
     int slot = 1;
@@ -2300,10 +2371,12 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void aead_encrypt( int key_type_arg, data_t * key_data,
-                   int alg_arg, data_t * input_data,
-                   data_t * additional_data, data_t * nonce,
-                   data_t * expected_result )
+void aead_encrypt( int key_type_arg, data_t *key_data,
+                   int alg_arg,
+                   data_t *nonce,
+                   data_t *additional_data,
+                   data_t *input_data,
+                   data_t *expected_result )
 {
     int slot = 1;
     psa_key_type_t key_type = key_type_arg;
@@ -2356,10 +2429,13 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
-void aead_decrypt( int key_type_arg, data_t * key_data,
-                   int alg_arg, data_t * input_data,
-                   data_t * additional_data, data_t * nonce,
-                   data_t * expected_data, int expected_result_arg )
+void aead_decrypt( int key_type_arg, data_t *key_data,
+                   int alg_arg,
+                   data_t *nonce,
+                   data_t *additional_data,
+                   data_t *input_data,
+                   data_t *expected_data,
+                   int expected_result_arg )
 {
     int slot = 1;
     psa_key_type_t key_type = key_type_arg;
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index ca9d557..215110a 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -94,6 +94,47 @@
 exit: ;
 }
 
+void mac_algorithm_core( psa_algorithm_t alg, int classification_flags,
+                         psa_key_type_t key_type, size_t key_bits,
+                         size_t length )
+{
+    /* Algorithm classification */
+    TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
+    TEST_ASSERT( PSA_ALG_IS_MAC( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
+    algorithm_classification( alg, classification_flags );
+
+    /* Length */
+    TEST_ASSERT( length == PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) );
+
+exit: ;
+}
+
+void aead_algorithm_core( psa_algorithm_t alg, int classification_flags,
+                          size_t tag_length )
+{
+    /* Algorithm classification */
+    TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
+    TEST_ASSERT( PSA_ALG_IS_AEAD( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
+    TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
+    algorithm_classification( alg, classification_flags );
+
+    /* Tag length */
+    TEST_ASSERT( tag_length == PSA_AEAD_TAG_LENGTH( alg ) );
+
+exit: ;
+}
+
 /* END_HEADER */
 
 /* BEGIN_DEPENDENCIES
@@ -151,23 +192,32 @@
 {
     psa_algorithm_t alg = alg_arg;
     size_t length = length_arg;
+    size_t n;
     size_t key_type = key_type_arg;
     size_t key_bits = key_bits_arg;
 
-    /* Algorithm classification */
-    TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
-    TEST_ASSERT( PSA_ALG_IS_MAC( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
-    algorithm_classification( alg, classification_flags );
-
-    /* Length */
-    TEST_ASSERT( length == PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) );
+    mac_algorithm_core( alg, classification_flags,
+                        key_type, key_bits, length );
+    TEST_ASSERT( PSA_ALG_FULL_LENGTH_MAC( alg ) == alg );
     TEST_ASSERT( length <= PSA_MAC_MAX_SIZE );
+
+    /* Truncated versions */
+    for( n = 1; n <= length; n++ )
+    {
+        psa_algorithm_t truncated_alg = PSA_ALG_TRUNCATED_MAC( alg, n );
+        mac_algorithm_core( truncated_alg, classification_flags,
+                            key_type, key_bits, n );
+        TEST_ASSERT( PSA_ALG_FULL_LENGTH_MAC( truncated_alg ) == alg );
+        /* Check that calling PSA_ALG_TRUNCATED_MAC twice gives the length
+         * of the outer truncation (even if the outer length is smaller than
+         * the inner length). */
+        TEST_ASSERT( PSA_ALG_TRUNCATED_MAC( truncated_alg, 1 ) ==
+                     PSA_ALG_TRUNCATED_MAC( alg, 1 ) );
+        TEST_ASSERT( PSA_ALG_TRUNCATED_MAC( truncated_alg, length - 1 ) ==
+                     PSA_ALG_TRUNCATED_MAC( alg, length - 1) );
+        TEST_ASSERT( PSA_ALG_TRUNCATED_MAC( truncated_alg, length ) ==
+                     PSA_ALG_TRUNCATED_MAC( alg, length ) );
+    }
 }
 /* END_CASE */
 
@@ -179,14 +229,22 @@
     psa_algorithm_t alg = alg_arg;
     psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH( alg );
     size_t block_size = block_size_arg;
+    size_t length = length_arg;
+    size_t n;
 
     TEST_ASSERT( PSA_ALG_IS_HASH( hash_alg ) );
     TEST_ASSERT( PSA_ALG_HMAC( hash_alg ) == alg );
 
     TEST_ASSERT( block_size <= PSA_HMAC_MAX_HASH_BLOCK_SIZE );
 
-    test_mac_algorithm( alg_arg, ALG_IS_HMAC, length_arg,
-                        PSA_KEY_TYPE_HMAC, PSA_BYTES_TO_BITS( length_arg ) );
+    test_mac_algorithm( alg_arg, ALG_IS_HMAC, length,
+                        PSA_KEY_TYPE_HMAC, PSA_BYTES_TO_BITS( length ) );
+
+    for( n = 1; n <= length; n++ )
+    {
+        psa_algorithm_t truncated_alg = PSA_ALG_TRUNCATED_MAC( alg, n );
+        TEST_ASSERT( PSA_ALG_HMAC_GET_HASH( truncated_alg ) == hash_alg );
+    }
 }
 /* END_CASE */
 
@@ -214,20 +272,30 @@
 {
     psa_algorithm_t alg = alg_arg;
     size_t tag_length = tag_length_arg;
+    size_t n;
 
-    /* Algorithm classification */
-    TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
-    TEST_ASSERT( PSA_ALG_IS_AEAD( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
-    TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
-    algorithm_classification( alg, classification_flags );
+    aead_algorithm_core( alg, classification_flags, tag_length );
 
-    /* Tag length */
-    TEST_ASSERT( tag_length == PSA_AEAD_TAG_SIZE( alg ) );
+    /* Truncated versions */
+    for( n = 1; n <= tag_length; n++ )
+    {
+        psa_algorithm_t truncated_alg = PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, n );
+        aead_algorithm_core( truncated_alg, classification_flags, n );
+        TEST_ASSERT(
+            PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH( truncated_alg ) == alg );
+        /* Check that calling PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH twice gives
+         * the length of the outer truncation (even if the outer length is
+         * smaller than the inner length). */
+        TEST_ASSERT(
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, 1 ) ==
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 1 ) );
+        TEST_ASSERT(
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, tag_length - 1 ) ==
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, tag_length - 1) );
+        TEST_ASSERT(
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, tag_length ) ==
+            PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, tag_length ) );
+    }
 }
 /* END_CASE */