aboutsummaryrefslogtreecommitdiff
path: root/interface/include
diff options
context:
space:
mode:
authorMaulik Patel <Maulik.Patel@arm.com>2021-05-14 11:44:53 +0100
committerKarl Zhang <karl.zhang@arm.com>2021-05-17 11:57:23 +0200
commit13b27cf6a74062d76a5fce384ff8c77e9e2de9d2 (patch)
tree9e1bc8ae720c7aba445f6a685bf1501e56ed0c7e /interface/include
parentfd7caf8e3a1eae0adaebe658d42b4b08f05c8450 (diff)
downloadtrusted-firmware-m-13b27cf6a74062d76a5fce384ff8c77e9e2de9d2.tar.gz
Crypto: Upgrade MbedTLS to 2.26
Sets the MBEDCRYPTO_VERSION to 2.26.0. Updates headers in include/psa folder. Adds a patch for psa arch test. This patch updates crypto api test cases for psa_mac_sign_setup (226) and psa_mac_verify_setup (229) against unknown MAC algorithm such that key passed is valid but the algorithm is unknown. Also, as per PSA Crypto Spec 1.0.0, Fix the expected return value to PSA_ERROR_INVALID_ARGUMENT for incompatible key to MAC algorithm. Signed-off-by: Maulik Patel <maulik.patel@arm.com> Change-Id: I8f42736a9e5bd7fbf604146b43ef28180e741fc3
Diffstat (limited to 'interface/include')
-rw-r--r--interface/include/psa/crypto.h40
-rw-r--r--interface/include/psa/crypto_compat.h24
-rw-r--r--interface/include/psa/crypto_sizes.h574
-rw-r--r--interface/include/psa/crypto_types.h79
-rw-r--r--interface/include/psa/crypto_values.h177
5 files changed, 698 insertions, 196 deletions
diff --git a/interface/include/psa/crypto.h b/interface/include/psa/crypto.h
index e9d3c66d46..0099baab7d 100644
--- a/interface/include/psa/crypto.h
+++ b/interface/include/psa/crypto.h
@@ -78,10 +78,14 @@ extern "C" {
*
* \retval #PSA_SUCCESS
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
+ * \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_INVALID
+ * \retval #PSA_ERROR_DATA_CORRUPT
*/
psa_status_t psa_crypto_init(void);
@@ -228,6 +232,14 @@ static psa_key_usage_t psa_get_key_usage_flags(
* - An algorithm value permits this particular algorithm.
* - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified
* signature scheme with any hash algorithm.
+ * - An algorithm built from #PSA_ALG_AT_LEAST_THIS_LENGTH_MAC allows
+ * any MAC algorithm from the same base class (e.g. CMAC) which
+ * generates/verifies a MAC length greater than or equal to the length
+ * encoded in the wildcard algorithm.
+ * - An algorithm built from #PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG
+ * allows any AEAD algorithm from the same base class (e.g. CCM) which
+ * generates/verifies a tag length greater than or equal to the length
+ * encoded in the wildcard algorithm.
*
* This function overwrites any algorithm policy
* previously set in \p attributes.
@@ -336,6 +348,8 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes);
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
@@ -469,6 +483,8 @@ psa_status_t psa_purge_key(psa_key_id_t key);
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
+ * \retval #PSA_ERROR_DATA_INVALID
+ * \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_BAD_STATE
@@ -508,6 +524,10 @@ psa_status_t psa_copy_key(psa_key_id_t source_key,
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* There was an failure in communication with the cryptoprocessor.
* The key material may still be present in the cryptoprocessor.
+ * \retval #PSA_ERROR_DATA_INVALID
+ * This error is typically a result of either storage corruption on a
+ * cleartext storage backend, or an attempt to read data that was
+ * written by an incompatible version of the library.
* \retval #PSA_ERROR_STORAGE_FAILURE
* The storage is corrupted. Implementations shall make a best effort
* to erase key material even in this stage, however applications
@@ -593,6 +613,8 @@ psa_status_t psa_destroy_key(psa_key_id_t key);
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval #PSA_ERROR_DATA_CORRUPT
+ * \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
@@ -681,7 +703,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p data buffer is too small. You can determine a
* sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(\c type, \c bits)
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits)
* where \c type is the key type
* and \c bits is the key size in bits.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -751,7 +773,7 @@ psa_status_t psa_export_key(psa_key_id_t key,
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p data buffer is too small. You can determine a
* sufficient buffer size by calling
- * #PSA_KEY_EXPORT_MAX_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits)
* where \c type is the key type
* and \c bits is the key size in bits.
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -790,7 +812,7 @@ psa_status_t psa_export_public_key(psa_key_id_t key,
* \param hash_size Size of the \p hash buffer in bytes.
* \param[out] hash_length On success, the number of bytes
* that make up the hash value. This is always
- * #PSA_HASH_SIZE(\p alg).
+ * #PSA_HASH_LENGTH(\p alg).
*
* \retval #PSA_SUCCESS
* Success.
@@ -1000,7 +1022,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation,
* \param hash_size Size of the \p hash buffer in bytes.
* \param[out] hash_length On success, the number of bytes
* that make up the hash value. This is always
- * #PSA_HASH_SIZE(\c alg) where \c alg is the
+ * #PSA_HASH_LENGTH(\c alg) where \c alg is the
* hash algorithm that is calculated.
*
* \retval #PSA_SUCCESS
@@ -1009,7 +1031,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation,
* The operation state is not valid (it must be active).
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p hash buffer is too small. You can determine a
- * sufficient buffer size by calling #PSA_HASH_SIZE(\c alg)
+ * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg)
* where \c alg is the hash algorithm that is calculated.
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
@@ -1447,7 +1469,7 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation,
* \param mac_size Size of the \p mac buffer in bytes.
* \param[out] mac_length On success, the number of bytes
* that make up the MAC value. This is always
- * #PSA_MAC_FINAL_SIZE(\c key_type, \c key_bits, \c alg)
+ * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg)
* where \c key_type and \c key_bits are the type and
* bit-size respectively of the key and \c alg is the
* MAC algorithm that is calculated.
@@ -1459,7 +1481,7 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation,
* operation).
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
* The size of the \p mac buffer is too small. You can determine a
- * sufficient buffer size by calling PSA_MAC_FINAL_SIZE().
+ * sufficient buffer size by calling PSA_MAC_LENGTH().
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
@@ -3524,6 +3546,8 @@ psa_status_t psa_key_derivation_output_bytes(
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
+ * \retval #PSA_ERROR_DATA_INVALID
+ * \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
@@ -3689,6 +3713,8 @@ psa_status_t psa_generate_random(uint8_t *output,
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval #PSA_ERROR_DATA_INVALID
+ * \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
diff --git a/interface/include/psa/crypto_compat.h b/interface/include/psa/crypto_compat.h
index 8ca1f6a687..17dcee2d9e 100644
--- a/interface/include/psa/crypto_compat.h
+++ b/interface/include/psa/crypto_compat.h
@@ -98,7 +98,18 @@ typedef MBEDTLS_PSA_DEPRECATED psa_algorithm_t mbedtls_deprecated_psa_algorithm_
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGNATURE_MAX_SIZE )
#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) \
MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) )
-
+#define PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) )
+#define PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ) )
+#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE )
+#define PSA_HASH_SIZE( alg ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_HASH_LENGTH( alg ) )
+#define PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_MAC_LENGTH( key_type, key_bits, alg ) )
+#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN \
+ MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE )
/*
* Deprecated PSA Crypto function names (PSA Crypto API <= 1.0 beta3)
*/
@@ -232,6 +243,15 @@ MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_verify( psa_key_handle_t key,
#define PSA_ALG_CHACHA20 \
MBEDTLS_DEPRECATED_CONSTANT(psa_algorithm_t, PSA_ALG_STREAM_CIPHER)
+/*
+ * Renamed AEAD tag length macros (PSA Crypto API <= 1.0 beta3)
+ */
+#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH( aead_alg ) \
+ MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( aead_alg ) )
+#define PSA_ALG_AEAD_WITH_TAG_LENGTH( aead_alg, tag_length ) \
+ MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_AEAD_WITH_SHORTENED_TAG( aead_alg, tag_length ) )
+
+
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/** Open a handle to an existing persistent key.
@@ -287,6 +307,8 @@ MBEDTLS_PSA_DEPRECATED psa_status_t psa_asymmetric_verify( psa_key_handle_t key,
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
* \retval #PSA_ERROR_CORRUPTION_DETECTED
* \retval #PSA_ERROR_STORAGE_FAILURE
+ * \retval #PSA_ERROR_DATA_INVALID
+ * \retval #PSA_ERROR_DATA_CORRUPT
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
diff --git a/interface/include/psa/crypto_sizes.h b/interface/include/psa/crypto_sizes.h
index 4d13e412af..0608d71d10 100644
--- a/interface/include/psa/crypto_sizes.h
+++ b/interface/include/psa/crypto_sizes.h
@@ -47,11 +47,9 @@
*
* \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) \
- ( \
+#define PSA_HASH_LENGTH(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 : \
@@ -73,9 +71,8 @@
*
* Maximum size of a hash.
*
- * This macro must expand to a compile-time constant integer. This value
- * should be the maximum size of a hash supported by the implementation,
- * in bytes, and must be no smaller than this maximum.
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a hash in bytes.
*/
/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-226,
* 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for
@@ -87,9 +84,8 @@
*
* Maximum size of a MAC.
*
- * This macro must expand to a compile-time constant integer. This value
- * should be the maximum size of a MAC supported by the implementation,
- * in bytes, and must be no smaller than this maximum.
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a MAC in bytes.
*/
/* All non-HMAC MACs have a maximum size that's smaller than the
* minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */
@@ -109,15 +105,18 @@
* 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 tag size for all supported AEAD algorithms, in bytes.
+ *
+ * See also #PSA_AEAD_TAG_LENGTH(\p alg).
+ */
+#define PSA_AEAD_TAG_MAX_SIZE 16
+
/* The maximum size of an RSA key on this implementation, in bits.
* This is a vendor-specific macro.
*
@@ -136,10 +135,11 @@
/* The maximum size of an ECC key on this implementation, in bits */
#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521
-/** \def PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN
+/** This macro returns the maximum supported length of the PSK for the
+ * TLS-1.2 PSK-to-MS key derivation
+ * (#PSA_ALG_TLS12_PSK_TO_MS(\p hash_alg)).
*
- * This macro returns the maximum length of the PSK supported
- * by the TLS-1.2 PSK-to-MS key derivation.
+ * The maximum supported length does not depend on the chosen hash algorithm.
*
* Quoting RFC 4279, Sect 5.3:
* TLS implementations supporting these ciphersuites MUST support
@@ -148,17 +148,22 @@
* keys is RECOMMENDED.
*
* Therefore, no implementation should define a value smaller than 64
- * for #PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN.
+ * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE.
*/
-#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN 128
+#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128
+
+/** The maximum size of a block cipher. */
+#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16
-/** The maximum size of a block cipher supported by the implementation. */
-#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE 16
/** The size of the output of psa_mac_sign_finish(), in bytes.
*
* This is also the MAC size that psa_mac_verify_finish() expects.
*
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
* \param key_type The type of the MAC key.
* \param key_bits The size of the MAC key in bits.
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
@@ -172,10 +177,10 @@
* \return Unspecified if the key parameters are not consistent
* with the algorithm.
*/
-#define PSA_MAC_FINAL_SIZE(key_type, key_bits, alg) \
- ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
- PSA_ALG_IS_HMAC(alg) ? PSA_HASH_SIZE(PSA_ALG_HMAC_GET_HASH(alg)) : \
- PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+#define PSA_MAC_LENGTH(key_type, key_bits, alg) \
+ ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \
+ PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \
+ PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
((void)(key_type), (void)(key_bits), 0))
/** The maximum size of the output of psa_aead_encrypt(), in bytes.
@@ -185,6 +190,10 @@
* insufficient buffer size. Depending on the algorithm, the actual size of
* the ciphertext may be smaller.
*
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -193,15 +202,33 @@
* \return The AEAD ciphertext size for the specified
* algorithm.
* 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_ENCRYPT_OUTPUT_SIZE(alg, plaintext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(plaintext_length) + PSA_AEAD_TAG_LENGTH(alg) : \
0)
+/** A sufficient output buffer size for psa_aead_encrypt(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the ciphertext buffer is at least this large, it is guaranteed
+ * that psa_aead_encrypt() will not fail due to an insufficient buffer size.
+ *
+ * \note This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * See also #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p alg, \p plaintext_length).
+ *
+ * \param plaintext_length Size of the plaintext in bytes.
+ *
+ * \return A sufficient output buffer size for any of the
+ * supported key types and AEAD algorithms.
+ *
+ */
+#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \
+ ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE)
+
+
/** The maximum size of the output of psa_aead_decrypt(), in bytes.
*
* If the size of the plaintext buffer is at least this large, it is
@@ -209,6 +236,10 @@
* insufficient buffer size. Depending on the algorithm, the actual size of
* the plaintext may be smaller.
*
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -217,15 +248,78 @@
* \return The AEAD ciphertext size for the specified
* algorithm.
* 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_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
0)
+/** A sufficient output buffer size for psa_aead_decrypt(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the plaintext buffer is at least this large, it is guaranteed
+ * that psa_aead_decrypt() will not fail due to an insufficient buffer size.
+ *
+ * \note This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * See also #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p alg, \p ciphertext_length).
+ *
+ * \param ciphertext_length Size of the ciphertext in bytes.
+ *
+ * \return A sufficient output buffer size for any of the
+ * supported key types and AEAD algorithms.
+ *
+ */
+#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \
+ (ciphertext_length)
+
+/** The default nonce size for an AEAD algorithm, in bytes.
+ *
+ * This macro can be used to allocate a buffer of sufficient size to
+ * store the nonce output from #psa_aead_generate_nonce().
+ *
+ * See also #PSA_AEAD_NONCE_MAX_SIZE.
+ *
+ * \note This is not the maximum size of nonce supported as input to
+ * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(),
+ * just the default size that is generated by #psa_aead_generate_nonce().
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is compatible with
+ * algorithm \p alg.
+ *
+ * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_AEAD(\p alg) is true).
+ *
+ * \return The default nonce size for the specified key type and algorithm.
+ * If the key type or AEAD algorithm is not recognized,
+ * or the parameters are incompatible, return 0.
+ */
+#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 && \
+ (PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CCM || \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_GCM) ? 12 : \
+ (key_type) == PSA_KEY_TYPE_CHACHA20 && \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \
+ 0)
+
+/** The maximum default nonce size among all supported pairs of key types and
+ * AEAD algorithms, in bytes.
+ *
+ * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH()
+ * may return.
+ *
+ * \note This is not the maximum size of nonce supported as input to
+ * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(),
+ * just the largest size that may be generated by
+ * #psa_aead_generate_nonce().
+ */
+#define PSA_AEAD_NONCE_MAX_SIZE 12
+
/** A sufficient output buffer size for psa_aead_update().
*
* If the size of the output buffer is at least this large, it is
@@ -233,6 +327,10 @@
* insufficient buffer size. The actual size of the output may be smaller
* in any given call.
*
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
* \param alg An AEAD algorithm
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_AEAD(\p alg) is true).
@@ -241,19 +339,29 @@
* \return A sufficient output buffer size for the specified
* algorithm.
* 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.
*/
/* For all the AEAD modes defined in this specification, it is possible
* to emit output without delay. However, hardware may not always be
* capable of this. So for modes based on a block cipher, allow the
* implementation to delay the output until it has a full block. */
-#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
- (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
+#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
+ (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)) : \
(input_length))
+/** A sufficient output buffer size for psa_aead_update(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_aead_update() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_AEAD_UPDATE_OUTPUT_SIZE(\p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)))
+
/** A sufficient ciphertext buffer size for psa_aead_finish().
*
* If the size of the ciphertext buffer is at least this large, it is
@@ -268,15 +376,19 @@
* \return A sufficient ciphertext buffer size for the
* specified algorithm.
* 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_FINISH_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
+ PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \
0)
+/** A sufficient ciphertext buffer size for psa_aead_finish(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p alg).
+ */
+#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
/** A sufficient plaintext buffer size for psa_aead_verify().
*
* If the size of the plaintext buffer is at least this large, it is
@@ -291,18 +403,22 @@
* \return A sufficient plaintext buffer size for the
* specified algorithm.
* 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_VERIFY_OUTPUT_SIZE(alg) \
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
- PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
+ PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \
0)
+/** A sufficient plaintext buffer size for psa_aead_verify(), for any of the
+ * supported key types and AEAD algorithms.
+ *
+ * See also #PSA_AEAD_VERIFY_OUTPUT_SIZE(\p alg).
+ */
+#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
(PSA_ALG_IS_RSA_OAEP(alg) ? \
- 2 * PSA_HASH_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
+ 2 * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \
11 /*PKCS#1v1.5*/)
/**
@@ -336,9 +452,8 @@
* a buffer size in bytes that guarantees that
* psa_sign_hash() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
- * If the parameters are a valid combination that is not supported
- * by the implementation, this macro shall return either a
- * sensible size or 0.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
@@ -354,9 +469,8 @@
*
* Maximum size of an asymmetric signature.
*
- * This macro must expand to a compile-time constant integer. This value
- * should be the maximum size of a signature supported by the implementation,
- * in bytes, and must be no smaller than this maximum.
+ * This macro expands to a compile-time constant integer. This value
+ * is the maximum size of a signature in bytes.
*/
#define PSA_SIGNATURE_MAX_SIZE \
(PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE ? \
@@ -383,9 +497,8 @@
* a buffer size in bytes that guarantees that
* psa_asymmetric_encrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
- * If the parameters are a valid combination that is not supported
- * by the implementation, this macro shall return either a
- * sensible size or 0.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
@@ -394,6 +507,15 @@
((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
0)
+/** A sufficient output buffer size for psa_asymmetric_encrypt(), for any
+ * supported asymmetric encryption.
+ *
+ * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg).
+ */
+/* This macro assumes that RSA is the only supported asymmetric encryption. */
+#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS))
+
/** Sufficient output buffer size for psa_asymmetric_decrypt().
*
* This macro returns a sufficient buffer size for a plaintext produced using
@@ -414,9 +536,8 @@
* a buffer size in bytes that guarantees that
* psa_asymmetric_decrypt() will not fail with
* #PSA_ERROR_BUFFER_TOO_SMALL.
- * If the parameters are a valid combination that is not supported
- * by the implementation, this macro shall return either a
- * sensible size or 0.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
* If the parameters are not valid, the
* return value is unspecified.
*/
@@ -425,6 +546,16 @@
PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \
0)
+/** A sufficient output buffer size for psa_asymmetric_decrypt(), for any
+ * supported asymmetric decryption.
+ *
+ * This macro assumes that RSA is the only supported asymmetric encryption.
+ *
+ * See also #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg).
+ */
+#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS))
+
/* Maximum size of the ASN.1 encoding of an INTEGER with the specified
* number of bits.
*
@@ -535,12 +666,13 @@
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
(PSA_BITS_TO_BYTES(key_bits))
-/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
+/** Sufficient output buffer size for psa_export_key() or
+ * psa_export_public_key().
*
* This macro returns a compile-time constant if its arguments are
* compile-time constants.
*
- * \warning This function may call its arguments multiple times or
+ * \warning This macro may evaluate its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
@@ -553,7 +685,7 @@
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
* size_t key_bits = psa_get_key_bits(&attributes);
- * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
+ * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
@@ -562,18 +694,46 @@
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
- * For psa_export_public_key(), calculate the buffer size from the
- * public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
- * to convert a key pair type to the corresponding public key type.
+ * \param key_type A supported key type.
+ * \param key_bits The size of the key in bits.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_export_key() or psa_export_public_key() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not supported,
+ * return either a sensible size or 0.
+ * If the parameters are not valid, the return value is unspecified.
+ */
+#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
+ (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ 0)
+
+/** Sufficient output buffer size for psa_export_public_key().
+ *
+ * This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * The following code illustrates how to allocate enough memory to export
+ * a public key by querying the key type and size at runtime.
* \code{c}
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
* psa_status_t status;
* status = psa_get_key_attributes(key, &attributes);
* if (status != PSA_SUCCESS) handle_error(...);
* psa_key_type_t key_type = psa_get_key_type(&attributes);
- * psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
* size_t key_bits = psa_get_key_bits(&attributes);
- * size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
+ * size_t buffer_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits);
* psa_reset_key_attributes(&attributes);
* uint8_t *buffer = malloc(buffer_size);
* if (buffer == NULL) handle_error(...);
@@ -582,73 +742,96 @@
* if (status != PSA_SUCCESS) handle_error(...);
* \endcode
*
- * \param key_type A supported key type.
- * \param key_bits The size of the key in bits.
- *
- * \return If the parameters are valid and supported, return
- * a buffer size in bytes that guarantees that
- * psa_sign_hash() will not fail with
- * #PSA_ERROR_BUFFER_TOO_SMALL.
- * If the parameters are a valid combination that is not supported
- * by the implementation, this macro shall return either a
- * sensible size or 0.
- * If the parameters are not valid, the
- * return value is unspecified.
+ * \param key_type A public key or key pair key type.
+ * \param key_bits The size of the key in bits.
+ *
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_export_public_key() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that is not
+ * supported, return either a sensible size or 0.
+ * If the parameters are not valid,
+ * the return value is unspecified.
+ *
+ * If the parameters are valid and supported,
+ * return the same result as
+ * #PSA_EXPORT_KEY_OUTPUT_SIZE(
+ * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type),
+ * \p key_bits).
*/
-#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
- (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
- (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
- (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
- (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
- (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
- PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
- PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
+ PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
0)
-/** The default nonce size for an AEAD algorithm, in bytes.
+/** Sufficient buffer size for exporting any asymmetric key pair.
*
- * This macro can be used to allocate a buffer of sufficient size to
- * store the nonce output from #psa_aead_generate_nonce().
+ * This macro expands to a compile-time constant integer. This value is
+ * a sufficient buffer size when calling psa_export_key() to export any
+ * asymmetric key pair, regardless of the exact key type and key size.
*
- * See also #PSA_AEAD_NONCE_MAX_SIZE.
+ * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
+ */
+#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \
+ (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
+ PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \
+ PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \
+ PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS))
+
+/** Sufficient buffer size for exporting any asymmetric public key.
*
- * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
- * #psa_aead_encrypt() or #psa_aead_decrypt(), just the default size that is generated by
- * #psa_aead_generate_nonce().
+ * This macro expands to a compile-time constant integer. This value is
+ * a sufficient buffer size when calling psa_export_key() or
+ * psa_export_public_key() to export any asymmetric public key,
+ * regardless of the exact key type and key size.
+ *
+ * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits).
+ */
+#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \
+ (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \
+ PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \
+ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS))
+
+/** Sufficient output buffer size for psa_raw_key_agreement().
+ *
+ * This macro returns a compile-time constant if its arguments are
+ * compile-time constants.
*
* \warning This macro may evaluate its arguments multiple times or
* zero times, so you should not pass arguments that contain
* side effects.
*
- * \param key_type A symmetric key type that is compatible with algorithm \p alg.
+ * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE.
*
- * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that
- * #PSA_ALG_IS_AEAD(\p alg) is true).
+ * \param key_type A supported key type.
+ * \param key_bits The size of the key in bits.
*
- * \return The default nonce size for the specified key type and algorithm.
- * If the key type or AEAD algorithm is not recognized,
- * or the parameters are incompatible, return 0.
- * An implementation can return either 0 or a correct size for a key type
- * and AEAD algorithm that it recognizes, but does not support.
+ * \return If the parameters are valid and supported, return
+ * a buffer size in bytes that guarantees that
+ * psa_raw_key_agreement() will not fail with
+ * #PSA_ERROR_BUFFER_TOO_SMALL.
+ * If the parameters are a valid combination that
+ * is not supported, return either a sensible size or 0.
+ * If the parameters are not valid,
+ * the return value is unspecified.
*/
-#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \
- (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) == 16 && \
- (PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CCM || \
- PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_GCM) ? 12 : \
- (key_type) == PSA_KEY_TYPE_CHACHA20 && \
- PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \
+/* FFDH is not yet supported in PSA. */
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \
+ (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? \
+ PSA_BITS_TO_BYTES(key_bits) : \
0)
-/** The maximum default nonce size among all supported pairs of key types and
- * AEAD algorithms, in bytes.
+/** Maximum size of the output from psa_raw_key_agreement().
*
- * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() may return.
+ * This macro expands to a compile-time constant integer. This value is the
+ * maximum size of the output any raw key agreement algorithm, in bytes.
*
- * \note This is not the maximum size of nonce supported as input to #psa_aead_set_nonce(),
- * #psa_aead_encrypt() or #psa_aead_decrypt(), just the largest size that may be generated by
- * #psa_aead_generate_nonce().
+ * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits).
*/
-#define PSA_AEAD_NONCE_MAX_SIZE 12
+#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \
+ (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS))
/** The default IV size for a cipher algorithm, in bytes.
*
@@ -674,17 +857,15 @@
* If the algorithm does not use an IV, return 0.
* If the key type or cipher algorithm is not recognized,
* or the parameters are incompatible, return 0.
- * An implementation can return either 0 or a correct size for a key type
- * and cipher algorithm that it recognizes, but does not support.
*/
#define PSA_CIPHER_IV_LENGTH(key_type, alg) \
- (PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) > 1 && \
+ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \
((alg) == PSA_ALG_CTR || \
(alg) == PSA_ALG_CFB || \
(alg) == PSA_ALG_OFB || \
(alg) == PSA_ALG_XTS || \
(alg) == PSA_ALG_CBC_NO_PADDING || \
- (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type) : \
+ (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
(key_type) == PSA_KEY_TYPE_CHACHA20 && \
(alg) == PSA_ALG_STREAM_CIPHER ? 12 : \
0)
@@ -695,4 +876,163 @@
*/
#define PSA_CIPHER_IV_MAX_SIZE 16
+/** The maximum size of the output of psa_cipher_encrypt(), in bytes.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_encrypt() will not fail due to an insufficient buffer size.
+ * Depending on the algorithm, the actual size of the output might be smaller.
+ *
+ * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \warning This macro may evaluate its arguments multiple times or
+ * zero times, so you should not pass arguments that contain
+ * side effects.
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \
+ (alg == PSA_ALG_CBC_PKCS7 ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \
+ (input_length) + 1) + \
+ PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (input_length) + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \
+ 0))
+
+/** A sufficient output buffer size for psa_cipher_encrypt(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_encrypt() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ *
+ */
+#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \
+ (input_length) + 1) + \
+ PSA_CIPHER_IV_MAX_SIZE)
+
+/** The maximum size of the output of psa_cipher_decrypt(), in bytes.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_decrypt() will not fail due to an insufficient buffer size.
+ * Depending on the algorithm, the actual size of the output might be smaller.
+ *
+ * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible,
+ * return 0.
+ */
+#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \
+ (PSA_ALG_IS_CIPHER(alg) && \
+ ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \
+ (input_length) : \
+ 0)
+
+/** A sufficient output buffer size for psa_cipher_decrypt(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_decrypt() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \
+ (input_length)
+
+/** A sufficient output buffer size for psa_cipher_update().
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_update() will not fail due to an insufficient buffer size.
+ * The actual size of the output might be smaller in any given call.
+ *
+ * See also #PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(\p input_length).
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \param input_length Size of the input in bytes.
+ *
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible, return 0.
+ */
+#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (((alg) == PSA_ALG_CBC_PKCS7 || \
+ (alg) == PSA_ALG_CBC_NO_PADDING || \
+ (alg) == PSA_ALG_ECB_NO_PADDING) ? \
+ PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \
+ input_length) : \
+ (input_length)) : \
+ 0)
+
+/** A sufficient output buffer size for psa_cipher_update(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * If the size of the output buffer is at least this large, it is guaranteed
+ * that psa_cipher_update() will not fail due to an insufficient buffer size.
+ *
+ * See also #PSA_CIPHER_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length).
+ *
+ * \param input_length Size of the input in bytes.
+ */
+#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \
+ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length))
+
+/** A sufficient ciphertext buffer size for psa_cipher_finish().
+ *
+ * If the size of the ciphertext buffer is at least this large, it is
+ * guaranteed that psa_cipher_finish() will not fail due to an insufficient
+ * ciphertext buffer size. The actual size of the output might be smaller in
+ * any given call.
+ *
+ * See also #PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE().
+ *
+ * \param key_type A symmetric key type that is compatible with algorithm
+ * alg.
+ * \param alg A cipher algorithm (PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ * \return A sufficient output size for the specified key type and
+ * algorithm. If the key type or cipher algorithm is not
+ * recognized, or the parameters are incompatible, return 0.
+ */
+#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \
+ (PSA_ALG_IS_CIPHER(alg) ? \
+ (alg == PSA_ALG_CBC_PKCS7 ? \
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \
+ 0) : \
+ 0)
+
+/** A sufficient ciphertext buffer size for psa_cipher_finish(), for any of the
+ * supported key types and cipher algorithms.
+ *
+ * See also #PSA_CIPHER_FINISH_OUTPUT_SIZE(\p key_type, \p alg).
+ */
+#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE \
+ (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE)
+
#endif /* PSA_CRYPTO_SIZES_H */
diff --git a/interface/include/psa/crypto_types.h b/interface/include/psa/crypto_types.h
index bf51a2fa4e..0588d51d8d 100644
--- a/interface/include/psa/crypto_types.h
+++ b/interface/include/psa/crypto_types.h
@@ -103,14 +103,14 @@ typedef uint32_t psa_algorithm_t;
* whether the key is _volatile_ or _persistent_.
* See ::psa_key_persistence_t for more information.
* - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)):
- * location indicator. This value indicates where the key is stored
- * and where operations on the key are performed.
+ * location indicator. This value indicates which part of the system
+ * has access to the key material and can perform operations using the key.
* See ::psa_key_location_t for more information.
*
* Volatile keys are automatically destroyed when the application instance
* terminates or on a power reset of the device. Persistent keys are
* preserved until the application explicitly destroys them or until an
- * implementation-specific device management event occurs (for example,
+ * integration-specific device management event occurs (for example,
* a factory reset).
*
* Persistent keys have a key identifier of type #psa_key_id_t.
@@ -119,12 +119,10 @@ typedef uint32_t psa_algorithm_t;
* The application can call psa_open_key() to open a persistent key that
* it created previously.
*
- * This specification defines two basic lifetime values:
- * - Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are volatile.
- * All implementations should support this lifetime.
- * - Keys with the lifetime #PSA_KEY_LIFETIME_PERSISTENT are persistent.
- * All implementations that have access to persistent storage with
- * appropriate security guarantees should support this lifetime.
+ * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime
+ * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is
+ * available. Other lifetime values may be supported depending on the
+ * library configuration.
*/
typedef uint32_t psa_key_lifetime_t;
@@ -137,35 +135,21 @@ typedef uint32_t psa_key_lifetime_t;
* actually affect persistent keys at different levels is outside the
* scope of the PSA Cryptography specification.
*
- * This specification defines the following values of persistence levels:
+ * The PSA Cryptography specification defines the following values of
+ * persistence levels:
* - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key.
* A volatile key is automatically destroyed by the implementation when
* the application instance terminates. In particular, a volatile key
* is automatically destroyed on a power reset of the device.
* - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT:
* persistent key with a default lifetime.
- * Implementations should support this value if they support persistent
- * keys at all.
- * Applications should use this value if they have no specific needs that
- * are only met by implementation-specific features.
- * - \c 2-127: persistent key with a PSA-specified lifetime.
- * The PSA Cryptography specification does not define the meaning of these
- * values, but other PSA specifications may do so.
- * - \c 128-254: persistent key with a vendor-specified lifetime.
- * No PSA specification will define the meaning of these values, so
- * implementations may choose the meaning freely.
- * As a guideline, higher persistence levels should cause a key to survive
- * more management events than lower levels.
+ * - \c 2-254: currently not supported by Mbed TLS.
* - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY:
* read-only or write-once key.
* A key with this persistence level cannot be destroyed.
- * Implementations that support such keys may either allow their creation
- * through the PSA Cryptography API, preferably only to applications with
- * the appropriate privilege, or only expose keys created through
- * implementation-specific means such as a factory ROM engraving process.
- * Note that keys that are read-only due to policy restrictions
- * rather than due to physical limitations should not have this
- * persistence levels.
+ * Mbed TLS does not currently offer a way to create such keys, but
+ * integrations of Mbed TLS can use it for built-in keys that the
+ * application cannot modify (for example, a hardware unique key (HUK)).
*
* \note Key persistence levels are 8-bit values. Key management
* interfaces operate on lifetimes (type ::psa_key_lifetime_t) which
@@ -175,28 +159,30 @@ typedef uint8_t psa_key_persistence_t;
/** Encoding of key location indicators.
*
- * If an implementation of this API can make calls to external
+ * If an integration of Mbed TLS can make calls to external
* cryptoprocessors such as secure elements, the location of a key
* indicates which secure element performs the operations on the key.
- * If an implementation offers multiple physical locations for persistent
- * storage, the location indicator reflects at which physical location
- * the key is stored.
+ * Depending on the design of the secure element, the key
+ * material may be stored either in the secure element, or
+ * in wrapped (encrypted) form alongside the key metadata in the
+ * primary local storage.
*
- * This specification defines the following values of location indicators:
+ * The PSA Cryptography API specification defines the following values of
+ * location indicators:
* - \c 0: primary local storage.
- * All implementations should support this value.
+ * This location is always available.
* The primary local storage is typically the same storage area that
* contains the key metadata.
* - \c 1: primary secure element.
- * Implementations should support this value if there is a secure element
- * attached to the operating environment.
+ * Integrations of Mbed TLS should support this value if there is a secure
+ * element attached to the operating environment.
* As a guideline, secure elements may provide higher resistance against
* side channel and physical attacks than the primary local storage, but may
* have restrictions on supported key types, sizes, policies and operations
* and may have different performance characteristics.
* - \c 2-0x7fffff: other locations defined by a PSA specification.
* The PSA Cryptography API does not currently assign any meaning to these
- * locations, but future versions of this specification or other PSA
+ * locations, but future versions of that specification or other PSA
* specifications may do so.
* - \c 0x800000-0xffffff: vendor-defined locations.
* No PSA specification will assign a meaning to locations in this range.
@@ -211,7 +197,7 @@ typedef uint32_t psa_key_location_t;
*
* - Applications may freely choose key identifiers in the range
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
- * - Implementations may define additional key identifiers in the range
+ * - The implementation may define additional key identifiers in the range
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
* - 0 is reserved as an invalid key identifier.
* - Key identifiers outside these ranges are reserved for future use.
@@ -243,23 +229,18 @@ typedef uint32_t psa_key_usage_t;
* - The key's policy, comprising usage flags and a specification of
* the permitted algorithm(s).
* - Information about the key itself: the key type and its size.
- * - Implementations may define additional attributes.
+ * - Additional implementation-defined attributes.
*
* The actual key material is not considered an attribute of a key.
* Key attributes do not contain information that is generally considered
* highly confidential.
*
- * An attribute structure can be a simple data structure where each function
+ * An attribute structure works like a simple data structure where each function
* `psa_set_key_xxx` sets a field and the corresponding function
* `psa_get_key_xxx` retrieves the value of the corresponding field.
- * However, implementations may report values that are equivalent to the
- * original one, but have a different encoding. For example, an
- * implementation may use a more compact representation for types where
- * many bit-patterns are invalid or not supported, and store all values
- * that it does not support as a special marker value. In such an
- * implementation, after setting an invalid value, the corresponding
- * get function returns an invalid value which may not be the one that
- * was originally stored.
+ * However, a future version of the library may report values that are
+ * equivalent to the original one, but have a different encoding. Invalid
+ * values may be mapped to different, also invalid values.
*
* An attribute structure may contain references to auxiliary resources,
* for example pointers to allocated memory or indirect references to
diff --git a/interface/include/psa/crypto_values.h b/interface/include/psa/crypto_values.h
index 9cca6b24cf..25c6662c16 100644
--- a/interface/include/psa/crypto_values.h
+++ b/interface/include/psa/crypto_values.h
@@ -262,6 +262,46 @@
*/
#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136)
+/** Stored data has been corrupted.
+ *
+ * This error indicates that some persistent storage has suffered corruption.
+ * It does not indicate the following situations, which have specific error
+ * codes:
+ *
+ * - A corruption of volatile memory - use #PSA_ERROR_CORRUPTION_DETECTED.
+ * - A communication error between the cryptoprocessor and its external
+ * storage - use #PSA_ERROR_COMMUNICATION_FAILURE.
+ * - When the storage is in a valid state but is full - use
+ * #PSA_ERROR_INSUFFICIENT_STORAGE.
+ * - When the storage fails for other reasons - use
+ * #PSA_ERROR_STORAGE_FAILURE.
+ * - When the stored data is not valid - use #PSA_ERROR_DATA_INVALID.
+ *
+ * \note A storage corruption does not indicate that any data that was
+ * previously read is invalid. However this previously read data might no
+ * longer be readable from storage.
+ *
+ * When a storage failure occurs, it is no longer possible to ensure the
+ * global integrity of the keystore.
+ */
+#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
+
+/** Data read from storage is not valid for the implementation.
+ *
+ * This error indicates that some data read from storage does not have a valid
+ * format. It does not indicate the following situations, which have specific
+ * error codes:
+ *
+ * - When the storage or stored data is corrupted - use #PSA_ERROR_DATA_CORRUPT
+ * - When the storage fails for other reasons - use #PSA_ERROR_STORAGE_FAILURE
+ * - An invalid argument to the API - use #PSA_ERROR_INVALID_ARGUMENT
+ *
+ * This error is typically a result of either storage corruption on a
+ * cleartext storage backend, or an attempt to read data that was
+ * written by an incompatible version of the library.
+ */
+#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153)
+
/**@}*/
/** \defgroup crypto_types Key and algorithm types
@@ -355,7 +395,7 @@
* 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
+ * This size can be calculated with #PSA_HASH_LENGTH(\c alg) where
* \c alg is the HMAC algorithm or the underlying hash algorithm. */
#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x1100)
@@ -586,9 +626,9 @@
*
* \warning This macro may evaluate its argument multiple times.
*/
-#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \
+#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \
- 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \
+ 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \
0u)
/** Vendor-defined algorithm flag.
@@ -818,6 +858,14 @@
#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x003f0000)
#define PSA_MAC_TRUNCATION_OFFSET 16
+/* In the encoding of a MAC algorithm, the bit corresponding to
+ * #PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm
+ * is a wildcard algorithm. A key with such wildcard algorithm as permitted
+ * algorithm policy can be used with any algorithm corresponding to the
+ * same base class and having a (potentially truncated) MAC length greater or
+ * equal than the one encoded in #PSA_ALG_MAC_TRUNCATION_MASK. */
+#define PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000)
+
/** Macro to build a truncated MAC algorithm.
*
* A truncated MAC algorithm is identical to the corresponding MAC
@@ -851,8 +899,9 @@
* MAC algorithm or if \p mac_length is too small or
* too large for the specified MAC algorithm.
*/
-#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \
- (((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \
+#define PSA_ALG_TRUNCATED_MAC(mac_alg, mac_length) \
+ (((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) | \
((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK))
/** Macro to build the base MAC algorithm corresponding to a truncated
@@ -867,8 +916,9 @@
* \return Unspecified if \p alg is not a supported
* MAC algorithm.
*/
-#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \
- ((mac_alg) & ~PSA_ALG_MAC_TRUNCATION_MASK)
+#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \
+ ((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG))
/** Length to which a MAC algorithm is truncated.
*
@@ -884,6 +934,34 @@
#define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \
(((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
+/** Macro to build a MAC minimum-MAC-length wildcard algorithm.
+ *
+ * A minimum-MAC-length MAC wildcard algorithm permits all MAC algorithms
+ * sharing the same base algorithm, and where the (potentially truncated) MAC
+ * length of the specific algorithm is equal to or larger then the wildcard
+ * algorithm's minimum MAC length.
+ *
+ * \note When setting the minimum required MAC length to less than the
+ * smallest MAC length allowed by the base algorithm, this effectively
+ * becomes an 'any-MAC-length-allowed' policy for that base algorithm.
+ *
+ * \param mac_alg A MAC algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg)
+ * is true).
+ * \param min_mac_length Desired minimum length of the message authentication
+ * code in bytes. This must be at most the untruncated
+ * length of the MAC and must be at least 1.
+ *
+ * \return The corresponding MAC wildcard algorithm with the
+ * specified minimum length.
+ * \return Unspecified if \p mac_alg is not a supported MAC
+ * algorithm or if \p min_mac_length is less than 1 or
+ * too large for the specified MAC algorithm.
+ */
+#define PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(mac_alg, min_mac_length) \
+ ( PSA_ALG_TRUNCATED_MAC(mac_alg, min_mac_length) | \
+ PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG )
+
#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x03c00000)
/** The CBC-MAC construction over a block cipher
*
@@ -1044,6 +1122,14 @@
#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x003f0000)
#define PSA_AEAD_TAG_LENGTH_OFFSET 16
+/* In the encoding of an AEAD algorithm, the bit corresponding to
+ * #PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm
+ * is a wildcard algorithm. A key with such wildcard algorithm as permitted
+ * algorithm policy can be used with any algorithm corresponding to the
+ * same base class and having a tag length greater than or equal to the one
+ * encoded in #PSA_ALG_AEAD_TAG_LENGTH_MASK. */
+#define PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000)
+
/** Macro to build a shortened AEAD algorithm.
*
* A shortened AEAD algorithm is similar to the corresponding AEAD
@@ -1062,11 +1148,27 @@
* AEAD algorithm or if \p tag_length is not valid
* for the specified AEAD algorithm.
*/
-#define PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, tag_length) \
- (((aead_alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \
+#define PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, tag_length) \
+ (((aead_alg) & ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | \
+ PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)) | \
((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \
PSA_ALG_AEAD_TAG_LENGTH_MASK))
+/** Retrieve the tag length of a specified AEAD algorithm
+ *
+ * \param aead_alg An AEAD algorithm identifier (value of type
+ * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg)
+ * is true).
+ *
+ * \return The tag length specified by the input algorithm.
+ * \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_GET_TAG_LENGTH(aead_alg) \
+ (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \
+ PSA_AEAD_TAG_LENGTH_OFFSET )
+
/** Calculate the corresponding AEAD algorithm with the default tag length.
*
* \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that
@@ -1075,17 +1177,45 @@
* \return The corresponding AEAD algorithm with the default
* tag length for that algorithm.
*/
-#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(aead_alg) \
+#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(aead_alg) \
( \
- PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CCM) \
- PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_GCM) \
- PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CCM) \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_GCM) \
+ PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
0)
-#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH_CASE(aead_alg, ref) \
- PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
- PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \
+#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, ref) \
+ PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, 0) == \
+ PSA_ALG_AEAD_WITH_SHORTENED_TAG(ref, 0) ? \
ref :
+/** Macro to build an AEAD minimum-tag-length wildcard algorithm.
+ *
+ * A minimum-tag-length AEAD wildcard algorithm permits all AEAD algorithms
+ * sharing the same base algorithm, and where the tag length of the specific
+ * algorithm is equal to or larger then the minimum tag length specified by the
+ * wildcard algorithm.
+ *
+ * \note When setting the minimum required tag length to less than the
+ * smallest tag length allowed by the base algorithm, this effectively
+ * becomes an 'any-tag-length-allowed' policy for that base algorithm.
+ *
+ * \param aead_alg An AEAD algorithm identifier (value of type
+ * #psa_algorithm_t such that
+ * #PSA_ALG_IS_AEAD(\p aead_alg) is true).
+ * \param min_tag_length Desired minimum length of the authentication tag in
+ * bytes. This must be at least 1 and at most the largest
+ * allowed tag length of the algorithm.
+ *
+ * \return The corresponding AEAD wildcard algorithm with the
+ * specified minimum length.
+ * \return Unspecified if \p aead_alg is not a supported
+ * AEAD algorithm or if \p min_tag_length is less than 1
+ * or too large for the specified AEAD algorithm.
+ */
+#define PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(aead_alg, min_tag_length) \
+ ( PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, min_tag_length) | \
+ PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG )
+
#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x06000200)
/** RSA PKCS#1 v1.5 signature with hashing.
*
@@ -1532,9 +1662,13 @@
* \return This macro may return either 0 or 1 if \c alg is not a supported
* algorithm identifier.
*/
-#define PSA_ALG_IS_WILDCARD(alg) \
- (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \
- PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \
+#define PSA_ALG_IS_WILDCARD(alg) \
+ (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \
+ PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \
+ PSA_ALG_IS_MAC(alg) ? \
+ (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \
+ PSA_ALG_IS_AEAD(alg) ? \
+ (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \
(alg) == PSA_ALG_ANY_HASH)
/**@}*/
@@ -1560,13 +1694,12 @@
*
* 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
+ * not define any mechanism to wipe a storage area, but integrations 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.
+ * application. Integrations of Mbed TLS may support other persistent lifetimes.
* See ::psa_key_lifetime_t for more information.
*/
#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)