From a200ee6098f499b1ce1c4ad3143737ad4dd39367 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Thu, 17 Dec 2020 14:09:38 +0100 Subject: [PATCH 01/11] Move AEAD macros next to each other Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 91 ++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 3956834103..d52f85f3c8 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -283,6 +283,54 @@ (ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \ 0) +/** 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. + * An implementation can return either 0 or a correct size for a key + * type and AEAD algorithm that it recognizes, but does not support. + */ +#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_LENGTH(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 : \ + 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 @@ -643,49 +691,6 @@ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ 0) -/** 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. - * An implementation can return either 0 or a correct size for a key type - * and AEAD algorithm that it recognizes, but does not support. - */ -#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 - /** The default IV size for a cipher algorithm, in bytes. * * The IV that is generated as part of a call to #psa_cipher_encrypt() is always From 0687b2b2360e95183b50bd4f970045d4347fa264 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Wed, 6 May 2020 16:05:37 +0200 Subject: [PATCH 02/11] Add macros for output buffer sizes Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index d52f85f3c8..119acaaf56 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -141,6 +141,13 @@ (((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 \ + (PSA_ALG_AEAD_TAG_LENGTH_MASK >> PSA_AEAD_TAG_LENGTH_OFFSET) + /* The maximum size of an RSA key on this implementation, in bits. * This is a vendor-specific macro. * @@ -259,6 +266,24 @@ (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. + * + * 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 @@ -283,6 +308,23 @@ (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. + * + * 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 @@ -382,6 +424,14 @@ 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_MAX_BLOCK_CIPHER_BLOCK_SIZE) + + /** A sufficient plaintext buffer size for psa_aead_verify(). * * If the size of the plaintext buffer is at least this large, it is From 8809fb64eb0bc4305ca392190a3a67dadc89b2d2 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Tue, 2 Jun 2020 14:27:06 +0200 Subject: [PATCH 03/11] Add and update size macros for ciphers and keys Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 56 +++++++++++++++++++++++++++++++++++++ include/psa/crypto_values.h | 3 ++ 2 files changed, 59 insertions(+) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 119acaaf56..b1d329c70b 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -785,4 +785,60 @@ */ #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. + * + * \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. 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_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && PSA_KEY_TYPE_IS_SYMMETRIC(key_type) ? \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + (((input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) + 1) / \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) + 1) * \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) ) : \ + 0) + +/** 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. + * + * \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. 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_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && PSA_KEY_TYPE_IS_SYMMETRIC(key_type) ? \ + (input_length) : \ + 0) + #endif /* PSA_CRYPTO_SIZES_H */ diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 7002631a1a..a7bc5ae945 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -354,6 +354,9 @@ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_RAW || \ ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) +/** Whether a key type is symmetric. */ +#define PSA_KEY_TYPE_IS_SYMMETRIC(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) /** Whether a key type is asymmetric: either a key pair or a public key. */ #define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ From ee6bb560a6029dd247866dc5021977b388ed9707 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Wed, 17 Jun 2020 10:11:11 +0200 Subject: [PATCH 04/11] Remove out of scope macros Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 22 ++++++++++++---------- include/psa/crypto_values.h | 3 --- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index b1d329c70b..3f3587c355 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -806,13 +806,14 @@ * a correct size for a key type and cipher algorithm * that it recognizes, but does not support. */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) && PSA_KEY_TYPE_IS_SYMMETRIC(key_type) ? \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - (((input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) + 1) / \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) + 1) * \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) ) : \ +#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && \ + ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + (((input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) + 1) / \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) + 1) * \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) ) : \ 0) /** The maximum size of the output of psa_cipher_decrypt(), in bytes. @@ -836,9 +837,10 @@ * a correct size for a key type and cipher algorithm * that it recognizes, but does not support. */ -#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) && PSA_KEY_TYPE_IS_SYMMETRIC(key_type) ? \ - (input_length) : \ +#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) #endif /* PSA_CRYPTO_SIZES_H */ diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index a7bc5ae945..7002631a1a 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -354,9 +354,6 @@ (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_RAW || \ ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) -/** Whether a key type is symmetric. */ -#define PSA_KEY_TYPE_IS_SYMMETRIC(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) /** Whether a key type is asymmetric: either a key pair or a public key. */ #define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ From fbd9f1e68377ededed41df52a84ed88dc3e59131 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Mon, 29 Jun 2020 10:38:39 +0200 Subject: [PATCH 05/11] Add and update macros for output buffer sizes Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 314 +++++++++++++++++++++++++++++++++++-- 1 file changed, 298 insertions(+), 16 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 3f3587c355..8473d7eae0 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -396,10 +396,25 @@ * 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_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)) : \ - (input_length)) +#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \ + (PSA_AEAD_TAG_LENGTH(alg) != 0 ? \ + (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)) : \ + (input_length)) : \ + 0) + +/** 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(). * @@ -429,8 +444,7 @@ * * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p alg). */ -#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE) - +#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) /** A sufficient plaintext buffer size for psa_aead_verify(). * @@ -455,6 +469,13 @@ 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_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ @@ -549,6 +570,14 @@ ((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). + */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS)) + /** Sufficient output buffer size for psa_asymmetric_decrypt(). * * This macro returns a sufficient buffer size for a plaintext produced using @@ -580,6 +609,14 @@ 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. + * + * 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_MAX_KEY_BITS)) + /* Maximum size of the ASN.1 encoding of an INTEGER with the specified * number of bits. * @@ -741,6 +778,144 @@ 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 function can evaluate its arguments multiple times or + * zero times. Providing arguments that have side effects will + * result in implementation-specific behavior, and is non-portable. + * + * 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); + * size_t key_bits = psa_get_key_bits(&attributes); + * 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(...); + * size_t buffer_length; + * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length); + * if (status != PSA_SUCCESS) + * handle_error(...); + * \endcode + * + * \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 by the + * implementation, this macro must 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, + * it is recommended that this macro returns 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_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, 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_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_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 buffer size for exporting any asymmetric key pair. + * + * This macro must expand to a compile-time constant integer. This value must + * be a sufficient buffer size when calling psa_export_key() to export any + * asymmetric key pair that is supported by the implementation, regardless of + * the exact key type and key 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_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS)) : \ + (PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS))) + +/** Sufficient buffer size for exporting any asymmetric public key. + * + * This macro must expand to a compile-time constant integer. This value must + * be a sufficient buffer size when calling psa_export_key() or + * psa_export_public_key() to export any asymmetric public key that is + * supported by the implementation, 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_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS)) : \ + (PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ + PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_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 function can evaluate its arguments multiple times or + * zero times. Providing arguments that have side effects will + * result in implementation-specific behavior, and is non-portable. + * + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE. + * + * \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_raw_key_agreement() 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 must return either + * a sensible size or 0. If the parameters are not valid, + * the return value is unspecified. + */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? \ + 2 * PSA_BITS_TO_BYTES(key_bits) : \ + 0) + +/** Maximum size of the output from psa_raw_key_agreement(). + * + * This macro must expand to a compile-time constant integer. It is recommended + * that this value is the maximum size of the output any raw key agreement + * algorithm supported by the implementation, in bytes. The value must not be + * smaller than this maximum. + * + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ + (2 * PSA_BITS_TO_BYTES(key_bits)) + /** The default IV size for a cipher algorithm, in bytes. * * The IV that is generated as part of a call to #psa_cipher_encrypt() is always @@ -791,7 +966,11 @@ * 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. + * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length). + * + * \warning This function can evaluate its arguments multiple times or + * zero times. Providing arguments that have side effects will + * result in implementation-specific behavior, and is non-portable. * * \param key_type A symmetric key type that is compatible with algorithm * alg. @@ -806,23 +985,37 @@ * a correct size for a key type and cipher algorithm * that it recognizes, but does not support. */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) && \ - ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - (((input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) + 1) / \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) + 1) * \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ - (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) ) : \ +#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && \ + ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ + (input_length) + PSA_CIPHER_IV_LENGTH(key_type, 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) + PSA_BLOCK_CIPHER_BLOCK_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. + * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length). * * \param key_type A symmetric key type that is compatible with algorithm * alg. @@ -843,4 +1036,93 @@ (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. + * 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_UPDATE_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) + PSA_CIPHER_IV_LENGTH(key_type, alg) : \ + 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) \ + ((input_length) + PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + +/** 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. + * 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_FINISH_OUTPUT_SIZE(key_type, alg) \ + (PSA_ALG_IS_CIPHER(alg) && \ + ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + (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 */ From e86bdcaa1173309b63991aeff7017591d7c7da26 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Thu, 7 Jan 2021 14:26:12 +0100 Subject: [PATCH 06/11] Fix size macros and its documentation Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 148 +++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 8473d7eae0..53c4b9d5fb 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -145,8 +145,7 @@ * * See also #PSA_AEAD_TAG_LENGTH(\p alg). */ -#define PSA_AEAD_TAG_MAX_SIZE \ - (PSA_ALG_AEAD_TAG_LENGTH_MASK >> PSA_AEAD_TAG_LENGTH_OFFSET) +#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. @@ -249,6 +248,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). @@ -272,6 +275,9 @@ * 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. @@ -291,6 +297,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). @@ -380,6 +390,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). @@ -397,11 +411,9 @@ * 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_AEAD_TAG_LENGTH(alg) != 0 ? \ - (PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length)) : \ - (input_length)) : \ - 0) + (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. @@ -573,10 +585,12 @@ /** A sufficient output buffer size for psa_asymmetric_encrypt(), for any * supported asymmetric encryption. * + * This macro assumes that RSA is the only supported asymmetric encryption. + * * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). */ #define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \ - (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS)) + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) /** Sufficient output buffer size for psa_asymmetric_decrypt(). * @@ -612,10 +626,12 @@ /** 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_MAX_KEY_BITS)) + (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. @@ -783,9 +799,9 @@ * This macro returns a compile-time constant if its arguments are * compile-time constants. * - * \warning This function can evaluate its arguments multiple times or - * zero times. Providing arguments that have side effects will - * result in implementation-specific behavior, and is non-portable. + * \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. @@ -793,19 +809,16 @@ * 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(...); + * 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_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(...); + * if (buffer == NULL) handle_error(...); * size_t buffer_length; * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length); - * if (status != PSA_SUCCESS) - * handle_error(...); + * if (status != PSA_SUCCESS) handle_error(...); * \endcode * * \param key_type A public key or key pair key type. @@ -827,10 +840,9 @@ * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type), * \p key_bits). */ -#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, 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_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_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) /** Sufficient buffer size for exporting any asymmetric key pair. @@ -842,17 +854,11 @@ * * 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_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) : \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS)) : \ - (PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(PSA_MAX_KEY_BITS) : \ - PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_MAX_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. * @@ -864,26 +870,20 @@ * * 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_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) : \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS)) : \ - (PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) > \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) ? \ - PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(PSA_MAX_KEY_BITS) : \ - PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_MAX_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 function can evaluate its arguments multiple times or - * zero times. Providing arguments that have side effects will - * result in implementation-specific behavior, and is non-portable. + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. * * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE. * @@ -899,9 +899,10 @@ * a sensible size or 0. If the parameters are not valid, * the return value is unspecified. */ +/* 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) ? \ - 2 * PSA_BITS_TO_BYTES(key_bits) : \ + PSA_BITS_TO_BYTES(key_bits) : \ 0) /** Maximum size of the output from psa_raw_key_agreement(). @@ -914,7 +915,7 @@ * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). */ #define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ - (2 * PSA_BITS_TO_BYTES(key_bits)) + (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)) /** The default IV size for a cipher algorithm, in bytes. * @@ -968,9 +969,9 @@ * * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length). * - * \warning This function can evaluate its arguments multiple times or - * zero times. Providing arguments that have side effects will - * result in implementation-specific behavior, and is non-portable. + * \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. @@ -981,18 +982,16 @@ * \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. An implementation can return either 0 or - * a correct size for a key type and cipher algorithm - * that it recognizes, but does not support. + * return 0. */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (PSA_ALG_IS_CIPHER(alg) && \ - ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ - (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg)) : \ - (input_length) + PSA_CIPHER_IV_LENGTH(key_type, alg) ) : \ - 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) + 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. @@ -1070,10 +1069,14 @@ * for a key type and cipher algorithm that it recognizes, * but does not support. */ -#define PSA_CIPHER_UPDATE_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) + PSA_CIPHER_IV_LENGTH(key_type, alg) : \ +#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 @@ -1109,12 +1112,11 @@ * for a key type and cipher algorithm that it recognizes, * but does not support. */ -#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ - (PSA_ALG_IS_CIPHER(alg) && \ - ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ - (alg == PSA_ALG_CBC_PKCS7 ? \ - PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ - 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 From ceface2247a6b8e91756ecc741fc1a8bbeb8e4fe Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Thu, 21 Jan 2021 12:26:17 +0100 Subject: [PATCH 07/11] Add test for ouput buffer size macros Signed-off-by: gabor-mezei-arm --- tests/src/psa_exercise_key.c | 33 +++- tests/suites/test_suite_psa_crypto.function | 192 ++++++++++++++++++-- 2 files changed, 203 insertions(+), 22 deletions(-) diff --git a/tests/src/psa_exercise_key.c b/tests/src/psa_exercise_key.c index 9f80d7b65a..408227d87c 100644 --- a/tests/src/psa_exercise_key.c +++ b/tests/src/psa_exercise_key.c @@ -467,7 +467,7 @@ psa_status_t mbedtls_test_psa_key_agreement_with_self( private_key_type = psa_get_key_type( &attributes ); key_bits = psa_get_key_bits( &attributes ); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type ); - public_key_length = PSA_EXPORT_KEY_OUTPUT_SIZE( public_key_type, key_bits ); + public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_key_type, key_bits ); ASSERT_ALLOC( public_key, public_key_length ); PSA_ASSERT( psa_export_public_key( key, public_key, public_key_length, &public_key_length ) ); @@ -509,7 +509,7 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( private_key_type = psa_get_key_type( &attributes ); key_bits = psa_get_key_bits( &attributes ); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( private_key_type ); - public_key_length = PSA_EXPORT_KEY_OUTPUT_SIZE( public_key_type, key_bits ); + public_key_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_key_type, key_bits ); ASSERT_ALLOC( public_key, public_key_length ); PSA_ASSERT( psa_export_public_key( key, public_key, public_key_length, @@ -518,6 +518,15 @@ psa_status_t mbedtls_test_psa_raw_key_agreement_with_self( status = psa_raw_key_agreement( alg, key, public_key, public_key_length, output, sizeof( output ), &output_length ); + if ( status == PSA_SUCCESS ) + { + TEST_ASSERT( output_length <= + PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( private_key_type, + key_bits ) ); + TEST_ASSERT( output_length <= + PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE ); + } + exit: /* * Key attributes may have been returned by psa_get_key_attributes() @@ -625,6 +634,8 @@ int mbedtls_test_psa_exported_key_sanity_check( if( ! mbedtls_test_asn1_skip_integer( &p, end, 1, bits / 2 + 1, 0 ) ) goto exit; TEST_EQUAL( p, end ); + + TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE ); } else #endif /* MBEDTLS_RSA_C */ @@ -634,6 +645,8 @@ int mbedtls_test_psa_exported_key_sanity_check( { /* Just the secret value */ TEST_EQUAL( exported_length, PSA_BITS_TO_BYTES( bits ) ); + + TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE ); } else #endif /* MBEDTLS_ECP_C */ @@ -658,6 +671,12 @@ int mbedtls_test_psa_exported_key_sanity_check( if( ! mbedtls_test_asn1_skip_integer( &p, end, 2, bits, 1 ) ) goto exit; TEST_EQUAL( p, end ); + + + TEST_ASSERT( exported_length <= + PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( type, bits ) ); + TEST_ASSERT( exported_length <= + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE ); } else #endif /* MBEDTLS_RSA_C */ @@ -665,6 +684,12 @@ int mbedtls_test_psa_exported_key_sanity_check( #if defined(MBEDTLS_ECP_C) if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ) ) { + + TEST_ASSERT( exported_length <= + PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( type, bits ) ); + TEST_ASSERT( exported_length <= + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE ); + if( PSA_KEY_TYPE_ECC_GET_FAMILY( type ) == PSA_ECC_FAMILY_MONTGOMERY ) { /* The representation of an ECC Montgomery public key is @@ -785,8 +810,8 @@ static int exercise_export_public_key( mbedtls_svc_key_id_t key ) public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( psa_get_key_type( &attributes ) ); - exported_size = PSA_EXPORT_KEY_OUTPUT_SIZE( public_type, - psa_get_key_bits( &attributes ) ); + exported_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_type, + psa_get_key_bits( &attributes ) ); ASSERT_ALLOC( exported, exported_size ); PSA_ASSERT( psa_export_public_key( key, diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 7ae672573e..c6563b3646 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -613,7 +613,10 @@ void import_export( data_t *data, reexported, reexported_length ); PSA_ASSERT( psa_destroy_key( key2 ) ); } - TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_OUTPUT_SIZE( type, psa_get_key_bits( &got_attributes ) ) ); + TEST_ASSERT( exported_length <= + PSA_EXPORT_KEY_OUTPUT_SIZE( type, + psa_get_key_bits( &got_attributes ) ) ); + TEST_ASSERT( exported_length <= PSA_EXPORT_KEY_PAIR_MAX_SIZE ); destroy: /* Destroy the key */ @@ -674,6 +677,10 @@ void import_export_public_key( data_t *data, bits = psa_get_key_bits( &attributes ); TEST_ASSERT( expected_public_key->len <= PSA_EXPORT_KEY_OUTPUT_SIZE( public_type, bits ) ); + TEST_ASSERT( expected_public_key->len <= + PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE( public_type, bits ) ); + TEST_ASSERT( expected_public_key->len <= + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE ); ASSERT_COMPARE( expected_public_key->x, expected_public_key->len, exported, exported_length ); } @@ -2399,19 +2406,29 @@ void cipher_encrypt( int alg_arg, int key_type_arg, PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } - output_buffer_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output_buffer_size <= + PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output, output_buffer_size ); PSA_ASSERT( psa_cipher_update( &operation, input->x, input->len, output, output_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) ); total_output_length += function_output_length; + status = psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); total_output_length += function_output_length; TEST_EQUAL( status, expected_status ); @@ -2467,8 +2484,9 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } - output_buffer_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output_buffer_size <= + PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output, output_buffer_size ); TEST_ASSERT( first_part_size <= input->len ); @@ -2476,7 +2494,12 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, output, output_buffer_size, &function_output_length ) ); TEST_ASSERT( function_output_length == output1_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size) ); total_output_length += function_output_length; + PSA_ASSERT( psa_cipher_update( &operation, input->x + first_part_size, input->len - first_part_size, @@ -2484,11 +2507,22 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, output_buffer_size - total_output_length, &function_output_length ) ); TEST_ASSERT( function_output_length == output2_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, + alg, + input->len - first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) ); total_output_length += function_output_length; + PSA_ASSERT( psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation ) ); @@ -2540,8 +2574,9 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } - output_buffer_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output_buffer_size <= + PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output, output_buffer_size ); TEST_ASSERT( first_part_size <= input->len ); @@ -2550,7 +2585,12 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, output, output_buffer_size, &function_output_length ) ); TEST_ASSERT( function_output_length == output1_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) ); total_output_length += function_output_length; + PSA_ASSERT( psa_cipher_update( &operation, input->x + first_part_size, input->len - first_part_size, @@ -2558,11 +2598,22 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, output_buffer_size - total_output_length, &function_output_length ) ); TEST_ASSERT( function_output_length == output2_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, + alg, + input->len - first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) ); total_output_length += function_output_length; + PSA_ASSERT( psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); total_output_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation ) ); @@ -2611,19 +2662,29 @@ void cipher_decrypt( int alg_arg, int key_type_arg, PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } - output_buffer_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output_buffer_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output_buffer_size <= + PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output, output_buffer_size ); PSA_ASSERT( psa_cipher_update( &operation, input->x, input->len, output, output_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) ); total_output_length += function_output_length; + status = psa_cipher_finish( &operation, output + total_output_length, output_buffer_size - total_output_length, &function_output_length ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); total_output_length += function_output_length; TEST_EQUAL( status, expected_status ); @@ -2682,23 +2743,37 @@ void cipher_verify_output( int alg_arg, int key_type_arg, iv, iv_size, &iv_length ) ); } - output1_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output1_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output1_size <= + PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output1, output1_size ); PSA_ASSERT( psa_cipher_update( &operation1, input->x, input->len, output1, output1_size, &output1_length ) ); + TEST_ASSERT( output1_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, input->len ) ); + TEST_ASSERT( output1_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len ) ); + PSA_ASSERT( psa_cipher_finish( &operation1, output1 + output1_length, output1_size - output1_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); output1_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation1 ) ); output2_size = output1_length; + TEST_ASSERT( output2_size <= + PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) ); + TEST_ASSERT( output2_size <= + PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) ); ASSERT_ALLOC( output2, output2_size ); if( iv_length > 0 ) @@ -2710,11 +2785,20 @@ void cipher_verify_output( int alg_arg, int key_type_arg, PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length, output2, output2_size, &output2_length ) ); + TEST_ASSERT( output2_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, output1_length ) ); + TEST_ASSERT( output2_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( output1_length ) ); + function_output_length = 0; PSA_ASSERT( psa_cipher_finish( &operation2, output2 + output2_length, output2_size - output2_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); output2_length += function_output_length; @@ -2776,8 +2860,9 @@ void cipher_verify_output_multipart( int alg_arg, &iv_length ) ); } - output1_buffer_size = ( (size_t) input->len + - PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) ); + output1_buffer_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE( key_type, alg, input->len ); + TEST_ASSERT( output1_buffer_size <= + PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE( input->len ) ); ASSERT_ALLOC( output1, output1_buffer_size ); TEST_ASSERT( first_part_size <= input->len ); @@ -2785,6 +2870,10 @@ void cipher_verify_output_multipart( int alg_arg, PSA_ASSERT( psa_cipher_update( &operation1, input->x, first_part_size, output1, output1_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) ); output1_length += function_output_length; PSA_ASSERT( psa_cipher_update( &operation1, @@ -2792,17 +2881,31 @@ void cipher_verify_output_multipart( int alg_arg, input->len - first_part_size, output1, output1_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, + alg, + input->len - first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( input->len - first_part_size ) ); output1_length += function_output_length; PSA_ASSERT( psa_cipher_finish( &operation1, output1 + output1_length, output1_buffer_size - output1_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); output1_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation1 ) ); output2_buffer_size = output1_length; + TEST_ASSERT( output2_buffer_size <= + PSA_CIPHER_DECRYPT_OUTPUT_SIZE( key_type, alg, output1_length ) ); + TEST_ASSERT( output2_buffer_size <= + PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE( output1_length ) ); ASSERT_ALLOC( output2, output2_buffer_size ); if( iv_length > 0 ) @@ -2814,6 +2917,10 @@ void cipher_verify_output_multipart( int alg_arg, PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size, output2, output2_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, alg, first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( first_part_size ) ); output2_length += function_output_length; PSA_ASSERT( psa_cipher_update( &operation2, @@ -2821,12 +2928,22 @@ void cipher_verify_output_multipart( int alg_arg, output1_length - first_part_size, output2, output2_buffer_size, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_SIZE( key_type, + alg, + output1_length - first_part_size ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE( output1_length - first_part_size ) ); output2_length += function_output_length; PSA_ASSERT( psa_cipher_finish( &operation2, output2 + output2_length, output2_buffer_size - output2_length, &function_output_length ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_SIZE( key_type, alg ) ); + TEST_ASSERT( function_output_length <= + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE ); output2_length += function_output_length; PSA_ASSERT( psa_cipher_abort( &operation2 ) ); @@ -2898,6 +3015,9 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, TEST_EQUAL( input_data->len, PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, output_length ) ); + TEST_ASSERT( input_data->len <= + PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( output_length ) ); + TEST_EQUAL( psa_aead_decrypt( key, alg, nonce->x, nonce->len, additional_data->x, @@ -2942,6 +3062,8 @@ void aead_encrypt( int key_type_arg, data_t *key_data, * should be exact. */ TEST_EQUAL( output_size, PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) ); + TEST_ASSERT( output_size <= + PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) ); ASSERT_ALLOC( output_data, output_size ); PSA_ASSERT( psa_crypto_init( ) ); @@ -3001,11 +3123,15 @@ void aead_decrypt( int key_type_arg, data_t *key_data, psa_status_t status = PSA_ERROR_GENERIC_ERROR; output_size = input_data->len - tag_length; - /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE - * should be exact. */ if( expected_result != PSA_ERROR_INVALID_ARGUMENT ) + { + /* For all currently defined algorithms, PSA_AEAD_DECRYPT_OUTPUT_SIZE + * should be exact. */ TEST_EQUAL( output_size, PSA_AEAD_DECRYPT_OUTPUT_SIZE( alg, input_data->len ) ); + TEST_ASSERT( output_size <= + PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( input_data->len ) ); + } ASSERT_ALLOC( output_data, output_size ); PSA_ASSERT( psa_crypto_init( ) ); @@ -3374,7 +3500,9 @@ void asymmetric_encrypt( int key_type_arg, /* Determine the maximum output length */ PSA_ASSERT( psa_get_key_attributes( key, &attributes ) ); key_bits = psa_get_key_bits( &attributes ); + output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg ); + TEST_ASSERT( output_size <= PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE ); ASSERT_ALLOC( output, output_size ); /* Encrypt the input */ @@ -3446,9 +3574,15 @@ void asymmetric_encrypt_decrypt( int key_type_arg, /* Determine the maximum ciphertext length */ PSA_ASSERT( psa_get_key_attributes( key, &attributes ) ); key_bits = psa_get_key_bits( &attributes ); + output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg ); + TEST_ASSERT( output_size <= PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE ); ASSERT_ALLOC( output, output_size ); + output2_size = input_data->len; + TEST_ASSERT( output2_size <= + PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( key_type, key_bits, alg ) ); + TEST_ASSERT( output2_size <= PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE ); ASSERT_ALLOC( output2, output2_size ); /* We test encryption by checking that encrypt-then-decrypt gives back @@ -3496,14 +3630,12 @@ void asymmetric_decrypt( int key_type_arg, mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; + size_t key_bits; unsigned char *output = NULL; size_t output_size = 0; size_t output_length = ~0; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - output_size = expected_data->len; - ASSERT_ALLOC( output, output_size ); - PSA_ASSERT( psa_crypto_init( ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT ); @@ -3513,6 +3645,14 @@ void asymmetric_decrypt( int key_type_arg, PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, &key ) ); + PSA_ASSERT( psa_get_key_attributes( key, &attributes ) ); + key_bits = psa_get_key_bits( &attributes ); + + /* Determine the maximum ciphertext length */ + output_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( key_type, key_bits, alg ); + TEST_ASSERT( output_size <= PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE ); + ASSERT_ALLOC( output, output_size ); + PSA_ASSERT( psa_asymmetric_decrypt( key, alg, input_data->x, input_data->len, label->x, label->len, @@ -3910,6 +4050,14 @@ void derive_output( int alg_arg, PSA_ASSERT( psa_import_key( &attributes, inputs[i]->x, inputs[i]->len, &keys[i] ) ); + + if ( PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) ) + { + PSA_ASSERT( psa_get_key_attributes( keys[i], &attributes ) ); + TEST_ASSERT( PSA_BITS_TO_BYTES( psa_get_key_bits( &attributes ) ) <= + PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ); + } + PSA_ASSERT( psa_key_derivation_input_key( &operation, steps[i], keys[i] ) ); break; @@ -4295,6 +4443,7 @@ void raw_key_agreement( int alg_arg, psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; unsigned char *output = NULL; size_t output_length = ~0; + size_t key_bits; ASSERT_ALLOC( output, expected_output->len ); PSA_ASSERT( psa_crypto_init( ) ); @@ -4306,12 +4455,19 @@ void raw_key_agreement( int alg_arg, our_key_data->x, our_key_data->len, &our_key ) ); + PSA_ASSERT( psa_get_key_attributes( our_key, &attributes ) ); + key_bits = psa_get_key_bits( &attributes ); + PSA_ASSERT( psa_raw_key_agreement( alg, our_key, peer_key_data->x, peer_key_data->len, output, expected_output->len, &output_length ) ); ASSERT_COMPARE( output, output_length, expected_output->x, expected_output->len ); + TEST_ASSERT( output_length <= + PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE( our_key_type, key_bits ) ); + TEST_ASSERT( output_length <= + PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE ); exit: mbedtls_free( output ); From c6f2480854e11878fa8f3be4433772ef9c8953c1 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Mon, 15 Feb 2021 15:56:29 +0100 Subject: [PATCH 08/11] Fix documentation Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 121 ++++++++++++------------------------- 1 file changed, 39 insertions(+), 82 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 53c4b9d5fb..5483586400 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -65,8 +65,6 @@ * * \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_LENGTH(alg) \ ( \ @@ -91,9 +89,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 @@ -110,9 +107,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. */ @@ -132,9 +128,6 @@ * 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) ? \ @@ -211,7 +204,7 @@ */ #define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128 -/** The maximum size of a block cipher supported by the implementation. */ +/** The maximum size of a block cipher. */ #define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16 /** The size of the output of psa_mac_sign_finish(), in bytes. @@ -260,9 +253,6 @@ * \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 ? \ @@ -309,9 +299,6 @@ * \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 ? \ @@ -324,6 +311,9 @@ * 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. @@ -359,8 +349,6 @@ * \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. */ #define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 && \ @@ -402,9 +390,6 @@ * \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 @@ -442,9 +427,6 @@ * \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) ? \ @@ -472,9 +454,6 @@ * \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) ? \ @@ -524,9 +503,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. */ @@ -542,9 +520,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 ? \ @@ -571,9 +548,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. */ @@ -585,10 +561,9 @@ /** A sufficient output buffer size for psa_asymmetric_encrypt(), for any * supported asymmetric encryption. * - * This macro assumes that RSA is the only 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)) @@ -612,9 +587,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. */ @@ -778,11 +752,9 @@ * 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 - * by the implementation, this macro shall return either a - * sensible size or 0. - * If the parameters are not valid, the - * return value is unspecified. + * 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) : \ @@ -827,15 +799,14 @@ * \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 by the - * implementation, this macro must return either - * a sensible size or 0. If the parameters are not valid, + * #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, - * it is recommended that this macro returns the same - * result as + * 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). @@ -847,10 +818,9 @@ /** Sufficient buffer size for exporting any asymmetric key pair. * - * This macro must expand to a compile-time constant integer. This value must - * be a sufficient buffer size when calling psa_export_key() to export any - * asymmetric key pair that is supported by the implementation, regardless of - * the exact key type and key size. + * 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_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). */ @@ -862,11 +832,10 @@ /** Sufficient buffer size for exporting any asymmetric public key. * - * This macro must expand to a compile-time constant integer. This value must - * be a sufficient buffer size when calling psa_export_key() or - * psa_export_public_key() to export any asymmetric public key that is - * supported by the implementation, regardless of the exact key type and key - * size. + * 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). */ @@ -893,10 +862,10 @@ * \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 by - * the implementation, this macro must return either - * a sensible size or 0. If the parameters are not valid, + * #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. */ /* FFDH is not yet supported in PSA. */ @@ -907,10 +876,8 @@ /** Maximum size of the output from psa_raw_key_agreement(). * - * This macro must expand to a compile-time constant integer. It is recommended - * that this value is the maximum size of the output any raw key agreement - * algorithm supported by the implementation, in bytes. The value must not be - * smaller than this maximum. + * 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. * * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). */ @@ -940,8 +907,6 @@ * 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_LENGTH(key_type) > 1 && \ @@ -1025,9 +990,7 @@ * \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. An implementation can return either 0 or - * a correct size for a key type and cipher algorithm - * that it recognizes, but does not support. + * return 0. */ #define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ (PSA_ALG_IS_CIPHER(alg) && \ @@ -1065,9 +1028,6 @@ * \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. - * 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_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ (PSA_ALG_IS_CIPHER(alg) ? \ @@ -1108,9 +1068,6 @@ * \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. - * 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_FINISH_OUTPUT_SIZE(key_type, alg) \ (PSA_ALG_IS_CIPHER(alg) ? \ From 286a36e17d918920cbdb41a885886df36179b9c9 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Fri, 5 Mar 2021 15:54:21 +0100 Subject: [PATCH 09/11] Fix size macros Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 5483586400..2a822d7f4d 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -352,10 +352,10 @@ */ #define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ (PSA_BLOCK_CIPHER_BLOCK_LENGTH(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 : \ + (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_TAG_LENGTH(alg) == PSA_ALG_CHACHA20_POLY1305 ? 12 : \ + 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 @@ -1050,7 +1050,7 @@ * \param input_length Size of the input in bytes. */ #define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ - ((input_length) + PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length)) /** A sufficient ciphertext buffer size for psa_cipher_finish(). * From 9c3b5077e606f1fa58f768a2c632088055b7729a Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Wed, 10 Mar 2021 15:57:44 +0100 Subject: [PATCH 10/11] Update PSA_CIPHER_ENCRYPT_OUTPUT_SIZE Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 2a822d7f4d..b5fb47ddb1 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -952,8 +952,8 @@ #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) + PSA_CIPHER_IV_LENGTH((key_type), \ - (alg))) : \ + (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)) From 5699101ac9b5e8c19b3b2a0679b8d52f56f4d3d6 Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Wed, 10 Mar 2021 16:43:14 +0100 Subject: [PATCH 11/11] Update PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE Signed-off-by: gabor-mezei-arm --- include/psa/crypto_sizes.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index b5fb47ddb1..a87492f838 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -971,7 +971,8 @@ */ #define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \ - (input_length) + 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. *