Merge pull request #3 from gilles-peskine-arm/key_ladder_demo-maybe_uninitialized

Fix maybe-uninitialized warning
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index c58d22a..fa8045c 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -53,272 +53,18 @@
 extern "C" {
 #endif
 
-/** \defgroup basic Basic definitions
+/* The file "crypto_types.h" declares types that encode errors,
+ * algorithms, key types, policies, etc. */
+#include "crypto_types.h"
+
+/* The file "crypto_values.h" declares macros to build and analyze values
+ * of integral types defined in "crypto_types.h". */
+#include "crypto_values.h"
+
+/** \defgroup initialization Library initialization
  * @{
  */
 
-#if defined(PSA_SUCCESS)
-/* If PSA_SUCCESS is defined, assume that PSA crypto is being used
- * together with PSA IPC, which also defines the identifier
- * PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case;
- * the other error code names don't clash. Also define psa_status_t as
- * an alias for the type used by PSA IPC. This is a temporary hack
- * until we unify error reporting in PSA IPC and PSA crypto.
- *
- * Note that psa_defs.h must be included before this header!
- */
-typedef psa_error_t psa_status_t;
-
-#else /* defined(PSA_SUCCESS) */
-
-/**
- * \brief Function return status.
- *
- * This is either #PSA_SUCCESS (which is zero), indicating success,
- * or a nonzero value indicating that an error occurred. Errors are
- * encoded as one of the \c PSA_ERROR_xxx values defined here.
- */
-typedef int32_t psa_status_t;
-
-/** The action was completed successfully. */
-#define PSA_SUCCESS ((psa_status_t)0)
-
-#endif /* !defined(PSA_SUCCESS) */
-
-/** An error occurred that does not correspond to any defined
- * failure cause.
- *
- * Implementations may use this error code if none of the other standard
- * error codes are applicable. */
-#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)1)
-
-/** The requested operation or a parameter is not supported
- * by this implementation.
- *
- * Implementations should return this error code when an enumeration
- * parameter such as a key type, algorithm, etc. is not recognized.
- * If a combination of parameters is recognized and identified as
- * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
-#define PSA_ERROR_NOT_SUPPORTED         ((psa_status_t)2)
-
-/** The requested action is denied by a policy.
- *
- * Implementations should return this error code when the parameters
- * are recognized as valid and supported, and a policy explicitly
- * denies the requested operation.
- *
- * If a subset of the parameters of a function call identify a
- * forbidden operation, and another subset of the parameters are
- * not valid or not supported, it is unspecified whether the function
- * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
- * #PSA_ERROR_INVALID_ARGUMENT. */
-#define PSA_ERROR_NOT_PERMITTED         ((psa_status_t)3)
-
-/** An output buffer is too small.
- *
- * Applications can call the \c PSA_xxx_SIZE macro listed in the function
- * description to determine a sufficient buffer size.
- *
- * Implementations should preferably return this error code only
- * in cases when performing the operation with a larger output
- * buffer would succeed. However implementations may return this
- * error if a function has invalid or unsupported parameters in addition
- * to the parameters that determine the necessary output buffer size. */
-#define PSA_ERROR_BUFFER_TOO_SMALL      ((psa_status_t)4)
-
-/** A slot is occupied, but must be empty to carry out the
- * requested action.
- *
- * If a handle is invalid, it does not designate an occupied slot.
- * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
- */
-#define PSA_ERROR_OCCUPIED_SLOT         ((psa_status_t)5)
-
-/** A slot is empty, but must be occupied to carry out the
- * requested action.
- *
- * If a handle is invalid, it does not designate an empty slot.
- * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
- */
-#define PSA_ERROR_EMPTY_SLOT            ((psa_status_t)6)
-
-/** The requested action cannot be performed in the current state.
- *
- * Multipart operations return this error when one of the
- * functions is called out of sequence. Refer to the function
- * descriptions for permitted sequencing of functions.
- *
- * Implementations shall not return this error code to indicate
- * that a key slot is occupied when it needs to be free or vice versa,
- * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
- * as applicable. */
-#define PSA_ERROR_BAD_STATE             ((psa_status_t)7)
-
-/** The parameters passed to the function are invalid.
- *
- * Implementations may return this error any time a parameter or
- * combination of parameters are recognized as invalid.
- *
- * Implementations shall not return this error code to indicate
- * that a key slot is occupied when it needs to be free or vice versa,
- * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
- * as applicable.
- *
- * Implementation shall not return this error code to indicate that a
- * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
- * instead.
- */
-#define PSA_ERROR_INVALID_ARGUMENT      ((psa_status_t)8)
-
-/** There is not enough runtime memory.
- *
- * If the action is carried out across multiple security realms, this
- * error can refer to available memory in any of the security realms. */
-#define PSA_ERROR_INSUFFICIENT_MEMORY   ((psa_status_t)9)
-
-/** There is not enough persistent storage.
- *
- * Functions that modify the key storage return this error code if
- * there is insufficient storage space on the host media. In addition,
- * many functions that do not otherwise access storage may return this
- * error code if the implementation requires a mandatory log entry for
- * the requested action and the log storage space is full. */
-#define PSA_ERROR_INSUFFICIENT_STORAGE  ((psa_status_t)10)
-
-/** There was a communication failure inside the implementation.
- *
- * This can indicate a communication failure between the application
- * and an external cryptoprocessor or between the cryptoprocessor and
- * an external volatile or persistent memory. A communication failure
- * may be transient or permanent depending on the cause.
- *
- * \warning If a function returns this error, it is undetermined
- * whether the requested action has completed or not. Implementations
- * should return #PSA_SUCCESS on successful completion whenver
- * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
- * if the requested action was completed successfully in an external
- * cryptoprocessor but there was a breakdown of communication before
- * the cryptoprocessor could report the status to the application.
- */
-#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11)
-
-/** There was a storage failure that may have led to data loss.
- *
- * This error indicates that some persistent storage is corrupted.
- * It should not be used for a corruption of volatile memory
- * (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
- * between the cryptoprocessor and its external storage (use
- * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
- * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
- *
- * Note that a storage failure does not indicate that any data that was
- * previously read is invalid. However this previously read data may no
- * longer be readable from storage.
- *
- * When a storage failure occurs, it is no longer possible to ensure
- * the global integrity of the keystore. Depending on the global
- * integrity guarantees offered by the implementation, access to other
- * data may or may not fail even if the data is still readable but
- * its integrity canont be guaranteed.
- *
- * Implementations should only use this error code to report a
- * permanent storage corruption. However application writers should
- * keep in mind that transient errors while reading the storage may be
- * reported using this error code. */
-#define PSA_ERROR_STORAGE_FAILURE       ((psa_status_t)12)
-
-/** A hardware failure was detected.
- *
- * A hardware failure may be transient or permanent depending on the
- * cause. */
-#define PSA_ERROR_HARDWARE_FAILURE      ((psa_status_t)13)
-
-/** A tampering attempt was detected.
- *
- * If an application receives this error code, there is no guarantee
- * that previously accessed or computed data was correct and remains
- * confidential. Applications should not perform any security function
- * and should enter a safe failure state.
- *
- * Implementations may return this error code if they detect an invalid
- * state that cannot happen during normal operation and that indicates
- * that the implementation's security guarantees no longer hold. Depending
- * on the implementation architecture and on its security and safety goals,
- * the implementation may forcibly terminate the application.
- *
- * This error code is intended as a last resort when a security breach
- * is detected and it is unsure whether the keystore data is still
- * protected. Implementations shall only return this error code
- * to report an alarm from a tampering detector, to indicate that
- * the confidentiality of stored data can no longer be guaranteed,
- * or to indicate that the integrity of previously returned data is now
- * considered compromised. Implementations shall not use this error code
- * to indicate a hardware failure that merely makes it impossible to
- * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE,
- * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE,
- * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code
- * instead).
- *
- * This error indicates an attack against the application. Implementations
- * shall not return this error code as a consequence of the behavior of
- * the application itself. */
-#define PSA_ERROR_TAMPERING_DETECTED    ((psa_status_t)14)
-
-/** There is not enough entropy to generate random data needed
- * for the requested action.
- *
- * This error indicates a failure of a hardware random generator.
- * Application writers should note that this error can be returned not
- * only by functions whose purpose is to generate random data, such
- * as key, IV or nonce generation, but also by functions that execute
- * an algorithm with a randomized result, as well as functions that
- * use randomization of intermediate computations as a countermeasure
- * to certain attacks.
- *
- * Implementations should avoid returning this error after psa_crypto_init()
- * has succeeded. Implementations should generate sufficient
- * entropy during initialization and subsequently use a cryptographically
- * secure pseudorandom generator (PRNG). However implementations may return
- * this error at any time if a policy requires the PRNG to be reseeded
- * during normal operation. */
-#define PSA_ERROR_INSUFFICIENT_ENTROPY  ((psa_status_t)15)
-
-/** The signature, MAC or hash is incorrect.
- *
- * Verification functions return this error if the verification
- * calculations completed successfully, and the value to be verified
- * was determined to be incorrect.
- *
- * If the value to verify has an invalid size, implementations may return
- * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
-#define PSA_ERROR_INVALID_SIGNATURE     ((psa_status_t)16)
-
-/** The decrypted padding is incorrect.
- *
- * \warning In some protocols, when decrypting data, it is essential that
- * the behavior of the application does not depend on whether the padding
- * is correct, down to precise timing. Applications should prefer
- * protocols that use authenticated encryption rather than plain
- * encryption. If the application must perform a decryption of
- * unauthenticated data, the application writer should take care not
- * to reveal whether the padding is invalid.
- *
- * Implementations should strive to make valid and invalid padding
- * as close as possible to indistinguishable to an external observer.
- * In particular, the timing of a decryption operation should not
- * depend on the validity of the padding. */
-#define PSA_ERROR_INVALID_PADDING       ((psa_status_t)17)
-
-/** The generator has insufficient capacity left.
- *
- * Once a function returns this error, attempts to read from the
- * generator will always return this error. */
-#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18)
-
-/** The key handle is not valid.
- */
-#define PSA_ERROR_INVALID_HANDLE        ((psa_status_t)19)
-
 /**
  * \brief Library initialization.
  *
@@ -345,1094 +91,12 @@
  */
 psa_status_t psa_crypto_init(void);
 
-#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
-#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
-
-/**@}*/
-
-/** \defgroup crypto_types Key and algorithm types
- * @{
- */
-
-/** \brief Encoding of a key type.
- */
-typedef uint32_t psa_key_type_t;
-
-/** An invalid key type value.
- *
- * Zero is not the encoding of any key type.
- */
-#define PSA_KEY_TYPE_NONE                       ((psa_key_type_t)0x00000000)
-
-/** Vendor-defined flag
- *
- * Key types defined by this standard will never have the
- * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types
- * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should
- * respect the bitwise structure used by standard encodings whenever practical.
- */
-#define PSA_KEY_TYPE_VENDOR_FLAG                ((psa_key_type_t)0x80000000)
-
-#define PSA_KEY_TYPE_CATEGORY_MASK              ((psa_key_type_t)0x70000000)
-#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC         ((psa_key_type_t)0x40000000)
-#define PSA_KEY_TYPE_CATEGORY_RAW               ((psa_key_type_t)0x50000000)
-#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY        ((psa_key_type_t)0x60000000)
-#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR          ((psa_key_type_t)0x70000000)
-
-#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR         ((psa_key_type_t)0x10000000)
-
-/** Whether a key type is vendor-defined. */
-#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
-    (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
-
-/** Whether a key type is an unstructured array of bytes.
- *
- * This encompasses both symmetric keys and non-key data.
- */
-#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \
-    (((type) & PSA_KEY_TYPE_CATEGORY_MASK & ~(psa_key_type_t)0x10000000) == \
-     PSA_KEY_TYPE_CATEGORY_SYMMETRIC)
-
-/** Whether a key type is asymmetric: either a key pair or a public key. */
-#define PSA_KEY_TYPE_IS_ASYMMETRIC(type)                                \
-    (((type) & PSA_KEY_TYPE_CATEGORY_MASK                               \
-      & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) ==                            \
-     PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
-/** Whether a key type is the public part of a key pair. */
-#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type)                                \
-    (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
-/** Whether a key type is a key pair containing a private part and a public
- * part. */
-#define PSA_KEY_TYPE_IS_KEYPAIR(type)                                   \
-    (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
-/** The key pair type corresponding to a public key type.
- *
- * You may also pass a key pair type as \p type, it will be left unchanged.
- *
- * \param type      A public key type or key pair type.
- *
- * \return          The corresponding key pair type.
- *                  If \p type is not a public key or a key pair,
- *                  the return value is undefined.
- */
-#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type)        \
-    ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
-/** The public key type corresponding to a key pair type.
- *
- * You may also pass a key pair type as \p type, it will be left unchanged.
- *
- * \param type      A public key type or key pair type.
- *
- * \return          The corresponding public key type.
- *                  If \p type is not a public key or a key pair,
- *                  the return value is undefined.
- */
-#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type)        \
-    ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
-
-/** Raw data.
- *
- * A "key" of this type cannot be used for any cryptographic operation.
- * Applications may use this type to store arbitrary data in the keystore. */
-#define PSA_KEY_TYPE_RAW_DATA                   ((psa_key_type_t)0x50000001)
-
-/** HMAC key.
- *
- * The key policy determines which underlying hash algorithm the key can be
- * used for.
- *
- * HMAC keys should generally have the same size as the underlying hash.
- * This size can be calculated with #PSA_HASH_SIZE(\c alg) where
- * \c alg is the HMAC algorithm or the underlying hash algorithm. */
-#define PSA_KEY_TYPE_HMAC                       ((psa_key_type_t)0x51000000)
-
-/** A secret for key derivation.
- *
- * The key policy determines which key derivation algorithm the key
- * can be used for.
- */
-#define PSA_KEY_TYPE_DERIVE                     ((psa_key_type_t)0x52000000)
-
-/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
- *
- * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
- * 32 bytes (AES-256).
- */
-#define PSA_KEY_TYPE_AES                        ((psa_key_type_t)0x40000001)
-
-/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
- *
- * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or
- * 24 bytes (3-key 3DES).
- *
- * Note that single DES and 2-key 3DES are weak and strongly
- * deprecated and should only be used to decrypt legacy data. 3-key 3DES
- * is weak and deprecated and should only be used in legacy protocols.
- */
-#define PSA_KEY_TYPE_DES                        ((psa_key_type_t)0x40000002)
-
-/** Key for an cipher, AEAD or MAC algorithm based on the
- * Camellia block cipher. */
-#define PSA_KEY_TYPE_CAMELLIA                   ((psa_key_type_t)0x40000003)
-
-/** Key for the RC4 stream cipher.
- *
- * Note that RC4 is weak and deprecated and should only be used in
- * legacy protocols. */
-#define PSA_KEY_TYPE_ARC4                       ((psa_key_type_t)0x40000004)
-
-/** RSA public key. */
-#define PSA_KEY_TYPE_RSA_PUBLIC_KEY             ((psa_key_type_t)0x60010000)
-/** RSA key pair (private and public key). */
-#define PSA_KEY_TYPE_RSA_KEYPAIR                ((psa_key_type_t)0x70010000)
-/** Whether a key type is an RSA key (pair or public-only). */
-#define PSA_KEY_TYPE_IS_RSA(type)                                       \
-    (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
-
-/** DSA public key. */
-#define PSA_KEY_TYPE_DSA_PUBLIC_KEY             ((psa_key_type_t)0x60020000)
-/** DSA key pair (private and public key). */
-#define PSA_KEY_TYPE_DSA_KEYPAIR                ((psa_key_type_t)0x70020000)
-/** Whether a key type is an DSA key (pair or public-only). */
-#define PSA_KEY_TYPE_IS_DSA(type)                                       \
-    (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
-
-#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE        ((psa_key_type_t)0x60030000)
-#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE           ((psa_key_type_t)0x70030000)
-#define PSA_KEY_TYPE_ECC_CURVE_MASK             ((psa_key_type_t)0x0000ffff)
-/** Elliptic curve key pair. */
-#define PSA_KEY_TYPE_ECC_KEYPAIR(curve)         \
-    (PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
-/** Elliptic curve public key. */
-#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)              \
-    (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
-
-/** Whether a key type is an elliptic curve key (pair or public-only). */
-#define PSA_KEY_TYPE_IS_ECC(type)                                       \
-    ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) &                        \
-      ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
-#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type)                               \
-    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
-     PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
-#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)                            \
-    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
-     PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
-
-/** The type of PSA elliptic curve identifiers. */
-typedef uint16_t psa_ecc_curve_t;
-/** Extract the curve from an elliptic curve key type. */
-#define PSA_KEY_TYPE_GET_CURVE(type)                             \
-    ((psa_ecc_curve_t) (PSA_KEY_TYPE_IS_ECC(type) ?              \
-                        ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \
-                        0))
-
-/* The encoding of curve identifiers is currently aligned with the
- * TLS Supported Groups Registry (formerly known as the
- * TLS EC Named Curve Registry)
- * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
- * The values are defined by RFC 8422 and RFC 7027. */
-#define PSA_ECC_CURVE_SECT163K1         ((psa_ecc_curve_t) 0x0001)
-#define PSA_ECC_CURVE_SECT163R1         ((psa_ecc_curve_t) 0x0002)
-#define PSA_ECC_CURVE_SECT163R2         ((psa_ecc_curve_t) 0x0003)
-#define PSA_ECC_CURVE_SECT193R1         ((psa_ecc_curve_t) 0x0004)
-#define PSA_ECC_CURVE_SECT193R2         ((psa_ecc_curve_t) 0x0005)
-#define PSA_ECC_CURVE_SECT233K1         ((psa_ecc_curve_t) 0x0006)
-#define PSA_ECC_CURVE_SECT233R1         ((psa_ecc_curve_t) 0x0007)
-#define PSA_ECC_CURVE_SECT239K1         ((psa_ecc_curve_t) 0x0008)
-#define PSA_ECC_CURVE_SECT283K1         ((psa_ecc_curve_t) 0x0009)
-#define PSA_ECC_CURVE_SECT283R1         ((psa_ecc_curve_t) 0x000a)
-#define PSA_ECC_CURVE_SECT409K1         ((psa_ecc_curve_t) 0x000b)
-#define PSA_ECC_CURVE_SECT409R1         ((psa_ecc_curve_t) 0x000c)
-#define PSA_ECC_CURVE_SECT571K1         ((psa_ecc_curve_t) 0x000d)
-#define PSA_ECC_CURVE_SECT571R1         ((psa_ecc_curve_t) 0x000e)
-#define PSA_ECC_CURVE_SECP160K1         ((psa_ecc_curve_t) 0x000f)
-#define PSA_ECC_CURVE_SECP160R1         ((psa_ecc_curve_t) 0x0010)
-#define PSA_ECC_CURVE_SECP160R2         ((psa_ecc_curve_t) 0x0011)
-#define PSA_ECC_CURVE_SECP192K1         ((psa_ecc_curve_t) 0x0012)
-#define PSA_ECC_CURVE_SECP192R1         ((psa_ecc_curve_t) 0x0013)
-#define PSA_ECC_CURVE_SECP224K1         ((psa_ecc_curve_t) 0x0014)
-#define PSA_ECC_CURVE_SECP224R1         ((psa_ecc_curve_t) 0x0015)
-#define PSA_ECC_CURVE_SECP256K1         ((psa_ecc_curve_t) 0x0016)
-#define PSA_ECC_CURVE_SECP256R1         ((psa_ecc_curve_t) 0x0017)
-#define PSA_ECC_CURVE_SECP384R1         ((psa_ecc_curve_t) 0x0018)
-#define PSA_ECC_CURVE_SECP521R1         ((psa_ecc_curve_t) 0x0019)
-#define PSA_ECC_CURVE_BRAINPOOL_P256R1  ((psa_ecc_curve_t) 0x001a)
-#define PSA_ECC_CURVE_BRAINPOOL_P384R1  ((psa_ecc_curve_t) 0x001b)
-#define PSA_ECC_CURVE_BRAINPOOL_P512R1  ((psa_ecc_curve_t) 0x001c)
-#define PSA_ECC_CURVE_CURVE25519        ((psa_ecc_curve_t) 0x001d)
-#define PSA_ECC_CURVE_CURVE448          ((psa_ecc_curve_t) 0x001e)
-
-/** The block size of a block cipher.
- *
- * \param type  A cipher key type (value of type #psa_key_type_t).
- *
- * \return      The block size for a block cipher, or 1 for a stream cipher.
- *              The return value is undefined if \p type is not a supported
- *              cipher key type.
- *
- * \note It is possible to build stream cipher algorithms on top of a block
- *       cipher, for example CTR mode (#PSA_ALG_CTR).
- *       This macro only takes the key type into account, so it cannot be
- *       used to determine the size of the data that #psa_cipher_update()
- *       might buffer for future processing in general.
- *
- * \note This macro returns a compile-time constant if its argument is one.
- *
- * \warning This macro may evaluate its argument multiple times.
- */
-#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type)            \
-    (                                                \
-        (type) == PSA_KEY_TYPE_AES ? 16 :            \
-        (type) == PSA_KEY_TYPE_DES ? 8 :             \
-        (type) == PSA_KEY_TYPE_CAMELLIA ? 16 :       \
-        (type) == PSA_KEY_TYPE_ARC4 ? 1 :            \
-        0)
-
-/** \brief Encoding of a cryptographic algorithm.
- *
- * For algorithms that can be applied to multiple key types, this type
- * does not encode the key type. For example, for symmetric ciphers
- * based on a block cipher, #psa_algorithm_t encodes the block cipher
- * mode and the padding mode while the block cipher itself is encoded
- * via #psa_key_type_t.
- */
-typedef uint32_t psa_algorithm_t;
-
-#define PSA_ALG_VENDOR_FLAG                     ((psa_algorithm_t)0x80000000)
-#define PSA_ALG_CATEGORY_MASK                   ((psa_algorithm_t)0x7f000000)
-#define PSA_ALG_CATEGORY_HASH                   ((psa_algorithm_t)0x01000000)
-#define PSA_ALG_CATEGORY_MAC                    ((psa_algorithm_t)0x02000000)
-#define PSA_ALG_CATEGORY_CIPHER                 ((psa_algorithm_t)0x04000000)
-#define PSA_ALG_CATEGORY_AEAD                   ((psa_algorithm_t)0x06000000)
-#define PSA_ALG_CATEGORY_SIGN                   ((psa_algorithm_t)0x10000000)
-#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION  ((psa_algorithm_t)0x12000000)
-#define PSA_ALG_CATEGORY_KEY_AGREEMENT          ((psa_algorithm_t)0x22000000)
-#define PSA_ALG_CATEGORY_KEY_DERIVATION         ((psa_algorithm_t)0x30000000)
-#define PSA_ALG_CATEGORY_KEY_SELECTION          ((psa_algorithm_t)0x31000000)
-
-#define PSA_ALG_IS_VENDOR_DEFINED(alg)                                  \
-    (((alg) & PSA_ALG_VENDOR_FLAG) != 0)
-
-/** Whether the specified algorithm is a hash algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a hash algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_HASH(alg)                                            \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH)
-
-/** Whether the specified algorithm is a MAC algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a MAC algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_MAC(alg)                                             \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC)
-
-/** Whether the specified algorithm is a symmetric cipher algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_CIPHER(alg)                                          \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER)
-
-/** Whether the specified algorithm is an authenticated encryption
- * with associated data (AEAD) algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is an AEAD algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_AEAD(alg)                                            \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD)
-
-/** Whether the specified algorithm is a public-key signature algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a public-key signature algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_SIGN(alg)                                            \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN)
-
-/** Whether the specified algorithm is a public-key encryption algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a public-key encryption algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)                           \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
-
-#define PSA_ALG_KEY_SELECTION_FLAG              ((psa_algorithm_t)0x01000000)
-/** Whether the specified algorithm is a key agreement algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a key agreement algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_KEY_AGREEMENT(alg)                                   \
-    (((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) ==   \
-     PSA_ALG_CATEGORY_KEY_AGREEMENT)
-
-/** Whether the specified algorithm is a key derivation algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a key derivation algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_KEY_DERIVATION(alg)                                  \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
-
-/** Whether the specified algorithm is a key selection algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a key selection algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_KEY_SELECTION(alg)                                   \
-    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION)
-
-#define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
-#define PSA_ALG_MD2                             ((psa_algorithm_t)0x01000001)
-#define PSA_ALG_MD4                             ((psa_algorithm_t)0x01000002)
-#define PSA_ALG_MD5                             ((psa_algorithm_t)0x01000003)
-#define PSA_ALG_RIPEMD160                       ((psa_algorithm_t)0x01000004)
-#define PSA_ALG_SHA_1                           ((psa_algorithm_t)0x01000005)
-/** SHA2-224 */
-#define PSA_ALG_SHA_224                         ((psa_algorithm_t)0x01000008)
-/** SHA2-256 */
-#define PSA_ALG_SHA_256                         ((psa_algorithm_t)0x01000009)
-/** SHA2-384 */
-#define PSA_ALG_SHA_384                         ((psa_algorithm_t)0x0100000a)
-/** SHA2-512 */
-#define PSA_ALG_SHA_512                         ((psa_algorithm_t)0x0100000b)
-/** SHA2-512/224 */
-#define PSA_ALG_SHA_512_224                     ((psa_algorithm_t)0x0100000c)
-/** SHA2-512/256 */
-#define PSA_ALG_SHA_512_256                     ((psa_algorithm_t)0x0100000d)
-/** SHA3-224 */
-#define PSA_ALG_SHA3_224                        ((psa_algorithm_t)0x01000010)
-/** SHA3-256 */
-#define PSA_ALG_SHA3_256                        ((psa_algorithm_t)0x01000011)
-/** SHA3-384 */
-#define PSA_ALG_SHA3_384                        ((psa_algorithm_t)0x01000012)
-/** SHA3-512 */
-#define PSA_ALG_SHA3_512                        ((psa_algorithm_t)0x01000013)
-
-#define PSA_ALG_MAC_SUBCATEGORY_MASK            ((psa_algorithm_t)0x00c00000)
-#define PSA_ALG_HMAC_BASE                       ((psa_algorithm_t)0x02800000)
-/** Macro to build an HMAC algorithm.
- *
- * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding HMAC algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_HMAC(hash_alg)                                  \
-    (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-
-#define PSA_ALG_HMAC_GET_HASH(hmac_alg)                             \
-    (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK))
-
-/** Whether the specified algorithm is an HMAC algorithm.
- *
- * HMAC is a family of MAC algorithms that are based on a hash function.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is an HMAC algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_HMAC(alg)                                            \
-    (((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)
-#define PSA_ALG_GMAC                            ((psa_algorithm_t)0x02c00003)
-
-/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier.
- */
-#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg)                                \
-    (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
-     PSA_ALG_CIPHER_MAC_BASE)
-
-#define PSA_ALG_CIPHER_STREAM_FLAG              ((psa_algorithm_t)0x00800000)
-#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG          ((psa_algorithm_t)0x00400000)
-
-/** Whether the specified algorithm is a stream cipher.
- *
- * A stream cipher is a symmetric cipher that encrypts or decrypts messages
- * by applying a bitwise-xor with a stream of bytes that is generated
- * from a key.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \p alg is not a supported
- *         algorithm identifier or if it is not a symmetric cipher algorithm.
- */
-#define PSA_ALG_IS_STREAM_CIPHER(alg)            \
-    (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \
-        (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG))
-
-/** The ARC4 stream cipher algorithm.
- */
-#define PSA_ALG_ARC4                            ((psa_algorithm_t)0x04800001)
-
-/** The CTR stream cipher mode.
- *
- * CTR is a stream cipher which is built from a block cipher.
- * The underlying block cipher is determined by the key type.
- * For example, to use AES-128-CTR, use this algorithm with
- * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
- */
-#define PSA_ALG_CTR                             ((psa_algorithm_t)0x04c00001)
-
-#define PSA_ALG_CFB                             ((psa_algorithm_t)0x04c00002)
-
-#define PSA_ALG_OFB                             ((psa_algorithm_t)0x04c00003)
-
-/** The XTS cipher mode.
- *
- * XTS is a cipher mode which is built from a block cipher. It requires at
- * least one full block of input, but beyond this minimum the input
- * does not need to be a whole number of blocks.
- */
-#define PSA_ALG_XTS                             ((psa_algorithm_t)0x044000ff)
-
-/** The CBC block cipher chaining mode, with no padding.
- *
- * The underlying block cipher is determined by the key type.
- *
- * This symmetric cipher mode can only be used with messages whose lengths
- * are whole number of blocks for the chosen block cipher.
- */
-#define PSA_ALG_CBC_NO_PADDING                  ((psa_algorithm_t)0x04600100)
-
-/** The CBC block cipher chaining mode with PKCS#7 padding.
- *
- * The underlying block cipher is determined by the key type.
- *
- * This is the padding method defined by PKCS#7 (RFC 2315) &sect;10.3.
- */
-#define PSA_ALG_CBC_PKCS7                       ((psa_algorithm_t)0x04600101)
-
-#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.
- *
- * This is the signature scheme defined by RFC 8017
- * (PKCS#1: RSA Cryptography Specifications) under the name
- * RSASSA-PKCS1-v1_5.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding RSA PKCS#1 v1.5 signature algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)                             \
-    (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-/** Raw PKCS#1 v1.5 signature.
- *
- * The input to this algorithm is the DigestInfo structure used by
- * RFC 8017 (PKCS#1: RSA Cryptography Specifications), &sect;9.2
- * steps 3&ndash;6.
- */
-#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
-#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)                               \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
-
-#define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x10030000)
-/** RSA PSS signature with hashing.
- *
- * This is the signature scheme defined by RFC 8017
- * (PKCS#1: RSA Cryptography Specifications) under the name
- * RSASSA-PSS, with the message generation function MGF1, and with
- * a salt length equal to the length of the hash. The specified
- * hash algorithm is used to hash the input message, to create the
- * salted hash, and for the mask generation.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding RSA PSS signature algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_RSA_PSS(hash_alg)                               \
-    (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_RSA_PSS(alg)                                 \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
-
-#define PSA_ALG_DSA_BASE                        ((psa_algorithm_t)0x10040000)
-/** DSA signature with hashing.
- *
- * This is the signature scheme defined by FIPS 186-4,
- * with a random per-message secret number (*k*).
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding DSA signature algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_DSA(hash_alg)                             \
-    (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_DETERMINISTIC_DSA_BASE          ((psa_algorithm_t)0x10050000)
-#define PSA_ALG_DSA_DETERMINISTIC_FLAG          ((psa_algorithm_t)0x00010000)
-#define PSA_ALG_DETERMINISTIC_DSA(hash_alg)                             \
-    (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_DSA(alg)                                             \
-    (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) ==  \
-     PSA_ALG_DSA_BASE)
-#define PSA_ALG_DSA_IS_DETERMINISTIC(alg)               \
-    (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
-#define PSA_ALG_IS_DETERMINISTIC_DSA(alg)                       \
-    (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
-#define PSA_ALG_IS_RANDOMIZED_DSA(alg)                          \
-    (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
-
-#define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x10060000)
-/** ECDSA signature with hashing.
- *
- * This is the ECDSA signature scheme defined by ANSI X9.62,
- * with a random per-message secret number (*k*).
- *
- * The representation of the signature as a byte string consists of
- * the concatentation of the signature values *r* and *s*. Each of
- * *r* and *s* is encoded as an *N*-octet string, where *N* is the length
- * of the base point of the curve in octets. Each value is represented
- * in big-endian order (most significant octet first).
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding ECDSA signature algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_ECDSA(hash_alg)                                 \
-    (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-/** ECDSA signature without hashing.
- *
- * This is the same signature scheme as #PSA_ALG_ECDSA(), but
- * without specifying a hash algorithm. This algorithm may only be
- * used to sign or verify a sequence of bytes that should be an
- * already-calculated hash. Note that the input is padded with
- * zeros on the left or truncated on the left as required to fit
- * the curve size.
- */
-#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE
-#define PSA_ALG_DETERMINISTIC_ECDSA_BASE        ((psa_algorithm_t)0x10070000)
-/** Deterministic ECDSA signature with hashing.
- *
- * This is the deterministic ECDSA signature scheme defined by RFC 6979.
- *
- * The representation of a signature is the same as with #PSA_ALG_ECDSA().
- *
- * Note that when this algorithm is used for verification, signatures
- * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the
- * same private key are accepted. In other words,
- * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from
- * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding deterministic ECDSA signature
- *                      algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg)                           \
-    (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_ECDSA(alg)                                           \
-    (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) ==  \
-     PSA_ALG_ECDSA_BASE)
-#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)             \
-    (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
-#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)                             \
-    (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
-#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg)                                \
-    (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
-
-/** Get the hash used by a hash-and-sign signature algorithm.
- *
- * A hash-and-sign algorithm is a signature algorithm which is
- * composed of two phases: first a hashing phase which does not use
- * the key and produces a hash of the input message, then a signing
- * phase which only uses the hash and the key and not the message
- * itself.
- *
- * \param alg   A signature algorithm (\c PSA_ALG_XXX value such that
- *              #PSA_ALG_IS_SIGN(\p alg) is true).
- *
- * \return      The underlying hash algorithm if \p alg is a hash-and-sign
- *              algorithm.
- * \return      0 if \p alg is a signature algorithm that does not
- *              follow the hash-and-sign structure.
- * \return      Unspecified if \p alg is not a signature algorithm or
- *              if it is not supported by the implementation.
- */
-#define PSA_ALG_SIGN_GET_HASH(alg)                                     \
-    (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||   \
-     PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ?                    \
-     ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 :        \
-     ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :             \
-     0)
-
-/** RSA PKCS#1 v1.5 encryption.
- */
-#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x12020000)
-
-#define PSA_ALG_RSA_OAEP_BASE                   ((psa_algorithm_t)0x12030000)
-/** RSA OAEP encryption.
- *
- * This is the encryption scheme defined by RFC 8017
- * (PKCS#1: RSA Cryptography Specifications) under the name
- * RSAES-OAEP, with the message generation function MGF1.
- *
- * \param hash_alg      The hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true) to use
- *                      for MGF1.
- *
- * \return              The corresponding RSA OAEP signature algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_RSA_OAEP(hash_alg)                              \
-    (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_RSA_OAEP(alg)                                \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
-#define PSA_ALG_RSA_OAEP_GET_HASH(alg)                          \
-    (PSA_ALG_IS_RSA_OAEP(alg) ?                                 \
-     ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :      \
-     0)
-
-#define PSA_ALG_HKDF_BASE                       ((psa_algorithm_t)0x30000100)
-/** Macro to build an HKDF algorithm.
- *
- * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding HKDF algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_HKDF(hash_alg)                                  \
-    (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-/** Whether the specified algorithm is an HKDF algorithm.
- *
- * HKDF is a family of key derivation algorithms that are based on a hash
- * function and the HMAC construction.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \c alg is an HKDF algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \c alg is not a supported
- *         key derivation algorithm identifier.
- */
-#define PSA_ALG_IS_HKDF(alg)                            \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE)
-#define PSA_ALG_HKDF_GET_HASH(hkdf_alg)                         \
-    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
-
-#define PSA_ALG_TLS12_PRF_BASE                     ((psa_algorithm_t)0x30000200)
-/** Macro to build a TLS-1.2 PRF algorithm.
- *
- * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
- * specified in Section 5 of RFC 5246. It is based on HMAC and can be
- * used with either SHA-256 or SHA-384.
- *
- * For the application to TLS-1.2, the salt and label arguments passed
- * to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246,
- * respectively. For example, for TLS key expansion, the salt is the
- * concatenation of ServerHello.Random + ClientHello.Random,
- * while the label is "key expansion".
- *
- * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
- * TLS 1.2 PRF using HMAC-SHA-256.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding TLS-1.2 PRF algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_TLS12_PRF(hash_alg)                                  \
-    (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-
-/** Whether the specified algorithm is a TLS-1.2 PRF algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \c alg is not a supported
- *         key derivation algorithm identifier.
- */
-#define PSA_ALG_IS_TLS12_PRF(alg)                                    \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE)
-#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg)                         \
-    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
-
-#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300)
-/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
- *
- * In a pure-PSK handshake in TLS 1.2, the master secret is derived
- * from the PreSharedKey (PSK) through the application of padding
- * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5).
- * The latter is based on HMAC and can be used with either SHA-256
- * or SHA-384.
- *
- * For the application to TLS-1.2, the salt passed to psa_key_derivation()
- * (and forwarded to the TLS-1.2 PRF) is the concatenation of the
- * ClientHello.Random + ServerHello.Random, while the label is "master secret"
- * or "extended master secret".
- *
- * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
- * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
- *
- * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
- *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
- *
- * \return              The corresponding TLS-1.2 PSK to MS algorithm.
- * \return              Unspecified if \p alg is not a supported
- *                      hash algorithm.
- */
-#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg)                                  \
-    (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
-
-/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \c alg is not a supported
- *         key derivation algorithm identifier.
- */
-#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg)                                    \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE)
-#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg)                         \
-    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
-
-#define PSA_ALG_KEY_DERIVATION_MASK             ((psa_algorithm_t)0x010fffff)
-
-/** Use a shared secret as is.
- *
- * Specify this algorithm as the selection component of a key agreement
- * to use the raw result of the key agreement as key material.
- *
- * \warning The raw result of a key agreement algorithm such as finite-field
- * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
- * not be used directly as key material. It can however be used as the secret
- * input in a key derivation algorithm.
- */
-#define PSA_ALG_SELECT_RAW                      ((psa_algorithm_t)0x31000001)
-
-#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg)                              \
-    (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
-
-#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg)                              \
-    ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK)
-
-#define PSA_ALG_FFDH_BASE                       ((psa_algorithm_t)0x22100000)
-/** The Diffie-Hellman key agreement algorithm.
- *
- * This algorithm combines the finite-field Diffie-Hellman (DH) key
- * agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement,
- * to produce a shared secret from a private key and the peer's
- * public key, with a key selection or key derivation algorithm to produce
- * one or more shared keys and other shared cryptographic material.
- *
- * The shared secret produced by key agreement and passed as input to the
- * derivation or selection algorithm \p kdf_alg is the shared secret
- * `g^{ab}` in big-endian format.
- * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
- * in bits.
- *
- * \param kdf_alg       A key derivation algorithm (\c PSA_ALG_XXX value such
- *                      that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
- *                      or a key selection algorithm (\c PSA_ALG_XXX value such
- *                      that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
- *
- * \return              The Diffie-Hellman algorithm with the specified
- *                      selection or derivation algorithm.
- */
-#define PSA_ALG_FFDH(kdf_alg) \
-    (PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
-/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
- *
- * This includes every supported key selection or key agreement algorithm
- * for the output of the Diffie-Hellman calculation.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise.
- *         This macro may return either 0 or 1 if \c alg is not a supported
- *         key agreement algorithm identifier.
- */
-#define PSA_ALG_IS_FFDH(alg) \
-    (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE)
-
-#define PSA_ALG_ECDH_BASE                       ((psa_algorithm_t)0x22200000)
-/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
- *
- * This algorithm combines the elliptic curve Diffie-Hellman key
- * agreement to produce a shared secret from a private key and the peer's
- * public key, with a key selection or key derivation algorithm to produce
- * one or more shared keys and other shared cryptographic material.
- *
- * The shared secret produced by key agreement and passed as input to the
- * derivation or selection algorithm \p kdf_alg is the x-coordinate of
- * the shared secret point. It is always `ceiling(m / 8)` bytes long where
- * `m` is the bit size associated with the curve, i.e. the bit size of the
- * order of the curve's coordinate field. When `m` is not a multiple of 8,
- * the byte containing the most significant bit of the shared secret
- * is padded with zero bits. The byte order is either little-endian
- * or big-endian depending on the curve type.
- *
- * - For Montgomery curves (curve types `PSA_ECC_CURVE_CURVEXXX`),
- *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
- *   in little-endian byte order.
- *   The bit size is 448 for Curve448 and 255 for Curve25519.
- * - For Weierstrass curves over prime fields (curve types
- *   `PSA_ECC_CURVE_SECPXXX` and `PSA_ECC_CURVE_BRAINPOOL_PXXX`),
- *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
- *   in big-endian byte order.
- *   The bit size is `m = ceiling(log_2(p))` for the field `F_p`.
- * - For Weierstrass curves over binary fields (curve types
- *   `PSA_ECC_CURVE_SECTXXX`),
- *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
- *   in big-endian byte order.
- *   The bit size is `m` for the field `F_{2^m}`.
- *
- * \param kdf_alg       A key derivation algorithm (\c PSA_ALG_XXX value such
- *                      that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
- *                      or a selection algorithm (\c PSA_ALG_XXX value such
- *                      that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
- *
- * \return              The Diffie-Hellman algorithm with the specified
- *                      selection or derivation algorithm.
- */
-#define PSA_ALG_ECDH(kdf_alg) \
-    (PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
-/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
- * algorithm.
- *
- * This includes every supported key selection or key agreement algorithm
- * for the output of the Diffie-Hellman calculation.
- *
- * \param alg An algorithm identifier (value of type #psa_algorithm_t).
- *
- * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm,
- *         0 otherwise.
- *         This macro may return either 0 or 1 if \c alg is not a supported
- *         key agreement algorithm identifier.
- */
-#define PSA_ALG_IS_ECDH(alg) \
-    (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE)
-
 /**@}*/
 
 /** \defgroup key_management Key management
  * @{
  */
 
-/** Encoding of key lifetimes.
- */
-typedef uint32_t psa_key_lifetime_t;
-
-/** Encoding of identifiers of persistent keys.
- */
-typedef uint32_t psa_key_id_t;
-
-/** A volatile key only exists as long as the handle to it is not closed.
- * The key material is guaranteed to be erased on a power reset.
- */
-#define PSA_KEY_LIFETIME_VOLATILE               ((psa_key_lifetime_t)0x00000000)
-
-/** The default storage area for persistent keys.
- *
- * A persistent key remains in storage until it is explicitly destroyed or
- * until the corresponding storage area is wiped. This specification does
- * not define any mechanism to wipe a storage area, but implementations may
- * provide their own mechanism (for example to perform a factory reset,
- * to prepare for device refurbishment, or to uninstall an application).
- *
- * This lifetime value is the default storage area for the calling
- * application. Implementations may offer other storage areas designated
- * by other lifetime values as implementation-specific extensions.
- */
-#define PSA_KEY_LIFETIME_PERSISTENT             ((psa_key_lifetime_t)0x00000001)
-
 /** \brief Retrieve the lifetime of an open key.
  *
  * \param handle        Handle to query.
@@ -1906,68 +570,6 @@
  * @{
  */
 
-/** \brief Encoding of permitted usage on a key. */
-typedef uint32_t psa_key_usage_t;
-
-/** Whether the key may be exported.
- *
- * A public key or the public part of a key pair may always be exported
- * regardless of the value of this permission flag.
- *
- * If a key does not have export permission, implementations shall not
- * allow the key to be exported in plain form from the cryptoprocessor,
- * whether through psa_export_key() or through a proprietary interface.
- * The key may however be exportable in a wrapped form, i.e. in a form
- * where it is encrypted by another key.
- */
-#define PSA_KEY_USAGE_EXPORT                    ((psa_key_usage_t)0x00000001)
-
-/** Whether the key may be used to encrypt a message.
- *
- * This flag allows the key to be used for a symmetric encryption operation,
- * for an AEAD encryption-and-authentication operation,
- * or for an asymmetric encryption operation,
- * if otherwise permitted by the key's type and policy.
- *
- * For a key pair, this concerns the public key.
- */
-#define PSA_KEY_USAGE_ENCRYPT                   ((psa_key_usage_t)0x00000100)
-
-/** Whether the key may be used to decrypt a message.
- *
- * This flag allows the key to be used for a symmetric decryption operation,
- * for an AEAD decryption-and-verification operation,
- * or for an asymmetric decryption operation,
- * if otherwise permitted by the key's type and policy.
- *
- * For a key pair, this concerns the private key.
- */
-#define PSA_KEY_USAGE_DECRYPT                   ((psa_key_usage_t)0x00000200)
-
-/** Whether the key may be used to sign a message.
- *
- * This flag allows the key to be used for a MAC calculation operation
- * or for an asymmetric signature operation,
- * if otherwise permitted by the key's type and policy.
- *
- * For a key pair, this concerns the private key.
- */
-#define PSA_KEY_USAGE_SIGN                      ((psa_key_usage_t)0x00000400)
-
-/** Whether the key may be used to verify a message signature.
- *
- * This flag allows the key to be used for a MAC verification operation
- * or for an asymmetric signature verification operation,
- * if otherwise permitted by by the key's type and policy.
- *
- * For a key pair, this concerns the public key.
- */
-#define PSA_KEY_USAGE_VERIFY                    ((psa_key_usage_t)0x00000800)
-
-/** Whether the key may be used to derive other keys.
- */
-#define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00001000)
-
 /** The type of the key policy data structure.
  *
  * This is an implementation-defined \c struct. Applications should not
@@ -2075,39 +677,6 @@
  * as directed by the documentation of a specific implementation. */
 typedef struct psa_hash_operation_s psa_hash_operation_t;
 
-/** The size of the output of psa_hash_finish(), in bytes.
- *
- * This is also the hash size that psa_hash_verify() expects.
- *
- * \param alg   A hash algorithm (\c PSA_ALG_XXX value such that
- *              #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
- *              (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
- *              hash algorithm).
- *
- * \return The hash size for the specified hash algorithm.
- *         If the hash algorithm is not recognized, return 0.
- *         An implementation may return either 0 or the correct size
- *         for a hash algorithm that it recognizes, but does not support.
- */
-#define PSA_HASH_SIZE(alg)                                      \
-    (                                                           \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 :            \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 :            \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 :            \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 :      \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 :          \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 :        \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 :        \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 :        \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 :        \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 :    \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 :    \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 :       \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 :       \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 :       \
-        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 :       \
-        0)
-
 /** Start a multipart hash operation.
  *
  * The sequence of operations to calculate a hash (message digest)
@@ -2828,26 +1397,6 @@
  * @{
  */
 
-/** The tag size for an AEAD algorithm, in bytes.
- *
- * \param alg                 An AEAD algorithm
- *                            (\c PSA_ALG_XXX value such that
- *                            #PSA_ALG_IS_AEAD(\p alg) is true).
- *
- * \return                    The tag size for the specified algorithm.
- *                            If the AEAD algorithm does not have an identified
- *                            tag that can be distinguished from the rest of
- *                            the ciphertext, return 0.
- *                            If the AEAD algorithm is not recognized, return 0.
- *                            An implementation may return either 0 or a
- *                            correct size for an AEAD algorithm that it
- *                            recognizes, but does not support.
- */
-#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.
  *
  * \param handle                  Handle to the key to use for the operation.
@@ -2971,17 +1520,6 @@
  */
 
 /**
- * \brief ECDSA signature size for a given curve bit size
- *
- * \param curve_bits    Curve size in bits.
- * \return              Signature size in bytes.
- *
- * \note This macro returns a compile-time constant if its argument is one.
- */
-#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits)    \
-    (PSA_BITS_TO_BYTES(curve_bits) * 2)
-
-/**
  * \brief Sign a hash or short message with a private key.
  *
  * Note that to perform a hash-and-sign signature algorithm, you must
@@ -3070,11 +1608,6 @@
                                    const uint8_t *signature,
                                    size_t signature_length);
 
-#define PSA_RSA_MINIMUM_PADDING_SIZE(alg)                               \
-    (PSA_ALG_IS_RSA_OAEP(alg) ?                                         \
-     2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 :      \
-     11 /*PKCS#1v1.5*/)
-
 /**
  * \brief Encrypt a short message with a public key.
  *
diff --git a/include/psa/crypto_accel_driver.h b/include/psa/crypto_accel_driver.h
new file mode 100644
index 0000000..b752fed
--- /dev/null
+++ b/include/psa/crypto_accel_driver.h
@@ -0,0 +1,796 @@
+/**
+ * \file psa/crypto_accel_driver.h
+ * \brief PSA cryptography accelerator driver module
+ *
+ * This header declares types and function signatures for cryptography
+ * drivers that access key material directly. This is meant for
+ * on-chip cryptography accelerators.
+ *
+ * This file is part of the PSA Crypto Driver Model, containing functions for
+ * driver developers to implement to enable hardware to be called in a
+ * standardized way by a PSA Cryptographic API implementation. The functions
+ * comprising the driver model, which driver authors implement, are not
+ * intended to be called by application developers.
+ */
+
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef PSA_CRYPTO_ACCEL_DRIVER_H
+#define PSA_CRYPTO_ACCEL_DRIVER_H
+
+#include "crypto_driver_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup driver_digest Message Digests
+ *
+ * Generation and authentication of Message Digests (aka hashes) must be done
+ * in parts using the following sequence:
+ * - `psa_drv_hash_setup_t`
+ * - `psa_drv_hash_update_t`
+ * - ...
+ * - `psa_drv_hash_finish_t`
+ *
+ * If a previously started Message Digest operation needs to be terminated
+ * before the `psa_drv_hash_finish_t` operation is complete, it should be aborted
+ * by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated
+ * resources not being freed or in other undefined behavior.
+ */
+/**@{*/
+
+/** \brief The hardware-specific hash context structure
+ *
+ * The contents of this structure are implementation dependent and are
+ * therefore not described here
+ */
+typedef struct psa_drv_hash_context_s psa_drv_hash_context_t;
+
+/** \brief The function prototype for the start operation of a hash (message
+ * digest) operation
+ *
+ *  Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_hash_<ALGO>_setup
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying hash function
+ *
+ * \param[in,out] p_context     A structure that will contain the
+ * hardware-specific hash context
+ *
+ * \retval  PSA_SUCCESS     Success.
+ */
+typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context);
+
+/** \brief The function prototype for the update operation of a hash (message
+ * digest) operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_hash_<ALGO>_update
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously-established hash operation to be
+ *                              continued
+ * \param[in] p_input           A buffer containing the message to be appended
+ *                              to the hash operation
+ * \param[in] input_length      The size in bytes of the input message buffer
+ */
+typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context,
+                                              const uint8_t *p_input,
+                                              size_t input_length);
+
+/** \brief  The prototype for the finish operation of a hash (message digest)
+ * operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_hash_<ALGO>_finish
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started hash operation to be
+ *                              fiinished
+ * \param[out] p_output         A buffer where the generated digest will be
+ *                              placed
+ * \param[in] output_size       The size in bytes of the buffer that has been
+ *                              allocated for the `p_output` buffer
+ * \param[out] p_output_length  The number of bytes placed in `p_output` after
+ *                              success
+ *
+ * \retval PSA_SUCCESS
+ *          Success.
+ */
+typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context,
+                                              uint8_t *p_output,
+                                              size_t output_size,
+                                              size_t *p_output_length);
+
+/** \brief The function prototype for the abort operation of a hash (message
+ * digest) operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_hash_<ALGO>_abort
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm
+ *
+ * \param[in,out] p_context A hardware-specific structure for the previously
+ *                          started hash operation to be aborted
+ */
+typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context);
+
+/**@}*/
+
+/** \defgroup transparent_mac Transparent Message Authentication Code
+ * Generation and authentication of Message Authentication Codes (MACs) using
+ * transparent keys can be done either as a single function call (via the
+ * `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t`
+ * functions), or in parts using the following sequence:
+ * - `psa_drv_mac_transparent_setup_t`
+ * - `psa_drv_mac_transparent_update_t`
+ * - `psa_drv_mac_transparent_update_t`
+ * - ...
+ * - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t`
+ *
+ * If a previously started Transparent MAC operation needs to be terminated, it
+ * should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may
+ * result in allocated resources not being freed or in other undefined
+ * behavior.
+ *
+ */
+/**@{*/
+
+/** \brief The hardware-specific transparent-key MAC context structure
+ *
+ * The contents of this structure are implementation dependent and are
+ * therefore not described here.
+ */
+typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t;
+
+/** \brief The function prototype for the setup operation of a
+ * transparent-key MAC operation
+ *
+ *  Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_setup
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT`
+ * is the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in,out] p_context     A structure that will contain the
+ *                              hardware-specific MAC context
+ * \param[in] p_key             A buffer containing the cleartext key material
+ *                              to be used in the operation
+ * \param[in] key_length        The size in bytes of the key material
+ *
+ * \retval  PSA_SUCCESS
+ *          Success.
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context,
+                                                        const uint8_t *p_key,
+                                                        size_t key_length);
+
+/** \brief The function prototype for the update operation of a
+ * transparent-key MAC operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_update
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT`
+ * is the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously-established MAC operation to be
+ *                              continued
+ * \param[in] p_input           A buffer containing the message to be appended
+ *                              to the MAC operation
+ * \param[in] input_length      The size in bytes of the input message buffer
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context,
+                                                         const uint8_t *p_input,
+                                                         size_t input_length);
+
+/** \brief  The function prototype for the finish operation of a
+ * transparent-key MAC operation
+ *
+ * Functions that implement the prototype should be named in the following
+ *  convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
+ * the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started MAC operation to be
+ *                              finished
+ * \param[out] p_mac            A buffer where the generated MAC will be placed
+ * \param[in] mac_length        The size in bytes of the buffer that has been
+ *                              allocated for the `p_mac` buffer
+ *
+ * \retval PSA_SUCCESS
+ *          Success.
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context,
+                                                         uint8_t *p_mac,
+                                                         size_t mac_length);
+
+/** \brief The function prototype for the finish and verify operation of a
+ * transparent-key MAC operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish_verify
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
+ * the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started MAC operation to be
+ *                              verified and finished
+ * \param[in] p_mac             A buffer containing the MAC that will be used
+ *                              for verification
+ * \param[in] mac_length        The size in bytes of the data in the `p_mac`
+ *                              buffer
+ *
+ * \retval PSA_SUCCESS
+ *          The operation completed successfully and the comparison matched
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context,
+                                                                const uint8_t *p_mac,
+                                                                size_t mac_length);
+
+/** \brief The function prototype for the abort operation for a previously
+ * started transparent-key MAC operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_abort
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
+ * the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started MAC operation to be
+ *                              aborted
+ *
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context);
+
+/** \brief The function prototype for a one-shot operation of a transparent-key
+ * MAC operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
+ * the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in] p_input        A buffer containing the data to be MACed
+ * \param[in] input_length   The length in bytes of the `p_input` data
+ * \param[in] p_key          A buffer containing the key material to be used
+ *                           for the MAC operation
+ * \param[in] key_length     The length in bytes of the `p_key` data
+ * \param[in] alg            The algorithm to be performed
+ * \param[out] p_mac         The buffer where the resulting MAC will be placed
+ *                           upon success
+ * \param[in] mac_length     The length in bytes of the `p_mac` buffer
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input,
+                                                  size_t input_length,
+                                                  const uint8_t *p_key,
+                                                  size_t key_length,
+                                                  psa_algorithm_t alg,
+                                                  uint8_t *p_mac,
+                                                  size_t mac_length);
+
+/** \brief The function prototype for a one-shot operation of a transparent-key
+ * MAC Verify operation
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_verify
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
+ * the specific variant of a MAC operation (such as HMAC or CMAC)
+ *
+ * \param[in] p_input        A buffer containing the data to be MACed
+ * \param[in] input_length   The length in bytes of the `p_input` data
+ * \param[in] p_key          A buffer containing the key material to be used
+ *                           for the MAC operation
+ * \param[in] key_length     The length in bytes of the `p_key` data
+ * \param[in] alg            The algorithm to be performed
+ * \param[in] p_mac          The MAC data to be compared
+ * \param[in] mac_length     The length in bytes of the `p_mac` buffer
+ *
+ * \retval PSA_SUCCESS
+ *  The operation completed successfully and the comparison matched
+ */
+typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input,
+                                                         size_t input_length,
+                                                         const uint8_t *p_key,
+                                                         size_t key_length,
+                                                         psa_algorithm_t alg,
+                                                         const uint8_t *p_mac,
+                                                         size_t mac_length);
+/**@}*/
+
+/** \defgroup transparent_cipher Transparent Block Cipher
+ * Encryption and Decryption using transparent keys in block modes other than
+ * ECB must be done in multiple parts, using the following flow:
+ * - `psa_drv_cipher_transparent_setup_t`
+ * - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode)
+ * - `psa_drv_cipher_transparent_update_t`
+ * - ...
+ * - `psa_drv_cipher_transparent_finish_t`
+
+ * If a previously started Transparent Cipher operation needs to be terminated,
+ * it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do
+ * so may result in allocated resources not being freed or in other undefined
+ * behavior.
+ */
+/**@{*/
+
+/** \brief The hardware-specific transparent-key Cipher context structure
+ *
+ * The contents of this structure are implementation dependent and are
+ * therefore not described here.
+ */
+typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t;
+
+/** \brief The function prototype for the setup operation of transparent-key
+ * block cipher operations.
+ *  Functions that implement the prototype should be named in the following
+ * conventions:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_setup_<CIPHER_NAME>_<MODE>
+ * ~~~~~~~~~~~~~
+ * Where
+ * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
+ * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
+ * or for stream ciphers:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_setup_<CIPHER_NAME>
+ * ~~~~~~~~~~~~~
+ * Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4)
+ *
+ * \param[in,out] p_context     A structure that will contain the
+ *                              hardware-specific cipher context
+ * \param[in] direction         Indicates if the operation is an encrypt or a
+ *                              decrypt
+ * \param[in] p_key_data        A buffer containing the cleartext key material
+ *                              to be used in the operation
+ * \param[in] key_data_size     The size in bytes of the key material
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context,
+                                                           psa_encrypt_or_decrypt_t direction,
+                                                           const uint8_t *p_key_data,
+                                                           size_t key_data_size);
+
+/** \brief The function prototype for the set initialization vector operation
+ * of transparent-key block cipher operations
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_set_iv_<CIPHER_NAME>_<MODE>
+ * ~~~~~~~~~~~~~
+ * Where
+ * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
+ * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
+ *
+ * \param[in,out] p_context     A structure that contains the previously setup
+ *                              hardware-specific cipher context
+ * \param[in] p_iv              A buffer containing the initialization vecotr
+ * \param[in] iv_length         The size in bytes of the contents of `p_iv`
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context,
+                                                            const uint8_t *p_iv,
+                                                            size_t iv_length);
+
+/** \brief The function prototype for the update operation of transparent-key
+ * block cipher operations.
+ *
+ *  Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_update_<CIPHER_NAME>_<MODE>
+ * ~~~~~~~~~~~~~
+ * Where
+ * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
+ * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
+ *
+ * \param[in,out] p_context         A hardware-specific structure for the
+ *                                  previously started cipher operation
+ * \param[in] p_input               A buffer containing the data to be
+ *                                  encrypted or decrypted
+ * \param[in] input_size            The size in bytes of the `p_input` buffer
+ * \param[out] p_output             A caller-allocated buffer where the
+ *                                  generated output will be placed
+ * \param[in] output_size           The size in bytes of the `p_output` buffer
+ * \param[out] p_output_length      After completion, will contain the number
+ *                                  of bytes placed in the `p_output` buffer
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context,
+                                                            const uint8_t *p_input,
+                                                            size_t input_size,
+                                                            uint8_t *p_output,
+                                                            size_t output_size,
+                                                            size_t *p_output_length);
+
+/** \brief The function prototype for the finish operation of transparent-key
+ * block cipher operations.
+ *
+ *  Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_finish_<CIPHER_NAME>_<MODE>
+ * ~~~~~~~~~~~~~
+ * Where
+ * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
+ * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started cipher operation
+ * \param[out] p_output         A caller-allocated buffer where the generated
+ *                              output will be placed
+ * \param[in] output_size       The size in bytes of the `p_output` buffer
+ * \param[out] p_output_length  After completion, will contain the number of
+ *                              bytes placed in the `p_output` buffer
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context,
+                                                            uint8_t *p_output,
+                                                            size_t output_size,
+                                                            size_t *p_output_length);
+
+/** \brief The function prototype for the abort operation of transparent-key
+ * block cipher operations.
+ *
+ *  Functions that implement the following prototype should be named in the
+ * following convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_cipher_transparent_abort_<CIPHER_NAME>_<MODE>
+ * ~~~~~~~~~~~~~
+ * Where
+ * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
+ * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started cipher operation
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context);
+
+/**@}*/
+
+/** \defgroup aead_transparent AEAD Transparent
+ *
+ * Authenticated Encryption with Additional Data (AEAD) operations with
+ * transparent keys must be done in one function call. While this creates a
+ * burden for implementers as there must be sufficient space in memory for the
+ * entire message, it prevents decrypted data from being made available before
+ * the authentication operation is complete and the data is known to be
+ * authentic.
+ */
+/**@{*/
+
+/** Process an authenticated encryption operation using an opaque key.
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_aead_<ALGO>_encrypt
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the AEAD algorithm
+ *
+ * \param[in] p_key                     A pointer to the key material
+ * \param[in] key_length                The size in bytes of the key material
+ * \param[in] alg                       The AEAD algorithm to compute
+ *                                      (\c PSA_ALG_XXX value such that
+ *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
+ * \param[in] nonce                     Nonce or IV to use
+ * \param[in] nonce_length              Size of the `nonce` buffer in bytes
+ * \param[in] additional_data           Additional data that will be MACed
+ *                                      but not encrypted.
+ * \param[in] additional_data_length    Size of `additional_data` in bytes
+ * \param[in] plaintext                 Data that will be MACed and
+ *                                      encrypted.
+ * \param[in] plaintext_length          Size of `plaintext` in bytes
+ * \param[out] ciphertext               Output buffer for the authenticated and
+ *                                      encrypted data. The additional data is
+ *                                      not part of this output. For algorithms
+ *                                      where the encrypted data and the
+ *                                      authentication tag are defined as
+ *                                      separate outputs, the authentication
+ *                                      tag is appended to the encrypted data.
+ * \param[in] ciphertext_size           Size of the `ciphertext` buffer in
+ *                                      bytes
+ *                                      This must be at least
+ *                                      #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`,
+ *                                      `plaintext_length`).
+ * \param[out] ciphertext_length        On success, the size of the output in
+ *                                      the `ciphertext` buffer
+ *
+ * \retval #PSA_SUCCESS
+
+ */
+typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key,
+                                                           size_t key_length,
+                                                           psa_algorithm_t alg,
+                                                           const uint8_t *nonce,
+                                                           size_t nonce_length,
+                                                           const uint8_t *additional_data,
+                                                           size_t additional_data_length,
+                                                           const uint8_t *plaintext,
+                                                           size_t plaintext_length,
+                                                           uint8_t *ciphertext,
+                                                           size_t ciphertext_size,
+                                                           size_t *ciphertext_length);
+
+/** Process an authenticated decryption operation using an opaque key.
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_aead_<ALGO>_decrypt
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the AEAD algorithm
+ * \param[in] p_key                     A pointer to the key material
+ * \param[in] key_length                The size in bytes of the key material
+ * \param[in] alg                       The AEAD algorithm to compute
+ *                                      (\c PSA_ALG_XXX value such that
+ *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
+ * \param[in] nonce                     Nonce or IV to use
+ * \param[in] nonce_length              Size of the `nonce` buffer in bytes
+ * \param[in] additional_data           Additional data that has been MACed
+ *                                      but not encrypted
+ * \param[in] additional_data_length    Size of `additional_data` in bytes
+ * \param[in] ciphertext                Data that has been MACed and
+ *                                      encrypted
+ *                                      For algorithms where the encrypted data
+ *                                      and the authentication tag are defined
+ *                                      as separate inputs, the buffer must
+ *                                      contain the encrypted data followed by
+ *                                      the authentication tag.
+ * \param[in] ciphertext_length         Size of `ciphertext` in bytes
+ * \param[out] plaintext                Output buffer for the decrypted data
+ * \param[in] plaintext_size            Size of the `plaintext` buffer in
+ *                                      bytes
+ *                                      This must be at least
+ *                                      #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`,
+ *                                      `ciphertext_length`).
+ * \param[out] plaintext_length         On success, the size of the output
+ *                                      in the \b plaintext buffer
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ */
+typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key,
+                                                           size_t key_length,
+                                                           psa_algorithm_t alg,
+                                                           const uint8_t *nonce,
+                                                           size_t nonce_length,
+                                                           const uint8_t *additional_data,
+                                                           size_t additional_data_length,
+                                                           const uint8_t *ciphertext,
+                                                           size_t ciphertext_length,
+                                                           uint8_t *plaintext,
+                                                           size_t plaintext_size,
+                                                           size_t *plaintext_length);
+
+/**@}*/
+
+/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography
+ *
+ * Since the amount of data that can (or should) be encrypted or signed using
+ * asymmetric keys is limited by the key size, asymmetric key operations using
+ * transparent keys must be done in single function calls.
+ */
+/**@{*/
+
+
+/**
+ * \brief A function that signs a hash or short message with a transparent
+ * asymmetric private key
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_asymmetric_<ALGO>_sign
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the signing algorithm
+ *
+ * \param[in] p_key                 A buffer containing the private key
+ *                                  material
+ * \param[in] key_size              The size in bytes of the `p_key` data
+ * \param[in] alg                   A signature algorithm that is compatible
+ *                                  with the type of `p_key`
+ * \param[in] p_hash                The hash or message to sign
+ * \param[in] hash_length           Size of the `p_hash` buffer in bytes
+ * \param[out] p_signature          Buffer where the signature is to be written
+ * \param[in] signature_size        Size of the `p_signature` buffer in bytes
+ * \param[out] p_signature_length   On success, the number of bytes
+ *                                  that make up the returned signature value
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key,
+                                                              size_t key_size,
+                                                              psa_algorithm_t alg,
+                                                              const uint8_t *p_hash,
+                                                              size_t hash_length,
+                                                              uint8_t *p_signature,
+                                                              size_t signature_size,
+                                                              size_t *p_signature_length);
+
+/**
+ * \brief A function that verifies the signature a hash or short message using
+ * a transparent asymmetric public key
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_asymmetric_<ALGO>_verify
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the signing algorithm
+ *
+ * \param[in] p_key             A buffer containing the public key material
+ * \param[in] key_size          The size in bytes of the `p_key` data
+ * \param[in] alg               A signature algorithm that is compatible with
+ *                              the type of `key`
+ * \param[in] p_hash            The hash or message whose signature is to be
+ *                              verified
+ * \param[in] hash_length       Size of the `p_hash` buffer in bytes
+ * \param[in] p_signature       Buffer containing the signature to verify
+ * \param[in] signature_length  Size of the `p_signature` buffer in bytes
+ *
+ * \retval PSA_SUCCESS
+ *         The signature is valid.
+ */
+typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key,
+                                                                size_t key_size,
+                                                                psa_algorithm_t alg,
+                                                                const uint8_t *p_hash,
+                                                                size_t hash_length,
+                                                                const uint8_t *p_signature,
+                                                                size_t signature_length);
+
+/**
+ * \brief A function that encrypts a short message with a transparent
+ * asymmetric public key
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_asymmetric_<ALGO>_encrypt
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the encryption algorithm
+ *
+ * \param[in] p_key             A buffer containing the public key material
+ * \param[in] key_size          The size in bytes of the `p_key` data
+ * \param[in] alg               An asymmetric encryption algorithm that is
+ *                              compatible with the type of `key`
+ * \param[in] p_input           The message to encrypt
+ * \param[in] input_length      Size of the `p_input` buffer in bytes
+ * \param[in] p_salt            A salt or label, if supported by the
+ *                              encryption algorithm
+ *                              If the algorithm does not support a
+ *                              salt, pass `NULL`
+ *                              If the algorithm supports an optional
+ *                              salt and you do not want to pass a salt,
+ *                              pass `NULL`.
+ *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ *                              supported.
+ * \param[in] salt_length       Size of the `p_salt` buffer in bytes
+ *                              If `p_salt` is `NULL`, pass 0.
+ * \param[out] p_output         Buffer where the encrypted message is to
+ *                              be written
+ * \param[in] output_size       Size of the `p_output` buffer in bytes
+ * \param[out] p_output_length  On success, the number of bytes
+ *                              that make up the returned output
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key,
+                                                                 size_t key_size,
+                                                                 psa_algorithm_t alg,
+                                                                 const uint8_t *p_input,
+                                                                 size_t input_length,
+                                                                 const uint8_t *p_salt,
+                                                                 size_t salt_length,
+                                                                 uint8_t *p_output,
+                                                                 size_t output_size,
+                                                                 size_t *p_output_length);
+
+/**
+ * \brief Decrypt a short message with a transparent asymmetric private key
+ *
+ * Functions that implement the prototype should be named in the following
+ * convention:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_asymmetric_<ALGO>_decrypt
+ * ~~~~~~~~~~~~~
+ * Where `ALGO` is the name of the encryption algorithm
+ *
+ * \param[in] p_key             A buffer containing the private key material
+ * \param[in] key_size          The size in bytes of the `p_key` data
+ * \param[in] alg               An asymmetric encryption algorithm that is
+ *                              compatible with the type of `key`
+ * \param[in] p_input           The message to decrypt
+ * \param[in] input_length      Size of the `p_input` buffer in bytes
+ * \param[in] p_salt            A salt or label, if supported by the
+ *                              encryption algorithm
+ *                              If the algorithm does not support a
+ *                              salt, pass `NULL`.
+ *                              If the algorithm supports an optional
+ *                              salt and you do not want to pass a salt,
+ *                              pass `NULL`.
+ *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ *                              supported
+ * \param[in] salt_length       Size of the `p_salt` buffer in bytes
+ *                              If `p_salt` is `NULL`, pass 0
+ * \param[out] p_output         Buffer where the decrypted message is to
+ *                              be written
+ * \param[in] output_size       Size of the `p_output` buffer in bytes
+ * \param[out] p_output_length  On success, the number of bytes
+ *                              that make up the returned output
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key,
+                                                                 size_t key_size,
+                                                                 psa_algorithm_t alg,
+                                                                 const uint8_t *p_input,
+                                                                 size_t input_length,
+                                                                 const uint8_t *p_salt,
+                                                                 size_t salt_length,
+                                                                 uint8_t *p_output,
+                                                                 size_t output_size,
+                                                                 size_t *p_output_length);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_ACCEL_DRIVER_H */
diff --git a/include/psa/crypto_driver.h b/include/psa/crypto_driver.h
deleted file mode 100644
index a52ecc4..0000000
--- a/include/psa/crypto_driver.h
+++ /dev/null
@@ -1,1787 +0,0 @@
-/**
- * \file psa/crypto_driver.h
- * \brief Platform Security Architecture cryptographic driver module
- *
- * This file describes the PSA Crypto Driver Model, containing functions for
- * driver developers to implement to enable hardware to be called in a
- * standardized way by a PSA Cryptographic API implementation. The functions
- * comprising the driver model, which driver authors implement, are not
- * intended to be called by application developers.
- */
-
-/*
- *  Copyright (C) 2018, ARM Limited, All Rights Reserved
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  Licensed under the Apache License, Version 2.0 (the "License"); you may
- *  not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-#ifndef PSA_CRYPTO_DRIVER_H
-#define PSA_CRYPTO_DRIVER_H
-
-#include <stddef.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** The following types are redefinitions from the psa/crypto.h file.
- * It is intended that these will be moved to a new common header file to
- * avoid duplication. They are included here for expediency in publication.
- */
-typedef uint32_t psa_status_t;
-typedef uint32_t psa_algorithm_t;
-typedef uint8_t psa_encrypt_or_decrypt_t;
-typedef uint32_t psa_key_slot_t;
-typedef uint32_t psa_key_type_t;
-typedef uint32_t psa_key_usage_t;
-
-#define PSA_CRYPTO_DRIVER_ENCRYPT 1
-#define PSA_CRYPTO_DRIVER_DECRYPT 0
-
-/** \defgroup opaque_mac Opaque Message Authentication Code
- * Generation and authentication of Message Authentication Codes (MACs) using
- * opaque keys can be done either as a single function call (via the
- * `psa_drv_mac_opaque_generate_t` or `psa_drv_mac_opaque_verify_t` functions), or in
- * parts using the following sequence:
- * - `psa_drv_mac_opaque_setup_t`
- * - `psa_drv_mac_opaque_update_t`
- * - `psa_drv_mac_opaque_update_t`
- * - ...
- * - `psa_drv_mac_opaque_finish_t` or `psa_drv_mac_opaque_finish_verify_t`
- *
- * If a previously started Opaque MAC operation needs to be terminated, it
- * should be done so by the `psa_drv_mac_opaque_abort_t`. Failure to do so may
- * result in allocated resources not being freed or in other undefined
- * behavior.
- */
-/**@{*/
-/** \brief A function that starts a MAC operation for a PSA Crypto Driver
- * implementation using an opaque key
- *
- * \param[in,out] p_context     A structure that will contain the
- *                              hardware-specific MAC context
- * \param[in] key_slot          The slot of the key to be used for the
- *                              operation
- * \param[in] algorithm         The algorithm to be used to underly the MAC
- *                              operation
- *
- * \retval  PSA_SUCCESS
- *          Success.
- */
-typedef psa_status_t (*psa_drv_mac_opaque_setup_t)(void *p_context,
-                                                   psa_key_slot_t key_slot,
-                                                   psa_algorithm_t algorithm);
-
-/** \brief A function that continues a previously started MAC operation using
- * an opaque key
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously-established MAC operation to be
- *                              continued
- * \param[in] p_input           A buffer containing the message to be appended
- *                              to the MAC operation
- * \param[in] input_length  The size in bytes of the input message buffer
- */
-typedef psa_status_t (*psa_drv_mac_opaque_update_t)(void *p_context,
-                                                    const uint8_t *p_input,
-                                                    size_t input_length);
-
-/** \brief a function that completes a previously started MAC operation by
- * returning the resulting MAC using an opaque key
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started MAC operation to be
- *                              finished
- * \param[out] p_mac            A buffer where the generated MAC will be
- *                              placed
- * \param[in] mac_size          The size in bytes of the buffer that has been
- *                              allocated for the `output` buffer
- * \param[out] p_mac_length     After completion, will contain the number of
- *                              bytes placed in the `p_mac` buffer
- *
- * \retval PSA_SUCCESS
- *          Success.
- */
-typedef psa_status_t (*psa_drv_mac_opaque_finish_t)(void *p_context,
-                                                    uint8_t *p_mac,
-                                                    size_t mac_size,
-                                                    size_t *p_mac_length);
-
-/** \brief A function that completes a previously started MAC operation by
- * comparing the resulting MAC against a known value using an opaque key
- *
- * \param[in,out] p_context A hardware-specific structure for the previously
- *                          started MAC operation to be fiinished
- * \param[in] p_mac         The MAC value against which the resulting MAC will
- *                          be compared against
- * \param[in] mac_length    The size in bytes of the value stored in `p_mac`
- *
- * \retval PSA_SUCCESS
- *         The operation completed successfully and the MACs matched each
- *         other
- * \retval PSA_ERROR_INVALID_SIGNATURE
- *         The operation completed successfully, but the calculated MAC did
- *         not match the provided MAC
- */
-typedef psa_status_t (*psa_drv_mac_opaque_finish_verify_t)(void *p_context,
-                                                           const uint8_t *p_mac,
-                                                           size_t mac_length);
-
-/** \brief A function that aborts a previous started opaque-key MAC operation
-
- * \param[in,out] p_context A hardware-specific structure for the previously
- *                          started MAC operation to be aborted
- */
-typedef psa_status_t (*psa_drv_mac_opaque_abort_t)(void *p_context);
-
-/** \brief A function that performs a MAC operation in one command and returns
- * the calculated MAC using an opaque key
- *
- * \param[in] p_input           A buffer containing the message to be MACed
- * \param[in] input_length      The size in bytes of `p_input`
- * \param[in] key_slot          The slot of the key to be used
- * \param[in] alg               The algorithm to be used to underlie the MAC
- *                              operation
- * \param[out] p_mac            A buffer where the generated MAC will be
- *                              placed
- * \param[in] mac_size          The size in bytes of the `p_mac` buffer
- * \param[out] p_mac_length     After completion, will contain the number of
- *                              bytes placed in the `output` buffer
- *
- * \retval PSA_SUCCESS
- *         Success.
- */
-typedef psa_status_t (*psa_drv_mac_opaque_generate_t)(const uint8_t *p_input,
-                                                      size_t input_length,
-                                                      psa_key_slot_t key_slot,
-                                                      psa_algorithm_t alg,
-                                                      uint8_t *p_mac,
-                                                      size_t mac_size,
-                                                      size_t *p_mac_length);
-
-/** \brief A function that performs an MAC operation in one command and
- * compare the resulting MAC against a known value using an opaque key
- *
- * \param[in] p_input       A buffer containing the message to be MACed
- * \param[in] input_length  The size in bytes of `input`
- * \param[in] key_slot      The slot of the key to be used
- * \param[in] alg           The algorithm to be used to underlie the MAC
- *                          operation
- * \param[in] p_mac         The MAC value against which the resulting MAC will
- *                          be compared against
- * \param[in] mac_length   The size in bytes of `mac`
- *
- * \retval PSA_SUCCESS
- *         The operation completed successfully and the MACs matched each
- *         other
- * \retval PSA_ERROR_INVALID_SIGNATURE
- *         The operation completed successfully, but the calculated MAC did
- *         not match the provided MAC
- */
-typedef psa_status_t (*psa_drv_mac_opaque_verify_t)(const uint8_t *p_input,
-                                                    size_t input_length,
-                                                    psa_key_slot_t key_slot,
-                                                    psa_algorithm_t alg,
-                                                    const uint8_t *p_mac,
-                                                    size_t mac_length);
-
-/** \brief A struct containing all of the function pointers needed to
- * implement MAC operations using opaque keys.
- *
- * PSA Crypto API implementations should populate the table as appropriate
- * upon startup.
- *
- * If one of the functions is not implemented (such as
- * `psa_drv_mac_opaque_generate_t`), it should be set to NULL.
- *
- * Driver implementers should ensure that they implement all of the functions
- * that make sense for their hardware, and that they provide a full solution
- * (for example, if they support `p_setup`, they should also support
- * `p_update` and at least one of `p_finish` or `p_finish_verify`).
- *
- */
-typedef struct {
-    /**The size in bytes of the hardware-specific Opaque-MAC Context structure
-    */
-    size_t                              context_size;
-    /** Function that performs the setup operation
-     */
-    psa_drv_mac_opaque_setup_t          *p_setup;
-    /** Function that performs the update operation
-     */
-    psa_drv_mac_opaque_update_t         *p_update;
-    /** Function that completes the operation
-     */
-    psa_drv_mac_opaque_finish_t         *p_finish;
-    /** Function that completed a MAC operation with a verify check
-     */
-    psa_drv_mac_opaque_finish_verify_t  *p_finish_verify;
-    /** Function that aborts a previoustly started operation
-     */
-    psa_drv_mac_opaque_abort_t          *p_abort;
-    /** Function that performs the MAC operation in one call
-     */
-    psa_drv_mac_opaque_generate_t       *p_mac;
-    /** Function that performs the MAC and verify operation in one call
-     */
-    psa_drv_mac_opaque_verify_t         *p_mac_verify;
-} psa_drv_mac_opaque_t;
-/**@}*/
-
-/** \defgroup transparent_mac Transparent Message Authentication Code
- * Generation and authentication of Message Authentication Codes (MACs) using
- * transparent keys can be done either as a single function call (via the
- * `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t`
- * functions), or in parts using the following sequence:
- * - `psa_drv_mac_transparent_setup_t`
- * - `psa_drv_mac_transparent_update_t`
- * - `psa_drv_mac_transparent_update_t`
- * - ...
- * - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t`
- *
- * If a previously started Transparent MAC operation needs to be terminated, it
- * should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may
- * result in allocated resources not being freed or in other undefined
- * behavior.
- *
- */
-/**@{*/
-
-/** \brief The hardware-specific transparent-key MAC context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here.
- */
-typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t;
-
-/** \brief The function prototype for the setup operation of a
- * transparent-key MAC operation
- *
- *  Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_setup
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT`
- * is the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context     A structure that will contain the
- *                              hardware-specific MAC context
- * \param[in] p_key             A buffer containing the cleartext key material
- *                              to be used in the operation
- * \param[in] key_length        The size in bytes of the key material
- *
- * \retval  PSA_SUCCESS
- *          Success.
- */
-typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context,
-                                                        const uint8_t *p_key,
-                                                        size_t key_length);
-
-/** \brief The function prototype for the update operation of a
- * transparent-key MAC operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_update
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT`
- * is the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously-established MAC operation to be
- *                              continued
- * \param[in] p_input           A buffer containing the message to be appended
- *                              to the MAC operation
- * \param[in] input_length      The size in bytes of the input message buffer
- */
-typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context,
-                                                         const uint8_t *p_input,
-                                                         size_t input_length);
-
-/** \brief  The function prototype for the finish operation of a
- * transparent-key MAC operation
- *
- * Functions that implement the prototype should be named in the following
- *  convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started MAC operation to be
- *                              finished
- * \param[out] p_mac            A buffer where the generated MAC will be placed
- * \param[in] mac_length        The size in bytes of the buffer that has been
- *                              allocated for the `p_mac` buffer
- *
- * \retval PSA_SUCCESS
- *          Success.
- */
-typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context,
-                                                         uint8_t *p_mac,
-                                                         size_t mac_length);
-
-/** \brief The function prototype for the finish and verify operation of a
- * transparent-key MAC operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_finish_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started MAC operation to be
- *                              verified and finished
- * \param[in] p_mac             A buffer containing the MAC that will be used
- *                              for verification
- * \param[in] mac_length        The size in bytes of the data in the `p_mac`
- *                              buffer
- *
- * \retval PSA_SUCCESS
- *          The operation completed successfully and the comparison matched
- */
-typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context,
-                                                                const uint8_t *p_mac,
-                                                                size_t mac_length);
-
-/** \brief The function prototype for the abort operation for a previously
- * started transparent-key MAC operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_abort
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started MAC operation to be
- *                              aborted
- *
- */
-typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context);
-
-/** \brief The function prototype for a one-shot operation of a transparent-key
- * MAC operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in] p_input        A buffer containing the data to be MACed
- * \param[in] input_length   The length in bytes of the `p_input` data
- * \param[in] p_key          A buffer containing the key material to be used
- *                           for the MAC operation
- * \param[in] key_length     The length in bytes of the `p_key` data
- * \param[in] alg            The algorithm to be performed
- * \param[out] p_mac         The buffer where the resulting MAC will be placed
- *                           upon success
- * \param[in] mac_length     The length in bytes of the `p_mac` buffer
- */
-typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input,
-                                                  size_t input_length,
-                                                  const uint8_t *p_key,
-                                                  size_t key_length,
-                                                  psa_algorithm_t alg,
-                                                  uint8_t *p_mac,
-                                                  size_t mac_length);
-
-/** \brief The function prototype for a one-shot operation of a transparent-key
- * MAC Verify operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_mac_transparent_<ALGO>_<MAC_VARIANT>_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is
- * the specific variant of a MAC operation (such as HMAC or CMAC)
- *
- * \param[in] p_input        A buffer containing the data to be MACed
- * \param[in] input_length   The length in bytes of the `p_input` data
- * \param[in] p_key          A buffer containing the key material to be used
- *                           for the MAC operation
- * \param[in] key_length     The length in bytes of the `p_key` data
- * \param[in] alg            The algorithm to be performed
- * \param[in] p_mac          The MAC data to be compared
- * \param[in] mac_length     The length in bytes of the `p_mac` buffer
- *
- * \retval PSA_SUCCESS
- *  The operation completed successfully and the comparison matched
- */
-typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input,
-                                                         size_t input_length,
-                                                         const uint8_t *p_key,
-                                                         size_t key_length,
-                                                         psa_algorithm_t alg,
-                                                         const uint8_t *p_mac,
-                                                         size_t mac_length);
-/**@}*/
-
-/** \defgroup opaque_cipher Opaque Symmetric Ciphers
- *
- * Encryption and Decryption using opaque keys in block modes other than ECB
- * must be done in multiple parts, using the following flow:
- * - `psa_drv_cipher_opaque_setup_t`
- * - `psa_drv_cipher_opaque_set_iv_t` (optional depending upon block mode)
- * - `psa_drv_cipher_opaque_update_t`
- * - ...
- * - `psa_drv_cipher_opaque_finish_t`
-
- * If a previously started Opaque Cipher operation needs to be terminated, it
- * should be done so by the `psa_drv_cipher_opaque_abort_t`. Failure to do so may
- * result in allocated resources not being freed or in other undefined
- * behavior.
- *
- * In situations where a PSA Cryptographic API implementation is using a block
- * mode not-supported by the underlying hardware or driver, it can construct
- * the block mode itself, while calling the `psa_drv_cipher_opaque_ecb_t` function
- * pointer for the cipher operations.
- */
-/**@{*/
-
-/** \brief A function pointer that provides the cipher setup function for
- * opaque-key operations
- *
- * \param[in,out] p_context     A structure that will contain the
- *                              hardware-specific cipher context.
- * \param[in] key_slot          The slot of the key to be used for the
- *                              operation
- * \param[in] algorithm         The algorithm to be used in the cipher
- *                              operation
- * \param[in] direction         Indicates whether the operation is an encrypt
- *                              or decrypt
- *
- * \retval PSA_SUCCESS
- * \retval PSA_ERROR_NOT_SUPPORTED
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_setup_t)(void *p_context,
-                                                      psa_key_slot_t key_slot,
-                                                      psa_algorithm_t algorithm,
-                                                      psa_encrypt_or_decrypt_t direction);
-
-/** \brief A function pointer that sets the initialization vector (if
- * necessary) for an opaque cipher operation
- *
- * Rationale: The `psa_cipher_*` function in the PSA Cryptographic API has two
- * IV functions: one to set the IV, and one to generate it internally. The
- * generate function is not necessary for the drivers to implement as the PSA
- * Crypto implementation can do the generation using its RNG features.
- *
- * \param[in,out] p_context     A structure that contains the previously set up
- *                              hardware-specific cipher context
- * \param[in] p_iv              A buffer containing the initialization vector
- * \param[in] iv_length         The size (in bytes) of the `p_iv` buffer
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_set_iv_t)(void *p_context,
-                                                       const uint8_t *p_iv,
-                                                       size_t iv_length);
-
-/** \brief A function that continues a previously started opaque-key cipher
- * operation
- *
- * \param[in,out] p_context         A hardware-specific structure for the
- *                                  previously started cipher operation
- * \param[in] p_input               A buffer containing the data to be
- *                                  encrypted/decrypted
- * \param[in] input_size            The size in bytes of the buffer pointed to
- *                                  by `p_input`
- * \param[out] p_output             The caller-allocated buffer where the
- *                                  output will be placed
- * \param[in] output_size           The allocated size in bytes of the
- *                                  `p_output` buffer
- * \param[out] p_output_length      After completion, will contain the number
- *                                  of bytes placed in the `p_output` buffer
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_update_t)(void *p_context,
-                                                       const uint8_t *p_input,
-                                                       size_t input_size,
-                                                       uint8_t *p_output,
-                                                       size_t output_size,
-                                                       size_t *p_output_length);
-
-/** \brief A function that completes a previously started opaque-key cipher
- * operation
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started cipher operation
- * \param[out] p_output         The caller-allocated buffer where the output
- *                              will be placed
- * \param[in] output_size       The allocated size in bytes of the `p_output`
- *                              buffer
- * \param[out] p_output_length  After completion, will contain the number of
- *                              bytes placed in the `p_output` buffer
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_finish_t)(void *p_context,
-                                                       uint8_t *p_output,
-                                                       size_t output_size,
-                                                       size_t *p_output_length);
-
-/** \brief A function that aborts a previously started opaque-key cipher
- * operation
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started cipher operation
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_abort_t)(void *p_context);
-
-/** \brief A function that performs the ECB block mode for opaque-key cipher
- * operations
- *
- * Note: this function should only be used with implementations that do not
- * provide a needed higher-level operation.
- *
- * \param[in] key_slot      The slot of the key to be used for the operation
- * \param[in] algorithm     The algorithm to be used in the cipher operation
- * \param[in] direction     Indicates whether the operation is an encrypt or
- *                          decrypt
- * \param[in] p_input       A buffer containing the data to be
- *                          encrypted/decrypted
- * \param[in] input_size    The size in bytes of the buffer pointed to by
- *                          `p_input`
- * \param[out] p_output     The caller-allocated buffer where the output will
- *                          be placed
- * \param[in] output_size   The allocated size in bytes of the `p_output`
- *                          buffer
- *
- * \retval PSA_SUCCESS
- * \retval PSA_ERROR_NOT_SUPPORTED
- */
-typedef psa_status_t (*psa_drv_cipher_opaque_ecb_t)(psa_key_slot_t key_slot,
-                                                    psa_algorithm_t algorithm,
-                                                    psa_encrypt_or_decrypt_t direction,
-                                                    const uint8_t *p_input,
-                                                    size_t input_size,
-                                                    uint8_t *p_output,
-                                                    size_t output_size);
-
-/**
- * \brief A struct containing all of the function pointers needed to implement
- * cipher operations using opaque keys.
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented (such as
- * `psa_drv_cipher_opaque_ecb_t`), it should be set to NULL.
- */
-typedef struct {
-    /** The size in bytes of the hardware-specific Opaque Cipher context
-     * structure
-     */
-    size_t                         size;
-    /** Function that performs the setup operation */
-    psa_drv_cipher_opaque_setup_t  *p_setup;
-    /** Function that sets the IV (if necessary) */
-    psa_drv_cipher_opaque_set_iv_t *p_set_iv;
-    /** Function that performs the update operation */
-    psa_drv_cipher_opaque_update_t *p_update;
-    /** Function that completes the operation */
-    psa_drv_cipher_opaque_finish_t *p_finish;
-    /** Function that aborts the operation */
-    psa_drv_cipher_opaque_abort_t  *p_abort;
-    /** Function that performs ECB mode for the cipher
-     * (Danger: ECB mode should not be used directly by clients of the PSA
-     * Crypto Client API)
-     */
-    psa_drv_cipher_opaque_ecb_t    *p_ecb;
-} psa_drv_cipher_opaque_t;
-
-/**@}*/
-
-/** \defgroup transparent_cipher Transparent Block Cipher
- * Encryption and Decryption using transparent keys in block modes other than
- * ECB must be done in multiple parts, using the following flow:
- * - `psa_drv_cipher_transparent_setup_t`
- * - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode)
- * - `psa_drv_cipher_transparent_update_t`
- * - ...
- * - `psa_drv_cipher_transparent_finish_t`
-
- * If a previously started Transparent Cipher operation needs to be terminated,
- * it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do
- * so may result in allocated resources not being freed or in other undefined
- * behavior.
- */
-/**@{*/
-
-/** \brief The hardware-specific transparent-key Cipher context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here.
- */
-typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t;
-
-/** \brief The function prototype for the setup operation of transparent-key
- * block cipher operations.
- *  Functions that implement the prototype should be named in the following
- * conventions:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_setup_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- * or for stream ciphers:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_setup_<CIPHER_NAME>
- * ~~~~~~~~~~~~~
- * Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4)
- *
- * \param[in,out] p_context     A structure that will contain the
- *                              hardware-specific cipher context
- * \param[in] direction         Indicates if the operation is an encrypt or a
- *                              decrypt
- * \param[in] p_key_data        A buffer containing the cleartext key material
- *                              to be used in the operation
- * \param[in] key_data_size     The size in bytes of the key material
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context,
-                                                           psa_encrypt_or_decrypt_t direction,
-                                                           const uint8_t *p_key_data,
-                                                           size_t key_data_size);
-
-/** \brief The function prototype for the set initialization vector operation
- * of transparent-key block cipher operations
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_set_iv_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context     A structure that contains the previously setup
- *                              hardware-specific cipher context
- * \param[in] p_iv              A buffer containing the initialization vecotr
- * \param[in] iv_length         The size in bytes of the contents of `p_iv`
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context,
-                                                            const uint8_t *p_iv,
-                                                            size_t iv_length);
-
-/** \brief The function prototype for the update operation of transparent-key
- * block cipher operations.
- *
- *  Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_update_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context         A hardware-specific structure for the
- *                                  previously started cipher operation
- * \param[in] p_input               A buffer containing the data to be
- *                                  encrypted or decrypted
- * \param[in] input_size            The size in bytes of the `p_input` buffer
- * \param[out] p_output             A caller-allocated buffer where the
- *                                  generated output will be placed
- * \param[in] output_size           The size in bytes of the `p_output` buffer
- * \param[out] p_output_length      After completion, will contain the number
- *                                  of bytes placed in the `p_output` buffer
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context,
-                                                            const uint8_t *p_input,
-                                                            size_t input_size,
-                                                            uint8_t *p_output,
-                                                            size_t output_size,
-                                                            size_t *p_output_length);
-
-/** \brief The function prototype for the finish operation of transparent-key
- * block cipher operations.
- *
- *  Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_finish_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started cipher operation
- * \param[out] p_output         A caller-allocated buffer where the generated
- *                              output will be placed
- * \param[in] output_size       The size in bytes of the `p_output` buffer
- * \param[out] p_output_length  After completion, will contain the number of
- *                              bytes placed in the `p_output` buffer
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context,
-                                                            uint8_t *p_output,
-                                                            size_t output_size,
-                                                            size_t *p_output_length);
-
-/** \brief The function prototype for the abort operation of transparent-key
- * block cipher operations.
- *
- *  Functions that implement the following prototype should be named in the
- * following convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_cipher_transparent_abort_<CIPHER_NAME>_<MODE>
- * ~~~~~~~~~~~~~
- * Where
- * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES)
- * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR)
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started cipher operation
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context);
-
-/**@}*/
-
-/** \defgroup driver_digest Message Digests
- *
- * Generation and authentication of Message Digests (aka hashes) must be done
- * in parts using the following sequence:
- * - `psa_drv_hash_setup_t`
- * - `psa_drv_hash_update_t`
- * - ...
- * - `psa_drv_hash_finish_t`
- *
- * If a previously started Message Digest operation needs to be terminated
- * before the `psa_drv_hash_finish_t` operation is complete, it should be aborted
- * by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated
- * resources not being freed or in other undefined behavior.
- */
-/**@{*/
-
-/** \brief The hardware-specific hash context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here
- */
-typedef struct psa_drv_hash_context_s psa_drv_hash_context_t;
-
-/** \brief The function prototype for the start operation of a hash (message
- * digest) operation
- *
- *  Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_setup
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying hash function
- *
- * \param[in,out] p_context     A structure that will contain the
- * hardware-specific hash context
- *
- * \retval  PSA_SUCCESS     Success.
- */
-typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context);
-
-/** \brief The function prototype for the update operation of a hash (message
- * digest) operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_update
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously-established hash operation to be
- *                              continued
- * \param[in] p_input           A buffer containing the message to be appended
- *                              to the hash operation
- * \param[in] input_length      The size in bytes of the input message buffer
- */
-typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context,
-                                              const uint8_t *p_input,
-                                              size_t input_length);
-
-/** \brief  The prototype for the finish operation of a hash (message digest)
- * operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_finish
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context     A hardware-specific structure for the
- *                              previously started hash operation to be
- *                              fiinished
- * \param[out] p_output         A buffer where the generated digest will be
- *                              placed
- * \param[in] output_size       The size in bytes of the buffer that has been
- *                              allocated for the `p_output` buffer
- * \param[out] p_output_length  The number of bytes placed in `p_output` after
- *                              success
- *
- * \retval PSA_SUCCESS
- *          Success.
- */
-typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context,
-                                              uint8_t *p_output,
-                                              size_t output_size,
-                                              size_t *p_output_length);
-
-/** \brief The function prototype for the abort operation of a hash (message
- * digest) operation
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_hash_<ALGO>_abort
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the underlying algorithm
- *
- * \param[in,out] p_context A hardware-specific structure for the previously
- *                          started hash operation to be aborted
- */
-typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context);
-
-/**@}*/
-
-
-/** \defgroup opaque_asymmetric Opaque Asymmetric Cryptography
- *
- * Since the amount of data that can (or should) be encrypted or signed using
- * asymmetric keys is limited by the key size, asymmetric key operations using
- * opaque keys must be done in single function calls.
- */
-/**@{*/
-
-/**
- * \brief A function that signs a hash or short message with a private key
- *
- * \param[in] key_slot              Key slot of an asymmetric key pair
- * \param[in] alg                   A signature algorithm that is compatible
- *                                  with the type of `key`
- * \param[in] p_hash                The hash to sign
- * \param[in] hash_length           Size of the `p_hash` buffer in bytes
- * \param[out] p_signature          Buffer where the signature is to be written
- * \param[in] signature_size        Size of the `p_signature` buffer in bytes
- * \param[out] p_signature_length   On success, the number of bytes
- *                                  that make up the returned signature value
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_opaque_sign_t)(psa_key_slot_t key_slot,
-                                                         psa_algorithm_t alg,
-                                                         const uint8_t *p_hash,
-                                                         size_t hash_length,
-                                                         uint8_t *p_signature,
-                                                         size_t signature_size,
-                                                         size_t *p_signature_length);
-
-/**
- * \brief A function that verifies the signature a hash or short message using
- * an asymmetric public key
- *
- * \param[in] key_slot          Key slot of a public key or an asymmetric key
- *                              pair
- * \param[in] alg               A signature algorithm that is compatible with
- *                              the type of `key`
- * \param[in] p_hash            The hash whose signature is to be verified
- * \param[in] hash_length       Size of the `p_hash` buffer in bytes
- * \param[in] p_signature       Buffer containing the signature to verify
- * \param[in] signature_length  Size of the `p_signature` buffer in bytes
- *
- * \retval PSA_SUCCESS
- *         The signature is valid.
- */
-typedef psa_status_t (*psa_drv_asymmetric_opaque_verify_t)(psa_key_slot_t key_slot,
-                                                           psa_algorithm_t alg,
-                                                           const uint8_t *p_hash,
-                                                           size_t hash_length,
-                                                           const uint8_t *p_signature,
-                                                           size_t signature_length);
-
-/**
- * \brief A function that encrypts a short message with an asymmetric public
- * key
- *
- * \param[in] key_slot          Key slot of a public key or an asymmetric key
- *                              pair
- * \param[in] alg               An asymmetric encryption algorithm that is
- *                              compatible with the type of `key`
- * \param[in] p_input           The message to encrypt
- * \param[in] input_length      Size of the `p_input` buffer in bytes
- * \param[in] p_salt            A salt or label, if supported by the
- *                              encryption algorithm
- *                              If the algorithm does not support a
- *                              salt, pass `NULL`.
- *                              If the algorithm supports an optional
- *                              salt and you do not want to pass a salt,
- *                              pass `NULL`.
- *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- *                              supported.
- * \param[in] salt_length       Size of the `p_salt` buffer in bytes
- *                              If `p_salt` is `NULL`, pass 0.
- * \param[out] p_output         Buffer where the encrypted message is to
- *                              be written
- * \param[in] output_size       Size of the `p_output` buffer in bytes
- * \param[out] p_output_length  On success, the number of bytes that make up
- *                              the returned output
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_opaque_encrypt_t)(psa_key_slot_t key_slot,
-                                                            psa_algorithm_t alg,
-                                                            const uint8_t *p_input,
-                                                            size_t input_length,
-                                                            const uint8_t *p_salt,
-                                                            size_t salt_length,
-                                                            uint8_t *p_output,
-                                                            size_t output_size,
-                                                            size_t *p_output_length);
-
-/**
- * \brief Decrypt a short message with an asymmetric private key.
- *
- * \param[in] key_slot          Key slot of an asymmetric key pair
- * \param[in] alg               An asymmetric encryption algorithm that is
- *                              compatible with the type of `key`
- * \param[in] p_input           The message to decrypt
- * \param[in] input_length      Size of the `p_input` buffer in bytes
- * \param[in] p_salt            A salt or label, if supported by the
- *                              encryption algorithm
- *                              If the algorithm does not support a
- *                              salt, pass `NULL`.
- *                              If the algorithm supports an optional
- *                              salt and you do not want to pass a salt,
- *                              pass `NULL`.
- *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- *                              supported.
- * \param[in] salt_length       Size of the `p_salt` buffer in bytes
- *                              If `p_salt` is `NULL`, pass 0.
- * \param[out] p_output         Buffer where the decrypted message is to
- *                              be written
- * \param[in] output_size       Size of the `p_output` buffer in bytes
- * \param[out] p_output_length  On success, the number of bytes
- *                              that make up the returned output
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_opaque_decrypt_t)(psa_key_slot_t key_slot,
-                                                            psa_algorithm_t alg,
-                                                            const uint8_t *p_input,
-                                                            size_t input_length,
-                                                            const uint8_t *p_salt,
-                                                            size_t salt_length,
-                                                            uint8_t *p_output,
-                                                            size_t output_size,
-                                                            size_t *p_output_length);
-
-/**
- * \brief A struct containing all of the function pointers needed to implement
- * asymmetric cryptographic operations using opaque keys.
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
-    /** Function that performs the asymmetric sign operation */
-    psa_drv_asymmetric_opaque_sign_t    *p_sign;
-    /** Function that performs the asymmetric verify operation */
-    psa_drv_asymmetric_opaque_verify_t  *p_verify;
-    /** Function that performs the asymmetric encrypt operation */
-    psa_drv_asymmetric_opaque_encrypt_t *p_encrypt;
-    /** Function that performs the asymmetric decrypt operation */
-    psa_drv_asymmetric_opaque_decrypt_t *p_decrypt;
-} psa_drv_asymmetric_opaque_t;
-
-/**@}*/
-
-/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography
- *
- * Since the amount of data that can (or should) be encrypted or signed using
- * asymmetric keys is limited by the key size, asymmetric key operations using
- * transparent keys must be done in single function calls.
- */
-/**@{*/
-
-
-/**
- * \brief A function that signs a hash or short message with a transparent
- * asymmetric private key
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_asymmetric_<ALGO>_sign
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the signing algorithm
- *
- * \param[in] p_key                 A buffer containing the private key
- *                                  material
- * \param[in] key_size              The size in bytes of the `p_key` data
- * \param[in] alg                   A signature algorithm that is compatible
- *                                  with the type of `p_key`
- * \param[in] p_hash                The hash or message to sign
- * \param[in] hash_length           Size of the `p_hash` buffer in bytes
- * \param[out] p_signature          Buffer where the signature is to be written
- * \param[in] signature_size        Size of the `p_signature` buffer in bytes
- * \param[out] p_signature_length   On success, the number of bytes
- *                                  that make up the returned signature value
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key,
-                                                              size_t key_size,
-                                                              psa_algorithm_t alg,
-                                                              const uint8_t *p_hash,
-                                                              size_t hash_length,
-                                                              uint8_t *p_signature,
-                                                              size_t signature_size,
-                                                              size_t *p_signature_length);
-
-/**
- * \brief A function that verifies the signature a hash or short message using
- * a transparent asymmetric public key
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_asymmetric_<ALGO>_verify
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the signing algorithm
- *
- * \param[in] p_key             A buffer containing the public key material
- * \param[in] key_size          The size in bytes of the `p_key` data
- * \param[in] alg               A signature algorithm that is compatible with
- *                              the type of `key`
- * \param[in] p_hash            The hash or message whose signature is to be
- *                              verified
- * \param[in] hash_length       Size of the `p_hash` buffer in bytes
- * \param[in] p_signature       Buffer containing the signature to verify
- * \param[in] signature_length  Size of the `p_signature` buffer in bytes
- *
- * \retval PSA_SUCCESS
- *         The signature is valid.
- */
-typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key,
-                                                                size_t key_size,
-                                                                psa_algorithm_t alg,
-                                                                const uint8_t *p_hash,
-                                                                size_t hash_length,
-                                                                const uint8_t *p_signature,
-                                                                size_t signature_length);
-
-/**
- * \brief A function that encrypts a short message with a transparent
- * asymmetric public key
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_asymmetric_<ALGO>_encrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the encryption algorithm
- *
- * \param[in] p_key             A buffer containing the public key material
- * \param[in] key_size          The size in bytes of the `p_key` data
- * \param[in] alg               An asymmetric encryption algorithm that is
- *                              compatible with the type of `key`
- * \param[in] p_input           The message to encrypt
- * \param[in] input_length      Size of the `p_input` buffer in bytes
- * \param[in] p_salt            A salt or label, if supported by the
- *                              encryption algorithm
- *                              If the algorithm does not support a
- *                              salt, pass `NULL`
- *                              If the algorithm supports an optional
- *                              salt and you do not want to pass a salt,
- *                              pass `NULL`.
- *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- *                              supported.
- * \param[in] salt_length       Size of the `p_salt` buffer in bytes
- *                              If `p_salt` is `NULL`, pass 0.
- * \param[out] p_output         Buffer where the encrypted message is to
- *                              be written
- * \param[in] output_size       Size of the `p_output` buffer in bytes
- * \param[out] p_output_length  On success, the number of bytes
- *                              that make up the returned output
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key,
-                                                                 size_t key_size,
-                                                                 psa_algorithm_t alg,
-                                                                 const uint8_t *p_input,
-                                                                 size_t input_length,
-                                                                 const uint8_t *p_salt,
-                                                                 size_t salt_length,
-                                                                 uint8_t *p_output,
-                                                                 size_t output_size,
-                                                                 size_t *p_output_length);
-
-/**
- * \brief Decrypt a short message with a transparent asymmetric private key
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_asymmetric_<ALGO>_decrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the encryption algorithm
- *
- * \param[in] p_key             A buffer containing the private key material
- * \param[in] key_size          The size in bytes of the `p_key` data
- * \param[in] alg               An asymmetric encryption algorithm that is
- *                              compatible with the type of `key`
- * \param[in] p_input           The message to decrypt
- * \param[in] input_length      Size of the `p_input` buffer in bytes
- * \param[in] p_salt            A salt or label, if supported by the
- *                              encryption algorithm
- *                              If the algorithm does not support a
- *                              salt, pass `NULL`.
- *                              If the algorithm supports an optional
- *                              salt and you do not want to pass a salt,
- *                              pass `NULL`.
- *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
- *                              supported
- * \param[in] salt_length       Size of the `p_salt` buffer in bytes
- *                              If `p_salt` is `NULL`, pass 0
- * \param[out] p_output         Buffer where the decrypted message is to
- *                              be written
- * \param[in] output_size       Size of the `p_output` buffer in bytes
- * \param[out] p_output_length  On success, the number of bytes
- *                              that make up the returned output
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key,
-                                                                 size_t key_size,
-                                                                 psa_algorithm_t alg,
-                                                                 const uint8_t *p_input,
-                                                                 size_t input_length,
-                                                                 const uint8_t *p_salt,
-                                                                 size_t salt_length,
-                                                                 uint8_t *p_output,
-                                                                 size_t output_size,
-                                                                 size_t *p_output_length);
-
-/**@}*/
-
-/** \defgroup aead_opaque AEAD Opaque
- * Authenticated Encryption with Additional Data (AEAD) operations with opaque
- * keys must be done in one function call. While this creates a burden for
- * implementers as there must be sufficient space in memory for the entire
- * message, it prevents decrypted data from being made available before the
- * authentication operation is complete and the data is known to be authentic.
- */
-/**@{*/
-
-/** \brief Process an authenticated encryption operation using an opaque key
- *
- * \param[in] key_slot                  Slot containing the key to use.
- * \param[in] algorithm                 The AEAD algorithm to compute
- *                                      (\c PSA_ALG_XXX value such that
- *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] p_nonce                   Nonce or IV to use
- * \param[in] nonce_length              Size of the `p_nonce` buffer in bytes
- * \param[in] p_additional_data         Additional data that will be
- *                                      authenticated but not encrypted
- * \param[in] additional_data_length    Size of `p_additional_data` in bytes
- * \param[in] p_plaintext               Data that will be authenticated and
- *                                      encrypted
- * \param[in] plaintext_length          Size of `p_plaintext` in bytes
- * \param[out] p_ciphertext             Output buffer for the authenticated and
- *                                      encrypted data. The additional data is
- *                                      not part of this output. For algorithms
- *                                      where the encrypted data and the
- *                                      authentication tag are defined as
- *                                      separate outputs, the authentication
- *                                      tag is appended to the encrypted data.
- * \param[in] ciphertext_size           Size of the `p_ciphertext` buffer in
- *                                      bytes
- * \param[out] p_ciphertext_length      On success, the size of the output in
- *                                      the `p_ciphertext` buffer
- *
- * \retval #PSA_SUCCESS
- *         Success.
- */
-typedef psa_status_t (*psa_drv_aead_opaque_encrypt_t)(psa_key_slot_t key_slot,
-                                                      psa_algorithm_t algorithm,
-                                                      const uint8_t *p_nonce,
-                                                      size_t nonce_length,
-                                                      const uint8_t *p_additional_data,
-                                                      size_t additional_data_length,
-                                                      const uint8_t *p_plaintext,
-                                                      size_t plaintext_length,
-                                                      uint8_t *p_ciphertext,
-                                                      size_t ciphertext_size,
-                                                      size_t *p_ciphertext_length);
-
-/** Process an authenticated decryption operation using an opaque key
- *
- * \param[in] key_slot                  Slot containing the key to use
- * \param[in] algorithm                 The AEAD algorithm to compute
- *                                      (\c PSA_ALG_XXX value such that
- *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] p_nonce                   Nonce or IV to use
- * \param[in] nonce_length              Size of the `p_nonce` buffer in bytes
- * \param[in] p_additional_data         Additional data that has been
- *                                      authenticated but not encrypted
- * \param[in] additional_data_length    Size of `p_additional_data` in bytes
- * \param[in] p_ciphertext              Data that has been authenticated and
- *                                      encrypted.
- *                                      For algorithms where the encrypted data
- *                                      and the authentication tag are defined
- *                                      as separate inputs, the buffer must
- *                                      contain the encrypted data followed by
- *                                      the authentication tag.
- * \param[in] ciphertext_length         Size of `p_ciphertext` in bytes
- * \param[out] p_plaintext              Output buffer for the decrypted data
- * \param[in] plaintext_size            Size of the `p_plaintext` buffer in
- *                                      bytes
- * \param[out] p_plaintext_length       On success, the size of the output in
- *                                      the `p_plaintext` buffer
- *
- * \retval #PSA_SUCCESS
- *         Success.
- */
-typedef psa_status_t (*psa_drv_aead_opaque_decrypt_t)(psa_key_slot_t key_slot,
-                                                      psa_algorithm_t algorithm,
-                                                      const uint8_t *p_nonce,
-                                                      size_t nonce_length,
-                                                      const uint8_t *p_additional_data,
-                                                      size_t additional_data_length,
-                                                      const uint8_t *p_ciphertext,
-                                                      size_t ciphertext_length,
-                                                      uint8_t *p_plaintext,
-                                                      size_t plaintext_size,
-                                                      size_t *p_plaintext_length);
-
-/**
- * \brief A struct containing all of the function pointers needed to implement
- * Authenticated Encryption with Additional Data operations using opaque keys
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
-    /** Function that performs the AEAD encrypt operation */
-    psa_drv_aead_opaque_encrypt_t *p_encrypt;
-    /** Function that performs the AEAD decrypt operation */
-    psa_drv_aead_opaque_decrypt_t *p_decrypt;
-} psa_drv_aead_opaque_t;
-/**@}*/
-
-/** \defgroup aead_transparent AEAD Transparent
- *
- * Authenticated Encryption with Additional Data (AEAD) operations with
- * transparent keys must be done in one function call. While this creates a
- * burden for implementers as there must be sufficient space in memory for the
- * entire message, it prevents decrypted data from being made available before
- * the authentication operation is complete and the data is known to be
- * authentic.
- */
-/**@{*/
-
-/** Process an authenticated encryption operation using an opaque key.
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_aead_<ALGO>_encrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the AEAD algorithm
- *
- * \param[in] p_key                     A pointer to the key material
- * \param[in] key_length                The size in bytes of the key material
- * \param[in] alg                       The AEAD algorithm to compute
- *                                      (\c PSA_ALG_XXX value such that
- *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] nonce                     Nonce or IV to use
- * \param[in] nonce_length              Size of the `nonce` buffer in bytes
- * \param[in] additional_data           Additional data that will be MACed
- *                                      but not encrypted.
- * \param[in] additional_data_length    Size of `additional_data` in bytes
- * \param[in] plaintext                 Data that will be MACed and
- *                                      encrypted.
- * \param[in] plaintext_length          Size of `plaintext` in bytes
- * \param[out] ciphertext               Output buffer for the authenticated and
- *                                      encrypted data. The additional data is
- *                                      not part of this output. For algorithms
- *                                      where the encrypted data and the
- *                                      authentication tag are defined as
- *                                      separate outputs, the authentication
- *                                      tag is appended to the encrypted data.
- * \param[in] ciphertext_size           Size of the `ciphertext` buffer in
- *                                      bytes
- *                                      This must be at least
- *                                      #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`,
- *                                      `plaintext_length`).
- * \param[out] ciphertext_length        On success, the size of the output in
- *                                      the `ciphertext` buffer
- *
- * \retval #PSA_SUCCESS
-
- */
-typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key,
-                                                           size_t key_length,
-                                                           psa_algorithm_t alg,
-                                                           const uint8_t *nonce,
-                                                           size_t nonce_length,
-                                                           const uint8_t *additional_data,
-                                                           size_t additional_data_length,
-                                                           const uint8_t *plaintext,
-                                                           size_t plaintext_length,
-                                                           uint8_t *ciphertext,
-                                                           size_t ciphertext_size,
-                                                           size_t *ciphertext_length);
-
-/** Process an authenticated decryption operation using an opaque key.
- *
- * Functions that implement the prototype should be named in the following
- * convention:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_aead_<ALGO>_decrypt
- * ~~~~~~~~~~~~~
- * Where `ALGO` is the name of the AEAD algorithm
- * \param[in] p_key                     A pointer to the key material
- * \param[in] key_length                The size in bytes of the key material
- * \param[in] alg                       The AEAD algorithm to compute
- *                                      (\c PSA_ALG_XXX value such that
- *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
- * \param[in] nonce                     Nonce or IV to use
- * \param[in] nonce_length              Size of the `nonce` buffer in bytes
- * \param[in] additional_data           Additional data that has been MACed
- *                                      but not encrypted
- * \param[in] additional_data_length    Size of `additional_data` in bytes
- * \param[in] ciphertext                Data that has been MACed and
- *                                      encrypted
- *                                      For algorithms where the encrypted data
- *                                      and the authentication tag are defined
- *                                      as separate inputs, the buffer must
- *                                      contain the encrypted data followed by
- *                                      the authentication tag.
- * \param[in] ciphertext_length         Size of `ciphertext` in bytes
- * \param[out] plaintext                Output buffer for the decrypted data
- * \param[in] plaintext_size            Size of the `plaintext` buffer in
- *                                      bytes
- *                                      This must be at least
- *                                      #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`,
- *                                      `ciphertext_length`).
- * \param[out] plaintext_length         On success, the size of the output
- *                                      in the \b plaintext buffer
- *
- * \retval #PSA_SUCCESS
- *         Success.
- */
-typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key,
-                                                           size_t key_length,
-                                                           psa_algorithm_t alg,
-                                                           const uint8_t *nonce,
-                                                           size_t nonce_length,
-                                                           const uint8_t *additional_data,
-                                                           size_t additional_data_length,
-                                                           const uint8_t *ciphertext,
-                                                           size_t ciphertext_length,
-                                                           uint8_t *plaintext,
-                                                           size_t plaintext_size,
-                                                           size_t *plaintext_length);
-
-/**@}*/
-
-
-/** \defgroup driver_rng Entropy Generation
- */
-/**@{*/
-
-/** \brief A hardware-specific structure for a entropy providing hardware
- */
-typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t;
-
-/** \brief Initialize an entropy driver
- *
- *
- * \param[in,out] p_context             A hardware-specific structure
- *                                      containing any context information for
- *                                      the implementation
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context);
-
-/** \brief Get a specified number of bits from the entropy source
- *
- * It retrives `buffer_size` bytes of data from the entropy source. The entropy
- * source will always fill the provided buffer to its full size, however, most
- * entropy sources have biases, and the actual amount of entropy contained in
- * the buffer will be less than the number of bytes.
- * The driver will return the actual number of bytes of entropy placed in the
- * buffer in `p_received_entropy_bytes`.
- * A PSA Crypto API implementation will likely feed the output of this function
- * into a Digital Random Bit Generator (DRBG), and typically has a minimum
- * amount of entropy that it needs.
- * To accomplish this, the PSA Crypto implementation should be designed to call
- * this function multiple times until it has received the required amount of
- * entropy from the entropy source.
- *
- * \param[in,out] p_context                 A hardware-specific structure
- *                                          containing any context information
- *                                          for the implementation
- * \param[out] p_buffer                     A caller-allocated buffer for the
- *                                          retrieved entropy to be placed in
- * \param[in] buffer_size                   The allocated size of `p_buffer`
- * \param[out] p_received_entropy_bits      The amount of entropy (in bits)
- *                                          actually provided in `p_buffer`
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context,
-                                                   uint8_t *p_buffer,
-                                                   uint32_t buffer_size,
-                                                   uint32_t *p_received_entropy_bits);
-
-/**
- * \brief A struct containing all of the function pointers needed to interface
- * to an entropy source
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
-    /** Function that performs initialization for the entropy source */
-    psa_drv_entropy_init_t *p_init;
-    /** Function that performs the get_bits operation for the entropy source
-    */
-    psa_drv_entropy_get_bits_t *p_get_bits;
-} psa_drv_entropy_t;
-/**@}*/
-
-/** \defgroup driver_key_management Key Management
- * Currently, key management is limited to importing keys in the clear,
- * destroying keys, and exporting keys in the clear.
- * Whether a key may be exported is determined by the key policies in place
- * on the key slot.
- */
-/**@{*/
-
-/** \brief Import a key in binary format
- *
- * This function can support any output from psa_export_key(). Refer to the
- * documentation of psa_export_key() for the format for each key type.
- *
- * \param[in] key_slot      Slot where the key will be stored
- *                          This must be a valid slot for a key of the chosen
- *                          type. It must be unoccupied.
- * \param[in] type          Key type (a \c PSA_KEY_TYPE_XXX value)
- * \param[in] algorithm     Key algorithm (a \c PSA_ALG_XXX value)
- * \param[in] usage         The allowed uses of the key
- * \param[in] p_data        Buffer containing the key data
- * \param[in] data_length   Size of the `data` buffer in bytes
- *
- * \retval #PSA_SUCCESS
- *         Success.
- */
-typedef psa_status_t (*psa_drv_opaque_import_key_t)(psa_key_slot_t key_slot,
-                                                    psa_key_type_t type,
-                                                    psa_algorithm_t algorithm,
-                                                    psa_key_usage_t usage,
-                                                    const uint8_t *p_data,
-                                                    size_t data_length);
-
-/**
- * \brief Destroy a key and restore the slot to its default state
- *
- * This function destroys the content of the key slot from both volatile
- * memory and, if applicable, non-volatile storage. Implementations shall
- * make a best effort to ensure that any previous content of the slot is
- * unrecoverable.
- *
- * This function also erases any metadata such as policies. It returns the
- * specified slot to its default state.
- *
- * \param[in] key_slot        The key slot to erase.
- *
- * \retval #PSA_SUCCESS
- *         The slot's content, if any, has been erased.
- */
-typedef psa_status_t (*psa_drv_destroy_key_t)(psa_key_slot_t key);
-
-/**
- * \brief Export a key in binary format
- *
- * The output of this function can be passed to psa_import_key() to
- * create an equivalent object.
- *
- * If a key is created with `psa_import_key()` and then exported with
- * this function, it is not guaranteed that the resulting data is
- * identical: the implementation may choose a different representation
- * of the same key if the format permits it.
- *
- * For standard key types, the output format is as follows:
- *
- * - For symmetric keys (including MAC keys), the format is the
- *   raw bytes of the key.
- * - For DES, the key data consists of 8 bytes. The parity bits must be
- *   correct.
- * - For Triple-DES, the format is the concatenation of the
- *   two or three DES keys.
- * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
- *   is the non-encrypted DER representation defined by PKCS\#1 (RFC 8017)
- *   as RSAPrivateKey.
- * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the format
- *   is the DER representation defined by RFC 5280 as SubjectPublicKeyInfo.
- *
- * \param[in] key               Slot whose content is to be exported. This must
- *                              be an occupied key slot.
- * \param[out] p_data           Buffer where the key data is to be written.
- * \param[in] data_size         Size of the `p_data` buffer in bytes.
- * \param[out] p_data_length    On success, the number of bytes
- *                              that make up the key data.
- *
- * \retval #PSA_SUCCESS
- * \retval #PSA_ERROR_EMPTY_SLOT
- * \retval #PSA_ERROR_NOT_PERMITTED
- * \retval #PSA_ERROR_NOT_SUPPORTED
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_TAMPERING_DETECTED
- */
-typedef psa_status_t (*psa_drv_export_key_t)(psa_key_slot_t key,
-                                             uint8_t *p_data,
-                                             size_t data_size,
-                                             size_t *p_data_length);
-
-/**
- * \brief Export a public key or the public part of a key pair in binary format
- *
- * The output of this function can be passed to psa_import_key() to
- * create an object that is equivalent to the public key.
- *
- * For standard key types, the output format is as follows:
- *
- * - For RSA keys (#PSA_KEY_TYPE_RSA_KEYPAIR or #PSA_KEY_TYPE_RSA_PUBLIC_KEY),
- *   the format is the DER representation of the public key defined by RFC 5280
- *   as SubjectPublicKeyInfo.
- *
- * \param[in] key_slot          Slot whose content is to be exported. This must
- *                              be an occupied key slot.
- * \param[out] p_data           Buffer where the key data is to be written.
- * \param[in] data_size         Size of the `data` buffer in bytes.
- * \param[out] p_data_length    On success, the number of bytes
- *                              that make up the key data.
- *
- * \retval #PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_export_public_key_t)(psa_key_slot_t key,
-                                                    uint8_t *p_data,
-                                                    size_t data_size,
-                                                    size_t *p_data_length);
-
-/**
- * \brief A struct containing all of the function pointers needed to for key
- * management using opaque keys
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
-    /** Function that performs the key import operation */
-    psa_drv_opaque_import_key_t *p_import;
-    /** Function that performs the key destroy operation */
-    psa_drv_destroy_key_t       *p_destroy;
-    /** Function that performs the key export operation */
-    psa_drv_export_key_t        *p_export;
-    /** Function that perforsm the public key export operation */
-    psa_drv_export_public_key_t *p_export_public;
-} psa_drv_key_management_t;
-
-/**@}*/
-
-/** \defgroup driver_derivation Key Derivation and Agreement
- * Key derivation is the process of generating new key material using an
- * existing key and additional parameters, iterating through a basic
- * cryptographic function, such as a hash.
- * Key agreement is a part of cryptographic protocols that allows two parties
- * to agree on the same key value, but starting from different original key
- * material.
- * The flows are similar, and the PSA Crypto Driver Model uses the same functions
- * for both of the flows.
- *
- * There are two different final functions for the flows,
- * `psa_drv_key_derivation_derive` and `psa_drv_key_derivation_export`.
- * `psa_drv_key_derivation_derive` is used when the key material should be placed
- * in a slot on the hardware and not exposed to the caller.
- * `psa_drv_key_derivation_export` is used when the key material should be returned
- * to the PSA Cryptographic API implementation.
- *
- * Different key derivation algorithms require a different number of inputs.
- * Instead of having an API that takes as input variable length arrays, which
- * can be problemmatic to manage on embedded platforms, the inputs are passed
- * to the driver via a function, `psa_drv_key_derivation_collateral`, that is
- * called multiple times with different `collateral_id`s. Thus, for a key
- * derivation algorithm that required 3 paramter inputs, the flow would look
- * something like:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_key_derivation_setup(kdf_algorithm, source_key, dest_key_size_bytes);
- * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_0,
- *                                   p_collateral_0,
- *                                   collateral_0_size);
- * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_1,
- *                                   p_collateral_1,
- *                                   collateral_1_size);
- * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_2,
- *                                   p_collateral_2,
- *                                   collateral_2_size);
- * psa_drv_key_derivation_derive();
- * ~~~~~~~~~~~~~
- *
- * key agreement example:
- * ~~~~~~~~~~~~~{.c}
- * psa_drv_key_derivation_setup(alg, source_key. dest_key_size_bytes);
- * psa_drv_key_derivation_collateral(DHE_PUBKEY, p_pubkey, pubkey_size);
- * psa_drv_key_derivation_export(p_session_key,
- *                               session_key_size,
- *                               &session_key_length);
- * ~~~~~~~~~~~~~
- */
-/**@{*/
-
-/** \brief The hardware-specific key derivation context structure
- *
- * The contents of this structure are implementation dependent and are
- * therefore not described here
- */
-typedef struct psa_drv_key_derivation_context_s psa_drv_key_derivation_context_t;
-
-/** \brief Set up a key derivation operation by specifying the algorithm and
- * the source key sot
- *
- * \param[in,out] p_context A hardware-specific structure containing any
- *                          context information for the implementation
- * \param[in] kdf_alg       The algorithm to be used for the key derivation
- * \param[in] souce_key     The key to be used as the source material for the
- *                          key derivation
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_key_derivation_setup_t)(psa_drv_key_derivation_context_t *p_context,
-                                                       psa_algorithm_t kdf_alg,
-                                                       psa_key_slot_t source_key);
-
-/** \brief Provide collateral (parameters) needed for a key derivation or key
- * agreement operation
- *
- * Since many key derivation algorithms require multiple parameters, it is
- * expeced that this function may be called multiple times for the same
- * operation, each with a different algorithm-specific `collateral_id`
- *
- * \param[in,out] p_context     A hardware-specific structure containing any
- *                              context information for the implementation
- * \param[in] collateral_id     An ID for the collateral being provided
- * \param[in] p_collateral      A buffer containing the collateral data
- * \param[in] collateral_size   The size in bytes of the collateral
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_key_derivation_collateral_t)(psa_drv_key_derivation_context_t *p_context,
-                                                            uint32_t collateral_id,
-                                                            const uint8_t *p_collateral,
-                                                            size_t collateral_size);
-
-/** \brief Perform the final key derivation step and place the generated key
- * material in a slot
- * \param[in,out] p_context     A hardware-specific structure containing any
- *                              context information for the implementation
- * \param[in] dest_key          The slot where the generated key material
- *                              should be placed
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_key_derivation_derive_t)(psa_drv_key_derivation_context_t *p_context,
-                                                        psa_key_slot_t dest_key);
-
-/** \brief Perform the final step of a key agreement and place the generated
- * key material in a buffer
- *
- * \param[out] p_output         Buffer in which to place the generated key
- *                              material
- * \param[in] output_size       The size in bytes of `p_output`
- * \param[out] p_output_length  Upon success, contains the number of bytes of
- *                              key material placed in `p_output`
- *
- * \retval PSA_SUCCESS
- */
-typedef psa_status_t (*psa_drv_key_derivation_export_t)(uint8_t *p_output,
-                                                        size_t output_size,
-                                                        size_t *p_output_length);
-
-/**
- * \brief A struct containing all of the function pointers needed to for key
- * derivation and agreement
- *
- * PSA Crypto API implementations should populate instances of the table as
- * appropriate upon startup.
- *
- * If one of the functions is not implemented, it should be set to NULL.
- */
-typedef struct {
-    /** Function that performs the key derivation setup */
-    psa_drv_key_derivation_setup_t      *p_setup;
-    /** Function that sets the key derivation collateral */
-    psa_drv_key_derivation_collateral_t *p_collateral;
-    /** Function that performs the final key derivation step */
-    psa_drv_key_derivation_derive_t     *p_derive;
-    /** Function that perforsm the final key derivation or agreement and
-     * exports the key */
-    psa_drv_key_derivation_export_t     *p_export;
-} psa_drv_key_derivation_t;
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PSA_CRYPTO_DRIVER_H */
diff --git a/include/psa/crypto_driver_common.h b/include/psa/crypto_driver_common.h
new file mode 100644
index 0000000..6f1a5d5
--- /dev/null
+++ b/include/psa/crypto_driver_common.h
@@ -0,0 +1,54 @@
+/**
+ * \file psa/crypto_driver_common.h
+ * \brief Definitions for all PSA crypto drivers
+ *
+ * This file contains common definitions shared by all PSA crypto drivers.
+ * Do not include it directly: instead, include the header file(s) for
+ * the type(s) of driver that you are implementing. For example, if
+ * you are writing a driver for a chip that provides both a hardware
+ * random generator and an accelerator for some cryptographic algorithms,
+ * include `psa/crypto_entropy_driver.h` and `psa/crypto_accel_driver.h`.
+ *
+ * This file is part of the PSA Crypto Driver Model, containing functions for
+ * driver developers to implement to enable hardware to be called in a
+ * standardized way by a PSA Cryptographic API implementation. The functions
+ * comprising the driver model, which driver authors implement, are not
+ * intended to be called by application developers.
+ */
+
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef PSA_CRYPTO_DRIVER_COMMON_H
+#define PSA_CRYPTO_DRIVER_COMMON_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Include type definitions (psa_status_t, psa_algorithm_t,
+ * psa_key_type_t, etc.) and macros to build and analyze values
+ * of these types. */
+#include "crypto_types.h"
+#include "crypto_values.h"
+
+/** For encrypt-decrypt functions, whether the operation is an encryption
+ * or a decryption. */
+typedef enum {
+    PSA_CRYPTO_DRIVER_DECRYPT,
+    PSA_CRYPTO_DRIVER_ENCRYPT
+} psa_encrypt_or_decrypt_t;
+
+#endif /* PSA_CRYPTO_DRIVER_COMMON_H */
diff --git a/include/psa/crypto_entropy_driver.h b/include/psa/crypto_entropy_driver.h
new file mode 100644
index 0000000..f5e383e
--- /dev/null
+++ b/include/psa/crypto_entropy_driver.h
@@ -0,0 +1,111 @@
+/**
+ * \file psa/crypto_entropy_driver.h
+ * \brief PSA entropy source driver module
+ *
+ * This header declares types and function signatures for entropy sources.
+ *
+ * This file is part of the PSA Crypto Driver Model, containing functions for
+ * driver developers to implement to enable hardware to be called in a
+ * standardized way by a PSA Cryptographic API implementation. The functions
+ * comprising the driver model, which driver authors implement, are not
+ * intended to be called by application developers.
+ */
+
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef PSA_CRYPTO_ENTROPY_DRIVER_H
+#define PSA_CRYPTO_ENTROPY_DRIVER_H
+
+#include "crypto_driver_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup driver_rng Entropy Generation
+ */
+/**@{*/
+
+/** \brief A hardware-specific structure for a entropy providing hardware
+ */
+typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t;
+
+/** \brief Initialize an entropy driver
+ *
+ *
+ * \param[in,out] p_context             A hardware-specific structure
+ *                                      containing any context information for
+ *                                      the implementation
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context);
+
+/** \brief Get a specified number of bits from the entropy source
+ *
+ * It retrives `buffer_size` bytes of data from the entropy source. The entropy
+ * source will always fill the provided buffer to its full size, however, most
+ * entropy sources have biases, and the actual amount of entropy contained in
+ * the buffer will be less than the number of bytes.
+ * The driver will return the actual number of bytes of entropy placed in the
+ * buffer in `p_received_entropy_bytes`.
+ * A PSA Crypto API implementation will likely feed the output of this function
+ * into a Digital Random Bit Generator (DRBG), and typically has a minimum
+ * amount of entropy that it needs.
+ * To accomplish this, the PSA Crypto implementation should be designed to call
+ * this function multiple times until it has received the required amount of
+ * entropy from the entropy source.
+ *
+ * \param[in,out] p_context                 A hardware-specific structure
+ *                                          containing any context information
+ *                                          for the implementation
+ * \param[out] p_buffer                     A caller-allocated buffer for the
+ *                                          retrieved entropy to be placed in
+ * \param[in] buffer_size                   The allocated size of `p_buffer`
+ * \param[out] p_received_entropy_bits      The amount of entropy (in bits)
+ *                                          actually provided in `p_buffer`
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context,
+                                                   uint8_t *p_buffer,
+                                                   uint32_t buffer_size,
+                                                   uint32_t *p_received_entropy_bits);
+
+/**
+ * \brief A struct containing all of the function pointers needed to interface
+ * to an entropy source
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented, it should be set to NULL.
+ */
+typedef struct {
+    /** Function that performs initialization for the entropy source */
+    psa_drv_entropy_init_t *p_init;
+    /** Function that performs the get_bits operation for the entropy source
+    */
+    psa_drv_entropy_get_bits_t *p_get_bits;
+} psa_drv_entropy_t;
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_ENTROPY_DRIVER_H */
diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h
new file mode 100644
index 0000000..0578664
--- /dev/null
+++ b/include/psa/crypto_se_driver.h
@@ -0,0 +1,962 @@
+/**
+ * \file psa/crypto_se_driver.h
+ * \brief PSA external cryptoprocessor driver module
+ *
+ * This header declares types and function signatures for cryptography
+ * drivers that access key material via opaque references. This is
+ * meant for cryptoprocessors that have a separate key storage from the
+ * space in which the PSA Crypto implementation runs, typically secure
+ * elements.
+ *
+ * This file is part of the PSA Crypto Driver Model, containing functions for
+ * driver developers to implement to enable hardware to be called in a
+ * standardized way by a PSA Cryptographic API implementation. The functions
+ * comprising the driver model, which driver authors implement, are not
+ * intended to be called by application developers.
+ */
+
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef PSA_CRYPTO_SE_DRIVER_H
+#define PSA_CRYPTO_SE_DRIVER_H
+
+#include "crypto_driver_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** An internal designation of a key slot between the core part of the
+ * PSA Crypto implementation and the driver. The meaning of this value
+ * is driver-dependent. */
+typedef uint32_t psa_key_slot_t;
+
+/** \defgroup opaque_mac Opaque Message Authentication Code
+ * Generation and authentication of Message Authentication Codes (MACs) using
+ * opaque keys can be done either as a single function call (via the
+ * `psa_drv_mac_opaque_generate_t` or `psa_drv_mac_opaque_verify_t` functions), or in
+ * parts using the following sequence:
+ * - `psa_drv_mac_opaque_setup_t`
+ * - `psa_drv_mac_opaque_update_t`
+ * - `psa_drv_mac_opaque_update_t`
+ * - ...
+ * - `psa_drv_mac_opaque_finish_t` or `psa_drv_mac_opaque_finish_verify_t`
+ *
+ * If a previously started Opaque MAC operation needs to be terminated, it
+ * should be done so by the `psa_drv_mac_opaque_abort_t`. Failure to do so may
+ * result in allocated resources not being freed or in other undefined
+ * behavior.
+ */
+/**@{*/
+/** \brief A function that starts a MAC operation for a PSA Crypto Driver
+ * implementation using an opaque key
+ *
+ * \param[in,out] p_context     A structure that will contain the
+ *                              hardware-specific MAC context
+ * \param[in] key_slot          The slot of the key to be used for the
+ *                              operation
+ * \param[in] algorithm         The algorithm to be used to underly the MAC
+ *                              operation
+ *
+ * \retval  PSA_SUCCESS
+ *          Success.
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_setup_t)(void *p_context,
+                                                   psa_key_slot_t key_slot,
+                                                   psa_algorithm_t algorithm);
+
+/** \brief A function that continues a previously started MAC operation using
+ * an opaque key
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously-established MAC operation to be
+ *                              continued
+ * \param[in] p_input           A buffer containing the message to be appended
+ *                              to the MAC operation
+ * \param[in] input_length  The size in bytes of the input message buffer
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_update_t)(void *p_context,
+                                                    const uint8_t *p_input,
+                                                    size_t input_length);
+
+/** \brief a function that completes a previously started MAC operation by
+ * returning the resulting MAC using an opaque key
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started MAC operation to be
+ *                              finished
+ * \param[out] p_mac            A buffer where the generated MAC will be
+ *                              placed
+ * \param[in] mac_size          The size in bytes of the buffer that has been
+ *                              allocated for the `output` buffer
+ * \param[out] p_mac_length     After completion, will contain the number of
+ *                              bytes placed in the `p_mac` buffer
+ *
+ * \retval PSA_SUCCESS
+ *          Success.
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_finish_t)(void *p_context,
+                                                    uint8_t *p_mac,
+                                                    size_t mac_size,
+                                                    size_t *p_mac_length);
+
+/** \brief A function that completes a previously started MAC operation by
+ * comparing the resulting MAC against a known value using an opaque key
+ *
+ * \param[in,out] p_context A hardware-specific structure for the previously
+ *                          started MAC operation to be fiinished
+ * \param[in] p_mac         The MAC value against which the resulting MAC will
+ *                          be compared against
+ * \param[in] mac_length    The size in bytes of the value stored in `p_mac`
+ *
+ * \retval PSA_SUCCESS
+ *         The operation completed successfully and the MACs matched each
+ *         other
+ * \retval PSA_ERROR_INVALID_SIGNATURE
+ *         The operation completed successfully, but the calculated MAC did
+ *         not match the provided MAC
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_finish_verify_t)(void *p_context,
+                                                           const uint8_t *p_mac,
+                                                           size_t mac_length);
+
+/** \brief A function that aborts a previous started opaque-key MAC operation
+
+ * \param[in,out] p_context A hardware-specific structure for the previously
+ *                          started MAC operation to be aborted
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_abort_t)(void *p_context);
+
+/** \brief A function that performs a MAC operation in one command and returns
+ * the calculated MAC using an opaque key
+ *
+ * \param[in] p_input           A buffer containing the message to be MACed
+ * \param[in] input_length      The size in bytes of `p_input`
+ * \param[in] key_slot          The slot of the key to be used
+ * \param[in] alg               The algorithm to be used to underlie the MAC
+ *                              operation
+ * \param[out] p_mac            A buffer where the generated MAC will be
+ *                              placed
+ * \param[in] mac_size          The size in bytes of the `p_mac` buffer
+ * \param[out] p_mac_length     After completion, will contain the number of
+ *                              bytes placed in the `output` buffer
+ *
+ * \retval PSA_SUCCESS
+ *         Success.
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_generate_t)(const uint8_t *p_input,
+                                                      size_t input_length,
+                                                      psa_key_slot_t key_slot,
+                                                      psa_algorithm_t alg,
+                                                      uint8_t *p_mac,
+                                                      size_t mac_size,
+                                                      size_t *p_mac_length);
+
+/** \brief A function that performs an MAC operation in one command and
+ * compare the resulting MAC against a known value using an opaque key
+ *
+ * \param[in] p_input       A buffer containing the message to be MACed
+ * \param[in] input_length  The size in bytes of `input`
+ * \param[in] key_slot      The slot of the key to be used
+ * \param[in] alg           The algorithm to be used to underlie the MAC
+ *                          operation
+ * \param[in] p_mac         The MAC value against which the resulting MAC will
+ *                          be compared against
+ * \param[in] mac_length   The size in bytes of `mac`
+ *
+ * \retval PSA_SUCCESS
+ *         The operation completed successfully and the MACs matched each
+ *         other
+ * \retval PSA_ERROR_INVALID_SIGNATURE
+ *         The operation completed successfully, but the calculated MAC did
+ *         not match the provided MAC
+ */
+typedef psa_status_t (*psa_drv_mac_opaque_verify_t)(const uint8_t *p_input,
+                                                    size_t input_length,
+                                                    psa_key_slot_t key_slot,
+                                                    psa_algorithm_t alg,
+                                                    const uint8_t *p_mac,
+                                                    size_t mac_length);
+
+/** \brief A struct containing all of the function pointers needed to
+ * implement MAC operations using opaque keys.
+ *
+ * PSA Crypto API implementations should populate the table as appropriate
+ * upon startup.
+ *
+ * If one of the functions is not implemented (such as
+ * `psa_drv_mac_opaque_generate_t`), it should be set to NULL.
+ *
+ * Driver implementers should ensure that they implement all of the functions
+ * that make sense for their hardware, and that they provide a full solution
+ * (for example, if they support `p_setup`, they should also support
+ * `p_update` and at least one of `p_finish` or `p_finish_verify`).
+ *
+ */
+typedef struct {
+    /**The size in bytes of the hardware-specific Opaque-MAC Context structure
+    */
+    size_t                              context_size;
+    /** Function that performs the setup operation
+     */
+    psa_drv_mac_opaque_setup_t          *p_setup;
+    /** Function that performs the update operation
+     */
+    psa_drv_mac_opaque_update_t         *p_update;
+    /** Function that completes the operation
+     */
+    psa_drv_mac_opaque_finish_t         *p_finish;
+    /** Function that completed a MAC operation with a verify check
+     */
+    psa_drv_mac_opaque_finish_verify_t  *p_finish_verify;
+    /** Function that aborts a previoustly started operation
+     */
+    psa_drv_mac_opaque_abort_t          *p_abort;
+    /** Function that performs the MAC operation in one call
+     */
+    psa_drv_mac_opaque_generate_t       *p_mac;
+    /** Function that performs the MAC and verify operation in one call
+     */
+    psa_drv_mac_opaque_verify_t         *p_mac_verify;
+} psa_drv_mac_opaque_t;
+/**@}*/
+
+/** \defgroup opaque_cipher Opaque Symmetric Ciphers
+ *
+ * Encryption and Decryption using opaque keys in block modes other than ECB
+ * must be done in multiple parts, using the following flow:
+ * - `psa_drv_cipher_opaque_setup_t`
+ * - `psa_drv_cipher_opaque_set_iv_t` (optional depending upon block mode)
+ * - `psa_drv_cipher_opaque_update_t`
+ * - ...
+ * - `psa_drv_cipher_opaque_finish_t`
+
+ * If a previously started Opaque Cipher operation needs to be terminated, it
+ * should be done so by the `psa_drv_cipher_opaque_abort_t`. Failure to do so may
+ * result in allocated resources not being freed or in other undefined
+ * behavior.
+ *
+ * In situations where a PSA Cryptographic API implementation is using a block
+ * mode not-supported by the underlying hardware or driver, it can construct
+ * the block mode itself, while calling the `psa_drv_cipher_opaque_ecb_t` function
+ * pointer for the cipher operations.
+ */
+/**@{*/
+
+/** \brief A function pointer that provides the cipher setup function for
+ * opaque-key operations
+ *
+ * \param[in,out] p_context     A structure that will contain the
+ *                              hardware-specific cipher context.
+ * \param[in] key_slot          The slot of the key to be used for the
+ *                              operation
+ * \param[in] algorithm         The algorithm to be used in the cipher
+ *                              operation
+ * \param[in] direction         Indicates whether the operation is an encrypt
+ *                              or decrypt
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_setup_t)(void *p_context,
+                                                      psa_key_slot_t key_slot,
+                                                      psa_algorithm_t algorithm,
+                                                      psa_encrypt_or_decrypt_t direction);
+
+/** \brief A function pointer that sets the initialization vector (if
+ * necessary) for an opaque cipher operation
+ *
+ * Rationale: The `psa_cipher_*` function in the PSA Cryptographic API has two
+ * IV functions: one to set the IV, and one to generate it internally. The
+ * generate function is not necessary for the drivers to implement as the PSA
+ * Crypto implementation can do the generation using its RNG features.
+ *
+ * \param[in,out] p_context     A structure that contains the previously set up
+ *                              hardware-specific cipher context
+ * \param[in] p_iv              A buffer containing the initialization vector
+ * \param[in] iv_length         The size (in bytes) of the `p_iv` buffer
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_set_iv_t)(void *p_context,
+                                                       const uint8_t *p_iv,
+                                                       size_t iv_length);
+
+/** \brief A function that continues a previously started opaque-key cipher
+ * operation
+ *
+ * \param[in,out] p_context         A hardware-specific structure for the
+ *                                  previously started cipher operation
+ * \param[in] p_input               A buffer containing the data to be
+ *                                  encrypted/decrypted
+ * \param[in] input_size            The size in bytes of the buffer pointed to
+ *                                  by `p_input`
+ * \param[out] p_output             The caller-allocated buffer where the
+ *                                  output will be placed
+ * \param[in] output_size           The allocated size in bytes of the
+ *                                  `p_output` buffer
+ * \param[out] p_output_length      After completion, will contain the number
+ *                                  of bytes placed in the `p_output` buffer
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_update_t)(void *p_context,
+                                                       const uint8_t *p_input,
+                                                       size_t input_size,
+                                                       uint8_t *p_output,
+                                                       size_t output_size,
+                                                       size_t *p_output_length);
+
+/** \brief A function that completes a previously started opaque-key cipher
+ * operation
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started cipher operation
+ * \param[out] p_output         The caller-allocated buffer where the output
+ *                              will be placed
+ * \param[in] output_size       The allocated size in bytes of the `p_output`
+ *                              buffer
+ * \param[out] p_output_length  After completion, will contain the number of
+ *                              bytes placed in the `p_output` buffer
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_finish_t)(void *p_context,
+                                                       uint8_t *p_output,
+                                                       size_t output_size,
+                                                       size_t *p_output_length);
+
+/** \brief A function that aborts a previously started opaque-key cipher
+ * operation
+ *
+ * \param[in,out] p_context     A hardware-specific structure for the
+ *                              previously started cipher operation
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_abort_t)(void *p_context);
+
+/** \brief A function that performs the ECB block mode for opaque-key cipher
+ * operations
+ *
+ * Note: this function should only be used with implementations that do not
+ * provide a needed higher-level operation.
+ *
+ * \param[in] key_slot      The slot of the key to be used for the operation
+ * \param[in] algorithm     The algorithm to be used in the cipher operation
+ * \param[in] direction     Indicates whether the operation is an encrypt or
+ *                          decrypt
+ * \param[in] p_input       A buffer containing the data to be
+ *                          encrypted/decrypted
+ * \param[in] input_size    The size in bytes of the buffer pointed to by
+ *                          `p_input`
+ * \param[out] p_output     The caller-allocated buffer where the output will
+ *                          be placed
+ * \param[in] output_size   The allocated size in bytes of the `p_output`
+ *                          buffer
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ */
+typedef psa_status_t (*psa_drv_cipher_opaque_ecb_t)(psa_key_slot_t key_slot,
+                                                    psa_algorithm_t algorithm,
+                                                    psa_encrypt_or_decrypt_t direction,
+                                                    const uint8_t *p_input,
+                                                    size_t input_size,
+                                                    uint8_t *p_output,
+                                                    size_t output_size);
+
+/**
+ * \brief A struct containing all of the function pointers needed to implement
+ * cipher operations using opaque keys.
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented (such as
+ * `psa_drv_cipher_opaque_ecb_t`), it should be set to NULL.
+ */
+typedef struct {
+    /** The size in bytes of the hardware-specific Opaque Cipher context
+     * structure
+     */
+    size_t                         size;
+    /** Function that performs the setup operation */
+    psa_drv_cipher_opaque_setup_t  *p_setup;
+    /** Function that sets the IV (if necessary) */
+    psa_drv_cipher_opaque_set_iv_t *p_set_iv;
+    /** Function that performs the update operation */
+    psa_drv_cipher_opaque_update_t *p_update;
+    /** Function that completes the operation */
+    psa_drv_cipher_opaque_finish_t *p_finish;
+    /** Function that aborts the operation */
+    psa_drv_cipher_opaque_abort_t  *p_abort;
+    /** Function that performs ECB mode for the cipher
+     * (Danger: ECB mode should not be used directly by clients of the PSA
+     * Crypto Client API)
+     */
+    psa_drv_cipher_opaque_ecb_t    *p_ecb;
+} psa_drv_cipher_opaque_t;
+
+/**@}*/
+
+/** \defgroup opaque_asymmetric Opaque Asymmetric Cryptography
+ *
+ * Since the amount of data that can (or should) be encrypted or signed using
+ * asymmetric keys is limited by the key size, asymmetric key operations using
+ * opaque keys must be done in single function calls.
+ */
+/**@{*/
+
+/**
+ * \brief A function that signs a hash or short message with a private key
+ *
+ * \param[in] key_slot              Key slot of an asymmetric key pair
+ * \param[in] alg                   A signature algorithm that is compatible
+ *                                  with the type of `key`
+ * \param[in] p_hash                The hash to sign
+ * \param[in] hash_length           Size of the `p_hash` buffer in bytes
+ * \param[out] p_signature          Buffer where the signature is to be written
+ * \param[in] signature_size        Size of the `p_signature` buffer in bytes
+ * \param[out] p_signature_length   On success, the number of bytes
+ *                                  that make up the returned signature value
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_opaque_sign_t)(psa_key_slot_t key_slot,
+                                                         psa_algorithm_t alg,
+                                                         const uint8_t *p_hash,
+                                                         size_t hash_length,
+                                                         uint8_t *p_signature,
+                                                         size_t signature_size,
+                                                         size_t *p_signature_length);
+
+/**
+ * \brief A function that verifies the signature a hash or short message using
+ * an asymmetric public key
+ *
+ * \param[in] key_slot          Key slot of a public key or an asymmetric key
+ *                              pair
+ * \param[in] alg               A signature algorithm that is compatible with
+ *                              the type of `key`
+ * \param[in] p_hash            The hash whose signature is to be verified
+ * \param[in] hash_length       Size of the `p_hash` buffer in bytes
+ * \param[in] p_signature       Buffer containing the signature to verify
+ * \param[in] signature_length  Size of the `p_signature` buffer in bytes
+ *
+ * \retval PSA_SUCCESS
+ *         The signature is valid.
+ */
+typedef psa_status_t (*psa_drv_asymmetric_opaque_verify_t)(psa_key_slot_t key_slot,
+                                                           psa_algorithm_t alg,
+                                                           const uint8_t *p_hash,
+                                                           size_t hash_length,
+                                                           const uint8_t *p_signature,
+                                                           size_t signature_length);
+
+/**
+ * \brief A function that encrypts a short message with an asymmetric public
+ * key
+ *
+ * \param[in] key_slot          Key slot of a public key or an asymmetric key
+ *                              pair
+ * \param[in] alg               An asymmetric encryption algorithm that is
+ *                              compatible with the type of `key`
+ * \param[in] p_input           The message to encrypt
+ * \param[in] input_length      Size of the `p_input` buffer in bytes
+ * \param[in] p_salt            A salt or label, if supported by the
+ *                              encryption algorithm
+ *                              If the algorithm does not support a
+ *                              salt, pass `NULL`.
+ *                              If the algorithm supports an optional
+ *                              salt and you do not want to pass a salt,
+ *                              pass `NULL`.
+ *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ *                              supported.
+ * \param[in] salt_length       Size of the `p_salt` buffer in bytes
+ *                              If `p_salt` is `NULL`, pass 0.
+ * \param[out] p_output         Buffer where the encrypted message is to
+ *                              be written
+ * \param[in] output_size       Size of the `p_output` buffer in bytes
+ * \param[out] p_output_length  On success, the number of bytes that make up
+ *                              the returned output
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_opaque_encrypt_t)(psa_key_slot_t key_slot,
+                                                            psa_algorithm_t alg,
+                                                            const uint8_t *p_input,
+                                                            size_t input_length,
+                                                            const uint8_t *p_salt,
+                                                            size_t salt_length,
+                                                            uint8_t *p_output,
+                                                            size_t output_size,
+                                                            size_t *p_output_length);
+
+/**
+ * \brief Decrypt a short message with an asymmetric private key.
+ *
+ * \param[in] key_slot          Key slot of an asymmetric key pair
+ * \param[in] alg               An asymmetric encryption algorithm that is
+ *                              compatible with the type of `key`
+ * \param[in] p_input           The message to decrypt
+ * \param[in] input_length      Size of the `p_input` buffer in bytes
+ * \param[in] p_salt            A salt or label, if supported by the
+ *                              encryption algorithm
+ *                              If the algorithm does not support a
+ *                              salt, pass `NULL`.
+ *                              If the algorithm supports an optional
+ *                              salt and you do not want to pass a salt,
+ *                              pass `NULL`.
+ *                              For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is
+ *                              supported.
+ * \param[in] salt_length       Size of the `p_salt` buffer in bytes
+ *                              If `p_salt` is `NULL`, pass 0.
+ * \param[out] p_output         Buffer where the decrypted message is to
+ *                              be written
+ * \param[in] output_size       Size of the `p_output` buffer in bytes
+ * \param[out] p_output_length  On success, the number of bytes
+ *                              that make up the returned output
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_asymmetric_opaque_decrypt_t)(psa_key_slot_t key_slot,
+                                                            psa_algorithm_t alg,
+                                                            const uint8_t *p_input,
+                                                            size_t input_length,
+                                                            const uint8_t *p_salt,
+                                                            size_t salt_length,
+                                                            uint8_t *p_output,
+                                                            size_t output_size,
+                                                            size_t *p_output_length);
+
+/**
+ * \brief A struct containing all of the function pointers needed to implement
+ * asymmetric cryptographic operations using opaque keys.
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented, it should be set to NULL.
+ */
+typedef struct {
+    /** Function that performs the asymmetric sign operation */
+    psa_drv_asymmetric_opaque_sign_t    *p_sign;
+    /** Function that performs the asymmetric verify operation */
+    psa_drv_asymmetric_opaque_verify_t  *p_verify;
+    /** Function that performs the asymmetric encrypt operation */
+    psa_drv_asymmetric_opaque_encrypt_t *p_encrypt;
+    /** Function that performs the asymmetric decrypt operation */
+    psa_drv_asymmetric_opaque_decrypt_t *p_decrypt;
+} psa_drv_asymmetric_opaque_t;
+
+/**@}*/
+
+/** \defgroup aead_opaque AEAD Opaque
+ * Authenticated Encryption with Additional Data (AEAD) operations with opaque
+ * keys must be done in one function call. While this creates a burden for
+ * implementers as there must be sufficient space in memory for the entire
+ * message, it prevents decrypted data from being made available before the
+ * authentication operation is complete and the data is known to be authentic.
+ */
+/**@{*/
+
+/** \brief Process an authenticated encryption operation using an opaque key
+ *
+ * \param[in] key_slot                  Slot containing the key to use.
+ * \param[in] algorithm                 The AEAD algorithm to compute
+ *                                      (\c PSA_ALG_XXX value such that
+ *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
+ * \param[in] p_nonce                   Nonce or IV to use
+ * \param[in] nonce_length              Size of the `p_nonce` buffer in bytes
+ * \param[in] p_additional_data         Additional data that will be
+ *                                      authenticated but not encrypted
+ * \param[in] additional_data_length    Size of `p_additional_data` in bytes
+ * \param[in] p_plaintext               Data that will be authenticated and
+ *                                      encrypted
+ * \param[in] plaintext_length          Size of `p_plaintext` in bytes
+ * \param[out] p_ciphertext             Output buffer for the authenticated and
+ *                                      encrypted data. The additional data is
+ *                                      not part of this output. For algorithms
+ *                                      where the encrypted data and the
+ *                                      authentication tag are defined as
+ *                                      separate outputs, the authentication
+ *                                      tag is appended to the encrypted data.
+ * \param[in] ciphertext_size           Size of the `p_ciphertext` buffer in
+ *                                      bytes
+ * \param[out] p_ciphertext_length      On success, the size of the output in
+ *                                      the `p_ciphertext` buffer
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ */
+typedef psa_status_t (*psa_drv_aead_opaque_encrypt_t)(psa_key_slot_t key_slot,
+                                                      psa_algorithm_t algorithm,
+                                                      const uint8_t *p_nonce,
+                                                      size_t nonce_length,
+                                                      const uint8_t *p_additional_data,
+                                                      size_t additional_data_length,
+                                                      const uint8_t *p_plaintext,
+                                                      size_t plaintext_length,
+                                                      uint8_t *p_ciphertext,
+                                                      size_t ciphertext_size,
+                                                      size_t *p_ciphertext_length);
+
+/** Process an authenticated decryption operation using an opaque key
+ *
+ * \param[in] key_slot                  Slot containing the key to use
+ * \param[in] algorithm                 The AEAD algorithm to compute
+ *                                      (\c PSA_ALG_XXX value such that
+ *                                      #PSA_ALG_IS_AEAD(`alg`) is true)
+ * \param[in] p_nonce                   Nonce or IV to use
+ * \param[in] nonce_length              Size of the `p_nonce` buffer in bytes
+ * \param[in] p_additional_data         Additional data that has been
+ *                                      authenticated but not encrypted
+ * \param[in] additional_data_length    Size of `p_additional_data` in bytes
+ * \param[in] p_ciphertext              Data that has been authenticated and
+ *                                      encrypted.
+ *                                      For algorithms where the encrypted data
+ *                                      and the authentication tag are defined
+ *                                      as separate inputs, the buffer must
+ *                                      contain the encrypted data followed by
+ *                                      the authentication tag.
+ * \param[in] ciphertext_length         Size of `p_ciphertext` in bytes
+ * \param[out] p_plaintext              Output buffer for the decrypted data
+ * \param[in] plaintext_size            Size of the `p_plaintext` buffer in
+ *                                      bytes
+ * \param[out] p_plaintext_length       On success, the size of the output in
+ *                                      the `p_plaintext` buffer
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ */
+typedef psa_status_t (*psa_drv_aead_opaque_decrypt_t)(psa_key_slot_t key_slot,
+                                                      psa_algorithm_t algorithm,
+                                                      const uint8_t *p_nonce,
+                                                      size_t nonce_length,
+                                                      const uint8_t *p_additional_data,
+                                                      size_t additional_data_length,
+                                                      const uint8_t *p_ciphertext,
+                                                      size_t ciphertext_length,
+                                                      uint8_t *p_plaintext,
+                                                      size_t plaintext_size,
+                                                      size_t *p_plaintext_length);
+
+/**
+ * \brief A struct containing all of the function pointers needed to implement
+ * Authenticated Encryption with Additional Data operations using opaque keys
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented, it should be set to NULL.
+ */
+typedef struct {
+    /** Function that performs the AEAD encrypt operation */
+    psa_drv_aead_opaque_encrypt_t *p_encrypt;
+    /** Function that performs the AEAD decrypt operation */
+    psa_drv_aead_opaque_decrypt_t *p_decrypt;
+} psa_drv_aead_opaque_t;
+/**@}*/
+
+/** \defgroup driver_key_management Key Management
+ * Currently, key management is limited to importing keys in the clear,
+ * destroying keys, and exporting keys in the clear.
+ * Whether a key may be exported is determined by the key policies in place
+ * on the key slot.
+ */
+/**@{*/
+
+/** \brief Import a key in binary format
+ *
+ * This function can support any output from psa_export_key(). Refer to the
+ * documentation of psa_export_key() for the format for each key type.
+ *
+ * \param[in] key_slot      Slot where the key will be stored
+ *                          This must be a valid slot for a key of the chosen
+ *                          type. It must be unoccupied.
+ * \param[in] type          Key type (a \c PSA_KEY_TYPE_XXX value)
+ * \param[in] algorithm     Key algorithm (a \c PSA_ALG_XXX value)
+ * \param[in] usage         The allowed uses of the key
+ * \param[in] p_data        Buffer containing the key data
+ * \param[in] data_length   Size of the `data` buffer in bytes
+ *
+ * \retval #PSA_SUCCESS
+ *         Success.
+ */
+typedef psa_status_t (*psa_drv_opaque_import_key_t)(psa_key_slot_t key_slot,
+                                                    psa_key_type_t type,
+                                                    psa_algorithm_t algorithm,
+                                                    psa_key_usage_t usage,
+                                                    const uint8_t *p_data,
+                                                    size_t data_length);
+
+/**
+ * \brief Destroy a key and restore the slot to its default state
+ *
+ * This function destroys the content of the key slot from both volatile
+ * memory and, if applicable, non-volatile storage. Implementations shall
+ * make a best effort to ensure that any previous content of the slot is
+ * unrecoverable.
+ *
+ * This function also erases any metadata such as policies. It returns the
+ * specified slot to its default state.
+ *
+ * \param[in] key_slot        The key slot to erase.
+ *
+ * \retval #PSA_SUCCESS
+ *         The slot's content, if any, has been erased.
+ */
+typedef psa_status_t (*psa_drv_destroy_key_t)(psa_key_slot_t key);
+
+/**
+ * \brief Export a key in binary format
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an equivalent object.
+ *
+ * If a key is created with `psa_import_key()` and then exported with
+ * this function, it is not guaranteed that the resulting data is
+ * identical: the implementation may choose a different representation
+ * of the same key if the format permits it.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For symmetric keys (including MAC keys), the format is the
+ *   raw bytes of the key.
+ * - For DES, the key data consists of 8 bytes. The parity bits must be
+ *   correct.
+ * - For Triple-DES, the format is the concatenation of the
+ *   two or three DES keys.
+ * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEYPAIR), the format
+ *   is the non-encrypted DER representation defined by PKCS\#1 (RFC 8017)
+ *   as RSAPrivateKey.
+ * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the format
+ *   is the DER representation defined by RFC 5280 as SubjectPublicKeyInfo.
+ *
+ * \param[in] key               Slot whose content is to be exported. This must
+ *                              be an occupied key slot.
+ * \param[out] p_data           Buffer where the key data is to be written.
+ * \param[in] data_size         Size of the `p_data` buffer in bytes.
+ * \param[out] p_data_length    On success, the number of bytes
+ *                              that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_EMPTY_SLOT
+ * \retval #PSA_ERROR_NOT_PERMITTED
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_TAMPERING_DETECTED
+ */
+typedef psa_status_t (*psa_drv_export_key_t)(psa_key_slot_t key,
+                                             uint8_t *p_data,
+                                             size_t data_size,
+                                             size_t *p_data_length);
+
+/**
+ * \brief Export a public key or the public part of a key pair in binary format
+ *
+ * The output of this function can be passed to psa_import_key() to
+ * create an object that is equivalent to the public key.
+ *
+ * For standard key types, the output format is as follows:
+ *
+ * - For RSA keys (#PSA_KEY_TYPE_RSA_KEYPAIR or #PSA_KEY_TYPE_RSA_PUBLIC_KEY),
+ *   the format is the DER representation of the public key defined by RFC 5280
+ *   as SubjectPublicKeyInfo.
+ *
+ * \param[in] key_slot          Slot whose content is to be exported. This must
+ *                              be an occupied key slot.
+ * \param[out] p_data           Buffer where the key data is to be written.
+ * \param[in] data_size         Size of the `data` buffer in bytes.
+ * \param[out] p_data_length    On success, the number of bytes
+ *                              that make up the key data.
+ *
+ * \retval #PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_export_public_key_t)(psa_key_slot_t key,
+                                                    uint8_t *p_data,
+                                                    size_t data_size,
+                                                    size_t *p_data_length);
+
+/**
+ * \brief A struct containing all of the function pointers needed to for key
+ * management using opaque keys
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented, it should be set to NULL.
+ */
+typedef struct {
+    /** Function that performs the key import operation */
+    psa_drv_opaque_import_key_t *p_import;
+    /** Function that performs the key destroy operation */
+    psa_drv_destroy_key_t       *p_destroy;
+    /** Function that performs the key export operation */
+    psa_drv_export_key_t        *p_export;
+    /** Function that perforsm the public key export operation */
+    psa_drv_export_public_key_t *p_export_public;
+} psa_drv_key_management_t;
+
+/**@}*/
+
+/** \defgroup driver_derivation Key Derivation and Agreement
+ * Key derivation is the process of generating new key material using an
+ * existing key and additional parameters, iterating through a basic
+ * cryptographic function, such as a hash.
+ * Key agreement is a part of cryptographic protocols that allows two parties
+ * to agree on the same key value, but starting from different original key
+ * material.
+ * The flows are similar, and the PSA Crypto Driver Model uses the same functions
+ * for both of the flows.
+ *
+ * There are two different final functions for the flows,
+ * `psa_drv_key_derivation_derive` and `psa_drv_key_derivation_export`.
+ * `psa_drv_key_derivation_derive` is used when the key material should be placed
+ * in a slot on the hardware and not exposed to the caller.
+ * `psa_drv_key_derivation_export` is used when the key material should be returned
+ * to the PSA Cryptographic API implementation.
+ *
+ * Different key derivation algorithms require a different number of inputs.
+ * Instead of having an API that takes as input variable length arrays, which
+ * can be problemmatic to manage on embedded platforms, the inputs are passed
+ * to the driver via a function, `psa_drv_key_derivation_collateral`, that is
+ * called multiple times with different `collateral_id`s. Thus, for a key
+ * derivation algorithm that required 3 paramter inputs, the flow would look
+ * something like:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_key_derivation_setup(kdf_algorithm, source_key, dest_key_size_bytes);
+ * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_0,
+ *                                   p_collateral_0,
+ *                                   collateral_0_size);
+ * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_1,
+ *                                   p_collateral_1,
+ *                                   collateral_1_size);
+ * psa_drv_key_derivation_collateral(kdf_algorithm_collateral_id_2,
+ *                                   p_collateral_2,
+ *                                   collateral_2_size);
+ * psa_drv_key_derivation_derive();
+ * ~~~~~~~~~~~~~
+ *
+ * key agreement example:
+ * ~~~~~~~~~~~~~{.c}
+ * psa_drv_key_derivation_setup(alg, source_key. dest_key_size_bytes);
+ * psa_drv_key_derivation_collateral(DHE_PUBKEY, p_pubkey, pubkey_size);
+ * psa_drv_key_derivation_export(p_session_key,
+ *                               session_key_size,
+ *                               &session_key_length);
+ * ~~~~~~~~~~~~~
+ */
+/**@{*/
+
+/** \brief The hardware-specific key derivation context structure
+ *
+ * The contents of this structure are implementation dependent and are
+ * therefore not described here
+ */
+typedef struct psa_drv_key_derivation_context_s psa_drv_key_derivation_context_t;
+
+/** \brief Set up a key derivation operation by specifying the algorithm and
+ * the source key sot
+ *
+ * \param[in,out] p_context A hardware-specific structure containing any
+ *                          context information for the implementation
+ * \param[in] kdf_alg       The algorithm to be used for the key derivation
+ * \param[in] souce_key     The key to be used as the source material for the
+ *                          key derivation
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_key_derivation_setup_t)(psa_drv_key_derivation_context_t *p_context,
+                                                       psa_algorithm_t kdf_alg,
+                                                       psa_key_slot_t source_key);
+
+/** \brief Provide collateral (parameters) needed for a key derivation or key
+ * agreement operation
+ *
+ * Since many key derivation algorithms require multiple parameters, it is
+ * expeced that this function may be called multiple times for the same
+ * operation, each with a different algorithm-specific `collateral_id`
+ *
+ * \param[in,out] p_context     A hardware-specific structure containing any
+ *                              context information for the implementation
+ * \param[in] collateral_id     An ID for the collateral being provided
+ * \param[in] p_collateral      A buffer containing the collateral data
+ * \param[in] collateral_size   The size in bytes of the collateral
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_key_derivation_collateral_t)(psa_drv_key_derivation_context_t *p_context,
+                                                            uint32_t collateral_id,
+                                                            const uint8_t *p_collateral,
+                                                            size_t collateral_size);
+
+/** \brief Perform the final key derivation step and place the generated key
+ * material in a slot
+ * \param[in,out] p_context     A hardware-specific structure containing any
+ *                              context information for the implementation
+ * \param[in] dest_key          The slot where the generated key material
+ *                              should be placed
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_key_derivation_derive_t)(psa_drv_key_derivation_context_t *p_context,
+                                                        psa_key_slot_t dest_key);
+
+/** \brief Perform the final step of a key agreement and place the generated
+ * key material in a buffer
+ *
+ * \param[out] p_output         Buffer in which to place the generated key
+ *                              material
+ * \param[in] output_size       The size in bytes of `p_output`
+ * \param[out] p_output_length  Upon success, contains the number of bytes of
+ *                              key material placed in `p_output`
+ *
+ * \retval PSA_SUCCESS
+ */
+typedef psa_status_t (*psa_drv_key_derivation_export_t)(uint8_t *p_output,
+                                                        size_t output_size,
+                                                        size_t *p_output_length);
+
+/**
+ * \brief A struct containing all of the function pointers needed to for key
+ * derivation and agreement
+ *
+ * PSA Crypto API implementations should populate instances of the table as
+ * appropriate upon startup.
+ *
+ * If one of the functions is not implemented, it should be set to NULL.
+ */
+typedef struct {
+    /** Function that performs the key derivation setup */
+    psa_drv_key_derivation_setup_t      *p_setup;
+    /** Function that sets the key derivation collateral */
+    psa_drv_key_derivation_collateral_t *p_collateral;
+    /** Function that performs the final key derivation step */
+    psa_drv_key_derivation_derive_t     *p_derive;
+    /** Function that perforsm the final key derivation or agreement and
+     * exports the key */
+    psa_drv_key_derivation_export_t     *p_export;
+} psa_drv_key_derivation_t;
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_CRYPTO_SE_DRIVER_H */
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index 7e17956..5ad695a 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -50,6 +50,42 @@
 #include MBEDTLS_CONFIG_FILE
 #endif
 
+#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
+#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
+
+/** The size of the output of psa_hash_finish(), in bytes.
+ *
+ * This is also the hash size that psa_hash_verify() expects.
+ *
+ * \param alg   A hash algorithm (\c PSA_ALG_XXX value such that
+ *              #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm
+ *              (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a
+ *              hash algorithm).
+ *
+ * \return The hash size for the specified hash algorithm.
+ *         If the hash algorithm is not recognized, return 0.
+ *         An implementation may return either 0 or the correct size
+ *         for a hash algorithm that it recognizes, but does not support.
+ */
+#define PSA_HASH_SIZE(alg)                                      \
+    (                                                           \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 :            \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 :      \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 :          \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 :        \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 :    \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 :    \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 :       \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 :       \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 :       \
+        PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 :       \
+        0)
+
 /** \def PSA_HASH_MAX_SIZE
  *
  * Maximum size of a hash.
@@ -84,6 +120,26 @@
  */
 #define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE
 
+/** The tag size for an AEAD algorithm, in bytes.
+ *
+ * \param alg                 An AEAD algorithm
+ *                            (\c PSA_ALG_XXX value such that
+ *                            #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return                    The tag size for the specified algorithm.
+ *                            If the AEAD algorithm does not have an identified
+ *                            tag that can be distinguished from the rest of
+ *                            the ciphertext, return 0.
+ *                            If the AEAD algorithm is not recognized, return 0.
+ *                            An implementation may return either 0 or a
+ *                            correct size for an AEAD algorithm that it
+ *                            recognizes, but does not support.
+ */
+#define PSA_AEAD_TAG_LENGTH(alg)                                        \
+    (PSA_ALG_IS_AEAD(alg) ?                                             \
+     (((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \
+     0)
+
 /* The maximum size of an RSA key on this implementation, in bits.
  * This is a vendor-specific macro.
  *
@@ -236,6 +292,22 @@
      (plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) :              \
      0)
 
+#define PSA_RSA_MINIMUM_PADDING_SIZE(alg)                               \
+    (PSA_ALG_IS_RSA_OAEP(alg) ?                                         \
+     2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 :      \
+     11 /*PKCS#1v1.5*/)
+
+/**
+ * \brief ECDSA signature size for a given curve bit size
+ *
+ * \param curve_bits    Curve size in bits.
+ * \return              Signature size in bytes.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ */
+#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits)    \
+    (PSA_BITS_TO_BYTES(curve_bits) * 2)
+
 /** Safe signature buffer size for psa_asymmetric_sign().
  *
  * This macro returns a safe buffer size for a signature using a key
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
new file mode 100644
index 0000000..9b44d6a
--- /dev/null
+++ b/include/psa/crypto_types.h
@@ -0,0 +1,101 @@
+/**
+ * \file psa/crypto_types.h
+ *
+ * \brief PSA cryptography module: type aliases.
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h. Drivers must include the appropriate driver
+ * header file.
+ *
+ * This file contains portable definitions of integral types for properties
+ * of cryptographic keys, designations of cryptographic algorithms, and
+ * error codes returned by the library.
+ *
+ * This header file does not declare any function.
+ */
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_TYPES_H
+#define PSA_CRYPTO_TYPES_H
+
+#include <stdint.h>
+
+/** \defgroup error Error codes
+ * @{
+ */
+
+/**
+ * \brief Function return status.
+ *
+ * This is either #PSA_SUCCESS (which is zero), indicating success,
+ * or a nonzero value indicating that an error occurred. Errors are
+ * encoded as one of the \c PSA_ERROR_xxx values defined here.
+ */
+typedef int32_t psa_status_t;
+
+/**@}*/
+
+/** \defgroup crypto_types Key and algorithm types
+ * @{
+ */
+
+/** \brief Encoding of a key type.
+ */
+typedef uint32_t psa_key_type_t;
+
+/** The type of PSA elliptic curve identifiers. */
+typedef uint16_t psa_ecc_curve_t;
+
+/** \brief Encoding of a cryptographic algorithm.
+ *
+ * For algorithms that can be applied to multiple key types, this type
+ * does not encode the key type. For example, for symmetric ciphers
+ * based on a block cipher, #psa_algorithm_t encodes the block cipher
+ * mode and the padding mode while the block cipher itself is encoded
+ * via #psa_key_type_t.
+ */
+typedef uint32_t psa_algorithm_t;
+
+/**@}*/
+
+/** \defgroup key_lifetimes Key lifetimes
+ * @{
+ */
+
+/** Encoding of key lifetimes.
+ */
+typedef uint32_t psa_key_lifetime_t;
+
+/** Encoding of identifiers of persistent keys.
+ */
+typedef uint32_t psa_key_id_t;
+
+/**@}*/
+
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/** \brief Encoding of permitted usage on a key. */
+typedef uint32_t psa_key_usage_t;
+
+/**@}*/
+
+#endif /* PSA_CRYPTO_TYPES_H */
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
new file mode 100644
index 0000000..4d25835
--- /dev/null
+++ b/include/psa/crypto_values.h
@@ -0,0 +1,1420 @@
+/**
+ * \file psa/crypto_values.h
+ *
+ * \brief PSA cryptography module: macros to build and analyze integer values.
+ *
+ * \note This file may not be included directly. Applications must
+ * include psa/crypto.h. Drivers must include the appropriate driver
+ * header file.
+ *
+ * This file contains portable definitions of macros to build and analyze
+ * values of integral types that encode properties of cryptographic keys,
+ * designations of cryptographic algorithms, and error codes returned by
+ * the library.
+ *
+ * This header file only defines preprocessor macros.
+ */
+/*
+ *  Copyright (C) 2018, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License"); you may
+ *  not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#ifndef PSA_CRYPTO_VALUES_H
+#define PSA_CRYPTO_VALUES_H
+
+/** \defgroup error Error codes
+ * @{
+ */
+
+#if !defined(PSA_SUCCESS)
+/* If PSA_SUCCESS is defined, assume that PSA crypto is being used
+ * together with PSA IPC, which also defines the identifier
+ * PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case;
+ * the other error code names don't clash. This is a temporary hack
+ * until we unify error reporting in PSA IPC and PSA crypto.
+ *
+ * Note that psa_defs.h must be included before this header!
+ */
+/** The action was completed successfully. */
+#define PSA_SUCCESS ((psa_status_t)0)
+#endif /* !defined(PSA_SUCCESS) */
+
+/** An error occurred that does not correspond to any defined
+ * failure cause.
+ *
+ * Implementations may use this error code if none of the other standard
+ * error codes are applicable. */
+#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)1)
+
+/** The requested operation or a parameter is not supported
+ * by this implementation.
+ *
+ * Implementations should return this error code when an enumeration
+ * parameter such as a key type, algorithm, etc. is not recognized.
+ * If a combination of parameters is recognized and identified as
+ * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */
+#define PSA_ERROR_NOT_SUPPORTED         ((psa_status_t)2)
+
+/** The requested action is denied by a policy.
+ *
+ * Implementations should return this error code when the parameters
+ * are recognized as valid and supported, and a policy explicitly
+ * denies the requested operation.
+ *
+ * If a subset of the parameters of a function call identify a
+ * forbidden operation, and another subset of the parameters are
+ * not valid or not supported, it is unspecified whether the function
+ * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or
+ * #PSA_ERROR_INVALID_ARGUMENT. */
+#define PSA_ERROR_NOT_PERMITTED         ((psa_status_t)3)
+
+/** An output buffer is too small.
+ *
+ * Applications can call the \c PSA_xxx_SIZE macro listed in the function
+ * description to determine a sufficient buffer size.
+ *
+ * Implementations should preferably return this error code only
+ * in cases when performing the operation with a larger output
+ * buffer would succeed. However implementations may return this
+ * error if a function has invalid or unsupported parameters in addition
+ * to the parameters that determine the necessary output buffer size. */
+#define PSA_ERROR_BUFFER_TOO_SMALL      ((psa_status_t)4)
+
+/** A slot is occupied, but must be empty to carry out the
+ * requested action.
+ *
+ * If a handle is invalid, it does not designate an occupied slot.
+ * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
+ */
+#define PSA_ERROR_OCCUPIED_SLOT         ((psa_status_t)5)
+
+/** A slot is empty, but must be occupied to carry out the
+ * requested action.
+ *
+ * If a handle is invalid, it does not designate an empty slot.
+ * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE.
+ */
+#define PSA_ERROR_EMPTY_SLOT            ((psa_status_t)6)
+
+/** The requested action cannot be performed in the current state.
+ *
+ * Multipart operations return this error when one of the
+ * functions is called out of sequence. Refer to the function
+ * descriptions for permitted sequencing of functions.
+ *
+ * Implementations shall not return this error code to indicate
+ * that a key slot is occupied when it needs to be free or vice versa,
+ * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
+ * as applicable. */
+#define PSA_ERROR_BAD_STATE             ((psa_status_t)7)
+
+/** The parameters passed to the function are invalid.
+ *
+ * Implementations may return this error any time a parameter or
+ * combination of parameters are recognized as invalid.
+ *
+ * Implementations shall not return this error code to indicate
+ * that a key slot is occupied when it needs to be free or vice versa,
+ * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT
+ * as applicable.
+ *
+ * Implementation shall not return this error code to indicate that a
+ * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
+ * instead.
+ */
+#define PSA_ERROR_INVALID_ARGUMENT      ((psa_status_t)8)
+
+/** There is not enough runtime memory.
+ *
+ * If the action is carried out across multiple security realms, this
+ * error can refer to available memory in any of the security realms. */
+#define PSA_ERROR_INSUFFICIENT_MEMORY   ((psa_status_t)9)
+
+/** There is not enough persistent storage.
+ *
+ * Functions that modify the key storage return this error code if
+ * there is insufficient storage space on the host media. In addition,
+ * many functions that do not otherwise access storage may return this
+ * error code if the implementation requires a mandatory log entry for
+ * the requested action and the log storage space is full. */
+#define PSA_ERROR_INSUFFICIENT_STORAGE  ((psa_status_t)10)
+
+/** There was a communication failure inside the implementation.
+ *
+ * This can indicate a communication failure between the application
+ * and an external cryptoprocessor or between the cryptoprocessor and
+ * an external volatile or persistent memory. A communication failure
+ * may be transient or permanent depending on the cause.
+ *
+ * \warning If a function returns this error, it is undetermined
+ * whether the requested action has completed or not. Implementations
+ * should return #PSA_SUCCESS on successful completion whenver
+ * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE
+ * if the requested action was completed successfully in an external
+ * cryptoprocessor but there was a breakdown of communication before
+ * the cryptoprocessor could report the status to the application.
+ */
+#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11)
+
+/** There was a storage failure that may have led to data loss.
+ *
+ * This error indicates that some persistent storage is corrupted.
+ * It should not be used for a corruption of volatile memory
+ * (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
+ * between the cryptoprocessor and its external storage (use
+ * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
+ * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
+ *
+ * Note that a storage failure does not indicate that any data that was
+ * previously read is invalid. However this previously read data may no
+ * longer be readable from storage.
+ *
+ * When a storage failure occurs, it is no longer possible to ensure
+ * the global integrity of the keystore. Depending on the global
+ * integrity guarantees offered by the implementation, access to other
+ * data may or may not fail even if the data is still readable but
+ * its integrity canont be guaranteed.
+ *
+ * Implementations should only use this error code to report a
+ * permanent storage corruption. However application writers should
+ * keep in mind that transient errors while reading the storage may be
+ * reported using this error code. */
+#define PSA_ERROR_STORAGE_FAILURE       ((psa_status_t)12)
+
+/** A hardware failure was detected.
+ *
+ * A hardware failure may be transient or permanent depending on the
+ * cause. */
+#define PSA_ERROR_HARDWARE_FAILURE      ((psa_status_t)13)
+
+/** A tampering attempt was detected.
+ *
+ * If an application receives this error code, there is no guarantee
+ * that previously accessed or computed data was correct and remains
+ * confidential. Applications should not perform any security function
+ * and should enter a safe failure state.
+ *
+ * Implementations may return this error code if they detect an invalid
+ * state that cannot happen during normal operation and that indicates
+ * that the implementation's security guarantees no longer hold. Depending
+ * on the implementation architecture and on its security and safety goals,
+ * the implementation may forcibly terminate the application.
+ *
+ * This error code is intended as a last resort when a security breach
+ * is detected and it is unsure whether the keystore data is still
+ * protected. Implementations shall only return this error code
+ * to report an alarm from a tampering detector, to indicate that
+ * the confidentiality of stored data can no longer be guaranteed,
+ * or to indicate that the integrity of previously returned data is now
+ * considered compromised. Implementations shall not use this error code
+ * to indicate a hardware failure that merely makes it impossible to
+ * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE,
+ * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE,
+ * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code
+ * instead).
+ *
+ * This error indicates an attack against the application. Implementations
+ * shall not return this error code as a consequence of the behavior of
+ * the application itself. */
+#define PSA_ERROR_TAMPERING_DETECTED    ((psa_status_t)14)
+
+/** There is not enough entropy to generate random data needed
+ * for the requested action.
+ *
+ * This error indicates a failure of a hardware random generator.
+ * Application writers should note that this error can be returned not
+ * only by functions whose purpose is to generate random data, such
+ * as key, IV or nonce generation, but also by functions that execute
+ * an algorithm with a randomized result, as well as functions that
+ * use randomization of intermediate computations as a countermeasure
+ * to certain attacks.
+ *
+ * Implementations should avoid returning this error after psa_crypto_init()
+ * has succeeded. Implementations should generate sufficient
+ * entropy during initialization and subsequently use a cryptographically
+ * secure pseudorandom generator (PRNG). However implementations may return
+ * this error at any time if a policy requires the PRNG to be reseeded
+ * during normal operation. */
+#define PSA_ERROR_INSUFFICIENT_ENTROPY  ((psa_status_t)15)
+
+/** The signature, MAC or hash is incorrect.
+ *
+ * Verification functions return this error if the verification
+ * calculations completed successfully, and the value to be verified
+ * was determined to be incorrect.
+ *
+ * If the value to verify has an invalid size, implementations may return
+ * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */
+#define PSA_ERROR_INVALID_SIGNATURE     ((psa_status_t)16)
+
+/** The decrypted padding is incorrect.
+ *
+ * \warning In some protocols, when decrypting data, it is essential that
+ * the behavior of the application does not depend on whether the padding
+ * is correct, down to precise timing. Applications should prefer
+ * protocols that use authenticated encryption rather than plain
+ * encryption. If the application must perform a decryption of
+ * unauthenticated data, the application writer should take care not
+ * to reveal whether the padding is invalid.
+ *
+ * Implementations should strive to make valid and invalid padding
+ * as close as possible to indistinguishable to an external observer.
+ * In particular, the timing of a decryption operation should not
+ * depend on the validity of the padding. */
+#define PSA_ERROR_INVALID_PADDING       ((psa_status_t)17)
+
+/** The generator has insufficient capacity left.
+ *
+ * Once a function returns this error, attempts to read from the
+ * generator will always return this error. */
+#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18)
+
+/** The key handle is not valid.
+ */
+#define PSA_ERROR_INVALID_HANDLE        ((psa_status_t)19)
+
+/**@}*/
+
+/** \defgroup crypto_types Key and algorithm types
+ * @{
+ */
+
+/** An invalid key type value.
+ *
+ * Zero is not the encoding of any key type.
+ */
+#define PSA_KEY_TYPE_NONE                       ((psa_key_type_t)0x00000000)
+
+/** Vendor-defined flag
+ *
+ * Key types defined by this standard will never have the
+ * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types
+ * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should
+ * respect the bitwise structure used by standard encodings whenever practical.
+ */
+#define PSA_KEY_TYPE_VENDOR_FLAG                ((psa_key_type_t)0x80000000)
+
+#define PSA_KEY_TYPE_CATEGORY_MASK              ((psa_key_type_t)0x70000000)
+#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC         ((psa_key_type_t)0x40000000)
+#define PSA_KEY_TYPE_CATEGORY_RAW               ((psa_key_type_t)0x50000000)
+#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY        ((psa_key_type_t)0x60000000)
+#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR          ((psa_key_type_t)0x70000000)
+
+#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR         ((psa_key_type_t)0x10000000)
+
+/** Whether a key type is vendor-defined. */
+#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \
+    (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0)
+
+/** Whether a key type is an unstructured array of bytes.
+ *
+ * This encompasses both symmetric keys and non-key data.
+ */
+#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \
+    (((type) & PSA_KEY_TYPE_CATEGORY_MASK & ~(psa_key_type_t)0x10000000) == \
+     PSA_KEY_TYPE_CATEGORY_SYMMETRIC)
+
+/** Whether a key type is asymmetric: either a key pair or a public key. */
+#define PSA_KEY_TYPE_IS_ASYMMETRIC(type)                                \
+    (((type) & PSA_KEY_TYPE_CATEGORY_MASK                               \
+      & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) ==                            \
+     PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
+/** Whether a key type is the public part of a key pair. */
+#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type)                                \
+    (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
+/** Whether a key type is a key pair containing a private part and a public
+ * part. */
+#define PSA_KEY_TYPE_IS_KEYPAIR(type)                                   \
+    (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
+/** The key pair type corresponding to a public key type.
+ *
+ * You may also pass a key pair type as \p type, it will be left unchanged.
+ *
+ * \param type      A public key type or key pair type.
+ *
+ * \return          The corresponding key pair type.
+ *                  If \p type is not a public key or a key pair,
+ *                  the return value is undefined.
+ */
+#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type)        \
+    ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
+/** The public key type corresponding to a key pair type.
+ *
+ * You may also pass a key pair type as \p type, it will be left unchanged.
+ *
+ * \param type      A public key type or key pair type.
+ *
+ * \return          The corresponding public key type.
+ *                  If \p type is not a public key or a key pair,
+ *                  the return value is undefined.
+ */
+#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type)        \
+    ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
+
+/** Raw data.
+ *
+ * A "key" of this type cannot be used for any cryptographic operation.
+ * Applications may use this type to store arbitrary data in the keystore. */
+#define PSA_KEY_TYPE_RAW_DATA                   ((psa_key_type_t)0x50000001)
+
+/** HMAC key.
+ *
+ * The key policy determines which underlying hash algorithm the key can be
+ * used for.
+ *
+ * HMAC keys should generally have the same size as the underlying hash.
+ * This size can be calculated with #PSA_HASH_SIZE(\c alg) where
+ * \c alg is the HMAC algorithm or the underlying hash algorithm. */
+#define PSA_KEY_TYPE_HMAC                       ((psa_key_type_t)0x51000000)
+
+/** A secret for key derivation.
+ *
+ * The key policy determines which key derivation algorithm the key
+ * can be used for.
+ */
+#define PSA_KEY_TYPE_DERIVE                     ((psa_key_type_t)0x52000000)
+
+/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
+ *
+ * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
+ * 32 bytes (AES-256).
+ */
+#define PSA_KEY_TYPE_AES                        ((psa_key_type_t)0x40000001)
+
+/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES).
+ *
+ * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or
+ * 24 bytes (3-key 3DES).
+ *
+ * Note that single DES and 2-key 3DES are weak and strongly
+ * deprecated and should only be used to decrypt legacy data. 3-key 3DES
+ * is weak and deprecated and should only be used in legacy protocols.
+ */
+#define PSA_KEY_TYPE_DES                        ((psa_key_type_t)0x40000002)
+
+/** Key for an cipher, AEAD or MAC algorithm based on the
+ * Camellia block cipher. */
+#define PSA_KEY_TYPE_CAMELLIA                   ((psa_key_type_t)0x40000003)
+
+/** Key for the RC4 stream cipher.
+ *
+ * Note that RC4 is weak and deprecated and should only be used in
+ * legacy protocols. */
+#define PSA_KEY_TYPE_ARC4                       ((psa_key_type_t)0x40000004)
+
+/** RSA public key. */
+#define PSA_KEY_TYPE_RSA_PUBLIC_KEY             ((psa_key_type_t)0x60010000)
+/** RSA key pair (private and public key). */
+#define PSA_KEY_TYPE_RSA_KEYPAIR                ((psa_key_type_t)0x70010000)
+/** Whether a key type is an RSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_RSA(type)                                       \
+    (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
+
+/** DSA public key. */
+#define PSA_KEY_TYPE_DSA_PUBLIC_KEY             ((psa_key_type_t)0x60020000)
+/** DSA key pair (private and public key). */
+#define PSA_KEY_TYPE_DSA_KEYPAIR                ((psa_key_type_t)0x70020000)
+/** Whether a key type is an DSA key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_DSA(type)                                       \
+    (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
+
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE        ((psa_key_type_t)0x60030000)
+#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE           ((psa_key_type_t)0x70030000)
+#define PSA_KEY_TYPE_ECC_CURVE_MASK             ((psa_key_type_t)0x0000ffff)
+/** Elliptic curve key pair. */
+#define PSA_KEY_TYPE_ECC_KEYPAIR(curve)         \
+    (PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
+/** Elliptic curve public key. */
+#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)              \
+    (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
+
+/** Whether a key type is an elliptic curve key (pair or public-only). */
+#define PSA_KEY_TYPE_IS_ECC(type)                                       \
+    ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) &                        \
+      ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+/** Whether a key type is an elliptic curve key pair. */
+#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type)                               \
+    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
+     PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
+/** Whether a key type is an elliptic curve public key. */
+#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type)                            \
+    (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) ==                         \
+     PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
+
+/** Extract the curve from an elliptic curve key type. */
+#define PSA_KEY_TYPE_GET_CURVE(type)                             \
+    ((psa_ecc_curve_t) (PSA_KEY_TYPE_IS_ECC(type) ?              \
+                        ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \
+                        0))
+
+/* The encoding of curve identifiers is currently aligned with the
+ * TLS Supported Groups Registry (formerly known as the
+ * TLS EC Named Curve Registry)
+ * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
+ * The values are defined by RFC 8422 and RFC 7027. */
+#define PSA_ECC_CURVE_SECT163K1         ((psa_ecc_curve_t) 0x0001)
+#define PSA_ECC_CURVE_SECT163R1         ((psa_ecc_curve_t) 0x0002)
+#define PSA_ECC_CURVE_SECT163R2         ((psa_ecc_curve_t) 0x0003)
+#define PSA_ECC_CURVE_SECT193R1         ((psa_ecc_curve_t) 0x0004)
+#define PSA_ECC_CURVE_SECT193R2         ((psa_ecc_curve_t) 0x0005)
+#define PSA_ECC_CURVE_SECT233K1         ((psa_ecc_curve_t) 0x0006)
+#define PSA_ECC_CURVE_SECT233R1         ((psa_ecc_curve_t) 0x0007)
+#define PSA_ECC_CURVE_SECT239K1         ((psa_ecc_curve_t) 0x0008)
+#define PSA_ECC_CURVE_SECT283K1         ((psa_ecc_curve_t) 0x0009)
+#define PSA_ECC_CURVE_SECT283R1         ((psa_ecc_curve_t) 0x000a)
+#define PSA_ECC_CURVE_SECT409K1         ((psa_ecc_curve_t) 0x000b)
+#define PSA_ECC_CURVE_SECT409R1         ((psa_ecc_curve_t) 0x000c)
+#define PSA_ECC_CURVE_SECT571K1         ((psa_ecc_curve_t) 0x000d)
+#define PSA_ECC_CURVE_SECT571R1         ((psa_ecc_curve_t) 0x000e)
+#define PSA_ECC_CURVE_SECP160K1         ((psa_ecc_curve_t) 0x000f)
+#define PSA_ECC_CURVE_SECP160R1         ((psa_ecc_curve_t) 0x0010)
+#define PSA_ECC_CURVE_SECP160R2         ((psa_ecc_curve_t) 0x0011)
+#define PSA_ECC_CURVE_SECP192K1         ((psa_ecc_curve_t) 0x0012)
+#define PSA_ECC_CURVE_SECP192R1         ((psa_ecc_curve_t) 0x0013)
+#define PSA_ECC_CURVE_SECP224K1         ((psa_ecc_curve_t) 0x0014)
+#define PSA_ECC_CURVE_SECP224R1         ((psa_ecc_curve_t) 0x0015)
+#define PSA_ECC_CURVE_SECP256K1         ((psa_ecc_curve_t) 0x0016)
+#define PSA_ECC_CURVE_SECP256R1         ((psa_ecc_curve_t) 0x0017)
+#define PSA_ECC_CURVE_SECP384R1         ((psa_ecc_curve_t) 0x0018)
+#define PSA_ECC_CURVE_SECP521R1         ((psa_ecc_curve_t) 0x0019)
+#define PSA_ECC_CURVE_BRAINPOOL_P256R1  ((psa_ecc_curve_t) 0x001a)
+#define PSA_ECC_CURVE_BRAINPOOL_P384R1  ((psa_ecc_curve_t) 0x001b)
+#define PSA_ECC_CURVE_BRAINPOOL_P512R1  ((psa_ecc_curve_t) 0x001c)
+#define PSA_ECC_CURVE_CURVE25519        ((psa_ecc_curve_t) 0x001d)
+#define PSA_ECC_CURVE_CURVE448          ((psa_ecc_curve_t) 0x001e)
+
+/** The block size of a block cipher.
+ *
+ * \param type  A cipher key type (value of type #psa_key_type_t).
+ *
+ * \return      The block size for a block cipher, or 1 for a stream cipher.
+ *              The return value is undefined if \p type is not a supported
+ *              cipher key type.
+ *
+ * \note It is possible to build stream cipher algorithms on top of a block
+ *       cipher, for example CTR mode (#PSA_ALG_CTR).
+ *       This macro only takes the key type into account, so it cannot be
+ *       used to determine the size of the data that #psa_cipher_update()
+ *       might buffer for future processing in general.
+ *
+ * \note This macro returns a compile-time constant if its argument is one.
+ *
+ * \warning This macro may evaluate its argument multiple times.
+ */
+#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type)            \
+    (                                                \
+        (type) == PSA_KEY_TYPE_AES ? 16 :            \
+        (type) == PSA_KEY_TYPE_DES ? 8 :             \
+        (type) == PSA_KEY_TYPE_CAMELLIA ? 16 :       \
+        (type) == PSA_KEY_TYPE_ARC4 ? 1 :            \
+        0)
+
+#define PSA_ALG_VENDOR_FLAG                     ((psa_algorithm_t)0x80000000)
+#define PSA_ALG_CATEGORY_MASK                   ((psa_algorithm_t)0x7f000000)
+#define PSA_ALG_CATEGORY_HASH                   ((psa_algorithm_t)0x01000000)
+#define PSA_ALG_CATEGORY_MAC                    ((psa_algorithm_t)0x02000000)
+#define PSA_ALG_CATEGORY_CIPHER                 ((psa_algorithm_t)0x04000000)
+#define PSA_ALG_CATEGORY_AEAD                   ((psa_algorithm_t)0x06000000)
+#define PSA_ALG_CATEGORY_SIGN                   ((psa_algorithm_t)0x10000000)
+#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION  ((psa_algorithm_t)0x12000000)
+#define PSA_ALG_CATEGORY_KEY_AGREEMENT          ((psa_algorithm_t)0x22000000)
+#define PSA_ALG_CATEGORY_KEY_DERIVATION         ((psa_algorithm_t)0x30000000)
+#define PSA_ALG_CATEGORY_KEY_SELECTION          ((psa_algorithm_t)0x31000000)
+
+#define PSA_ALG_IS_VENDOR_DEFINED(alg)                                  \
+    (((alg) & PSA_ALG_VENDOR_FLAG) != 0)
+
+/** Whether the specified algorithm is a hash algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a hash algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_HASH(alg)                                            \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH)
+
+/** Whether the specified algorithm is a MAC algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_MAC(alg)                                             \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC)
+
+/** Whether the specified algorithm is a symmetric cipher algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_CIPHER(alg)                                          \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER)
+
+/** Whether the specified algorithm is an authenticated encryption
+ * with associated data (AEAD) algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an AEAD algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_AEAD(alg)                                            \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD)
+
+/** Whether the specified algorithm is a public-key signature algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a public-key signature algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_SIGN(alg)                                            \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN)
+
+/** Whether the specified algorithm is a public-key encryption algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a public-key encryption algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg)                           \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
+
+#define PSA_ALG_KEY_SELECTION_FLAG              ((psa_algorithm_t)0x01000000)
+/** Whether the specified algorithm is a key agreement algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key agreement algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_AGREEMENT(alg)                                   \
+    (((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) ==   \
+     PSA_ALG_CATEGORY_KEY_AGREEMENT)
+
+/** Whether the specified algorithm is a key derivation algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key derivation algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_DERIVATION(alg)                                  \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+/** Whether the specified algorithm is a key selection algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a key selection algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_KEY_SELECTION(alg)                                   \
+    (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION)
+
+#define PSA_ALG_HASH_MASK                       ((psa_algorithm_t)0x000000ff)
+#define PSA_ALG_MD2                             ((psa_algorithm_t)0x01000001)
+#define PSA_ALG_MD4                             ((psa_algorithm_t)0x01000002)
+#define PSA_ALG_MD5                             ((psa_algorithm_t)0x01000003)
+#define PSA_ALG_RIPEMD160                       ((psa_algorithm_t)0x01000004)
+#define PSA_ALG_SHA_1                           ((psa_algorithm_t)0x01000005)
+/** SHA2-224 */
+#define PSA_ALG_SHA_224                         ((psa_algorithm_t)0x01000008)
+/** SHA2-256 */
+#define PSA_ALG_SHA_256                         ((psa_algorithm_t)0x01000009)
+/** SHA2-384 */
+#define PSA_ALG_SHA_384                         ((psa_algorithm_t)0x0100000a)
+/** SHA2-512 */
+#define PSA_ALG_SHA_512                         ((psa_algorithm_t)0x0100000b)
+/** SHA2-512/224 */
+#define PSA_ALG_SHA_512_224                     ((psa_algorithm_t)0x0100000c)
+/** SHA2-512/256 */
+#define PSA_ALG_SHA_512_256                     ((psa_algorithm_t)0x0100000d)
+/** SHA3-224 */
+#define PSA_ALG_SHA3_224                        ((psa_algorithm_t)0x01000010)
+/** SHA3-256 */
+#define PSA_ALG_SHA3_256                        ((psa_algorithm_t)0x01000011)
+/** SHA3-384 */
+#define PSA_ALG_SHA3_384                        ((psa_algorithm_t)0x01000012)
+/** SHA3-512 */
+#define PSA_ALG_SHA3_512                        ((psa_algorithm_t)0x01000013)
+
+#define PSA_ALG_MAC_SUBCATEGORY_MASK            ((psa_algorithm_t)0x00c00000)
+#define PSA_ALG_HMAC_BASE                       ((psa_algorithm_t)0x02800000)
+/** Macro to build an HMAC algorithm.
+ *
+ * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding HMAC algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_HMAC(hash_alg)                                  \
+    (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_HMAC_GET_HASH(hmac_alg)                             \
+    (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is an HMAC algorithm.
+ *
+ * HMAC is a family of MAC algorithms that are based on a hash function.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is an HMAC algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_HMAC(alg)                                            \
+    (((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)
+#define PSA_ALG_GMAC                            ((psa_algorithm_t)0x02c00003)
+
+/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier.
+ */
+#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg)                                \
+    (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \
+     PSA_ALG_CIPHER_MAC_BASE)
+
+#define PSA_ALG_CIPHER_STREAM_FLAG              ((psa_algorithm_t)0x00800000)
+#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG          ((psa_algorithm_t)0x00400000)
+
+/** Whether the specified algorithm is a stream cipher.
+ *
+ * A stream cipher is a symmetric cipher that encrypts or decrypts messages
+ * by applying a bitwise-xor with a stream of bytes that is generated
+ * from a key.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \p alg is not a supported
+ *         algorithm identifier or if it is not a symmetric cipher algorithm.
+ */
+#define PSA_ALG_IS_STREAM_CIPHER(alg)            \
+    (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \
+        (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG))
+
+/** The ARC4 stream cipher algorithm.
+ */
+#define PSA_ALG_ARC4                            ((psa_algorithm_t)0x04800001)
+
+/** The CTR stream cipher mode.
+ *
+ * CTR is a stream cipher which is built from a block cipher.
+ * The underlying block cipher is determined by the key type.
+ * For example, to use AES-128-CTR, use this algorithm with
+ * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes).
+ */
+#define PSA_ALG_CTR                             ((psa_algorithm_t)0x04c00001)
+
+#define PSA_ALG_CFB                             ((psa_algorithm_t)0x04c00002)
+
+#define PSA_ALG_OFB                             ((psa_algorithm_t)0x04c00003)
+
+/** The XTS cipher mode.
+ *
+ * XTS is a cipher mode which is built from a block cipher. It requires at
+ * least one full block of input, but beyond this minimum the input
+ * does not need to be a whole number of blocks.
+ */
+#define PSA_ALG_XTS                             ((psa_algorithm_t)0x044000ff)
+
+/** The CBC block cipher chaining mode, with no padding.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This symmetric cipher mode can only be used with messages whose lengths
+ * are whole number of blocks for the chosen block cipher.
+ */
+#define PSA_ALG_CBC_NO_PADDING                  ((psa_algorithm_t)0x04600100)
+
+/** The CBC block cipher chaining mode with PKCS#7 padding.
+ *
+ * The underlying block cipher is determined by the key type.
+ *
+ * This is the padding method defined by PKCS#7 (RFC 2315) &sect;10.3.
+ */
+#define PSA_ALG_CBC_PKCS7                       ((psa_algorithm_t)0x04600101)
+
+#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.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PKCS1-v1_5.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding RSA PKCS#1 v1.5 signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)                             \
+    (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Raw PKCS#1 v1.5 signature.
+ *
+ * The input to this algorithm is the DigestInfo structure used by
+ * RFC 8017 (PKCS#1: RSA Cryptography Specifications), &sect;9.2
+ * steps 3&ndash;6.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
+#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)                               \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
+
+#define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x10030000)
+/** RSA PSS signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PSS, with the message generation function MGF1, and with
+ * a salt length equal to the length of the hash. The specified
+ * hash algorithm is used to hash the input message, to create the
+ * salted hash, and for the mask generation.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding RSA PSS signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS(hash_alg)                               \
+    (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_PSS(alg)                                 \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
+
+#define PSA_ALG_DSA_BASE                        ((psa_algorithm_t)0x10040000)
+/** DSA signature with hashing.
+ *
+ * This is the signature scheme defined by FIPS 186-4,
+ * with a random per-message secret number (*k*).
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding DSA signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_DSA(hash_alg)                             \
+    (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_DETERMINISTIC_DSA_BASE          ((psa_algorithm_t)0x10050000)
+#define PSA_ALG_DSA_DETERMINISTIC_FLAG          ((psa_algorithm_t)0x00010000)
+#define PSA_ALG_DETERMINISTIC_DSA(hash_alg)                             \
+    (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_DSA(alg)                                             \
+    (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) ==  \
+     PSA_ALG_DSA_BASE)
+#define PSA_ALG_DSA_IS_DETERMINISTIC(alg)               \
+    (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_DSA(alg)                       \
+    (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_DSA(alg)                          \
+    (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
+
+#define PSA_ALG_ECDSA_BASE                      ((psa_algorithm_t)0x10060000)
+/** ECDSA signature with hashing.
+ *
+ * This is the ECDSA signature scheme defined by ANSI X9.62,
+ * with a random per-message secret number (*k*).
+ *
+ * The representation of the signature as a byte string consists of
+ * the concatentation of the signature values *r* and *s*. Each of
+ * *r* and *s* is encoded as an *N*-octet string, where *N* is the length
+ * of the base point of the curve in octets. Each value is represented
+ * in big-endian order (most significant octet first).
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding ECDSA signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_ECDSA(hash_alg)                                 \
+    (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** ECDSA signature without hashing.
+ *
+ * This is the same signature scheme as #PSA_ALG_ECDSA(), but
+ * without specifying a hash algorithm. This algorithm may only be
+ * used to sign or verify a sequence of bytes that should be an
+ * already-calculated hash. Note that the input is padded with
+ * zeros on the left or truncated on the left as required to fit
+ * the curve size.
+ */
+#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE
+#define PSA_ALG_DETERMINISTIC_ECDSA_BASE        ((psa_algorithm_t)0x10070000)
+/** Deterministic ECDSA signature with hashing.
+ *
+ * This is the deterministic ECDSA signature scheme defined by RFC 6979.
+ *
+ * The representation of a signature is the same as with #PSA_ALG_ECDSA().
+ *
+ * Note that when this algorithm is used for verification, signatures
+ * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the
+ * same private key are accepted. In other words,
+ * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from
+ * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding deterministic ECDSA signature
+ *                      algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg)                           \
+    (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_ECDSA(alg)                                           \
+    (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) ==  \
+     PSA_ALG_ECDSA_BASE)
+#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)             \
+    (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
+#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)                             \
+    (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg)                                \
+    (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg))
+
+/** Get the hash used by a hash-and-sign signature algorithm.
+ *
+ * A hash-and-sign algorithm is a signature algorithm which is
+ * composed of two phases: first a hashing phase which does not use
+ * the key and produces a hash of the input message, then a signing
+ * phase which only uses the hash and the key and not the message
+ * itself.
+ *
+ * \param alg   A signature algorithm (\c PSA_ALG_XXX value such that
+ *              #PSA_ALG_IS_SIGN(\p alg) is true).
+ *
+ * \return      The underlying hash algorithm if \p alg is a hash-and-sign
+ *              algorithm.
+ * \return      0 if \p alg is a signature algorithm that does not
+ *              follow the hash-and-sign structure.
+ * \return      Unspecified if \p alg is not a signature algorithm or
+ *              if it is not supported by the implementation.
+ */
+#define PSA_ALG_SIGN_GET_HASH(alg)                                     \
+    (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||   \
+     PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ?                    \
+     ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 :        \
+     ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :             \
+     0)
+
+/** RSA PKCS#1 v1.5 encryption.
+ */
+#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x12020000)
+
+#define PSA_ALG_RSA_OAEP_BASE                   ((psa_algorithm_t)0x12030000)
+/** RSA OAEP encryption.
+ *
+ * This is the encryption scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSAES-OAEP, with the message generation function MGF1.
+ *
+ * \param hash_alg      The hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true) to use
+ *                      for MGF1.
+ *
+ * \return              The corresponding RSA OAEP signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_RSA_OAEP(hash_alg)                              \
+    (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_OAEP(alg)                                \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
+#define PSA_ALG_RSA_OAEP_GET_HASH(alg)                          \
+    (PSA_ALG_IS_RSA_OAEP(alg) ?                                 \
+     ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH :      \
+     0)
+
+#define PSA_ALG_HKDF_BASE                       ((psa_algorithm_t)0x30000100)
+/** Macro to build an HKDF algorithm.
+ *
+ * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding HKDF algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_HKDF(hash_alg)                                  \
+    (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Whether the specified algorithm is an HKDF algorithm.
+ *
+ * HKDF is a family of key derivation algorithms that are based on a hash
+ * function and the HMAC construction.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an HKDF algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_HKDF(alg)                            \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE)
+#define PSA_ALG_HKDF_GET_HASH(hkdf_alg)                         \
+    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_TLS12_PRF_BASE                     ((psa_algorithm_t)0x30000200)
+/** Macro to build a TLS-1.2 PRF algorithm.
+ *
+ * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
+ * specified in Section 5 of RFC 5246. It is based on HMAC and can be
+ * used with either SHA-256 or SHA-384.
+ *
+ * For the application to TLS-1.2, the salt and label arguments passed
+ * to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246,
+ * respectively. For example, for TLS key expansion, the salt is the
+ * concatenation of ServerHello.Random + ClientHello.Random,
+ * while the label is "key expansion".
+ *
+ * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
+ * TLS 1.2 PRF using HMAC-SHA-256.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding TLS-1.2 PRF algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_TLS12_PRF(hash_alg)                                  \
+    (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a TLS-1.2 PRF algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_TLS12_PRF(alg)                                    \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE)
+#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg)                         \
+    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300)
+/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
+ *
+ * In a pure-PSK handshake in TLS 1.2, the master secret is derived
+ * from the PreSharedKey (PSK) through the application of padding
+ * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5).
+ * The latter is based on HMAC and can be used with either SHA-256
+ * or SHA-384.
+ *
+ * For the application to TLS-1.2, the salt passed to psa_key_derivation()
+ * (and forwarded to the TLS-1.2 PRF) is the concatenation of the
+ * ClientHello.Random + ServerHello.Random, while the label is "master secret"
+ * or "extended master secret".
+ *
+ * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
+ * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(\p hash_alg) is true).
+ *
+ * \return              The corresponding TLS-1.2 PSK to MS algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg)                                  \
+    (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+
+/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key derivation algorithm identifier.
+ */
+#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg)                                    \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE)
+#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg)                         \
+    (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
+
+#define PSA_ALG_KEY_DERIVATION_MASK             ((psa_algorithm_t)0x010fffff)
+
+/** Use a shared secret as is.
+ *
+ * Specify this algorithm as the selection component of a key agreement
+ * to use the raw result of the key agreement as key material.
+ *
+ * \warning The raw result of a key agreement algorithm such as finite-field
+ * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
+ * not be used directly as key material. It can however be used as the secret
+ * input in a key derivation algorithm.
+ */
+#define PSA_ALG_SELECT_RAW                      ((psa_algorithm_t)0x31000001)
+
+#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg)                              \
+    (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
+
+#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg)                              \
+    ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK)
+
+#define PSA_ALG_FFDH_BASE                       ((psa_algorithm_t)0x22100000)
+/** The Diffie-Hellman key agreement algorithm.
+ *
+ * This algorithm combines the finite-field Diffie-Hellman (DH) key
+ * agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement,
+ * to produce a shared secret from a private key and the peer's
+ * public key, with a key selection or key derivation algorithm to produce
+ * one or more shared keys and other shared cryptographic material.
+ *
+ * The shared secret produced by key agreement and passed as input to the
+ * derivation or selection algorithm \p kdf_alg is the shared secret
+ * `g^{ab}` in big-endian format.
+ * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
+ * in bits.
+ *
+ * \param kdf_alg       A key derivation algorithm (\c PSA_ALG_XXX value such
+ *                      that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
+ *                      or a key selection algorithm (\c PSA_ALG_XXX value such
+ *                      that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
+ *
+ * \return              The Diffie-Hellman algorithm with the specified
+ *                      selection or derivation algorithm.
+ */
+#define PSA_ALG_FFDH(kdf_alg) \
+    (PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
+/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
+ *
+ * This includes every supported key selection or key agreement algorithm
+ * for the output of the Diffie-Hellman calculation.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key agreement algorithm identifier.
+ */
+#define PSA_ALG_IS_FFDH(alg) \
+    (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE)
+
+#define PSA_ALG_ECDH_BASE                       ((psa_algorithm_t)0x22200000)
+/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
+ *
+ * This algorithm combines the elliptic curve Diffie-Hellman key
+ * agreement to produce a shared secret from a private key and the peer's
+ * public key, with a key selection or key derivation algorithm to produce
+ * one or more shared keys and other shared cryptographic material.
+ *
+ * The shared secret produced by key agreement and passed as input to the
+ * derivation or selection algorithm \p kdf_alg is the x-coordinate of
+ * the shared secret point. It is always `ceiling(m / 8)` bytes long where
+ * `m` is the bit size associated with the curve, i.e. the bit size of the
+ * order of the curve's coordinate field. When `m` is not a multiple of 8,
+ * the byte containing the most significant bit of the shared secret
+ * is padded with zero bits. The byte order is either little-endian
+ * or big-endian depending on the curve type.
+ *
+ * - For Montgomery curves (curve types `PSA_ECC_CURVE_CURVEXXX`),
+ *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ *   in little-endian byte order.
+ *   The bit size is 448 for Curve448 and 255 for Curve25519.
+ * - For Weierstrass curves over prime fields (curve types
+ *   `PSA_ECC_CURVE_SECPXXX` and `PSA_ECC_CURVE_BRAINPOOL_PXXX`),
+ *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ *   in big-endian byte order.
+ *   The bit size is `m = ceiling(log_2(p))` for the field `F_p`.
+ * - For Weierstrass curves over binary fields (curve types
+ *   `PSA_ECC_CURVE_SECTXXX`),
+ *   the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
+ *   in big-endian byte order.
+ *   The bit size is `m` for the field `F_{2^m}`.
+ *
+ * \param kdf_alg       A key derivation algorithm (\c PSA_ALG_XXX value such
+ *                      that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
+ *                      or a selection algorithm (\c PSA_ALG_XXX value such
+ *                      that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
+ *
+ * \return              The Diffie-Hellman algorithm with the specified
+ *                      selection or derivation algorithm.
+ */
+#define PSA_ALG_ECDH(kdf_alg) \
+    (PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
+/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
+ * algorithm.
+ *
+ * This includes every supported key selection or key agreement algorithm
+ * for the output of the Diffie-Hellman calculation.
+ *
+ * \param alg An algorithm identifier (value of type #psa_algorithm_t).
+ *
+ * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm,
+ *         0 otherwise.
+ *         This macro may return either 0 or 1 if \c alg is not a supported
+ *         key agreement algorithm identifier.
+ */
+#define PSA_ALG_IS_ECDH(alg) \
+    (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE)
+
+/**@}*/
+
+/** \defgroup key_lifetimes Key lifetimes
+ * @{
+ */
+
+/** A volatile key only exists as long as the handle to it is not closed.
+ * The key material is guaranteed to be erased on a power reset.
+ */
+#define PSA_KEY_LIFETIME_VOLATILE               ((psa_key_lifetime_t)0x00000000)
+
+/** The default storage area for persistent keys.
+ *
+ * A persistent key remains in storage until it is explicitly destroyed or
+ * until the corresponding storage area is wiped. This specification does
+ * not define any mechanism to wipe a storage area, but implementations may
+ * provide their own mechanism (for example to perform a factory reset,
+ * to prepare for device refurbishment, or to uninstall an application).
+ *
+ * This lifetime value is the default storage area for the calling
+ * application. Implementations may offer other storage areas designated
+ * by other lifetime values as implementation-specific extensions.
+ */
+#define PSA_KEY_LIFETIME_PERSISTENT             ((psa_key_lifetime_t)0x00000001)
+
+/**@}*/
+
+/** \defgroup policy Key policies
+ * @{
+ */
+
+/** Whether the key may be exported.
+ *
+ * A public key or the public part of a key pair may always be exported
+ * regardless of the value of this permission flag.
+ *
+ * If a key does not have export permission, implementations shall not
+ * allow the key to be exported in plain form from the cryptoprocessor,
+ * whether through psa_export_key() or through a proprietary interface.
+ * The key may however be exportable in a wrapped form, i.e. in a form
+ * where it is encrypted by another key.
+ */
+#define PSA_KEY_USAGE_EXPORT                    ((psa_key_usage_t)0x00000001)
+
+/** Whether the key may be used to encrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric encryption operation,
+ * for an AEAD encryption-and-authentication operation,
+ * or for an asymmetric encryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_ENCRYPT                   ((psa_key_usage_t)0x00000100)
+
+/** Whether the key may be used to decrypt a message.
+ *
+ * This flag allows the key to be used for a symmetric decryption operation,
+ * for an AEAD decryption-and-verification operation,
+ * or for an asymmetric decryption operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_DECRYPT                   ((psa_key_usage_t)0x00000200)
+
+/** Whether the key may be used to sign a message.
+ *
+ * This flag allows the key to be used for a MAC calculation operation
+ * or for an asymmetric signature operation,
+ * if otherwise permitted by the key's type and policy.
+ *
+ * For a key pair, this concerns the private key.
+ */
+#define PSA_KEY_USAGE_SIGN                      ((psa_key_usage_t)0x00000400)
+
+/** Whether the key may be used to verify a message signature.
+ *
+ * This flag allows the key to be used for a MAC verification operation
+ * or for an asymmetric signature verification operation,
+ * if otherwise permitted by by the key's type and policy.
+ *
+ * For a key pair, this concerns the public key.
+ */
+#define PSA_KEY_USAGE_VERIFY                    ((psa_key_usage_t)0x00000800)
+
+/** Whether the key may be used to derive other keys.
+ */
+#define PSA_KEY_USAGE_DERIVE                    ((psa_key_usage_t)0x00001000)
+
+/**@}*/
+
+#endif /* PSA_CRYPTO_VALUES_H */
diff --git a/programs/Makefile b/programs/Makefile
index f3627c9..2792b09 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -103,7 +103,7 @@
 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
+psa/psa_constant_names_generated.c: ../scripts/generate_psa_constants.py ../include/psa/crypto_values.h
 	../scripts/generate_psa_constants.py
 
 aes/aescrypt2$(EXEXT): aes/aescrypt2.c $(DEP)
diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py
index 7e4420b..3e4e88b 100755
--- a/scripts/generate_psa_constants.py
+++ b/scripts/generate_psa_constants.py
@@ -285,5 +285,5 @@
 if __name__ == '__main__':
     if not os.path.isdir('programs') and os.path.isdir('../programs'):
         os.chdir('..')
-    generate_psa_constants('include/psa/crypto.h',
+    generate_psa_constants('include/psa/crypto_values.h',
                            'programs/psa/psa_constant_names_generated.c')
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index cbe3fa0..5f9f7b0 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -90,6 +90,24 @@
         }                                           \
     } while( 0 )
 
+/** Evaluate two expressions and fail the test case if they have different
+ * values.
+ *
+ * \param expr1     An expression to evaluate.
+ * \param expr2     The expected value of \p expr1. This can be any
+ *                  expression, but it is typically a constant.
+ */
+#define TEST_EQUAL( expr1, expr2 )              \
+    TEST_ASSERT( ( expr1 ) == ( expr2 ) )
+
+/** Evaluate an expression and fail the test case if it returns an error.
+ *
+ * \param expr      The expression to evaluate. This is typically a call
+ *                  to a \c psa_xxx function that returns a value of type
+ *                  #psa_status_t.
+ */
+#define PSA_ASSERT( expr ) TEST_EQUAL( ( expr ), PSA_SUCCESS )
+
 /** Allocate memory dynamically and fail the test case if this fails.
  *
  * You must set \p pointer to \c NULL before calling this macro and
@@ -150,6 +168,58 @@
     mbedtls_exit( 1 );                                             \
 }
 
+#if defined(__GNUC__)
+/* Test if arg and &(arg)[0] have the same type. This is true if arg is
+ * an array but not if it's a pointer. */
+#define IS_ARRAY_NOT_POINTER( arg )                                     \
+    ( ! __builtin_types_compatible_p( __typeof__( arg ),                \
+                                      __typeof__( &( arg )[0] ) ) )
+#else
+/* On platforms where we don't know how to implement this check,
+ * omit it. Oh well, a non-portable check is better than nothing. */
+#define IS_ARRAY_NOT_POINTER( arg ) 1
+#endif
+
+/* A compile-time constant with the value 0. If `const_expr` is not a
+ * compile-time constant with a nonzero value, cause a compile-time error. */
+#define STATIC_ASSERT_EXPR( const_expr )                                \
+    ( 0 && sizeof( struct { int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
+/* Return the scalar value `value` (possibly promoted). This is a compile-time
+ * constant if `value` is. `condition` must be a compile-time constant.
+ * If `condition` is false, arrange to cause a compile-time error. */
+#define STATIC_ASSERT_THEN_RETURN( condition, value )   \
+    ( STATIC_ASSERT_EXPR( condition ) ? 0 : ( value ) )
+
+#define ARRAY_LENGTH_UNSAFE( array )            \
+    ( sizeof( array ) / sizeof( *( array ) ) )
+/** Return the number of elements of a static or stack array.
+ *
+ * \param array         A value of array (not pointer) type.
+ *
+ * \return The number of elements of the array.
+ */
+#define ARRAY_LENGTH( array )                                           \
+    ( STATIC_ASSERT_THEN_RETURN( IS_ARRAY_NOT_POINTER( array ),         \
+                                 ARRAY_LENGTH_UNSAFE( array ) ) )
+
+/** Return the smaller of two values.
+ *
+ * \param x         An integer-valued expression without side effects.
+ * \param y         An integer-valued expression without side effects.
+ *
+ * \return The smaller of \p x and \p y.
+ */
+#define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
+
+/** Return the larger of two values.
+ *
+ * \param x         An integer-valued expression without side effects.
+ * \param y         An integer-valued expression without side effects.
+ *
+ * \return The larger of \p x and \p y.
+ */
+#define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) )
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index c40ac5f..c1339c0 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -11,16 +11,6 @@
 
 #include "psa/crypto.h"
 
-#define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) )
-
-#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) )
-
-#if(UINT32_MAX > SIZE_MAX)
-#define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) ( ( x ) <= SIZE_MAX )
-#else
-#define PSA_CRYPTO_TEST_SIZE_T_RANGE( x ) 1
-#endif
-
 /** An invalid export length that will never be set by psa_export_key(). */
 static const size_t INVALID_EXPORT_LENGTH = ~0U;
 
@@ -141,13 +131,13 @@
 
     if( usage & PSA_KEY_USAGE_SIGN )
     {
-        TEST_ASSERT( psa_mac_sign_setup( &operation,
-                                         handle, alg ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_mac_update( &operation,
-                                     input, sizeof( input ) ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_mac_sign_finish( &operation,
-                                          mac, sizeof( mac ),
-                                          &mac_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_mac_sign_setup( &operation,
+                                        handle, alg ) );
+        PSA_ASSERT( psa_mac_update( &operation,
+                                    input, sizeof( input ) ) );
+        PSA_ASSERT( psa_mac_sign_finish( &operation,
+                                         mac, sizeof( mac ),
+                                         &mac_length ) );
     }
 
     if( usage & PSA_KEY_USAGE_VERIFY )
@@ -156,13 +146,12 @@
             ( usage & PSA_KEY_USAGE_SIGN ?
               PSA_SUCCESS :
               PSA_ERROR_INVALID_SIGNATURE );
-        TEST_ASSERT( psa_mac_verify_setup( &operation,
-                                           handle, alg ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_mac_update( &operation,
-                                     input, sizeof( input ) ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_mac_verify_finish( &operation,
-                                            mac,
-                                            mac_length ) == verify_status );
+        PSA_ASSERT( psa_mac_verify_setup( &operation,
+                                          handle, alg ) );
+        PSA_ASSERT( psa_mac_update( &operation,
+                                    input, sizeof( input ) ) );
+        TEST_EQUAL( psa_mac_verify_finish( &operation, mac, mac_length ),
+                    verify_status );
     }
 
     return( 1 );
@@ -187,19 +176,19 @@
 
     if( usage & PSA_KEY_USAGE_ENCRYPT )
     {
-        TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
-                                               handle, alg ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_cipher_generate_iv( &operation,
-                                             iv, sizeof( iv ),
-                                             &iv_length ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_cipher_update( &operation,
-                                        plaintext, sizeof( plaintext ),
-                                        ciphertext, sizeof( ciphertext ),
-                                        &ciphertext_length ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_cipher_finish( &operation,
-                                        ciphertext + ciphertext_length,
-                                        sizeof( ciphertext ) - ciphertext_length,
-                                        &part_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                              handle, alg ) );
+        PSA_ASSERT( psa_cipher_generate_iv( &operation,
+                                            iv, sizeof( iv ),
+                                            &iv_length ) );
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       plaintext, sizeof( plaintext ),
+                                       ciphertext, sizeof( ciphertext ),
+                                       &ciphertext_length ) );
+        PSA_ASSERT( psa_cipher_finish( &operation,
+                                       ciphertext + ciphertext_length,
+                                       sizeof( ciphertext ) - ciphertext_length,
+                                       &part_length ) );
         ciphertext_length += part_length;
     }
 
@@ -213,14 +202,14 @@
             TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) );
             iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE( type );
         }
-        TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
-                                               handle, alg ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_cipher_set_iv( &operation,
-                                        iv, iv_length ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_cipher_update( &operation,
-                                        ciphertext, ciphertext_length,
-                                        decrypted, sizeof( decrypted ),
-                                        &part_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                              handle, alg ) );
+        PSA_ASSERT( psa_cipher_set_iv( &operation,
+                                       iv, iv_length ) );
+        PSA_ASSERT( psa_cipher_update( &operation,
+                                       ciphertext, ciphertext_length,
+                                       decrypted, sizeof( decrypted ),
+                                       &part_length ) );
         status = psa_cipher_finish( &operation,
                                     decrypted + part_length,
                                     sizeof( decrypted ) - part_length,
@@ -230,7 +219,7 @@
          ciphertext, a padding error is likely.  */
         if( ( usage & PSA_KEY_USAGE_ENCRYPT ) ||
             PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) == 1 )
-            TEST_ASSERT( status == PSA_SUCCESS );
+            PSA_ASSERT( status );
         else
             TEST_ASSERT( status == PSA_SUCCESS ||
                          status == PSA_ERROR_INVALID_PADDING );
@@ -256,12 +245,12 @@
 
     if( usage & PSA_KEY_USAGE_ENCRYPT )
     {
-        TEST_ASSERT( psa_aead_encrypt( handle, alg,
-                                       nonce, nonce_length,
-                                       NULL, 0,
-                                       plaintext, sizeof( plaintext ),
-                                       ciphertext, sizeof( ciphertext ),
-                                       &ciphertext_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_aead_encrypt( handle, alg,
+                                      nonce, nonce_length,
+                                      NULL, 0,
+                                      plaintext, sizeof( plaintext ),
+                                      ciphertext, sizeof( ciphertext ),
+                                      &ciphertext_length ) );
     }
 
     if( usage & PSA_KEY_USAGE_DECRYPT )
@@ -270,12 +259,13 @@
             ( usage & PSA_KEY_USAGE_ENCRYPT ?
               PSA_SUCCESS :
               PSA_ERROR_INVALID_SIGNATURE );
-        TEST_ASSERT( psa_aead_decrypt( handle, alg,
-                                       nonce, nonce_length,
-                                       NULL, 0,
-                                       ciphertext, ciphertext_length,
-                                       plaintext, sizeof( plaintext ),
-                                       &plaintext_length ) == verify_status );
+        TEST_EQUAL( psa_aead_decrypt( handle, alg,
+                                      nonce, nonce_length,
+                                      NULL, 0,
+                                      ciphertext, ciphertext_length,
+                                      plaintext, sizeof( plaintext ),
+                                      &plaintext_length ),
+                    verify_status );
     }
 
     return( 1 );
@@ -301,10 +291,10 @@
         psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
         if( hash_alg != 0 )
             payload_length = PSA_HASH_SIZE( hash_alg );
-        TEST_ASSERT( psa_asymmetric_sign( handle, alg,
-                                          payload, payload_length,
-                                          signature, sizeof( signature ),
-                                          &signature_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_asymmetric_sign( handle, alg,
+                                         payload, payload_length,
+                                         signature, sizeof( signature ),
+                                         &signature_length ) );
     }
 
     if( usage & PSA_KEY_USAGE_VERIFY )
@@ -313,10 +303,10 @@
             ( usage & PSA_KEY_USAGE_SIGN ?
               PSA_SUCCESS :
               PSA_ERROR_INVALID_SIGNATURE );
-        TEST_ASSERT( psa_asymmetric_verify( handle, alg,
-                                            payload, payload_length,
-                                            signature, signature_length ) ==
-                     verify_status );
+        TEST_EQUAL( psa_asymmetric_verify( handle, alg,
+                                           payload, payload_length,
+                                           signature, signature_length ),
+                    verify_status );
     }
 
     return( 1 );
@@ -336,12 +326,11 @@
 
     if( usage & PSA_KEY_USAGE_ENCRYPT )
     {
-        TEST_ASSERT(
-            psa_asymmetric_encrypt( handle, alg,
-                                    plaintext, plaintext_length,
-                                    NULL, 0,
-                                    ciphertext, sizeof( ciphertext ),
-                                    &ciphertext_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
+                                            plaintext, plaintext_length,
+                                            NULL, 0,
+                                            ciphertext, sizeof( ciphertext ),
+                                            &ciphertext_length ) );
     }
 
     if( usage & PSA_KEY_USAGE_DECRYPT )
@@ -377,15 +366,15 @@
 
     if( usage & PSA_KEY_USAGE_DERIVE )
     {
-        TEST_ASSERT( psa_key_derivation( &generator,
-                                         handle, alg,
-                                         label, label_length,
-                                         seed, seed_length,
-                                         sizeof( output ) ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_generator_read( &generator,
-                                         output,
-                                         sizeof( output ) ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_key_derivation( &generator,
+                                        handle, alg,
+                                        label, label_length,
+                                        seed, seed_length,
+                                        sizeof( output ) ) );
+        PSA_ASSERT( psa_generator_read( &generator,
+                                        output,
+                                        sizeof( output ) ) );
+        PSA_ASSERT( psa_generator_abort( &generator ) );
     }
 
     return( 1 );
@@ -410,16 +399,15 @@
      * good enough: callers will report it as a failed test anyway. */
     psa_status_t status = PSA_ERROR_UNKNOWN_ERROR;
 
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          &private_key_type,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         &private_key_type,
+                                         &key_bits ) );
     public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type );
     public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits );
     ASSERT_ALLOC( public_key, public_key_length );
-    TEST_ASSERT( public_key != NULL );
-    TEST_ASSERT( psa_export_public_key( handle,
-                                        public_key, public_key_length,
-                                        &public_key_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_export_public_key( handle,
+                                       public_key, public_key_length,
+                                       &public_key_length ) );
 
     status = psa_key_agreement( generator, handle,
                                 public_key, public_key_length,
@@ -441,12 +429,11 @@
     {
         /* We need two keys to exercise key agreement. Exercise the
          * private key against its own public key. */
-        TEST_ASSERT( key_agreement_with_self( &generator, handle, alg ) ==
-                     PSA_SUCCESS );
-        TEST_ASSERT( psa_generator_read( &generator,
-                                         output,
-                                         sizeof( output ) ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+        PSA_ASSERT( key_agreement_with_self( &generator, handle, alg ) );
+        PSA_ASSERT( psa_generator_read( &generator,
+                                        output,
+                                        sizeof( output ) ) );
+        PSA_ASSERT( psa_generator_abort( &generator ) );
     }
     ok = 1;
 
@@ -498,8 +485,9 @@
     size_t len;
     size_t actual_bits;
     unsigned char msb;
-    TEST_ASSERT( mbedtls_asn1_get_tag( p, end, &len,
-                                       MBEDTLS_ASN1_INTEGER ) == 0 );
+    TEST_EQUAL( mbedtls_asn1_get_tag( p, end, &len,
+                                      MBEDTLS_ASN1_INTEGER ),
+                0 );
     /* Tolerate a slight departure from DER encoding:
      * - 0 may be represented by an empty string or a 1-byte string.
      * - The sign bit may be used as a value bit. */
@@ -552,7 +540,7 @@
                                       uint8_t *exported, size_t exported_length )
 {
     if( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) )
-        TEST_ASSERT( exported_length == ( bits + 7 ) / 8 );
+        TEST_EQUAL( exported_length, ( bits + 7 ) / 8 );
     else
         TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, bits ) );
 
@@ -594,10 +582,10 @@
          *       coefficient         INTEGER,  -- (inverse of q) mod p
          *   }
          */
-        TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
-                                           MBEDTLS_ASN1_SEQUENCE |
-                                           MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
-        TEST_ASSERT( p + len == end );
+        TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
+                                          MBEDTLS_ASN1_SEQUENCE |
+                                          MBEDTLS_ASN1_CONSTRUCTED ), 0 );
+        TEST_EQUAL( p + len, end );
         if( ! asn1_skip_integer( &p, end, 0, 0, 0 ) )
             goto exit;
         if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
@@ -618,8 +606,8 @@
             goto exit;
         if( ! asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) )
             goto exit;
-        TEST_ASSERT( p == end );
-     }
+        TEST_EQUAL( p, end );
+    }
     else
 #endif /* MBEDTLS_RSA_C */
 
@@ -627,7 +615,7 @@
     if( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
     {
         /* Just the secret value */
-        TEST_ASSERT( exported_length == PSA_BITS_TO_BYTES( bits ) );
+        TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) );
     }
     else
 #endif /* MBEDTLS_ECP_C */
@@ -647,15 +635,16 @@
          *      algorithm          OBJECT IDENTIFIER,
          *      parameters         ANY DEFINED BY algorithm OPTIONAL  }
          */
-        TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
-                                           MBEDTLS_ASN1_SEQUENCE |
-                                           MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
-        TEST_ASSERT( p + len == end );
-        TEST_ASSERT( mbedtls_asn1_get_alg( &p, end, &alg, &params ) == 0 );
+        TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
+                                          MBEDTLS_ASN1_SEQUENCE |
+                                          MBEDTLS_ASN1_CONSTRUCTED ),
+                    0 );
+        TEST_EQUAL( p + len, end );
+        TEST_EQUAL( mbedtls_asn1_get_alg( &p, end, &alg, &params ), 0 );
         if( ! is_oid_of_key_type( type, alg.p, alg.len ) )
             goto exit;
-        TEST_ASSERT( mbedtls_asn1_get_bitstring( &p, end, &bitstring ) == 0 );
-        TEST_ASSERT( p == end );
+        TEST_EQUAL( mbedtls_asn1_get_bitstring( &p, end, &bitstring ), 0 );
+        TEST_EQUAL( p, end );
         p = bitstring.p;
 #if defined(MBEDTLS_RSA_C)
         if( type == PSA_KEY_TYPE_RSA_PUBLIC_KEY )
@@ -664,16 +653,17 @@
              *      modulus            INTEGER,    -- n
              *      publicExponent     INTEGER  }  -- e
              */
-            TEST_ASSERT( bitstring.unused_bits == 0 );
-            TEST_ASSERT( mbedtls_asn1_get_tag( &p, end, &len,
-                                               MBEDTLS_ASN1_SEQUENCE |
-                                               MBEDTLS_ASN1_CONSTRUCTED ) == 0 );
-            TEST_ASSERT( p + len == end );
+            TEST_EQUAL( bitstring.unused_bits, 0 );
+            TEST_EQUAL( mbedtls_asn1_get_tag( &p, end, &len,
+                                              MBEDTLS_ASN1_SEQUENCE |
+                                              MBEDTLS_ASN1_CONSTRUCTED ),
+                        0 );
+            TEST_EQUAL( p + len, end );
             if( ! asn1_skip_integer( &p, end, bits, bits, 1 ) )
                 goto exit;
             if( ! asn1_skip_integer( &p, end, 2, bits, 1 ) )
                 goto exit;
-            TEST_ASSERT( p == end );
+            TEST_EQUAL( p, end );
         }
         else
 #endif /* MBEDTLS_RSA_C */
@@ -686,9 +676,9 @@
              *      -- then y_P as a n-bit string, big endian,
              *      -- where n is the order of the curve.
              */
-            TEST_ASSERT( bitstring.unused_bits == 0 );
-            TEST_ASSERT( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ) == end );
-            TEST_ASSERT( p[0] == 4 );
+            TEST_EQUAL( bitstring.unused_bits, 0 );
+            TEST_EQUAL( p + 1 + 2 * PSA_BITS_TO_BYTES( bits ), end );
+            TEST_EQUAL( p[0], 4 );
         }
         else
 #endif /* MBEDTLS_ECP_C */
@@ -723,22 +713,22 @@
     size_t exported_length = 0;
     int ok = 0;
 
-    TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle, &type, &bits ) );
 
     if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 &&
         ! PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
     {
-        TEST_ASSERT( psa_export_key( handle, NULL, 0, &exported_length ) ==
-                     PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( psa_export_key( handle, NULL, 0, &exported_length ),
+                    PSA_ERROR_NOT_PERMITTED );
         return( 1 );
     }
 
     exported_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits );
     ASSERT_ALLOC( exported, exported_size );
 
-    TEST_ASSERT( psa_export_key( handle,
-                                 exported, exported_size,
-                                 &exported_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_export_key( handle,
+                                exported, exported_size,
+                                &exported_length ) );
     ok = exported_key_sanity_check( type, bits, exported, exported_length );
 
 exit:
@@ -756,12 +746,11 @@
     size_t exported_length = 0;
     int ok = 0;
 
-    TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle, &type, &bits ) );
     if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( type ) )
     {
-        TEST_ASSERT( psa_export_public_key( handle,
-                                            NULL, 0, &exported_length ) ==
-                     PSA_ERROR_INVALID_ARGUMENT );
+        TEST_EQUAL( psa_export_public_key( handle, NULL, 0, &exported_length ),
+                    PSA_ERROR_INVALID_ARGUMENT );
         return( 1 );
     }
 
@@ -769,9 +758,9 @@
     exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type, bits );
     ASSERT_ALLOC( exported, exported_size );
 
-    TEST_ASSERT( psa_export_public_key( handle,
-                                        exported, exported_size,
-                                        &exported_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_export_public_key( handle,
+                                       exported, exported_size,
+                                       &exported_length ) );
     ok = exported_key_sanity_check( public_type, bits,
                                     exported, exported_length );
 
@@ -885,16 +874,14 @@
     psa_status_t expected_status = expected_status_arg;
     psa_status_t status;
 
-    TEST_ASSERT( data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) );
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
     status = psa_import_key( handle, type, data->x, data->len );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status == PSA_SUCCESS )
-        TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_destroy_key( handle ) );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -918,20 +905,20 @@
     psa_key_policy_t policy;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type1,
-                                   MAX( KEY_BITS_FROM_DATA( type1, data1 ),
-                                        KEY_BITS_FROM_DATA( type2, data2 ) ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type1,
+                                  MAX( KEY_BITS_FROM_DATA( type1, data1 ),
+                                       KEY_BITS_FROM_DATA( type2, data2 ) ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, usage, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     status = psa_import_key( handle, type1, data1->x, data1->len );
-    TEST_ASSERT( status == expected_import1_status );
+    TEST_EQUAL( status, expected_import1_status );
     status = psa_import_key( handle, type2, data2->x, data2->len );
-    TEST_ASSERT( status == expected_import2_status );
+    TEST_EQUAL( status, expected_import2_status );
 
     if( expected_import1_status == PSA_SUCCESS ||
         expected_import2_status == PSA_SUCCESS )
@@ -960,7 +947,7 @@
     int ret;
     size_t length;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
     ASSERT_ALLOC( buffer, buffer_size );
 
     TEST_ASSERT( ( ret = construct_fake_rsa_key( buffer, buffer_size, &p,
@@ -968,11 +955,11 @@
     length = ret;
 
     /* Try importing the key */
-    TEST_ASSERT( psa_allocate_key( type, bits, &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, bits, &handle ) );
     status = psa_import_key( handle, type, p, length );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status == PSA_SUCCESS )
-        TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_destroy_key( handle ) );
 
 exit:
     mbedtls_free( buffer );
@@ -1004,39 +991,36 @@
     size_t got_bits;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) );
     export_size = (ptrdiff_t) data->len + export_size_delta;
     ASSERT_ALLOC( exported, export_size );
     if( ! canonical_input )
         ASSERT_ALLOC( reexported, export_size );
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, expected_bits, &handle ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, expected_bits, &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, usage_arg, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_get_key_information(
-                     handle, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
+                PSA_ERROR_EMPTY_SLOT );
 
     /* Import the key */
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data->x, data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, type,
+                                data->x, data->len ) );
 
     /* Test the key information */
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          &got_type,
-                                          &got_bits ) == PSA_SUCCESS );
-    TEST_ASSERT( got_type == type );
-    TEST_ASSERT( got_bits == (size_t) expected_bits );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         &got_type,
+                                         &got_bits ) );
+    TEST_EQUAL( got_type, type );
+    TEST_EQUAL( got_bits, (size_t) expected_bits );
 
     /* Export the key */
     status = psa_export_key( handle,
                              exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == expected_export_status );
+    TEST_EQUAL( status, expected_export_status );
 
     /* The exported length must be set by psa_export_key() to a value between 0
      * and export_size. On errors, the exported length must be 0. */
@@ -1048,7 +1032,7 @@
                               export_size - exported_length ) );
     if( status != PSA_SUCCESS )
     {
-        TEST_ASSERT( exported_length == 0 );
+        TEST_EQUAL( exported_length, 0 );
         goto destroy;
     }
 
@@ -1060,28 +1044,27 @@
     else
     {
         psa_key_handle_t handle2;
-        TEST_ASSERT( psa_allocate_key( type, expected_bits, &handle2 ) ==
-                     PSA_SUCCESS );
-        TEST_ASSERT( psa_set_key_policy( handle2, &policy ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_allocate_key( type, expected_bits, &handle2 ) );
+        PSA_ASSERT( psa_set_key_policy( handle2, &policy ) );
 
-        TEST_ASSERT( psa_import_key( handle2, type,
-                                     exported,
-                                     exported_length ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_export_key( handle2,
-                                     reexported,
-                                     export_size,
-                                     &reexported_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_import_key( handle2, type,
+                                    exported,
+                                    exported_length ) );
+        PSA_ASSERT( psa_export_key( handle2,
+                                    reexported,
+                                    export_size,
+                                    &reexported_length ) );
         ASSERT_COMPARE( exported, exported_length,
                         reexported, reexported_length );
-        TEST_ASSERT( psa_close_key( handle2 ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_close_key( handle2 ) );
     }
     TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, got_bits ) );
 
 destroy:
     /* Destroy the key */
-    TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_key_information(
-                     handle, NULL, NULL ) == PSA_ERROR_INVALID_HANDLE );
+    PSA_ASSERT( psa_destroy_key( handle ) );
+    TEST_EQUAL( psa_get_key_information( handle, NULL, NULL ),
+                PSA_ERROR_INVALID_HANDLE );
 
 exit:
     mbedtls_free( exported );
@@ -1097,18 +1080,18 @@
     psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA;
     psa_status_t status;
     const uint8_t data[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, PSA_BYTES_TO_BITS( sizeof( data ) ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, PSA_BYTES_TO_BITS( sizeof( data ) ),
+                                  &handle ) );
 
     /* Import the key */
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data, sizeof( data ) ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, type,
+                                data, sizeof( data ) ) );
 
     /* Import the key again */
     status = psa_import_key( handle, type, data, sizeof( data ) );
-    TEST_ASSERT( status == PSA_ERROR_OCCUPIED_SLOT );
+    TEST_EQUAL( status, PSA_ERROR_OCCUPIED_SLOT );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1124,13 +1107,13 @@
     size_t exported_length = INVALID_EXPORT_LENGTH;
     psa_status_t expected_export_status = expected_export_status_arg;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* Export the key */
     status = psa_export_key( (psa_key_handle_t) handle,
                              exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == expected_export_status );
+    TEST_EQUAL( status, expected_export_status );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1148,19 +1131,19 @@
     size_t export_size = 0;
     size_t exported_length = INVALID_EXPORT_LENGTH;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0,
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0,
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     /* Export the key */
     status = psa_export_key( handle,
                              exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( status, PSA_ERROR_EMPTY_SLOT );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1176,16 +1159,16 @@
     psa_cipher_operation_t operation;
     int exercise_alg = PSA_ALG_CTR;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0,
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0,
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, exercise_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
-    TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( status, PSA_ERROR_EMPTY_SLOT );
 
 exit:
     psa_cipher_abort( &operation );
@@ -1205,21 +1188,21 @@
     psa_status_t expected_import_status = expected_import_status_arg;
     size_t exported_length = INVALID_EXPORT_LENGTH;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
 
     /* Import the key - expect failure */
     status = psa_import_key( handle, type,
-                                 data->x, data->len );
-    TEST_ASSERT( status == expected_import_status );
+                             data->x, data->len );
+    TEST_EQUAL( status, expected_import_status );
 
     /* Export the key */
     status = psa_export_key( handle,
                              exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( status, PSA_ERROR_EMPTY_SLOT );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1237,18 +1220,18 @@
     psa_status_t expected_import_status = expected_import_status_arg;
     int exercise_alg = PSA_ALG_CTR;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
 
     /* Import the key - expect failure */
     status = psa_import_key( handle, type,
-                                 data->x, data->len );
-    TEST_ASSERT( status == expected_import_status );
+                             data->x, data->len );
+    TEST_EQUAL( status, expected_import_status );
 
     status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
-    TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( status, PSA_ERROR_EMPTY_SLOT );
 
 exit:
     psa_cipher_abort( &operation );
@@ -1268,30 +1251,30 @@
     size_t export_size = 0;
     size_t exported_length = INVALID_EXPORT_LENGTH;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
     export_size = (ptrdiff_t) data->len;
     ASSERT_ALLOC( exported, export_size );
 
     /* Import the key */
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data->x, data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, type,
+                                data->x, data->len ) );
 
-    TEST_ASSERT( psa_export_key( handle, exported, export_size,
-                                 &exported_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_export_key( handle, exported, export_size,
+                                &exported_length ) );
 
     /* Destroy the key */
-    TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_destroy_key( handle ) );
 
     /* Export the key */
     status = psa_export_key( handle, exported, export_size,
                              &exported_length );
-    TEST_ASSERT( status == PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( status, PSA_ERROR_INVALID_HANDLE );
 
 exit:
     mbedtls_free( exported );
@@ -1317,30 +1300,29 @@
     size_t exported_length = INVALID_EXPORT_LENGTH;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     /* Import the key */
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data->x, data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, type,
+                                data->x, data->len ) );
 
     /* Export the public key */
     ASSERT_ALLOC( exported, export_size );
     status = psa_export_public_key( handle,
                                     exported, export_size,
                                     &exported_length );
-    TEST_ASSERT( status == expected_export_status );
+    TEST_EQUAL( status, expected_export_status );
     if( status == PSA_SUCCESS )
     {
         psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
         size_t bits;
-        TEST_ASSERT( psa_get_key_information( handle, NULL, &bits ) ==
-                     PSA_SUCCESS );
+        PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
         TEST_ASSERT( expected_public_key->len <=
                      PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) );
         ASSERT_COMPARE( expected_public_key->x, expected_public_key->len,
@@ -1370,24 +1352,24 @@
     size_t got_bits;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, usage, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     /* Import the key */
     status = psa_import_key( handle, type, data->x, data->len );
-    TEST_ASSERT( status == PSA_SUCCESS );
+    PSA_ASSERT( status );
 
     /* Test the key information */
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          &got_type,
-                                          &got_bits ) == PSA_SUCCESS );
-    TEST_ASSERT( got_type == type );
-    TEST_ASSERT( got_bits == bits );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         &got_type,
+                                         &got_bits ) );
+    TEST_EQUAL( got_type, type );
+    TEST_EQUAL( got_bits, bits );
 
     /* Do something with the key according to its type and permitted usage. */
     if( ! exercise_key( handle, usage, alg ) )
@@ -1412,25 +1394,25 @@
 
     memset( key, 0x2a, sizeof( key ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( sizeof( key ) ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( sizeof( key ) ),
+                                  &handle ) );
     psa_key_policy_init( &policy_set );
     psa_key_policy_init( &policy_get );
     psa_key_policy_set_usage( &policy_set, usage, alg );
 
-    TEST_ASSERT( psa_key_policy_get_usage( &policy_set ) == usage );
-    TEST_ASSERT( psa_key_policy_get_algorithm( &policy_set ) == alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy_set ) == PSA_SUCCESS );
+    TEST_EQUAL( psa_key_policy_get_usage( &policy_set ), usage );
+    TEST_EQUAL( psa_key_policy_get_algorithm( &policy_set ), alg );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key, sizeof( key ) ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key, sizeof( key ) ) );
 
-    TEST_ASSERT( psa_get_key_policy( handle, &policy_get ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
 
-    TEST_ASSERT( policy_get.usage == policy_set.usage );
-    TEST_ASSERT( policy_get.alg == policy_set.alg );
+    TEST_EQUAL( policy_get.usage, policy_set.usage );
+    TEST_EQUAL( policy_get.alg, policy_set.alg );
 
 exit:
     psa_destroy_key( handle );
@@ -1451,33 +1433,33 @@
     psa_status_t status;
     unsigned char mac[PSA_MAC_MAX_SIZE];
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = psa_mac_sign_setup( &operation, handle, exercise_alg );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
     psa_mac_abort( &operation );
 
     memset( mac, 0, sizeof( mac ) );
     status = psa_mac_verify_setup( &operation, handle, exercise_alg );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_mac_abort( &operation );
@@ -1498,32 +1480,32 @@
     psa_cipher_operation_t operation;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
     psa_cipher_abort( &operation );
 
     status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_cipher_abort( &operation );
@@ -1553,17 +1535,17 @@
     TEST_ASSERT( nonce_length <= sizeof( nonce ) );
     TEST_ASSERT( tag_length <= sizeof( tag ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = psa_aead_encrypt( handle, exercise_alg,
                                nonce, nonce_length,
@@ -1573,9 +1555,9 @@
                                &output_length );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
     memset( tag, 0, sizeof( tag ) );
     status = psa_aead_decrypt( handle, exercise_alg,
@@ -1586,9 +1568,9 @@
                                &output_length );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE );
+        TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_destroy_key( handle );
@@ -1611,21 +1593,21 @@
     unsigned char *buffer = NULL;
     size_t output_length;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          NULL,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         NULL,
+                                         &key_bits ) );
     buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits,
                                                         exercise_alg );
     ASSERT_ALLOC( buffer, buffer_length );
@@ -1637,9 +1619,9 @@
                                      &output_length );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
     if( buffer_length != 0 )
         memset( buffer, 0, buffer_length );
@@ -1650,9 +1632,9 @@
                                      &output_length );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 )
-        TEST_ASSERT( status == PSA_ERROR_INVALID_PADDING );
+        TEST_EQUAL( status, PSA_ERROR_INVALID_PADDING );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_destroy_key( handle );
@@ -1676,17 +1658,17 @@
     unsigned char signature[PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE] = {0};
     size_t signature_length;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = psa_asymmetric_sign( handle, exercise_alg,
                                   payload, payload_length,
@@ -1694,9 +1676,9 @@
                                   &signature_length );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
     memset( signature, 0, sizeof( signature ) );
     status = psa_asymmetric_verify( handle, exercise_alg,
@@ -1704,9 +1686,9 @@
                                     signature, sizeof( signature ) );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 )
-        TEST_ASSERT( status == PSA_ERROR_INVALID_SIGNATURE );
+        TEST_EQUAL( status, PSA_ERROR_INVALID_SIGNATURE );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_destroy_key( handle );
@@ -1726,17 +1708,17 @@
     psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = psa_key_derivation( &generator, handle,
                                  exercise_alg,
@@ -1745,9 +1727,9 @@
                                  1 );
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_generator_abort( &generator );
@@ -1769,25 +1751,25 @@
     psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, policy_usage, policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
     status = key_agreement_with_self( &generator, handle, exercise_alg );
 
     if( policy_alg == exercise_alg &&
         ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 )
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
     else
-        TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+        TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 
 exit:
     psa_generator_abort( &generator );
@@ -1805,11 +1787,11 @@
     psa_hash_operation_t operation;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     status = psa_hash_setup( &operation, alg );
     psa_hash_abort( &operation );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1828,25 +1810,23 @@
     size_t hash_len;
     psa_hash_operation_t operation;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* psa_hash_update without calling psa_hash_setup beforehand */
     memset( &operation, 0, sizeof( operation ) );
-    TEST_ASSERT( psa_hash_update( &operation,
-                                  input, sizeof( input ) ) ==
-                                  PSA_ERROR_INVALID_ARGUMENT );
+    TEST_EQUAL( psa_hash_update( &operation, input, sizeof( input ) ),
+                PSA_ERROR_INVALID_ARGUMENT );
 
     /* psa_hash_verify without calling psa_hash_setup beforehand */
     memset( &operation, 0, sizeof( operation ) );
-    TEST_ASSERT( psa_hash_verify( &operation,
-                                  hash, sizeof( hash ) ) ==
-                                  PSA_ERROR_INVALID_ARGUMENT );
+    TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
+                PSA_ERROR_INVALID_ARGUMENT );
 
     /* psa_hash_finish without calling psa_hash_setup beforehand */
     memset( &operation, 0, sizeof( operation ) );
-    TEST_ASSERT( psa_hash_finish( &operation,
-                                  hash, sizeof( hash ), &hash_len ) ==
-                                  PSA_ERROR_INVALID_ARGUMENT );
+    TEST_EQUAL( psa_hash_finish( &operation,
+                                 hash, sizeof( hash ), &hash_len ),
+                PSA_ERROR_INVALID_ARGUMENT );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1866,25 +1846,22 @@
     size_t expected_size = PSA_HASH_SIZE( alg );
     psa_hash_operation_t operation;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* psa_hash_verify with a smaller hash than expected */
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_verify( &operation,
-                                  hash, expected_size - 1 ) ==
-                                  PSA_ERROR_INVALID_SIGNATURE );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    TEST_EQUAL( psa_hash_verify( &operation, hash, expected_size - 1 ),
+                PSA_ERROR_INVALID_SIGNATURE );
 
     /* psa_hash_verify with a non-matching hash */
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_verify( &operation,
-                                  hash + 1, expected_size ) ==
-                                  PSA_ERROR_INVALID_SIGNATURE );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    TEST_EQUAL( psa_hash_verify( &operation, hash + 1, expected_size ),
+                PSA_ERROR_INVALID_SIGNATURE );
 
     /* psa_hash_verify with a hash longer than expected */
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_verify( &operation,
-                                  hash, sizeof( hash ) ) ==
-                                  PSA_ERROR_INVALID_SIGNATURE );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    TEST_EQUAL( psa_hash_verify( &operation, hash, sizeof( hash ) ),
+                PSA_ERROR_INVALID_SIGNATURE );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1900,13 +1877,13 @@
     psa_hash_operation_t operation;
     size_t hash_len;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* psa_hash_finish with a smaller hash buffer than expected */
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_finish( &operation,
-                                  hash, expected_size - 1,
-                                  &hash_len ) == PSA_ERROR_BUFFER_TOO_SMALL );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    TEST_EQUAL( psa_hash_finish( &operation,
+                                 hash, expected_size - 1, &hash_len ),
+                PSA_ERROR_BUFFER_TOO_SMALL );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -1927,22 +1904,22 @@
     psa_key_policy_t policy;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy,
                               PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
                               alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
     status = psa_mac_sign_setup( &operation, handle, alg );
     psa_mac_abort( &operation );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
 
 exit:
     psa_destroy_key( handle );
@@ -1974,29 +1951,29 @@
     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_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
     /* Calculate the MAC. */
-    TEST_ASSERT( psa_mac_sign_setup( &operation,
-                                     handle, 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 );
+    PSA_ASSERT( psa_mac_sign_setup( &operation,
+                                    handle, alg ) );
+    PSA_ASSERT( psa_mac_update( &operation,
+                                input->x, input->len ) );
+    PSA_ASSERT( psa_mac_sign_finish( &operation,
+                                     actual_mac, mac_buffer_size,
+                                     &mac_length ) );
 
     /* Compare with the expected value. */
-    TEST_ASSERT( mac_length == expected_mac->len );
-    TEST_ASSERT( memcmp( actual_mac, expected_mac->x, mac_length ) == 0 );
+    ASSERT_COMPARE( expected_mac->x, expected_mac->len,
+                    actual_mac, mac_length );
 
     /* Verify that the end of the buffer is untouched. */
     TEST_ASSERT( mem_is_char( actual_mac + mac_length, '+',
@@ -2023,32 +2000,25 @@
 
     TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE );
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( expected_mac != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_mac->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_mac_verify_setup( &operation,
-                                       handle, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_mac_update( &operation,
-                                 input->x, input->len ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_mac_verify_finish( &operation,
-                                        expected_mac->x,
-                                        expected_mac->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_mac_verify_setup( &operation,
+                                      handle, alg ) );
+    PSA_ASSERT( psa_destroy_key( handle ) );
+    PSA_ASSERT( psa_mac_update( &operation,
+                                input->x, input->len ) );
+    PSA_ASSERT( psa_mac_verify_finish( &operation,
+                                       expected_mac->x,
+                                       expected_mac->len ) );
 
 exit:
     psa_destroy_key( handle );
@@ -2070,20 +2040,20 @@
     psa_key_policy_t policy;
     psa_status_t status;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
     status = psa_cipher_encrypt_setup( &operation, handle, alg );
     psa_cipher_abort( &operation );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
 
 exit:
     psa_destroy_key( handle );
@@ -2111,40 +2081,33 @@
     psa_cipher_operation_t operation;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( expected_output != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
-
     iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
     memset( iv, 0x2a, iv_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation,
-                                    iv, iv_size ) == PSA_SUCCESS );
-    output_buffer_size = (size_t) input->len +
-                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    PSA_ASSERT( psa_cipher_set_iv( &operation,
+                                   iv, iv_size ) );
+    output_buffer_size = ( (size_t) input->len +
+                           PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output, output_buffer_size );
 
-    TEST_ASSERT( psa_cipher_update( &operation,
-                                    input->x, input->len,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x, input->len,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
     status = psa_cipher_finish( &operation,
                                 output + function_output_length,
@@ -2152,10 +2115,10 @@
                                 &function_output_length );
     total_output_length += function_output_length;
 
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( expected_status == PSA_SUCCESS )
     {
-        TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_cipher_abort( &operation ) );
         ASSERT_COMPARE( expected_output->x, expected_output->len,
                         output, total_output_length );
     }
@@ -2186,53 +2149,46 @@
     psa_cipher_operation_t operation;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( expected_output != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
-
     iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
     memset( iv, 0x2a, iv_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_encrypt_setup( &operation,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation,
-                                    iv, sizeof( iv ) ) == PSA_SUCCESS );
-    output_buffer_size = (size_t) input->len +
-                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    PSA_ASSERT( psa_cipher_set_iv( &operation,
+                                   iv, sizeof( iv ) ) );
+    output_buffer_size = ( (size_t) input->len +
+                           PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output, output_buffer_size );
 
     TEST_ASSERT( (unsigned int) first_part_size < input->len );
-    TEST_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_update( &operation,
-                                    input->x + first_part_size,
-                                    input->len - first_part_size,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x + first_part_size,
+                                   input->len - first_part_size,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_finish( &operation,
-                                    output + function_output_length,
-                                    output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_finish( &operation,
+                                   output + function_output_length,
+                                   output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
 
     ASSERT_COMPARE( expected_output->x, expected_output->len,
                     output, total_output_length );
@@ -2264,55 +2220,48 @@
     psa_cipher_operation_t operation;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( expected_output != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
-
     iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
     memset( iv, 0x2a, iv_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation,
-                                    iv, sizeof( iv ) ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_set_iv( &operation,
+                                   iv, sizeof( iv ) ) );
 
-    output_buffer_size = (size_t) input->len +
-                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output_buffer_size = ( (size_t) input->len +
+                           PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output, output_buffer_size );
 
     TEST_ASSERT( (unsigned int) first_part_size < input->len );
-    TEST_ASSERT( psa_cipher_update( &operation,
-                                    input->x, first_part_size,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x, first_part_size,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_update( &operation,
-                                    input->x + first_part_size,
-                                    input->len - first_part_size,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x + first_part_size,
+                                   input->len - first_part_size,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_finish( &operation,
-                                    output + function_output_length,
-                                    output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_finish( &operation,
+                                   output + function_output_length,
+                                   output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
-    TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation ) );
 
     ASSERT_COMPARE( expected_output->x, expected_output->len,
                     output, total_output_length );
@@ -2344,52 +2293,45 @@
     psa_cipher_operation_t operation;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( expected_output != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_output->len ) );
-
     iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
     memset( iv, 0x2a, iv_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_decrypt_setup( &operation,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation,
-                                    iv, iv_size ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_set_iv( &operation,
+                                   iv, iv_size ) );
 
-    output_buffer_size = (size_t) input->len +
-                         PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    output_buffer_size = ( (size_t) input->len +
+                           PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output, output_buffer_size );
 
-    TEST_ASSERT( psa_cipher_update( &operation,
-                                    input->x, input->len,
-                                    output, output_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation,
+                                   input->x, input->len,
+                                   output, output_buffer_size,
+                                   &function_output_length ) );
     total_output_length += function_output_length;
     status = psa_cipher_finish( &operation,
                                 output + function_output_length,
                                 output_buffer_size,
                                 &function_output_length );
     total_output_length += function_output_length;
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
 
     if( expected_status == PSA_SUCCESS )
     {
-        TEST_ASSERT( psa_cipher_abort( &operation ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_cipher_abort( &operation ) );
         ASSERT_COMPARE( expected_output->x, expected_output->len,
                         output, total_output_length );
     }
@@ -2423,62 +2365,57 @@
     psa_cipher_operation_t operation2;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_encrypt_setup( &operation1,
-                                           handle, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_cipher_decrypt_setup( &operation2,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
+                                          handle, alg ) );
+    PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_generate_iv( &operation1,
-                                         iv, iv_size,
-                                         &iv_length ) == PSA_SUCCESS );
-    output1_size = (size_t) input->len +
-                   PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    PSA_ASSERT( psa_cipher_generate_iv( &operation1,
+                                        iv, iv_size,
+                                        &iv_length ) );
+    output1_size = ( (size_t) input->len +
+                     PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output1, output1_size );
 
-    TEST_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
-                                    output1, output1_size,
-                                    &output1_length ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_cipher_finish( &operation1,
-                                    output1 + output1_length, output1_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len,
+                                   output1, output1_size,
+                                   &output1_length ) );
+    PSA_ASSERT( psa_cipher_finish( &operation1,
+                                   output1 + output1_length, output1_size,
+                                   &function_output_length ) );
 
     output1_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_abort( &operation1 ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation1 ) );
 
     output2_size = output1_length;
     ASSERT_ALLOC( output2, output2_size );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation2,
-                                    iv, iv_length ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
-                                    output2, output2_size,
-                                    &output2_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_set_iv( &operation2,
+                                   iv, iv_length ) );
+    PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length,
+                                   output2, output2_size,
+                                   &output2_length ) );
     function_output_length = 0;
-    TEST_ASSERT( psa_cipher_finish( &operation2,
-                                    output2 + output2_length,
-                                    output2_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_finish( &operation2,
+                                   output2 + output2_length,
+                                   output2_size,
+                                   &function_output_length ) );
 
     output2_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_abort( &operation2 ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation2 ) );
 
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
@@ -2514,81 +2451,76 @@
     psa_cipher_operation_t operation2;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key != NULL );
-    TEST_ASSERT( input != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key->x, key->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key->x, key->len ) );
 
-    TEST_ASSERT( psa_cipher_encrypt_setup( &operation1,
-                                           handle, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_cipher_decrypt_setup( &operation2,
-                                           handle, alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_encrypt_setup( &operation1,
+                                          handle, alg ) );
+    PSA_ASSERT( psa_cipher_decrypt_setup( &operation2,
+                                          handle, alg ) );
 
-    TEST_ASSERT( psa_cipher_generate_iv( &operation1,
-                                         iv, iv_size,
-                                         &iv_length ) == PSA_SUCCESS );
-    output1_buffer_size = (size_t) input->len +
-                          PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
+    PSA_ASSERT( psa_cipher_generate_iv( &operation1,
+                                        iv, iv_size,
+                                        &iv_length ) );
+    output1_buffer_size = ( (size_t) input->len +
+                            PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
     ASSERT_ALLOC( output1, output1_buffer_size );
 
     TEST_ASSERT( (unsigned int) first_part_size < input->len );
 
-    TEST_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
-                                    output1, output1_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size,
+                                   output1, output1_buffer_size,
+                                   &function_output_length ) );
     output1_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_update( &operation1,
-                                    input->x + first_part_size,
-                                    input->len - first_part_size,
-                                    output1, output1_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation1,
+                                   input->x + first_part_size,
+                                   input->len - first_part_size,
+                                   output1, output1_buffer_size,
+                                   &function_output_length ) );
     output1_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_finish( &operation1,
-                                    output1 + output1_length,
-                                    output1_buffer_size - output1_length,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_finish( &operation1,
+                                   output1 + output1_length,
+                                   output1_buffer_size - output1_length,
+                                   &function_output_length ) );
     output1_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_abort( &operation1 ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation1 ) );
 
     output2_buffer_size = output1_length;
     ASSERT_ALLOC( output2, output2_buffer_size );
 
-    TEST_ASSERT( psa_cipher_set_iv( &operation2,
-                                    iv, iv_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_set_iv( &operation2,
+                                   iv, iv_length ) );
 
-    TEST_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
-                                    output2, output2_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,
+                                   output2, output2_buffer_size,
+                                   &function_output_length ) );
     output2_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_update( &operation2,
-                                    output1 + first_part_size,
-                                    output1_length - first_part_size,
-                                    output2, output2_buffer_size,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_update( &operation2,
+                                   output1 + first_part_size,
+                                   output1_length - first_part_size,
+                                   output2, output2_buffer_size,
+                                   &function_output_length ) );
     output2_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_finish( &operation2,
-                                    output2 + output2_length,
-                                    output2_buffer_size - output2_length,
-                                    &function_output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_finish( &operation2,
+                                   output2 + output2_length,
+                                   output2_buffer_size - output2_length,
+                                   &function_output_length ) );
     output2_length += function_output_length;
 
-    TEST_ASSERT( psa_cipher_abort( &operation2 ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_cipher_abort( &operation2 ) );
 
     ASSERT_COMPARE( input->x, input->len, output2, output2_length );
 
@@ -2620,50 +2552,43 @@
     psa_status_t expected_result = expected_result_arg;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( nonce != NULL );
-    TEST_ASSERT( additional_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
-
     output_size = input_data->len + tag_length;
     ASSERT_ALLOC( output_data, output_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy,
                               PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
                               alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x, key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x, key_data->len ) );
 
-    TEST_ASSERT( psa_aead_encrypt( handle, alg,
-                                   nonce->x, nonce->len,
-                                   additional_data->x,
-                                   additional_data->len,
-                                   input_data->x, input_data->len,
-                                   output_data, output_size,
-                                   &output_length ) == expected_result );
+    TEST_EQUAL( psa_aead_encrypt( handle, alg,
+                                  nonce->x, nonce->len,
+                                  additional_data->x,
+                                  additional_data->len,
+                                  input_data->x, input_data->len,
+                                  output_data, output_size,
+                                  &output_length ),
+                expected_result );
 
     if( PSA_SUCCESS == expected_result )
     {
         ASSERT_ALLOC( output_data2, output_length );
 
-        TEST_ASSERT( psa_aead_decrypt( handle, alg,
-                                       nonce->x, nonce->len,
-                                       additional_data->x,
-                                       additional_data->len,
-                                       output_data, output_length,
-                                       output_data2, output_length,
-                                       &output_length2 ) == expected_result );
+        TEST_EQUAL( psa_aead_decrypt( handle, alg,
+                                      nonce->x, nonce->len,
+                                      additional_data->x,
+                                      additional_data->len,
+                                      output_data, output_length,
+                                      output_data2, output_length,
+                                      &output_length2 ),
+                    expected_result );
 
         ASSERT_COMPARE( input_data->x, input_data->len,
                         output_data2, output_length2 );
@@ -2694,38 +2619,27 @@
     size_t tag_length = 16;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( additional_data != NULL );
-    TEST_ASSERT( nonce != NULL );
-    TEST_ASSERT( expected_result != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_result->len ) );
-
     output_size = input_data->len + tag_length;
     ASSERT_ALLOC( output_data, output_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
-    TEST_ASSERT( psa_aead_encrypt( handle, alg,
-                                   nonce->x, nonce->len,
-                                   additional_data->x, additional_data->len,
-                                   input_data->x, input_data->len,
-                                   output_data, output_size,
-                                   &output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_aead_encrypt( handle, alg,
+                                  nonce->x, nonce->len,
+                                  additional_data->x, additional_data->len,
+                                  input_data->x, input_data->len,
+                                  output_data, output_size,
+                                  &output_length ) );
 
     ASSERT_COMPARE( expected_result->x, expected_result->len,
                     output_data, output_length );
@@ -2756,39 +2670,29 @@
     psa_key_policy_t policy;
     psa_status_t expected_result = expected_result_arg;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( additional_data != NULL );
-    TEST_ASSERT( nonce != NULL );
-    TEST_ASSERT( expected_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( additional_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( nonce->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_data->len ) );
-
     output_size = input_data->len + tag_length;
     ASSERT_ALLOC( output_data, output_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
-    TEST_ASSERT( psa_aead_decrypt( handle, alg,
-                                   nonce->x, nonce->len,
-                                   additional_data->x,
-                                   additional_data->len,
-                                   input_data->x, input_data->len,
-                                   output_data, output_size,
-                                   &output_length ) == expected_result );
+    TEST_EQUAL( psa_aead_decrypt( handle, alg,
+                                  nonce->x, nonce->len,
+                                  additional_data->x,
+                                  additional_data->len,
+                                  input_data->x, input_data->len,
+                                  output_data, output_size,
+                                  &output_length ),
+                expected_result );
 
     if( expected_result == PSA_SUCCESS )
         ASSERT_COMPARE( expected_data->x, expected_data->len,
@@ -2810,7 +2714,7 @@
     psa_key_type_t type = type_arg;
     psa_algorithm_t alg = alg_arg;
     size_t actual_size = PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( type, bits, alg );
-    TEST_ASSERT( actual_size == (size_t) expected_size_arg );
+    TEST_EQUAL( actual_size, (size_t) expected_size_arg );
 exit:
     ;
 }
@@ -2830,28 +2734,21 @@
     size_t signature_length = 0xdeadbeef;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( output_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( output_data->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          NULL,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         NULL,
+                                         &key_bits ) );
 
     /* Allocate a buffer which has the size advertized by the
      * library. */
@@ -2862,10 +2759,10 @@
     ASSERT_ALLOC( signature, signature_size );
 
     /* Perform the signature. */
-    TEST_ASSERT( psa_asymmetric_sign( handle, alg,
-                                      input_data->x, input_data->len,
-                                      signature, signature_size,
-                                      &signature_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_sign( handle, alg,
+                                     input_data->x, input_data->len,
+                                     signature, signature_size,
+                                     &signature_length ) );
     /* Verify that the signature is what is expected. */
     ASSERT_COMPARE( output_data->x, output_data->len,
                     signature, signature_length );
@@ -2892,31 +2789,26 @@
     size_t signature_length = 0xdeadbeef;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-
     ASSERT_ALLOC( signature, signature_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
     actual_status = psa_asymmetric_sign( handle, alg,
                                          input_data->x, input_data->len,
                                          signature, signature_size,
                                          &signature_length );
-    TEST_ASSERT( actual_status == expected_status );
+    TEST_EQUAL( actual_status, expected_status );
     /* The value of *signature_length is unspecified on error, but
      * whatever it is, it should be less than signature_size, so that
      * if the caller tries to read *signature_length bytes without
@@ -2943,23 +2835,23 @@
     size_t signature_length = 0xdeadbeef;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy,
                               PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY,
                               alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          NULL,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         NULL,
+                                         &key_bits ) );
 
     /* Allocate a buffer which has the size advertized by the
      * library. */
@@ -2970,19 +2862,19 @@
     ASSERT_ALLOC( signature, signature_size );
 
     /* Perform the signature. */
-    TEST_ASSERT( psa_asymmetric_sign( handle, alg,
-                                      input_data->x, input_data->len,
-                                      signature, signature_size,
-                                      &signature_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_sign( handle, alg,
+                                     input_data->x, input_data->len,
+                                     signature, signature_size,
+                                     &signature_length ) );
     /* Check that the signature length looks sensible. */
     TEST_ASSERT( signature_length <= signature_size );
     TEST_ASSERT( signature_length > 0 );
 
     /* Use the library to verify that the signature is correct. */
-    TEST_ASSERT( psa_asymmetric_verify(
-                     handle, alg,
-                     input_data->x, input_data->len,
-                     signature, signature_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_verify(
+                    handle, alg,
+                    input_data->x, input_data->len,
+                    signature, signature_length ) );
 
     if( input_data->len != 0 )
     {
@@ -2990,11 +2882,10 @@
          * detected as invalid. Flip a bit at the beginning, not at the end,
          * because ECDSA may ignore the last few bits of the input. */
         input_data->x[0] ^= 1;
-        TEST_ASSERT( psa_asymmetric_verify(
-                         handle, alg,
-                         input_data->x, input_data->len,
-                         signature,
-                         signature_length ) == PSA_ERROR_INVALID_SIGNATURE );
+        TEST_EQUAL( psa_asymmetric_verify( handle, alg,
+                                           input_data->x, input_data->len,
+                                           signature, signature_length ),
+                    PSA_ERROR_INVALID_SIGNATURE );
     }
 
 exit:
@@ -3016,30 +2907,23 @@
 
     TEST_ASSERT( signature_data->len <= PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE );
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( hash_data != NULL );
-    TEST_ASSERT( signature_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( hash_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( signature_data->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
-    TEST_ASSERT( psa_asymmetric_verify( handle, alg,
-                                        hash_data->x, hash_data->len,
-                                        signature_data->x,
-                                        signature_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_verify( handle, alg,
+                                       hash_data->x, hash_data->len,
+                                       signature_data->x,
+                                       signature_data->len ) );
 exit:
     psa_destroy_key( handle );
     mbedtls_psa_crypto_free( );
@@ -3059,32 +2943,25 @@
     psa_status_t expected_status = expected_status_arg;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( hash_data != NULL );
-    TEST_ASSERT( signature_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( hash_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( signature_data->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
     actual_status = psa_asymmetric_verify( handle, alg,
                                            hash_data->x, hash_data->len,
                                            signature_data->x,
                                            signature_data->len );
 
-    TEST_ASSERT( actual_status == expected_status );
+    TEST_EQUAL( actual_status, expected_status );
 
 exit:
     psa_destroy_key( handle );
@@ -3113,24 +2990,23 @@
     psa_status_t expected_status = expected_status_arg;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* Import the key */
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Determine the maximum output length */
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          NULL,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         NULL,
+                                         &key_bits ) );
     output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
     ASSERT_ALLOC( output, output_size );
 
@@ -3140,8 +3016,8 @@
                                             label->x, label->len,
                                             output, output_size,
                                             &output_length );
-    TEST_ASSERT( actual_status == expected_status );
-    TEST_ASSERT( output_length == expected_output_length );
+    TEST_EQUAL( actual_status, expected_status );
+    TEST_EQUAL( output_length, expected_output_length );
 
     /* If the label is empty, the test framework puts a non-null pointer
      * in label->x. Test that a null pointer works as well. */
@@ -3155,8 +3031,8 @@
                                                 NULL, label->len,
                                                 output, output_size,
                                                 &output_length );
-        TEST_ASSERT( actual_status == expected_status );
-        TEST_ASSERT( output_length == expected_output_length );
+        TEST_EQUAL( actual_status, expected_status );
+        TEST_EQUAL( output_length, expected_output_length );
     }
 
 exit:
@@ -3185,31 +3061,25 @@
     size_t output2_length = ~0;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy,
                               PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT,
                               alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
-
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Determine the maximum ciphertext length */
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          NULL,
-                                          &key_bits ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_get_key_information( handle,
+                                         NULL,
+                                         &key_bits ) );
     output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg );
     ASSERT_ALLOC( output, output_size );
     output2_size = input_data->len;
@@ -3218,20 +3088,20 @@
     /* We test encryption by checking that encrypt-then-decrypt gives back
      * the original plaintext because of the non-optional random
      * part of encryption process which prevents using fixed vectors. */
-    TEST_ASSERT( psa_asymmetric_encrypt( handle, alg,
-                                         input_data->x, input_data->len,
-                                         label->x, label->len,
-                                         output, output_size,
-                                         &output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_encrypt( handle, alg,
+                                        input_data->x, input_data->len,
+                                        label->x, label->len,
+                                        output, output_size,
+                                        &output_length ) );
     /* We don't know what ciphertext length to expect, but check that
      * it looks sensible. */
     TEST_ASSERT( output_length <= output_size );
 
-    TEST_ASSERT( psa_asymmetric_decrypt( handle, alg,
-                                         output, output_length,
-                                         label->x, label->len,
-                                         output2, output2_size,
-                                         &output2_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
+                                        output, output_length,
+                                        label->x, label->len,
+                                        output2, output2_size,
+                                        &output2_length ) );
     ASSERT_COMPARE( input_data->x, input_data->len,
                     output2, output2_length );
 
@@ -3259,35 +3129,28 @@
     size_t output_length = ~0;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( expected_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( expected_data->len ) );
-
     output_size = key_data->len;
     ASSERT_ALLOC( output, output_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
-    TEST_ASSERT( psa_asymmetric_decrypt( handle, alg,
-                                         input_data->x, input_data->len,
-                                         label->x, label->len,
-                                         output,
-                                         output_size,
-                                         &output_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
+                                        input_data->x, input_data->len,
+                                        label->x, label->len,
+                                        output,
+                                        output_size,
+                                        &output_length ) );
     ASSERT_COMPARE( expected_data->x, expected_data->len,
                     output, output_length );
 
@@ -3298,12 +3161,12 @@
         output_length = ~0;
         if( output_size != 0 )
             memset( output, 0, output_size );
-        TEST_ASSERT( psa_asymmetric_decrypt( handle, alg,
-                                             input_data->x, input_data->len,
-                                             NULL, label->len,
-                                             output,
-                                             output_size,
-                                             &output_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_asymmetric_decrypt( handle, alg,
+                                            input_data->x, input_data->len,
+                                            NULL, label->len,
+                                            output,
+                                            output_size,
+                                            &output_length ) );
         ASSERT_COMPARE( expected_data->x, expected_data->len,
                         output, output_length );
     }
@@ -3333,33 +3196,28 @@
     psa_status_t expected_status = expected_status_arg;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( key_data != NULL );
-    TEST_ASSERT( input_data != NULL );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( key_data->len ) );
-    TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( input_data->len ) );
-
     output_size = key_data->len;
     ASSERT_ALLOC( output, output_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   KEY_BITS_FROM_DATA( key_type, key_data ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  KEY_BITS_FROM_DATA( key_type, key_data ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
     actual_status = psa_asymmetric_decrypt( handle, alg,
                                             input_data->x, input_data->len,
                                             label->x, label->len,
                                             output, output_size,
                                             &output_length );
-    TEST_ASSERT( actual_status == expected_status );
+    TEST_EQUAL( actual_status, expected_status );
     TEST_ASSERT( output_length <= output_size );
 
     /* If the label is empty, the test framework puts a non-null pointer
@@ -3374,7 +3232,7 @@
                                                 NULL, label->len,
                                                 output, output_size,
                                                 &output_length );
-        TEST_ASSERT( actual_status == expected_status );
+        TEST_EQUAL( actual_status, expected_status );
         TEST_ASSERT( output_length <= output_size );
     }
 
@@ -3402,22 +3260,23 @@
     psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data->x,
+                                key_data->len ) );
 
-    TEST_ASSERT( psa_key_derivation( &generator, handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     requested_capacity ) == expected_status );
+    TEST_EQUAL( psa_key_derivation( &generator, handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    requested_capacity ),
+                expected_status );
 
 exit:
     psa_generator_abort( &generator );
@@ -3440,37 +3299,36 @@
                                    0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( key_type,
-                                   PSA_BYTES_TO_BITS( sizeof( key_data ) ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( key_type,
+                                  PSA_BYTES_TO_BITS( sizeof( key_data ) ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, key_type,
-                                 key_data,
-                                 sizeof( key_data ) ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, key_type,
+                                key_data,
+                                sizeof( key_data ) ) );
 
     /* valid key derivation */
-    TEST_ASSERT(  psa_key_derivation( &generator, handle, alg,
-                                      NULL, 0,
-                                      NULL, 0,
-                                      capacity ) == PSA_SUCCESS );
+    PSA_ASSERT(  psa_key_derivation( &generator, handle, alg,
+                                     NULL, 0,
+                                     NULL, 0,
+                                     capacity ) );
 
     /* state of generator shouldn't allow additional generation */
-    TEST_ASSERT(  psa_key_derivation( &generator, handle, alg,
-                                      NULL, 0,
-                                      NULL, 0,
-                                      capacity ) == PSA_ERROR_BAD_STATE );
+    TEST_EQUAL(  psa_key_derivation( &generator, handle, alg,
+                                     NULL, 0,
+                                     NULL, 0,
+                                     capacity ),
+                 PSA_ERROR_BAD_STATE );
 
-    TEST_ASSERT( psa_generator_read( &generator, buffer, capacity )
-                 == PSA_SUCCESS );
+    PSA_ASSERT( psa_generator_read( &generator, buffer, capacity ) );
 
-    TEST_ASSERT( psa_generator_read( &generator, buffer, capacity )
-                 == PSA_ERROR_INSUFFICIENT_CAPACITY );
-
+    TEST_EQUAL( psa_generator_read( &generator, buffer, capacity ),
+                PSA_ERROR_INSUFFICIENT_CAPACITY );
 
 exit:
     psa_generator_abort( &generator );
@@ -3479,7 +3337,6 @@
 }
 /* END_CASE */
 
-
 /* BEGIN_CASE */
 void test_derive_invalid_generator_tests( )
 {
@@ -3494,7 +3351,7 @@
     TEST_ASSERT( psa_get_generator_capacity( &generator, &capacity )
                  == PSA_SUCCESS ); // should be PSA_ERROR_BAD_STATE:#183
 
-    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_generator_abort( &generator ) );
 
     TEST_ASSERT( psa_generator_read( &generator, output_buffer, buffer_size )
                  == PSA_ERROR_INSUFFICIENT_CAPACITY ); // should be PSA_ERROR_BAD_STATE:#183
@@ -3540,28 +3397,27 @@
             expected_outputs[i] = NULL;
     }
     ASSERT_ALLOC( output_buffer, output_buffer_size );
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
-                                   PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
+                                  PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Extraction phase. */
-    TEST_ASSERT( psa_key_derivation( &generator, handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     requested_capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_generator_capacity( &generator,
-                                             &current_capacity ) ==
-                 PSA_SUCCESS );
-    TEST_ASSERT( current_capacity == requested_capacity );
+    PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    requested_capacity ) );
+    PSA_ASSERT( psa_get_generator_capacity( &generator,
+                                            &current_capacity ) );
+    TEST_EQUAL( current_capacity, requested_capacity );
     expected_capacity = requested_capacity;
 
     /* Expansion phase. */
@@ -3581,23 +3437,22 @@
                  output_sizes[i] > expected_capacity )
         {
             /* Capacity exceeded. */
-            TEST_ASSERT( status == PSA_ERROR_INSUFFICIENT_CAPACITY );
+            TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_CAPACITY );
             expected_capacity = 0;
             continue;
         }
         /* Success. Check the read data. */
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         if( output_sizes[i] != 0 )
-            TEST_ASSERT( memcmp( output_buffer, expected_outputs[i],
-                                 output_sizes[i] ) == 0 );
+            ASSERT_COMPARE( output_buffer, output_sizes[i],
+                            expected_outputs[i], output_sizes[i] );
         /* Check the generator status. */
         expected_capacity -= output_sizes[i];
-        TEST_ASSERT( psa_get_generator_capacity( &generator,
-                                                 &current_capacity ) ==
-                     PSA_SUCCESS );
-        TEST_ASSERT( expected_capacity == current_capacity );
+        PSA_ASSERT( psa_get_generator_capacity( &generator,
+                                                &current_capacity ) );
+        TEST_EQUAL( expected_capacity, current_capacity );
     }
-    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_generator_abort( &generator ) );
 
 exit:
     mbedtls_free( output_buffer );
@@ -3623,28 +3478,27 @@
     size_t current_capacity;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
-                                   PSA_BYTES_TO_BITS( key_data->len ),
-                                   &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
+                                  PSA_BYTES_TO_BITS( key_data->len ),
+                                  &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
-    TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Extraction phase. */
-    TEST_ASSERT( psa_key_derivation( &generator, handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     requested_capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_generator_capacity( &generator,
-                                             &current_capacity ) ==
-                 PSA_SUCCESS );
-    TEST_ASSERT( current_capacity == expected_capacity );
+    PSA_ASSERT( psa_key_derivation( &generator, handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    requested_capacity ) );
+    PSA_ASSERT( psa_get_generator_capacity( &generator,
+                                            &current_capacity ) );
+    TEST_EQUAL( current_capacity, expected_capacity );
 
     /* Expansion phase. */
     while( current_capacity > 0 )
@@ -3652,22 +3506,20 @@
         size_t read_size = sizeof( output_buffer );
         if( read_size > current_capacity )
             read_size = current_capacity;
-        TEST_ASSERT( psa_generator_read( &generator,
-                                         output_buffer,
-                                         read_size ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_generator_read( &generator,
+                                        output_buffer,
+                                        read_size ) );
         expected_capacity -= read_size;
-        TEST_ASSERT( psa_get_generator_capacity( &generator,
-                                                 &current_capacity ) ==
-                     PSA_SUCCESS );
-        TEST_ASSERT( current_capacity == expected_capacity );
+        PSA_ASSERT( psa_get_generator_capacity( &generator,
+                                                &current_capacity ) );
+        TEST_EQUAL( current_capacity, expected_capacity );
     }
 
     /* Check that the generator refuses to go over capacity. */
-    TEST_ASSERT( psa_generator_read( &generator,
-                                     output_buffer,
-                                     1 ) == PSA_ERROR_INSUFFICIENT_CAPACITY );
+    TEST_EQUAL( psa_generator_read( &generator, output_buffer, 1 ),
+                PSA_ERROR_INSUFFICIENT_CAPACITY );
 
-    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_generator_abort( &generator ) );
 
 exit:
     psa_generator_abort( &generator );
@@ -3699,38 +3551,38 @@
     psa_key_type_t got_type;
     size_t got_bits;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
-                                   PSA_BYTES_TO_BITS( key_data->len ),
-                                   &base_handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
+                                  PSA_BYTES_TO_BITS( key_data->len ),
+                                  &base_handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( base_handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
+    PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Derive a key. */
-    TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_allocate_key( derived_type, derived_bits,
-                                   &derived_handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    capacity ) );
+    PSA_ASSERT( psa_allocate_key( derived_type, derived_bits,
+                                  &derived_handle ) );
     psa_key_policy_set_usage( &policy, derived_usage, derived_alg );
-    TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_import_key( derived_handle,
-                                           derived_type,
-                                           derived_bits,
-                                           &generator ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
+    PSA_ASSERT( psa_generator_import_key( derived_handle,
+                                          derived_type,
+                                          derived_bits,
+                                          &generator ) );
 
     /* Test the key information */
-    TEST_ASSERT( psa_get_key_information( derived_handle,
-                                          &got_type,
-                                          &got_bits ) == PSA_SUCCESS );
-    TEST_ASSERT( got_type == derived_type );
-    TEST_ASSERT( got_bits == derived_bits );
+    PSA_ASSERT( psa_get_key_information( derived_handle,
+                                         &got_type,
+                                         &got_bits ) );
+    TEST_EQUAL( got_type, derived_type );
+    TEST_EQUAL( got_bits, derived_bits );
 
     /* Exercise the derived key. */
     if( ! exercise_key( derived_handle, derived_usage, derived_alg ) )
@@ -3767,61 +3619,62 @@
 
     ASSERT_ALLOC( output_buffer, capacity );
     ASSERT_ALLOC( export_buffer, capacity );
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
-                                   PSA_BYTES_TO_BITS( key_data->len ),
-                                   &base_handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
+                                  PSA_BYTES_TO_BITS( key_data->len ),
+                                  &base_handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( base_handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
-                                 key_data->x,
-                                 key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( base_handle, &policy ) );
+    PSA_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE,
+                                key_data->x,
+                                key_data->len ) );
 
     /* Derive some material and output it. */
-    TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_read( &generator,
-                                     output_buffer,
-                                     capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    capacity ) );
+    PSA_ASSERT( psa_generator_read( &generator,
+                                    output_buffer,
+                                    capacity ) );
+    PSA_ASSERT( psa_generator_abort( &generator ) );
 
     /* Derive the same output again, but this time store it in key objects. */
-    TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg,
-                                     salt->x, salt->len,
-                                     label->x, label->len,
-                                     capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, derived_bits,
-                                   &derived_handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_key_derivation( &generator, base_handle, alg,
+                                    salt->x, salt->len,
+                                    label->x, label->len,
+                                    capacity ) );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, derived_bits,
+                                  &derived_handle ) );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
-    TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_import_key( derived_handle,
-                                           PSA_KEY_TYPE_RAW_DATA,
-                                           derived_bits,
-                                           &generator ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_export_key( derived_handle,
-                                 export_buffer, bytes1,
-                                 &length ) == PSA_SUCCESS );
-    TEST_ASSERT( length == bytes1 );
-    TEST_ASSERT( psa_destroy_key( derived_handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA,
-                                   PSA_BYTES_TO_BITS( bytes2 ),
-                                   &derived_handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_import_key( derived_handle,
-                                           PSA_KEY_TYPE_RAW_DATA,
-                                           PSA_BYTES_TO_BITS( bytes2 ),
-                                           &generator ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_export_key( derived_handle,
-                                 export_buffer + bytes1, bytes2,
-                                 &length ) == PSA_SUCCESS );
-    TEST_ASSERT( length == bytes2 );
+    PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
+    PSA_ASSERT( psa_generator_import_key( derived_handle,
+                                          PSA_KEY_TYPE_RAW_DATA,
+                                          derived_bits,
+                                          &generator ) );
+    PSA_ASSERT( psa_export_key( derived_handle,
+                                export_buffer, bytes1,
+                                &length ) );
+    TEST_EQUAL( length, bytes1 );
+    PSA_ASSERT( psa_destroy_key( derived_handle ) );
+    PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA,
+                                  PSA_BYTES_TO_BITS( bytes2 ),
+                                  &derived_handle ) );
+    PSA_ASSERT( psa_set_key_policy( derived_handle, &policy ) );
+    PSA_ASSERT( psa_generator_import_key( derived_handle,
+                                          PSA_KEY_TYPE_RAW_DATA,
+                                          PSA_BYTES_TO_BITS( bytes2 ),
+                                          &generator ) );
+    PSA_ASSERT( psa_export_key( derived_handle,
+                                export_buffer + bytes1, bytes2,
+                                &length ) );
+    TEST_EQUAL( length, bytes2 );
 
     /* Compare the outputs from the two runs. */
-    TEST_ASSERT( memcmp( output_buffer, export_buffer, capacity ) == 0 );
+    ASSERT_COMPARE( output_buffer, bytes1 + bytes2,
+                    export_buffer, capacity );
 
 exit:
     mbedtls_free( output_buffer );
@@ -3845,23 +3698,24 @@
     psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( our_key_type,
-                                   KEY_BITS_FROM_DATA( our_key_type,
-                                                       our_key_data ),
-                                   &our_key ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( our_key_type,
+                                  KEY_BITS_FROM_DATA( our_key_type,
+                                                      our_key_data ),
+                                  &our_key ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( our_key, our_key_type,
-                                 our_key_data->x,
-                                 our_key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
+    PSA_ASSERT( psa_import_key( our_key, our_key_type,
+                                our_key_data->x,
+                                our_key_data->len ) );
 
-    TEST_ASSERT( psa_key_agreement( &generator,
-                                    our_key,
-                                    peer_key_data->x, peer_key_data->len,
-                                    alg ) == expected_status_arg );
+    TEST_EQUAL( psa_key_agreement( &generator,
+                                   our_key,
+                                   peer_key_data->x, peer_key_data->len,
+                                   alg ),
+                expected_status_arg );
 
 exit:
     psa_generator_abort( &generator );
@@ -3884,42 +3738,40 @@
     size_t actual_capacity;
     unsigned char output[16];
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( our_key_type,
-                                   KEY_BITS_FROM_DATA( our_key_type,
-                                                       our_key_data ),
-                                   &our_key ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( our_key_type,
+                                  KEY_BITS_FROM_DATA( our_key_type,
+                                                      our_key_data ),
+                                  &our_key ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( our_key, our_key_type,
-                                 our_key_data->x,
-                                 our_key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
+    PSA_ASSERT( psa_import_key( our_key, our_key_type,
+                                our_key_data->x,
+                                our_key_data->len ) );
 
-    TEST_ASSERT( psa_key_agreement( &generator,
-                                    our_key,
-                                    peer_key_data->x, peer_key_data->len,
-                                    alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_key_agreement( &generator,
+                                   our_key,
+                                   peer_key_data->x, peer_key_data->len,
+                                   alg ) );
 
     /* Test the advertized capacity. */
-    TEST_ASSERT( psa_get_generator_capacity(
-                     &generator, &actual_capacity ) == PSA_SUCCESS );
-    TEST_ASSERT( actual_capacity == (size_t) expected_capacity_arg );
+    PSA_ASSERT( psa_get_generator_capacity(
+                    &generator, &actual_capacity ) );
+    TEST_EQUAL( actual_capacity, (size_t) expected_capacity_arg );
 
     /* Test the actual capacity by reading the output. */
     while( actual_capacity > sizeof( output ) )
     {
-        TEST_ASSERT( psa_generator_read( &generator,
-                                         output, sizeof( output ) ) ==
-                     PSA_SUCCESS );
+        PSA_ASSERT( psa_generator_read( &generator,
+                                        output, sizeof( output ) ) );
         actual_capacity -= sizeof( output );
     }
-    TEST_ASSERT( psa_generator_read( &generator,
-                                     output, actual_capacity ) ==
-                 PSA_SUCCESS );
-    TEST_ASSERT( psa_generator_read( &generator, output, 1 ) ==
-                 PSA_ERROR_INSUFFICIENT_CAPACITY );
+    PSA_ASSERT( psa_generator_read( &generator,
+                                    output, actual_capacity ) );
+    TEST_EQUAL( psa_generator_read( &generator, output, 1 ),
+                PSA_ERROR_INSUFFICIENT_CAPACITY );
 
 exit:
     psa_generator_abort( &generator );
@@ -3944,38 +3796,36 @@
     ASSERT_ALLOC( actual_output, MAX( expected_output1->len,
                                       expected_output2->len ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( our_key_type,
-                                   KEY_BITS_FROM_DATA( our_key_type,
-                                                       our_key_data ),
-                                   &our_key ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( our_key_type,
+                                  KEY_BITS_FROM_DATA( our_key_type,
+                                                      our_key_data ),
+                                  &our_key ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg );
-    TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key( our_key, our_key_type,
-                                 our_key_data->x,
-                                 our_key_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( our_key, &policy ) );
+    PSA_ASSERT( psa_import_key( our_key, our_key_type,
+                                our_key_data->x,
+                                our_key_data->len ) );
 
-    TEST_ASSERT( psa_key_agreement( &generator,
-                                    our_key,
-                                    peer_key_data->x, peer_key_data->len,
-                                    alg ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_key_agreement( &generator,
+                                   our_key,
+                                   peer_key_data->x, peer_key_data->len,
+                                   alg ) );
 
-    TEST_ASSERT(
-        psa_generator_read( &generator,
-                            actual_output,
-                            expected_output1->len ) == PSA_SUCCESS );
-    TEST_ASSERT( memcmp( actual_output, expected_output1->x,
-                         expected_output1->len ) == 0 );
+    PSA_ASSERT( psa_generator_read( &generator,
+                                    actual_output,
+                                    expected_output1->len ) );
+    ASSERT_COMPARE( actual_output, expected_output1->len,
+                    expected_output1->x, expected_output1->len );
     if( expected_output2->len != 0 )
     {
-        TEST_ASSERT(
-            psa_generator_read( &generator,
-                                actual_output,
-                                expected_output2->len ) == PSA_SUCCESS );
-        TEST_ASSERT( memcmp( actual_output, expected_output2->x,
-                             expected_output2->len ) == 0 );
+        PSA_ASSERT( psa_generator_read( &generator,
+                                        actual_output,
+                                        expected_output2->len ) );
+        ASSERT_COMPARE( actual_output, expected_output2->len,
+                        expected_output2->x, expected_output2->len );
     }
 
 exit:
@@ -4000,7 +3850,7 @@
     ASSERT_ALLOC( changed, bytes );
     memcpy( output + bytes, trail, sizeof( trail ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     /* Run several times, to ensure that every output byte will be
      * nonzero at least once with overwhelming probability
@@ -4009,10 +3859,11 @@
     {
         if( bytes != 0 )
             memset( output, 0, bytes );
-        TEST_ASSERT( psa_generate_random( output, bytes ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_generate_random( output, bytes ) );
 
         /* Check that no more than bytes have been overwritten */
-        TEST_ASSERT( memcmp( output + bytes, trail, sizeof( trail ) ) == 0 );
+        ASSERT_COMPARE( output + bytes, sizeof( trail ),
+                        trail, sizeof( trail ) );
 
         for( i = 0; i < bytes; i++ )
         {
@@ -4055,25 +3906,24 @@
         expected_status == PSA_SUCCESS ? PSA_SUCCESS : PSA_ERROR_EMPTY_SLOT;
     psa_key_policy_t policy;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_allocate_key( type, bits, &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_allocate_key( type, bits, &handle ) );
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, usage, alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     /* Generate a key */
-    TEST_ASSERT( psa_generate_key( handle, type, bits,
-                                   NULL, 0 ) == expected_status );
+    TEST_EQUAL( psa_generate_key( handle, type, bits, NULL, 0 ),
+                expected_status );
 
     /* Test the key information */
-    TEST_ASSERT( psa_get_key_information( handle,
-                                          &got_type,
-                                          &got_bits ) == expected_info_status );
+    TEST_EQUAL( psa_get_key_information( handle, &got_type, &got_bits ),
+                expected_info_status );
     if( expected_info_status != PSA_SUCCESS )
         goto exit;
-    TEST_ASSERT( got_type == type );
-    TEST_ASSERT( got_bits == bits );
+    TEST_EQUAL( got_type, type );
+    TEST_EQUAL( got_bits, bits );
 
     /* Do something with the key according to its type and permitted usage. */
     if( ! exercise_key( handle, usage, alg ) )
@@ -4112,78 +3962,80 @@
     ASSERT_ALLOC( first_export, export_size );
     ASSERT_ALLOC( second_export, export_size );
 
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
-                                 type, bits,
-                                 &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
+                                type, bits,
+                                &handle ) );
     psa_key_policy_init( &policy_set );
     psa_key_policy_set_usage( &policy_set, policy_usage,
                               policy_alg );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy_set ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy_set ) );
 
     switch( generation_method )
     {
         case IMPORT_KEY:
             /* Import the key */
-            TEST_ASSERT( psa_import_key( handle, type,
-                                         data->x, data->len ) == PSA_SUCCESS );
+            PSA_ASSERT( psa_import_key( handle, type,
+                                        data->x, data->len ) );
             break;
 
         case GENERATE_KEY:
             /* Generate a key */
-            TEST_ASSERT( psa_generate_key( handle, type, bits,
-                                           NULL, 0 ) == PSA_SUCCESS );
+            PSA_ASSERT( psa_generate_key( handle, type, bits,
+                                          NULL, 0 ) );
             break;
 
         case DERIVE_KEY:
             /* Create base key */
-            TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
-                                           PSA_BYTES_TO_BITS( data->len ),
-                                           &base_key ) == PSA_SUCCESS );
+            PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE,
+                                          PSA_BYTES_TO_BITS( data->len ),
+                                          &base_key ) );
             psa_key_policy_init( &base_policy_set );
             psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE,
                                       base_policy_alg );
-            TEST_ASSERT( psa_set_key_policy(
-                base_key, &base_policy_set ) == PSA_SUCCESS );
-            TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
-                                         data->x, data->len ) == PSA_SUCCESS );
+            PSA_ASSERT( psa_set_key_policy(
+                            base_key, &base_policy_set ) );
+            PSA_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE,
+                                        data->x, data->len ) );
             /* Derive a key. */
-            TEST_ASSERT( psa_key_derivation( &generator, base_key,
-                                             base_policy_alg,
-                                             NULL, 0, NULL, 0,
-                                             export_size ) == PSA_SUCCESS );
-            TEST_ASSERT( psa_generator_import_key(
-                handle, PSA_KEY_TYPE_RAW_DATA,
-                bits, &generator ) == PSA_SUCCESS );
+            PSA_ASSERT( psa_key_derivation( &generator, base_key,
+                                            base_policy_alg,
+                                            NULL, 0, NULL, 0,
+                                            export_size ) );
+            PSA_ASSERT( psa_generator_import_key(
+                            handle, PSA_KEY_TYPE_RAW_DATA,
+                            bits, &generator ) );
             break;
     }
 
     /* Export the key */
-    TEST_ASSERT( psa_export_key( handle, first_export, export_size,
-                                 &first_exported_length ) == export_status );
+    TEST_EQUAL( psa_export_key( handle,
+                                first_export, export_size,
+                                &first_exported_length ),
+                export_status );
 
     /* Shutdown and restart */
     mbedtls_psa_crypto_free();
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
     /* Check key slot still contains key data */
-    TEST_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
-                               &handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_get_key_information(
-        handle, &type_get, &bits_get ) == PSA_SUCCESS );
-    TEST_ASSERT( type_get == type );
-    TEST_ASSERT( bits_get == (size_t) bits );
+    PSA_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1,
+                              &handle ) );
+    PSA_ASSERT( psa_get_key_information(
+                    handle, &type_get, &bits_get ) );
+    TEST_EQUAL( type_get, type );
+    TEST_EQUAL( bits_get, (size_t) bits );
 
-    TEST_ASSERT( psa_get_key_policy( handle, &policy_get ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_key_policy_get_usage(
-        &policy_get ) == policy_usage );
-    TEST_ASSERT( psa_key_policy_get_algorithm(
-        &policy_get ) == policy_alg );
+    PSA_ASSERT( psa_get_key_policy( handle, &policy_get ) );
+    TEST_EQUAL( psa_key_policy_get_usage( &policy_get ), policy_usage );
+    TEST_EQUAL( psa_key_policy_get_algorithm( &policy_get ), policy_alg );
 
     /* Export the key again */
-    TEST_ASSERT( psa_export_key( handle, second_export, export_size,
-                                 &second_exported_length ) == export_status );
+    TEST_EQUAL( psa_export_key( handle,
+                                second_export, export_size,
+                                &second_exported_length ),
+                export_status );
 
     if( export_status == PSA_SUCCESS )
     {
diff --git a/tests/suites/test_suite_psa_crypto_entropy.function b/tests/suites/test_suite_psa_crypto_entropy.function
index 46c77e9..727db43 100644
--- a/tests/suites/test_suite_psa_crypto_entropy.function
+++ b/tests/suites/test_suite_psa_crypto_entropy.function
@@ -6,11 +6,6 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
-/* MAX value support macro */
-#if !defined(MAX)
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
 /* Calculating the minimum allowed entropy size in bytes */
 #define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
 
@@ -52,12 +47,12 @@
     TEST_ASSERT( ( its_status == PSA_ITS_SUCCESS ) ||
                  ( its_status == PSA_ITS_ERROR_KEY_NOT_FOUND ) );
     status = mbedtls_psa_inject_entropy( seed, seed_length_a );
-    TEST_ASSERT( status == expected_status_a );
+    TEST_EQUAL( status, expected_status_a );
     status = mbedtls_psa_inject_entropy( seed, seed_length_b );
-    TEST_ASSERT( status == expected_status_b );
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_generate_random( output,
-                                      sizeof( output ) ) == PSA_SUCCESS );
+    TEST_EQUAL( status, expected_status_b );
+    PSA_ASSERT( psa_crypto_init( ) );
+    PSA_ASSERT( psa_generate_random( output,
+                                     sizeof( output ) ) );
     TEST_ASSERT( memcmp( output, zeros, sizeof( output ) ) != 0 );
 exit:
     mbedtls_free( seed );
@@ -82,19 +77,19 @@
     TEST_ASSERT( ( its_status == PSA_ITS_SUCCESS ) ||
                  ( its_status == PSA_ITS_ERROR_KEY_NOT_FOUND ) );
     status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
-    TEST_ASSERT( status == PSA_SUCCESS );
+    PSA_ASSERT( status );
     its_status =  psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
-    TEST_ASSERT( its_status == PSA_ITS_SUCCESS );
+    TEST_EQUAL( its_status, PSA_ITS_SUCCESS );
     status = psa_crypto_init( );
-    TEST_ASSERT( status == PSA_ERROR_INSUFFICIENT_ENTROPY );
+    TEST_EQUAL( status, PSA_ERROR_INSUFFICIENT_ENTROPY );
     status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
-    TEST_ASSERT( status == PSA_SUCCESS );
+    PSA_ASSERT( status );
     status = psa_crypto_init( );
-    TEST_ASSERT( status == PSA_SUCCESS );
+    PSA_ASSERT( status );
     mbedtls_psa_crypto_free( );
     /* The seed is written by nv_seed callback functions therefore the injection will fail */
     status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
-    TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED );
+    TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
 exit:
     psa_its_remove( PSA_CRYPTO_ITS_RANDOM_SEED_UID );
     mbedtls_psa_crypto_free( );
diff --git a/tests/suites/test_suite_psa_crypto_hash.function b/tests/suites/test_suite_psa_crypto_hash.function
index 14e6a97..5931a23 100644
--- a/tests/suites/test_suite_psa_crypto_hash.function
+++ b/tests/suites/test_suite_psa_crypto_hash.function
@@ -15,7 +15,7 @@
  * END_DEPENDENCIES
  */
 
- /* BEGIN_CASE */
+/* BEGIN_CASE */
 void hash_finish( int alg_arg, data_t *input, data_t *expected_hash )
 {
     psa_algorithm_t alg = alg_arg;
@@ -23,14 +23,14 @@
     size_t actual_hash_length;
     psa_hash_operation_t operation;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_update( &operation,
-                                  input->x, input->len ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_finish( &operation,
-                                  actual_hash, sizeof( actual_hash ),
-                                  &actual_hash_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    PSA_ASSERT( psa_hash_update( &operation,
+                                 input->x, input->len ) );
+    PSA_ASSERT( psa_hash_finish( &operation,
+                                 actual_hash, sizeof( actual_hash ),
+                                 &actual_hash_length ) );
     ASSERT_COMPARE( expected_hash->x, expected_hash->len,
                     actual_hash, actual_hash_length );
 
@@ -45,15 +45,15 @@
     psa_algorithm_t alg = alg_arg;
     psa_hash_operation_t operation;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_update( &operation,
-                                  input->x,
-                                  input->len ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_hash_verify( &operation,
-                                  expected_hash->x,
-                                  expected_hash->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_hash_setup( &operation, alg ) );
+    PSA_ASSERT( psa_hash_update( &operation,
+                                 input->x,
+                                 input->len ) );
+    PSA_ASSERT( psa_hash_verify( &operation,
+                                 expected_hash->x,
+                                 expected_hash->len ) );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -69,22 +69,21 @@
     psa_hash_operation_t operation;
     uint32_t len = 0;
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
     do
     {
         memset( actual_hash, 0, sizeof( actual_hash ) );
-        TEST_ASSERT( psa_hash_setup( &operation, alg ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_hash_setup( &operation, alg ) );
 
-        TEST_ASSERT( psa_hash_update( &operation,
-                                      input->x, len ) == PSA_SUCCESS );
-        TEST_ASSERT( psa_hash_update( &operation,
-                                      input->x + len, input->len - len ) ==
-                                      PSA_SUCCESS );
+        PSA_ASSERT( psa_hash_update( &operation,
+                                     input->x, len ) );
+        PSA_ASSERT( psa_hash_update( &operation,
+                                     input->x + len, input->len - len ) );
 
-        TEST_ASSERT( psa_hash_finish( &operation,
-                                      actual_hash, sizeof( actual_hash ),
-                                      &actual_hash_length ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_hash_finish( &operation,
+                                     actual_hash, sizeof( actual_hash ),
+                                     &actual_hash_length ) );
 
         ASSERT_COMPARE( expected_hash->x, expected_hash->len,
                         actual_hash, actual_hash_length );
diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function
index 132fe82..c8f6e1b 100644
--- a/tests/suites/test_suite_psa_crypto_init.function
+++ b/tests/suites/test_suite_psa_crypto_init.function
@@ -12,9 +12,6 @@
 #include "mbedtls/entropy.h"
 #include "mbedtls/entropy_poll.h"
 
-#define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
-#define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) )
-
 #define ENTROPY_MIN_NV_SEED_SIZE                                        \
     MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
 
@@ -142,9 +139,9 @@
     for( i = 0; i < count; i++ )
     {
         status = psa_crypto_init( );
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         status = psa_crypto_init( );
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         mbedtls_psa_crypto_free( );
     }
 }
@@ -156,7 +153,7 @@
     int i;
     for( i = 0; i < count; i++ )
     {
-        TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_crypto_init( ) );
         mbedtls_psa_crypto_free( );
     }
     mbedtls_psa_crypto_free( );
@@ -172,11 +169,11 @@
     for( i = 0; i < count; i++ )
     {
         status = psa_crypto_init( );
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         mbedtls_psa_crypto_free( );
     }
     status = psa_generate_random( random, sizeof( random ) );
-    TEST_ASSERT( status == PSA_ERROR_BAD_STATE );
+    TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
 }
 /* END_CASE */
 
@@ -189,11 +186,11 @@
     for( i = 0; i < count; i++ )
     {
         status = psa_crypto_init( );
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         mbedtls_psa_crypto_free( );
     }
     status = psa_import_key( 1, PSA_KEY_TYPE_RAW_DATA, data, sizeof( data ) );
-    TEST_ASSERT( status == PSA_ERROR_BAD_STATE );
+    TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
 }
 /* END_CASE */
 
@@ -204,16 +201,14 @@
     uint8_t random[10] = { 0 };
 
     custom_entropy_sources_mask = sources_arg;
-    TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
-                     custom_entropy_init, mbedtls_entropy_free ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
+                    custom_entropy_init, mbedtls_entropy_free ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == expected_init_status );
+    TEST_EQUAL( psa_crypto_init( ), expected_init_status );
     if( expected_init_status != PSA_SUCCESS )
         goto exit;
 
-    TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( psa_generate_random( random, sizeof( random ) ) );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -246,16 +241,14 @@
     fake_entropy_state.length_sequence = lengths;
 
     custom_entropy_sources_mask = ENTROPY_SOURCE_FAKE;
-    TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
-                     custom_entropy_init, mbedtls_entropy_free ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
+                    custom_entropy_init, mbedtls_entropy_free ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == expected_init_status );
+    TEST_EQUAL( psa_crypto_init( ), expected_init_status );
     if( expected_init_status != PSA_SUCCESS )
         goto exit;
 
-    TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( psa_generate_random( random, sizeof( random ) ) );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -275,16 +268,14 @@
     TEST_ASSERT( mbedtls_nv_seed_write( seed, seed_size ) >= 0 );
 
     custom_entropy_sources_mask = ENTROPY_SOURCE_NV_SEED;
-    TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
-                     custom_entropy_init, mbedtls_entropy_free ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( mbedtls_psa_crypto_configure_entropy_sources(
+                    custom_entropy_init, mbedtls_entropy_free ) );
 
-    TEST_ASSERT( psa_crypto_init( ) == expected_init_status );
+    TEST_EQUAL( psa_crypto_init( ), expected_init_status );
     if( expected_init_status != PSA_SUCCESS )
         goto exit;
 
-    TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) ==
-                 PSA_SUCCESS );
+    PSA_ASSERT( psa_generate_random( random, sizeof( random ) ) );
 
 exit:
     mbedtls_free( seed );
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index a8316c4..94e6f6c 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -46,7 +46,7 @@
 #define KEY_TYPE_IS_DSA                 ( 1u << 5 )
 #define KEY_TYPE_IS_ECC                 ( 1u << 6 )
 
-#define TEST_CLASSIFICATION_MACRO( flag, alg, flags )            \
+#define TEST_CLASSIFICATION_MACRO( flag, alg, flags )           \
     TEST_ASSERT( PSA_##flag( alg ) == !! ( ( flags ) & flag ) )
 
 void algorithm_classification( psa_algorithm_t alg, unsigned flags )
@@ -83,15 +83,15 @@
     TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_ECC, type, flags );
 
     /* Macros with derived semantics */
-    TEST_ASSERT( PSA_KEY_TYPE_IS_ASYMMETRIC( type ) ==
-                 ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ||
-                   PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
-    TEST_ASSERT( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) ==
-                 ( PSA_KEY_TYPE_IS_ECC( type ) &&
-                   PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
-    TEST_ASSERT( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) ==
-                 ( PSA_KEY_TYPE_IS_ECC( type ) &&
-                   PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
+    TEST_EQUAL( PSA_KEY_TYPE_IS_ASYMMETRIC( type ),
+                ( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ||
+                  PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
+    TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ),
+                ( PSA_KEY_TYPE_IS_ECC( type ) &&
+                  PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
+    TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ),
+                ( PSA_KEY_TYPE_IS_ECC( type ) &&
+                  PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
 
 exit: ;
 }
@@ -113,7 +113,7 @@
     algorithm_classification( alg, classification_flags );
 
     /* Length */
-    TEST_ASSERT( length == PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) );
+    TEST_EQUAL( length, PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) );
 
 exit: ;
 }
@@ -134,7 +134,7 @@
     algorithm_classification( alg, classification_flags );
 
     /* Tag length */
-    TEST_ASSERT( tag_length == PSA_AEAD_TAG_LENGTH( alg ) );
+    TEST_EQUAL( tag_length, PSA_AEAD_TAG_LENGTH( alg ) );
 
 exit: ;
 }
@@ -174,18 +174,18 @@
     algorithm_classification( alg, 0 );
 
     /* Dependent algorithms */
-    TEST_ASSERT( PSA_ALG_HMAC_GET_HASH( hmac_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( rsa_pkcs1v15_sign_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( rsa_pss_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( dsa_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( deterministic_dsa_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( ecdsa_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_SIGN_GET_HASH( deterministic_ecdsa_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_RSA_OAEP_GET_HASH( rsa_oaep_alg ) == alg );
-    TEST_ASSERT( PSA_ALG_HKDF_GET_HASH( hkdf_alg ) == alg );
+    TEST_EQUAL( PSA_ALG_HMAC_GET_HASH( hmac_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( rsa_pkcs1v15_sign_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( rsa_pss_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( dsa_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( deterministic_dsa_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( ecdsa_alg ), alg );
+    TEST_EQUAL( PSA_ALG_SIGN_GET_HASH( deterministic_ecdsa_alg ), alg );
+    TEST_EQUAL( PSA_ALG_RSA_OAEP_GET_HASH( rsa_oaep_alg ), alg );
+    TEST_EQUAL( PSA_ALG_HKDF_GET_HASH( hkdf_alg ), alg );
 
     /* Hash length */
-    TEST_ASSERT( length == PSA_HASH_SIZE( alg ) );
+    TEST_EQUAL( length, PSA_HASH_SIZE( alg ) );
     TEST_ASSERT( length <= PSA_HASH_MAX_SIZE );
 }
 /* END_CASE */
@@ -203,7 +203,7 @@
 
     mac_algorithm_core( alg, classification_flags,
                         key_type, key_bits, length );
-    TEST_ASSERT( PSA_ALG_FULL_LENGTH_MAC( alg ) == alg );
+    TEST_EQUAL( PSA_ALG_FULL_LENGTH_MAC( alg ), alg );
     TEST_ASSERT( length <= PSA_MAC_MAX_SIZE );
 
     /* Truncated versions */
@@ -212,16 +212,16 @@
         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 );
+        TEST_EQUAL( 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 ) );
+        TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, 1 ),
+                    PSA_ALG_TRUNCATED_MAC( alg, 1 ) );
+        TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, length - 1 ),
+                    PSA_ALG_TRUNCATED_MAC( alg, length - 1) );
+        TEST_EQUAL( PSA_ALG_TRUNCATED_MAC( truncated_alg, length ),
+                    PSA_ALG_TRUNCATED_MAC( alg, length ) );
     }
 }
 /* END_CASE */
@@ -238,7 +238,7 @@
     size_t n;
 
     TEST_ASSERT( PSA_ALG_IS_HASH( hash_alg ) );
-    TEST_ASSERT( PSA_ALG_HMAC( hash_alg ) == alg );
+    TEST_EQUAL( PSA_ALG_HMAC( hash_alg ), alg );
 
     TEST_ASSERT( block_size <= PSA_HMAC_MAX_HASH_BLOCK_SIZE );
 
@@ -248,7 +248,7 @@
     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 );
+        TEST_EQUAL( PSA_ALG_HMAC_GET_HASH( truncated_alg ), hash_alg );
     }
 }
 /* END_CASE */
@@ -287,20 +287,17 @@
     {
         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 );
+        TEST_EQUAL( 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 ) );
+        TEST_EQUAL( PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, 1 ),
+                    PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, 1 ) );
+        TEST_EQUAL( PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, tag_length - 1 ),
+                    PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, tag_length - 1) );
+        TEST_EQUAL( PSA_ALG_AEAD_WITH_TAG_LENGTH( truncated_alg, tag_length ),
+                    PSA_ALG_AEAD_WITH_TAG_LENGTH( alg, tag_length ) );
     }
 }
 /* END_CASE */
@@ -363,8 +360,8 @@
     /* Check combinations with key agreements */
     TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) );
     TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) );
-    TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ) == alg );
-    TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ) == alg );
+    TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ), alg );
+    TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ), alg );
 }
 /* END_CASE */
 
@@ -388,8 +385,8 @@
     /* Check combinations with key agreements */
     TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) );
     TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) );
-    TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ) == alg );
-    TEST_ASSERT( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ) == alg );
+    TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ), alg );
+    TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ), alg );
 }
 /* END_CASE */
 
@@ -416,7 +413,7 @@
     /* Shared secret derivation properties */
     TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( actual_post_alg ) ||
                  PSA_ALG_IS_KEY_SELECTION( actual_post_alg ) );
-    TEST_ASSERT( actual_post_alg == expected_post_alg );
+    TEST_EQUAL( actual_post_alg, expected_post_alg );
 }
 /* END_CASE */
 
@@ -431,22 +428,22 @@
     if( classification_flags & KEY_TYPE_IS_PUBLIC_KEY )
     {
         psa_key_type_t pair_type = PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( type );
-        TEST_ASSERT( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( pair_type ) == type );
+        TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( pair_type ), type );
         key_type_classification( pair_type,
                                  ( classification_flags
                                    & ~KEY_TYPE_IS_PUBLIC_KEY )
                                  | KEY_TYPE_IS_KEYPAIR );
-        TEST_ASSERT( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type ) == type );
+        TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type ), type );
     }
     if( classification_flags & KEY_TYPE_IS_KEYPAIR )
     {
         psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
-        TEST_ASSERT( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( public_type ) == type );
+        TEST_EQUAL( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( public_type ), type );
         key_type_classification( public_type,
                                  ( classification_flags
                                    & ~KEY_TYPE_IS_KEYPAIR )
                                  | KEY_TYPE_IS_PUBLIC_KEY );
-        TEST_ASSERT( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( type ) == type );
+        TEST_EQUAL( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( type ), type );
     }
 }
 /* END_CASE */
@@ -462,8 +459,8 @@
     test_key_type( public_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_PUBLIC_KEY );
     test_key_type( pair_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_KEYPAIR );
 
-    TEST_ASSERT( PSA_KEY_TYPE_GET_CURVE( public_type ) == curve );
-    TEST_ASSERT( PSA_KEY_TYPE_GET_CURVE( pair_type ) == curve );
+    TEST_EQUAL( PSA_KEY_TYPE_GET_CURVE( public_type ), curve );
+    TEST_EQUAL( PSA_KEY_TYPE_GET_CURVE( pair_type ), curve );
 
     /* Validate that the bit size is less than the maximum ECC bit size
      * in this implementation. There's no parameter that should be equal
diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function
index 08c7ca0..425dabb 100644
--- a/tests/suites/test_suite_psa_crypto_persistent_key.function
+++ b/tests/suites/test_suite_psa_crypto_persistent_key.function
@@ -66,13 +66,13 @@
                                               &key_data, &key_data_length,
                                               &key_type, &key_policy );
 
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
         goto exit;
 
-    TEST_ASSERT( key_type == (psa_key_type_t) expected_key_type );
-    TEST_ASSERT( key_policy.usage == (uint32_t) expected_key_usage );
-    TEST_ASSERT( key_policy.alg == (uint32_t) expected_key_alg );
+    TEST_EQUAL( key_type, (psa_key_type_t) expected_key_type );
+    TEST_EQUAL( key_policy.usage, (uint32_t) expected_key_usage );
+    TEST_EQUAL( key_policy.alg, (uint32_t) expected_key_alg );
     ASSERT_COMPARE( expected_key_data->x, expected_key_data->len,
                     key_data, key_data_length );
 
@@ -81,7 +81,6 @@
 }
 /* END_CASE */
 
-
 /* BEGIN_CASE */
 void save_large_persistent_key( int data_too_large, int expected_status )
 {
@@ -95,15 +94,16 @@
 
     ASSERT_ALLOC( data, data_length );
 
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                                 PSA_KEY_TYPE_RAW_DATA,
-                                 PSA_BYTES_TO_BITS( data_length ),
-                                 &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
+                                PSA_KEY_TYPE_RAW_DATA,
+                                PSA_BYTES_TO_BITS( data_length ),
+                                &handle ) );
 
-    TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_RAW_DATA,
-        data, data_length ) == expected_status );
+    TEST_EQUAL( psa_import_key( handle, PSA_KEY_TYPE_RAW_DATA,
+                                data, data_length ),
+                expected_status );
 
 exit:
     mbedtls_free( data );
@@ -123,43 +123,43 @@
     psa_key_type_t first_type = (psa_key_type_t) first_type_arg;
     psa_key_type_t second_type = (psa_key_type_t) second_type_arg;
 
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
     psa_key_policy_init( &policy );
 
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                                 first_type,
-                                 PSA_BYTES_TO_BITS( first_data->len ),
-                                 &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
+                                first_type,
+                                PSA_BYTES_TO_BITS( first_data->len ),
+                                &handle ) );
 
     if( should_store == 1 )
     {
-        TEST_ASSERT( psa_import_key(
-            handle, first_type,
-            first_data->x, first_data->len ) == PSA_SUCCESS );
+        PSA_ASSERT( psa_import_key(
+                        handle, first_type,
+                        first_data->x, first_data->len ) );
     }
 
     /* Destroy the key */
-    TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_destroy_key( handle ) );
 
     /* Check key slot storage is removed */
-    TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 );
-    TEST_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                               &handle ) == PSA_ERROR_EMPTY_SLOT );
-    TEST_ASSERT( handle == 0 );
+    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
+    TEST_EQUAL( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle ),
+                PSA_ERROR_EMPTY_SLOT );
+    TEST_EQUAL( handle, 0 );
 
     /* Shutdown and restart */
     mbedtls_psa_crypto_free();
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
     /* Create another key in the same slot */
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                                 second_type,
-                                 PSA_BYTES_TO_BITS( second_data->len ),
-                                 &handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_import_key(
-        handle, second_type,
-        second_data->x, second_data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
+                                second_type,
+                                PSA_BYTES_TO_BITS( second_data->len ),
+                                &handle ) );
+    PSA_ASSERT( psa_import_key(
+                    handle, second_type,
+                    second_data->x, second_data->len ) );
 
 exit:
     mbedtls_psa_crypto_free();
@@ -177,24 +177,24 @@
     psa_key_type_t type = (psa_key_type_t) type_arg;
     psa_key_handle_t handle = 0;
 
-    TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init() );
 
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                                 type,
-                                 PSA_BYTES_TO_BITS( data->len ),
-                                 &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
+                                type,
+                                PSA_BYTES_TO_BITS( data->len ),
+                                &handle ) );
     psa_key_policy_init( &policy );
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data->x, data->len ) == expected_status );
+    TEST_EQUAL( psa_import_key( handle, type, data->x, data->len ),
+                expected_status );
 
     if( expected_status != PSA_SUCCESS )
     {
-        TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 );
+        TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
         goto exit;
     }
 
-    TEST_ASSERT( psa_get_key_lifetime( handle, &lifetime ) == PSA_SUCCESS );
-    TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT );
+    PSA_ASSERT( psa_get_key_lifetime( handle, &lifetime ) );
+    TEST_EQUAL( lifetime, PSA_KEY_LIFETIME_PERSISTENT );
 
 exit:
     psa_destroy_persistent_key( key_id );
@@ -219,46 +219,46 @@
 
     ASSERT_ALLOC( exported, export_size );
 
-    TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
-                                 type,
-                                 PSA_BYTES_TO_BITS( data->len ),
-                                 &handle ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
+                                type,
+                                PSA_BYTES_TO_BITS( data->len ),
+                                &handle ) );
 
     psa_key_policy_init( &policy );
     psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT,
                               PSA_ALG_VENDOR_FLAG );
-    TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
 
     /* Import the key */
-    TEST_ASSERT( psa_import_key( handle, type,
-                                 data->x, data->len ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_import_key( handle, type,
+                                data->x, data->len ) );
 
-    TEST_ASSERT( psa_get_key_lifetime( handle, &lifetime_get ) == PSA_SUCCESS );
-    TEST_ASSERT( lifetime_get == PSA_KEY_LIFETIME_PERSISTENT );
+    PSA_ASSERT( psa_get_key_lifetime( handle, &lifetime_get ) );
+    TEST_EQUAL( lifetime_get, PSA_KEY_LIFETIME_PERSISTENT );
 
     /* Test the key information */
-    TEST_ASSERT( psa_get_key_information(
-        handle, &got_type, &got_bits ) == PSA_SUCCESS );
-    TEST_ASSERT( got_type == type );
-    TEST_ASSERT( got_bits == (size_t) expected_bits );
+    PSA_ASSERT( psa_get_key_information(
+                    handle, &got_type, &got_bits ) );
+    TEST_EQUAL( got_type, type );
+    TEST_EQUAL( got_bits, (size_t) expected_bits );
 
-    TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 1 );
+    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 1 );
 
     if( key_not_exist )
     {
         psa_destroy_persistent_key( key_id );
     }
     /* Export the key */
-    TEST_ASSERT( psa_export_key( handle, exported, export_size,
-                                 &exported_length ) == PSA_SUCCESS );
+    PSA_ASSERT( psa_export_key( handle, exported, export_size,
+                                &exported_length ) );
 
     ASSERT_COMPARE( data->x, data->len, exported, exported_length );
 
     /* Destroy the key */
-    TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS );
-    TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 );
+    PSA_ASSERT( psa_destroy_key( handle ) );
+    TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
 
 exit:
     mbedtls_free( exported );
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index fdcb5a9..3df0887 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -8,8 +8,6 @@
 
 #include "psa_crypto_storage.h"
 
-#define PSA_ASSERT( expr ) TEST_ASSERT( ( expr ) == PSA_SUCCESS )
-
 typedef enum
 {
     CLOSE_BY_CLOSE,
@@ -91,7 +89,7 @@
     PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
     PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) );
     PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
-    TEST_ASSERT( read_type == type );
+    TEST_EQUAL( read_type, type );
 
     /* Do something that invalidates the handle. */
     switch( close_method )
@@ -108,9 +106,9 @@
             break;
     }
     /* Test that the handle is now invalid. */
-    TEST_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ==
-                 PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_close_key( handle ) == PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
+                PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -147,13 +145,13 @@
     PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
     PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) );
     PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
-    TEST_ASSERT( read_type == type );
+    TEST_EQUAL( read_type, type );
 
     /* Close the key and reopen it. */
     PSA_ASSERT( psa_close_key( handle ) );
     PSA_ASSERT( psa_open_key( lifetime, id, &handle ) );
     PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
-    TEST_ASSERT( read_type == type );
+    TEST_EQUAL( read_type, type );
 
     /* Do something that invalidates the handle. */
     switch( close_method )
@@ -170,9 +168,9 @@
             break;
     }
     /* Test that the handle is now invalid. */
-    TEST_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ==
-                 PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_close_key( handle ) == PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
+                PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
 
     /* Try to reopen the key. If we destroyed it, check that it doesn't
      * exist, otherwise check that it still exists. */
@@ -182,11 +180,11 @@
         case CLOSE_BY_SHUTDOWN:
             PSA_ASSERT( psa_open_key( lifetime, id, &handle ) );
             PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) );
-            TEST_ASSERT( read_type == type );
+            TEST_EQUAL( read_type, type );
             break;
         case CLOSE_BY_DESTROY:
-            TEST_ASSERT( psa_open_key( lifetime, id, &handle ) ==
-                         PSA_ERROR_EMPTY_SLOT );
+            TEST_EQUAL( psa_open_key( lifetime, id, &handle ),
+                        PSA_ERROR_EMPTY_SLOT );
             break;
     }
 
@@ -232,9 +230,9 @@
         PSA_ASSERT( psa_close_key( handle1 ) );
 
     /* Attempt to create a new key in the same slot. */
-    TEST_ASSERT( psa_create_key( lifetime, id, type2, bits1, &handle2 ) ==
-                 PSA_ERROR_OCCUPIED_SLOT );
-    TEST_ASSERT( handle2 == 0 );
+    TEST_EQUAL( psa_create_key( lifetime, id, type2, bits1, &handle2 ),
+                PSA_ERROR_OCCUPIED_SLOT );
+    TEST_EQUAL( handle2, 0 );
 
     if( reopen_policy == CLOSE_AFTER )
         PSA_ASSERT( psa_close_key( handle1 ) );
@@ -245,8 +243,8 @@
     PSA_ASSERT( psa_get_key_policy( handle1, &read_policy ) );
     TEST_ASSERT( psa_key_policy_equal( &read_policy, &policy1 ) );
     PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) );
-    TEST_ASSERT( read_type == type1 );
-    TEST_ASSERT( read_bits == bits1 );
+    TEST_EQUAL( read_type, type1 );
+    TEST_EQUAL( read_bits, bits1 );
     PSA_ASSERT( psa_export_key( handle1,
                                 reexported, sizeof( reexported ),
                                 &reexported_length ) );
@@ -270,8 +268,8 @@
 
     PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_open_key( lifetime, id, &handle ) == expected_status );
-    TEST_ASSERT( handle == 0 );
+    TEST_EQUAL( psa_open_key( lifetime, id, &handle ), expected_status );
+    TEST_EQUAL( handle, 0 );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -294,10 +292,9 @@
 
     PSA_ASSERT( psa_crypto_init( ) );
 
-    TEST_ASSERT( psa_create_key( lifetime, id,
-                                 type, max_bits,
-                                 &handle ) == expected_status );
-    TEST_ASSERT( handle == 0 );
+    TEST_EQUAL( psa_create_key( lifetime, id, type, max_bits, &handle ),
+                expected_status );
+    TEST_EQUAL( handle, 0 );
 
 exit:
     mbedtls_psa_crypto_free( );
@@ -328,17 +325,17 @@
                                 material, sizeof( material ) ) );
 
     /* Attempt to close and destroy some invalid handles. */
-    TEST_ASSERT( psa_close_key( 0 ) == PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_close_key( handle1 - 1 ) == PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_close_key( handle1 + 1 ) == PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_destroy_key( 0 ) == PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_destroy_key( handle1 - 1 ) == PSA_ERROR_INVALID_HANDLE );
-    TEST_ASSERT( psa_destroy_key( handle1 + 1 ) == PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_close_key( 0 ), PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_close_key( handle1 - 1 ), PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_close_key( handle1 + 1 ), PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_destroy_key( 0 ), PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_destroy_key( handle1 - 1 ), PSA_ERROR_INVALID_HANDLE );
+    TEST_EQUAL( psa_destroy_key( handle1 + 1 ), PSA_ERROR_INVALID_HANDLE );
 
     /* After all this, check that the original handle is intact. */
     PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) );
-    TEST_ASSERT( read_type == PSA_KEY_TYPE_RAW_DATA );
-    TEST_ASSERT( read_bits == PSA_BYTES_TO_BITS( sizeof( material ) ) );
+    TEST_EQUAL( read_type, PSA_KEY_TYPE_RAW_DATA );
+    TEST_EQUAL( read_bits, PSA_BYTES_TO_BITS( sizeof( material ) ) );
     PSA_ASSERT( psa_close_key( handle1 ) );
 
 exit:
@@ -369,7 +366,7 @@
                                    &handles[i] );
         if( status == PSA_ERROR_INSUFFICIENT_MEMORY )
             break;
-        TEST_ASSERT( status == PSA_SUCCESS );
+        PSA_ASSERT( status );
         TEST_ASSERT( handles[i] != 0 );
         for( j = 0; j < i; j++ )
             TEST_ASSERT( handles[i] != handles[j] );
diff --git a/tests/suites/test_suite_psa_crypto_storage_file.function b/tests/suites/test_suite_psa_crypto_storage_file.function
index e753d78..e596be1 100644
--- a/tests/suites/test_suite_psa_crypto_storage_file.function
+++ b/tests/suites/test_suite_psa_crypto_storage_file.function
@@ -30,18 +30,17 @@
         file = fopen( slot_location, "wb+" );
         TEST_ASSERT( file != NULL );
         file_size = fwrite( data->x, 1, data->len, file );
-        TEST_ASSERT( file_size == data->len );
+        TEST_EQUAL( file_size, data->len );
         ret = fclose( file );
-        TEST_ASSERT( ret == 0 );
+        TEST_EQUAL( ret, 0 );
     }
 
     /* Read from the file with psa_crypto_storage_load. */
-    loaded_data = mbedtls_calloc( 1, capacity );
-    TEST_ASSERT( loaded_data != NULL );
+    ASSERT_ALLOC( loaded_data, capacity );
     status = psa_crypto_storage_load( id_to_load, loaded_data, file_size );
 
     /* Check we get the expected status. */
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
         goto exit;
 
@@ -69,7 +68,7 @@
     status = psa_crypto_storage_store( 1, data->x, data->len );
 
     /* Check that we got the expected status. */
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
         goto exit;
 
@@ -79,17 +78,16 @@
     fseek( file, 0, SEEK_END );
     file_size = (size_t) ftell( file );
     fseek( file, 0, SEEK_SET );
-    TEST_ASSERT( file_size == data->len );
+    TEST_EQUAL( file_size, data->len );
 
     /* Check that the file contents are what we expect */
-    loaded_data = mbedtls_calloc( 1, data->len );
-    TEST_ASSERT( loaded_data != NULL );
+    ASSERT_ALLOC( loaded_data, data->len );
 
     num_read = fread( loaded_data, 1, file_size, file );
-    TEST_ASSERT( num_read == file_size );
+    TEST_EQUAL( num_read, file_size );
     ASSERT_COMPARE( data->x, data->len, loaded_data, file_size );
     ret = fclose( file );
-    TEST_ASSERT( ret == 0 );
+    TEST_EQUAL( ret, 0 );
 
 exit:
     mbedtls_free( loaded_data );
@@ -97,7 +95,6 @@
 }
 /* END_CASE */
 
-
 /* BEGIN_CASE */
 void get_file_size( data_t *data, int expected_data_length,
                     int expected_status, int should_make_file )
@@ -114,16 +111,16 @@
         file = fopen( slot_location, "wb+" );
         TEST_ASSERT( file != NULL );
         file_size = fwrite( data->x, 1, data->len, file );
-        TEST_ASSERT( file_size == data->len );
+        TEST_EQUAL( file_size, data->len );
         ret = fclose( file );
-        TEST_ASSERT( ret == 0 );
+        TEST_EQUAL( ret, 0 );
     }
 
     /* Check get data size is what we expect */
     status = psa_crypto_storage_get_data_length( 1, &file_size );
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( expected_status == PSA_SUCCESS )
-        TEST_ASSERT( file_size == (size_t)expected_data_length );
+        TEST_EQUAL( file_size, (size_t)expected_data_length );
 
 exit:
     remove( slot_location );
@@ -143,13 +140,13 @@
     file = fopen( preexist_file_location, "wb" );
     TEST_ASSERT( file != NULL );
     ret = fclose( file );
-    TEST_ASSERT( ret == 0 );
+    TEST_EQUAL( ret, 0 );
 
     /* Write data to file. */
     status = psa_crypto_storage_store( 1, data->x, data->len );
 
     /* Check that we got the expected status. */
-    TEST_ASSERT( status == expected_status );
+    TEST_EQUAL( status, expected_status );
     if( status != PSA_SUCCESS )
         goto exit;
 
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index 366b97e..23d5c2c 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -226,11 +226,16 @@
     <ClInclude Include="..\..\include\mbedtls\x509_csr.h" />

     <ClInclude Include="..\..\include\mbedtls\xtea.h" />

     <ClInclude Include="..\..\include\psa\crypto.h" />

-    <ClInclude Include="..\..\include\psa\crypto_driver.h" />

+    <ClInclude Include="..\..\include\psa\crypto_accel_driver.h" />

+    <ClInclude Include="..\..\include\psa\crypto_driver_common.h" />

+    <ClInclude Include="..\..\include\psa\crypto_entropy_driver.h" />

     <ClInclude Include="..\..\include\psa\crypto_extra.h" />

     <ClInclude Include="..\..\include\psa\crypto_platform.h" />

+    <ClInclude Include="..\..\include\psa\crypto_se_driver.h" />

     <ClInclude Include="..\..\include\psa\crypto_sizes.h" />

     <ClInclude Include="..\..\include\psa\crypto_struct.h" />

+    <ClInclude Include="..\..\include\psa\crypto_types.h" />

+    <ClInclude Include="..\..\include\psa\crypto_values.h" />

     <ClInclude Include="..\..\library/psa_crypto_core.h" />

     <ClInclude Include="..\..\library/psa_crypto_invasive.h" />

     <ClInclude Include="..\..\library/psa_crypto_slot_management.h" />