diff --git a/examples/advanced/psa_crypto/custom_atca_params.h b/examples/advanced/psa_crypto/custom_atca_params.h index 33f879fc2e..9b1d729812 100644 --- a/examples/advanced/psa_crypto/custom_atca_params.h +++ b/examples/advanced/psa_crypto/custom_atca_params.h @@ -20,7 +20,9 @@ * */ #include "cryptoauthlib.h" -#include "psa/crypto.h" +#include "psa/asymmetric_signature/algorithm.h" +#include "psa/key/lifetime.h" +#include "psa/key/type.h" #ifdef __cplusplus extern "C" { diff --git a/sys/include/psa_crypto/psa/aead/sizes.h b/sys/include/psa_crypto/psa/aead/sizes.h new file mode 100644 index 0000000000..7229af1e12 --- /dev/null +++ b/sys/include/psa_crypto/psa/aead/sizes.h @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief AEAD size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "algorithm.h" + +/** + * @brief A sufficient plaintext buffer size for @ref psa_aead_decrypt(), + * for any of the supported key types and AEAD algorithms. + * + * @details If the size of the plaintext buffer is at least this large, + * it is guaranteed that @ref psa_aead_decrypt() will not fail due + * to an insufficient buffer size. + * + * See also @ref PSA_AEAD_DECRYPT_OUTPUT_SIZE(). + * + * @param ciphertext_length Size of the ciphertext in bytes. + */ +#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ +/* implementation-defined value */ + +/** + * @brief The length of a tag for an AEAD algorithm, in bytes. + * + * @details This is the size of the tag output from @ref psa_aead_finish(). + * If the size of the tag buffer is at least this large, it is guaranteed that + * @ref psa_aead_finish() will not fail due to an insufficient tag buffer size. + * + * See also @ref PSA_AEAD_TAG_MAX_SIZE. + * + * @param key_type The type of the AEAD key. + * @param key_bits The size of the AEAD key in bits. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_AEAD(@p alg) is true. + * + * @return The tag length for the specified algorithm and key. + * 0 if the AEAD algorithm does not have an identified tag that can be distinguished from + * the rest of the ciphertext. + * 0 if the AEAD algorithm is not recognized or not supported. + */ +#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \ + (PSA_ALG_IS_AEAD(alg) ? \ + (((alg) & 0x003f0000) >> 16) : \ + ((void) (key_type), (void) (key_bits), 0)) + +/** + * @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(), + * for any of the supported key types and AEAD algorithms. + * + * @details If the size of the tag buffer is at least this large, it is guaranteed that + * @ref psa_aead_finish() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_AEAD_TAG_LENGTH(). + */ +#define PSA_AEAD_TAG_MAX_SIZE (16) + +/** + * @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(), + * for AES key types and CCM algorithms. + * + * @details If the size of the tag buffer is at least this large, it is guaranteed that + * @ref psa_aead_finish() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_AEAD_TAG_LENGTH(). + */ +#define PSA_AES_CCM_TAG_MAX_SIZE (16) + +/** + * @brief A sufficient plaintext buffer size for @ref psa_aead_decrypt(), in bytes. + * + * @details If the size of the plaintext buffer is at least this large, it is guaranteed that + * @ref psa_aead_decrypt() will not fail due to an insufficient buffer size. Depending on + * the algorithm, the actual size of the plaintext might be smaller. + * + * See also @ref PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t + * such that @ref PSA_ALG_IS_AEAD(@p alg) is true. + * @param ciphertext_length Size of the ciphertext in bytes. + * + * @return The AEAD plaintext size for the specified key type and algorithm. + * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + ((ciphertext_length) > PSA_AEAD_TAG_LENGTH(key_type, 0, alg)) ? \ + (ciphertext_length) - PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0) + +/** + * @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(), + * for any of the supported key types and AEAD algorithms. + * + * @details If the size of the ciphertext buffer is at least this large, + * it is guaranteed that @ref psa_aead_encrypt() will not fail due to an insufficient + * buffer size. + * + * See also @ref PSA_AEAD_ENCRYPT_OUTPUT_SIZE(). + * + * @param plaintext_length Size of the plaintext in bytes. + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \ + ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE) + +/** + * @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(), in bytes. + * + * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that + * @ref psa_aead_encrypt() will not fail due to an insufficient buffer size. Depending on + * the algorithm, the actual size of the ciphertext might be smaller. + * + * See also @ref PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such + * that @ref PSA_ALG_IS_AEAD(alg) is true. + * @param plaintext_length Size of the plaintext in bytes. + * + * @return The AEAD ciphertext size for the specified key type and algorithm. + * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + (plaintext_length) + PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0) + +/** + * @brief A sufficient ciphertext buffer size for @ref psa_aead_finish(), + * for any of the supported key types and AEAD algorithms. + * + * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that + * @ref psa_aead_finish() will not fail due to an insufficient ciphertext buffer size. + * + * See also @ref PSA_AEAD_FINISH_OUTPUT_SIZE(). + */ +#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE /* implementation-defined value */ + +/** + * @brief A sufficient ciphertext buffer size for @ref psa_aead_finish(). + * + * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that + * @ref psa_aead_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 @ref PSA_AEAD_FINISH_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_AEAD(@p alg) is true. + * + * @return A sufficient ciphertext buffer 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_FINISH_OUTPUT_SIZE(key_type, alg) \ +/* implementation-defined value */ + +/** + * @brief The default nonce size for an AEAD algorithm, in bytes. + * + * @details If the size of the nonce buffer is at least this large, it is guaranteed that + * @ref psa_aead_generate_nonce() will not fail due to an insufficient buffer size. + * + * For most AEAD algorithms, @ref PSA_AEAD_NONCE_LENGTH() evaluates to the exact size of + * the nonce generated by @ref psa_aead_generate_nonce(). + * + * See also @ref PSA_AEAD_NONCE_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_AEAD(@p alg) is true. + * + * @return The default nonce size for the specified key type and algorithm. + * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#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_CCM))) || \ + (key_type == PSA_KEY_TYPE_CHACHA20 && \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CHACHA20_POLY1305) ? \ + 12 : 0) + +/** + * @brief A sufficient buffer size for storing the nonce generated by + * @ref psa_aead_generate_nonce(), for any of the supported key types and AEAD algorithms. + * + * @details If the size of the nonce buffer is at least this large, it is guaranteed that + * @ref psa_aead_generate_nonce() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_AEAD_NONCE_LENGTH(). + */ +#define PSA_AEAD_NONCE_MAX_SIZE (13) + +/** + * @brief A sufficient output buffer size for @ref psa_aead_update(), for any of the supported key + * types and AEAD algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_aead_update() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_AEAD_UPDATE_OUTPUT_SIZE(). + * + * @param input_length Size of the input in bytes. + */ +#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_aead_update(). + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_aead_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 @ref PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_AEAD(@p alg) is true. + * @param input_length Size of the input in bytes. + * + * @return A sufficient output buffer size for the specified key type and algorithm. + * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_aead_update(), for any of the supported key + * types and AEAD algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_aead_update() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_AEAD_UPDATE_OUTPUT_SIZE(). + * + * @param input_length Size of the input in bytes. + */ +#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE /* implementation-defined value */ + +/** + * @brief A sufficient plaintext buffer size for @ref psa_aead_verify(), in bytes. + * + * @details If the size of the plaintext buffer is at least this large, it is guaranteed that + * @ref psa_aead_verify() will not fail due to an insufficient plaintext buffer size. The + * actual size of the output might be smaller in any given call. + * + * See also @ref PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_AEAD(@p alg) is true. + * + * @return A sufficient plaintext buffer size for the specified key type and algorithm. + * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \ +/* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/aead/types.h b/sys/include/psa_crypto/psa/aead/types.h new file mode 100644 index 0000000000..21b2c2f8ec --- /dev/null +++ b/sys/include/psa_crypto/psa/aead/types.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief AEAD type definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure storing an AEAD operation context + * + * @note Not implemented, yet + */ +struct psa_aead_operation_s { + int dummy; /**< Not implemented, yet */ +}; + +/* These are all temporarily defined as some numeric type to prevent errors at compile time.*/ +/** + * @brief The type of the state object for multi-part AEAD operations. + * + * @details Before calling any function on an AEAD operation object, the application must + * initialize it by any of the following means: + * - Set the object to all-bits-zero, for example: + * @code + * @ref psa_aead_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * @endcode + * - Initialize the object to logical zero values by declaring the object as static + * or global without an explicit initializer, for example: + * @code + * static @ref psa_aead_operation_t operation; + * @endcode + * - Initialize the object to the initializer @ref PSA_AEAD_OPERATION_INIT, for example: + * @code + * @ref psa_aead_operation_t operation = @ref PSA_AEAD_OPERATION_INIT; + * @endcode + * - Assign the result of the function @ref psa_aead_operation_init() to the object, + * for example: + * @code + * @ref psa_aead_operation_t operation; + * operation = @ref psa_aead_operation_init(); + * @endcode + * + * This is an implementation-defined type. Applications that make assumptions about the + * content of this object will result in in implementation-specific behavior, and are + * non-portable. + */ +typedef struct psa_aead_operation_s psa_aead_operation_t; + +/** + * @brief This macro returns a suitable initializer for an AEAD operation object of type + * @ref psa_aead_operation_t. + */ +#define PSA_AEAD_OPERATION_INIT { 0 } + +/** + * @brief Return an initial value for an AEAD operation object. + * + * @return psa_aead_operation_t + */ +static inline psa_aead_operation_t psa_aead_operation_init(void) +{ + const psa_aead_operation_t v = PSA_AEAD_OPERATION_INIT; + + return v; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/asymmetric_encryption/sizes.h b/sys/include/psa_crypto/psa/asymmetric_encryption/sizes.h new file mode 100644 index 0000000000..834b809af6 --- /dev/null +++ b/sys/include/psa_crypto/psa/asymmetric_encryption/sizes.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Asymmetric encryption size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief A sufficient output buffer size for @ref psa_asymmetric_decrypt(), + * for any of the supported key types and asymmetric encryption algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_asymmetric_decrypt() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(). + */ +#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \ +/* implementation-defined value */ + +/** + * @brief Sufficient output buffer size for @ref psa_asymmetric_decrypt(). + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_asymmetric_decrypt() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also @ref PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE. + * + * @param key_type An asymmetric key type, either a key pair or a public key. + * @param key_bits The size of the key in bits. + * @param alg An asymmetric encryption algorithm: a value of type psa_algorithm_t such + * that @ref PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(@p alg) is true. + * + * @return A sufficient output buffer size for the specified asymmetric encryption algorithm + * and key parameters. + * 0 if the asymmetric encryption algorithm and key parameters are not supported. + * Unspecified if the parameters are not valid. + */ +#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_asymmetric_encrypt(), + * for any of the supported key types and asymmetric encryption algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_asymmetric_encrypt() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(). + */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE /* implementation-defined value */ + +/** + * @brief Sufficient output buffer size for @ref psa_asymmetric_encrypt(). + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_asymmetric_encrypt() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also @ref PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE. + * + * @param key_type An asymmetric key type, either a key pair or a public key. + * @param key_bits The size of the key in bits. + * @param alg An asymmetric encryption algorithm: a value of type psa_algorithm_t + * such that @ref PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(@p alg) is true. + * + * @return A sufficient output buffer size for the specified asymmetric encryption algorithm + * and key parameters. + * 0 if the asymmetric encryption algorithm and key parameters are not supported. + * Unspecified if the parameters are not valid. + */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ +/* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/asymmetric_signature/sizes.h b/sys/include/psa_crypto/psa/asymmetric_signature/sizes.h new file mode 100644 index 0000000000..75b1732990 --- /dev/null +++ b/sys/include/psa_crypto/psa/asymmetric_signature/sizes.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Asymmetric signature size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "psa/sizes.h" +#include "psa/key/type.h" + +/** + * @brief A sufficient signature buffer size for @ref psa_sign_message() and + * @ref psa_sign_hash(), for any of the supported key types and asymmetric signature + * algorithms. + * + * @details If the size of the signature buffer is at least this large, it is guaranteed that + * @ref psa_sign_message() and @ref psa_sign_hash() will not fail due to an insufficient + * buffer size. + * + * See also @ref PSA_SIGN_OUTPUT_SIZE(). + */ +#define PSA_SIGNATURE_MAX_SIZE /* implementation-defined value */ + +/** + * @brief ECDSA signature size for a given curve bit size + * + * @note This macro returns a compile-time constant if its argument is one. + * + * @param curve_bits Curve size in bits. + * + * @return Signature size in bytes. + */ +#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \ + ((size_t)(PSA_BITS_TO_BYTES(curve_bits) * 2)) + +/** + * @brief Sufficient signature buffer size for @ref psa_sign_message() and @ref psa_sign_hash(). + * + * @details If the size of the signature buffer is at least this large, it is guaranteed that + * @ref psa_sign_message() and @ref psa_sign_hash() will not fail due to an insufficient + * buffer size. The actual size of the output might be smaller in any given call. + * + * See also @ref PSA_SIGNATURE_MAX_SIZE. + * + * @param key_type An asymmetric key type. This can be a key pair type or a public key type. + * @param key_bits The size of the key in bits. + * @param alg The signature algorithm. + * + * @return A sufficient signature buffer size for the specified asymmetric signature algorithm and + * key parameters. + * 0 if algorithm and key parameters are not supported. + * If the parameters are not valid, the return value is unspecified. + */ +#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ + (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \ + ((void)alg, 0)) + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/cipher/sizes.h b/sys/include/psa_crypto/psa/cipher/sizes.h new file mode 100644 index 0000000000..e8572b0abf --- /dev/null +++ b/sys/include/psa_crypto/psa/cipher/sizes.h @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Cipher size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "kernel_defines.h" +#include "psa/cipher/algorithm.h" +#include "psa/key/type.h" + +/** + * @brief The block size of a block cipher. + * + * @note It is possible to build stream cipher algorithms on top of a block cipher, + * for example CTR mode (@ref PSA_ALG_CTR). This macro only takes the key type + * into account, so it cannot be used to determine the size of the data that + * @ref psa_cipher_update() might buffer for future processing in general. + * + * @param type A cipher key type (value of type @ref psa_key_type_t). + * + * @return The block size for a block cipher, or 1 for a stream cipher. + */ +#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \ + (1u << (((type) >> 8) & 7)) + +/** + * @brief The maximum block size of a block cipher supported by the implementation. + * + * @details See also @ref PSA_BLOCK_CIPHER_BLOCK_LENGTH(). + */ +#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE /* implementation-defined value */ + +/** + * @brief The default IV size for a cipher algorithm, in bytes. + * + * @details The IV that is generated as part of a call to @ref psa_cipher_encrypt() is always + * the default IV length for the algorithm. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the IV output from @ref psa_cipher_generate_iv() when using + * a multi-part cipher operation. + * + * See also @ref PSA_CIPHER_IV_MAX_SIZE. + * + * @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 (PSA_ALG_XXX value such that + * @ref PSA_ALG_IS_CIPHER(@p alg) is true) + * + * @return The default IV size for the specified key type and algorithm. + * 0, if the algorithm does not use an IV, if key type or cipher + * algorithm are not recognized or if the parameters are not compatible. + * + */ +#define PSA_CIPHER_IV_LENGTH(key_type, alg) \ + ((PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \ + ((alg) == PSA_ALG_CBC_NO_PADDING)) ? 16 : \ + (key_type == PSA_KEY_TYPE_CHACHA20) ? 12 : 0) + +/** + * @brief A sufficient buffer size for storing the IV generated by @ref psa_cipher_generate_iv(), + * for any of the supported key types and cipher algorithms. + * + * @details If the size of the IV buffer is at least this large, it is guaranteed that + * @ref psa_cipher_generate_iv() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_CIPHER_IV_LENGTH(). + */ +#define PSA_CIPHER_IV_MAX_SIZE /* implementation-defined value */ + +/** + * @brief The maximum size of the output of @ref psa_cipher_encrypt(), in bytes. + * + * @details If the size of the output buffer is at least this large, it is guaranteed + * that @ref 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 @ref PSA_CIPHER_ENCRYPT_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 + * @ref 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. + * 0 if the key type or cipher algorithm is not recognized, not supported or the + * parameters are incompatible. + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (input_length + PSA_CIPHER_IV_LENGTH(key_type, alg)) + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_encrypt(), for any of the supported + * key types and cipher algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_cipher_encrypt() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(). + * + * @param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ + (PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, input_length)) + +/** + * @brief The maximum size of the output of @ref psa_cipher_decrypt(), in bytes. + * + * @details If the size of the output buffer is at least this large, it is guaranteed + * that @ref 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 @ref PSA_CIPHER_DECRYPT_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 + * @ref 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. + * 0 if the key type or cipher algorithm is not recognized, or the parameters + * are incompatible. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (input_length - PSA_CIPHER_IV_LENGTH(key_type, alg)) + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_decrypt(), for any of the supported + * key types and cipher algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_cipher_decrypt() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_CIPHER_DECRYPT_OUTPUT_SIZE(). + * + * @param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \ + (input_length) + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_update(). + * + * @details If the size of the output buffer is at least this large, + * it is guaranteed that @ref 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 @ref PSA_CIPHER_UPDATE_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 + * @ref PSA_ALG_IS_CIPHER(alg) is true). + * @param input_length Size of the input in bytes. + * + * @return A sufficient output size for the specified key type and algorithm. + * 0 if the key type or cipher algorithm is not recognized, not supported or the parameters + * are incompatible. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_update(), + * for any of the supported key types and cipher algorithms. + * + * @details If the size of the output buffer is at least this large, + * it is guaranteed that @ref psa_cipher_update() will not fail + * due to an insufficient buffer size. + * + * See also @ref PSA_CIPHER_UPDATE_OUTPUT_SIZE(). + * + * @param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_finish(). + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_cipher_finish() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also @ref PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE. + * + * @param key_type A symmetric key type that is compatible with algorithm alg. + * @param alg A cipher algorithm: a value of type psa_algorithm_t such that + * @ref PSA_ALG_IS_CIPHER(@p alg) is true. + * + * @return A sufficient output size for the specified key type and algorithm. + * 0 if the key type or cipher algorithm is not recognized, not supported or the + * parameters are incompatible. + */ +#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ +/* implementation-defined value */ + +/** + * @brief A sufficient output buffer size for @ref psa_cipher_finish(), for any of the supported + * key types and cipher algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_cipher_finish() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_CIPHER_FINISH_OUTPUT_SIZE(). + */ +#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE /* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/cipher/types.h b/sys/include/psa_crypto/psa/cipher/types.h new file mode 100644 index 0000000000..26ff35e182 --- /dev/null +++ b/sys/include/psa_crypto/psa/cipher/types.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Cipher type definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "crypto/psa/riot_ciphers.h" +#include "kernel_defines.h" +#include "psa/algorithm.h" + +#if IS_USED(MODULE_PERIPH_CIPHER_AES_128_CBC) +#include "psa_periph_aes_ctx.h" +#endif + +#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) +#include "atca_params.h" +#endif + +/** + * @brief For encrypt-decrypt functions, whether the operation is an encryption + * or a decryption. + */ +typedef enum { + PSA_CRYPTO_DRIVER_DECRYPT, + PSA_CRYPTO_DRIVER_ENCRYPT +} psa_encrypt_or_decrypt_t; + +/** + * @brief Structure containing the cipher contexts needed by the application. + */ +typedef union { +#if IS_USED(MODULE_PSA_CIPHER_AES_128_ECB) ||\ + IS_USED(MODULE_PSA_CIPHER_AES_128_CBC) ||\ + defined(DOXYGEN) + psa_cipher_aes_128_ctx_t aes_128; /**< AES 128 context*/ +#endif +#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || defined(DOXYGEN) + psa_cipher_aes_192_ctx_t aes_192; /**< AES 192 context*/ +#endif +#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || defined(DOXYGEN) + psa_cipher_aes_256_ctx_t aes_256; /**< AES 256 context*/ +#endif +} psa_cipher_context_t; + +/** + * @brief Structure containing the secure element specific cipher contexts needed by the + * application. + */ +typedef struct { + psa_encrypt_or_decrypt_t direction; /**< Direction of this cipher operation */ + /** Structure containing a driver specific cipher context */ + union driver_context { + unsigned dummy; /**< Make the union non-empty even with no supported algorithms. */ + #if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN) + atca_aes_cbc_ctx_t atca_aes_cbc; /**< ATCA AES CBC context*/ + #endif + } drv_ctx; /**< SE specific cipher operation context */ +} psa_se_cipher_context_t; + +/** + * @brief Structure storing a cipher operation context + */ +struct psa_cipher_operation_s { + uint8_t iv_required : 1; /**< True if algorithm requires IV */ + uint8_t iv_set : 1; /**< True if IV was already set */ + uint8_t default_iv_length; /**< Default IV length for algorithm */ + psa_algorithm_t alg; /**< Operation algorithm*/ + /** Union containing cipher contexts for the executing backend */ + union cipher_context { + psa_cipher_context_t cipher_ctx; /**< Cipher context */ +#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN) + psa_se_cipher_context_t se_ctx; /**< SE Cipher context */ +#endif + } backend_ctx; /**< Backend specific cipher context */ +}; + +/** + * @brief The type of the state object for multi-part cipher operations. + * + * @details Before calling any function on a cipher operation object, the application must + * initialize it by any of the following means: + * - Set the object to all-bits-zero, for example: + * @code + * @ref psa_cipher_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * @endcode + * - Initialize the object to logical zero values by declaring the object as static or + * global without an explicit initializer, for example: + * @code + * static @ref psa_cipher_operation_t operation; + * @endcode + * - Initialize the object to the initializer @ref PSA_CIPHER_OPERATION_INIT, for example: + * @code + * @ref psa_cipher_operation_t operation = @ref PSA_CIPHER_OPERATION_INIT; + * @endcode + * - Assign the result of the function @ref psa_cipher_operation_init() to the object, + * for example: + * @code + * @ref psa_cipher_operation_t operation; + * operation = @ref psa_cipher_operation_init(); + * @endcode + * + * This is an implementation-defined type. Applications that make assumptions about the + * content of this object will result in in implementation-specific behavior, and are + * non-portable. + */ +typedef struct psa_cipher_operation_s psa_cipher_operation_t; + +/** + * @brief This macro returns a suitable initializer for a cipher operation + * object of type @ref psa_cipher_operation_t. + */ +#define PSA_CIPHER_OPERATION_INIT { 0 } + +/** + * @brief Return an initial value for a cipher operation object. + * + * @return psa_cipher_operation_t + */ +static inline psa_cipher_operation_t psa_cipher_operation_init(void) +{ + const psa_cipher_operation_t v = PSA_CIPHER_OPERATION_INIT; + + return v; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/crypto_contexts.h b/sys/include/psa_crypto/psa/crypto_contexts.h index 083182efd2..ec19362b76 100644 --- a/sys/include/psa_crypto/psa/crypto_contexts.h +++ b/sys/include/psa_crypto/psa/crypto_contexts.h @@ -24,80 +24,13 @@ extern "C" { #endif #include "kernel_defines.h" - #include "psa/crypto_includes.h" -#if IS_USED(MODULE_PSA_HASH) -/** - * @brief Structure containing the hash contexts needed by the application. - */ -typedef union { -#if IS_USED(MODULE_PSA_HASH_MD5) || defined(DOXYGEN) - psa_hashes_md5_ctx_t md5; /**< MD5 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_1) || defined(DOXYGEN) - psa_hashes_sha1_ctx_t sha1; /**< SHA-1 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_224) || defined(DOXYGEN) - psa_hashes_sha224_ctx_t sha224; /**< SHA-224 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_256) || defined(DOXYGEN) - psa_hashes_sha256_ctx_t sha256; /**< SHA-256 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_384) || defined(DOXYGEN) - psa_hashes_sha384_ctx_t sha384; /**< SHA-384 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_512) || defined(DOXYGEN) - psa_hashes_sha512_ctx_t sha512; /**< SHA-512 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA3_256) || IS_USED(MODULE_PSA_HASH_SHA3_384) \ -|| IS_USED(MODULE_PSA_HASH_SHA3_512) || defined(DOXYGEN) - psa_hashes_sha3_ctx_t sha3; /**< SHA-3 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_512_224) || defined(DOXYGEN) - psa_hashes_sha512_224_ctx_t sha512_224; /**< SHA-512/224 context */ -#endif -#if IS_USED(MODULE_PSA_HASH_SHA_512_256) || defined(DOXYGEN) - psa_hashes_sha512_256_ctx_t sha512_256; /**< SHA-512/256 context */ -#endif -} psa_hash_context_t; -#endif - -#if IS_USED(MODULE_PSA_CIPHER) -/** - * @brief Structure containing the cipher contexts needed by the application. - */ -typedef union { -#if IS_USED(MODULE_PSA_CIPHER_AES_128_ECB) ||\ - IS_USED(MODULE_PSA_CIPHER_AES_128_CBC) ||\ - defined(DOXYGEN) - psa_cipher_aes_128_ctx_t aes_128; /**< AES 128 context*/ -#endif -#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || defined(DOXYGEN) - psa_cipher_aes_192_ctx_t aes_192; /**< AES 192 context*/ -#endif -#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || defined(DOXYGEN) - psa_cipher_aes_256_ctx_t aes_256; /**< AES 256 context*/ -#endif -} psa_cipher_context_t; -#endif - -#if IS_USED(MODULE_PSA_SECURE_ELEMENT) -/** - * @brief Structure containing the secure element specific cipher contexts needed by the - * application. - */ -typedef struct { - psa_encrypt_or_decrypt_t direction; /**< Direction of this cipher operation */ - /** Structure containing a driver specific cipher context */ - union driver_context { - unsigned dummy; /**< Make the union non-empty even with no supported algorithms. */ - #if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN) - atca_aes_cbc_ctx_t atca_aes_cbc; /**< ATCA AES CBC context*/ - #endif - } drv_ctx; /**< SE specific cipher operation context */ -} psa_se_cipher_context_t; -#endif +#include "aead/types.h" +#include "hash/types.h" +#include "cipher/types.h" +#include "key_derivation/types.h" +#include "mac/types.h" #ifdef __cplusplus } diff --git a/sys/include/psa_crypto/psa/crypto_sizes.h b/sys/include/psa_crypto/psa/crypto_sizes.h index 2bd7d29764..7b76ca666b 100644 --- a/sys/include/psa_crypto/psa/crypto_sizes.h +++ b/sys/include/psa_crypto/psa/crypto_sizes.h @@ -31,1105 +31,17 @@ extern "C" { #include "kernel_defines.h" #include "crypto_values.h" -/** - * @brief Functions to convert bits to bytes - * - * @param bits - * - * @return Number of bytes contained in bits - */ -#define PSA_BITS_TO_BYTES(bits) (size_t)(((bits) + 7) / 8) - -/** - * @brief Functions to convert bytes to bits - * - * @param bytes - * - * @return Number of bits contained in bytes - */ -#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8) - -/** - * @brief Maximum key size in bytes, determined by the build system. - * - * @details The maximum key size is set automatically, depending on - * the features chosen at compile-time. They should not be - * changed manually. - */ -#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256)) -#define CONFIG_PSA_MAX_KEY_SIZE 64 -#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ - IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \ - IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \ - IS_USED(MODULE_PSA_AEAD_AES_256_CCM) || \ - IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256) || \ - IS_USED(MODULE_PSA_CIPHER_CHACHA20)) -#define CONFIG_PSA_MAX_KEY_SIZE 32 -#elif (IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || \ - IS_USED(MODULE_PSA_AEAD_AES_192_CCM) || \ - IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) -#define CONFIG_PSA_MAX_KEY_SIZE 24 -#elif (IS_USED(MODULE_PSA_CIPHER_AES_128_CBC)) || \ - (IS_USED(MODULE_PSA_AEAD_AES_128_CCM)) || \ - (IS_USED(MODULE_PSA_CIPHER_AES_128_ECB)) -#define CONFIG_PSA_MAX_KEY_SIZE 16 -#else -#define CONFIG_PSA_MAX_KEY_SIZE 0 -#endif - -/** - * @brief Number of required allocated asymmetric key pair slots. - * - * @details These should be defined by the developer to - * fit their requirements. The default number is 0. - */ -#ifndef CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT -#define CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT 0 -#endif - -/** - * @brief Number of required allocated single key slots. - * - * @details These should be defined by the developer to - * fit their requirements. The default number is 0. - */ -#ifndef CONFIG_PSA_SINGLE_KEY_COUNT -#define CONFIG_PSA_SINGLE_KEY_COUNT 0 -#endif - -/** - * @brief Number of required allocated protected key slots. - * - * @details These should be defined by the developer to - * fit their requirements. The default number is 5. - */ -#ifndef CONFIG_PSA_PROTECTED_KEY_COUNT -#if (IS_USED(MODULE_PSA_SECURE_ELEMENT)) -#define CONFIG_PSA_PROTECTED_KEY_COUNT 5 -#else -#define CONFIG_PSA_PROTECTED_KEY_COUNT 0 -#endif -#endif - -/** - * @brief A sufficient plaintext buffer size for @ref psa_aead_decrypt(), - * for any of the supported key types and AEAD algorithms. - * - * @details If the size of the plaintext buffer is at least this large, - * it is guaranteed that @ref psa_aead_decrypt() will not fail due - * to an insufficient buffer size. - * - * See also @ref PSA_AEAD_DECRYPT_OUTPUT_SIZE(). - * - * @param ciphertext_length Size of the ciphertext in bytes. - */ -#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ -/* implementation-defined value */ - -/** - * @brief The length of a tag for an AEAD algorithm, in bytes. - * - * @details This is the size of the tag output from @ref psa_aead_finish(). - * If the size of the tag buffer is at least this large, it is guaranteed that - * @ref psa_aead_finish() will not fail due to an insufficient tag buffer size. - * - * See also @ref PSA_AEAD_TAG_MAX_SIZE. - * - * @param key_type The type of the AEAD key. - * @param key_bits The size of the AEAD key in bits. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_AEAD(@p alg) is true. - * - * @return The tag length for the specified algorithm and key. - * 0 if the AEAD algorithm does not have an identified tag that can be distinguished from - * the rest of the ciphertext. - * 0 if the AEAD algorithm is not recognized or not supported. - */ -#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \ - (PSA_ALG_IS_AEAD(alg) ? \ - (((alg) & 0x003f0000) >> 16) : \ - ((void) (key_type), (void) (key_bits), 0)) - -/** - * @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(), - * for any of the supported key types and AEAD algorithms. - * - * @details If the size of the tag buffer is at least this large, it is guaranteed that - * @ref psa_aead_finish() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_AEAD_TAG_LENGTH(). - */ -#define PSA_AEAD_TAG_MAX_SIZE (16) - -/** - * @brief A sufficient buffer size for storing the tag output by @ref psa_aead_finish(), - * for AES key types and CCM algorithms. - * - * @details If the size of the tag buffer is at least this large, it is guaranteed that - * @ref psa_aead_finish() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_AEAD_TAG_LENGTH(). - */ -#define PSA_AES_CCM_TAG_MAX_SIZE (16) - -/** - * @brief A sufficient plaintext buffer size for @ref psa_aead_decrypt(), in bytes. - * - * @details If the size of the plaintext buffer is at least this large, it is guaranteed that - * @ref psa_aead_decrypt() will not fail due to an insufficient buffer size. Depending on - * the algorithm, the actual size of the plaintext might be smaller. - * - * See also @ref PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t - * such that @ref PSA_ALG_IS_AEAD(@p alg) is true. - * @param ciphertext_length Size of the ciphertext in bytes. - * - * @return The AEAD plaintext size for the specified key type and algorithm. - * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ - ((ciphertext_length) > PSA_AEAD_TAG_LENGTH(key_type, 0, alg)) ? \ - (ciphertext_length) - PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0) - -/** - * @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(), - * for any of the supported key types and AEAD algorithms. - * - * @details If the size of the ciphertext buffer is at least this large, - * it is guaranteed that @ref psa_aead_encrypt() will not fail due to an insufficient - * buffer size. - * - * See also @ref PSA_AEAD_ENCRYPT_OUTPUT_SIZE(). - * - * @param plaintext_length Size of the plaintext in bytes. - */ -#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \ - ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE) - -/** - * @brief A sufficient ciphertext buffer size for @ref psa_aead_encrypt(), in bytes. - * - * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that - * @ref psa_aead_encrypt() will not fail due to an insufficient buffer size. Depending on - * the algorithm, the actual size of the ciphertext might be smaller. - * - * See also @ref PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such - * that @ref PSA_ALG_IS_AEAD(alg) is true. - * @param plaintext_length Size of the plaintext in bytes. - * - * @return The AEAD ciphertext size for the specified key type and algorithm. - * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \ - (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ - (plaintext_length) + PSA_AEAD_TAG_LENGTH(key_type, 0, alg) : 0) - -/** - * @brief A sufficient ciphertext buffer size for @ref psa_aead_finish(), - * for any of the supported key types and AEAD algorithms. - * - * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that - * @ref psa_aead_finish() will not fail due to an insufficient ciphertext buffer size. - * - * See also @ref PSA_AEAD_FINISH_OUTPUT_SIZE(). - */ -#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient ciphertext buffer size for @ref psa_aead_finish(). - * - * @details If the size of the ciphertext buffer is at least this large, it is guaranteed that - * @ref psa_aead_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 @ref PSA_AEAD_FINISH_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_AEAD(@p alg) is true. - * - * @return A sufficient ciphertext buffer 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_FINISH_OUTPUT_SIZE(key_type, alg) \ -/* implementation-defined value */ - -/** - * @brief The default nonce size for an AEAD algorithm, in bytes. - * - * @details If the size of the nonce buffer is at least this large, it is guaranteed that - * @ref psa_aead_generate_nonce() will not fail due to an insufficient buffer size. - * - * For most AEAD algorithms, @ref PSA_AEAD_NONCE_LENGTH() evaluates to the exact size of - * the nonce generated by @ref psa_aead_generate_nonce(). - * - * See also @ref PSA_AEAD_NONCE_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_AEAD(@p alg) is true. - * - * @return The default nonce size for the specified key type and algorithm. - * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#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_CCM))) || \ - (key_type == PSA_KEY_TYPE_CHACHA20 && \ - PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(alg) == PSA_ALG_CHACHA20_POLY1305) ? \ - 12 : 0) - -/** - * @brief A sufficient buffer size for storing the nonce generated by - * @ref psa_aead_generate_nonce(), for any of the supported key types and AEAD algorithms. - * - * @details If the size of the nonce buffer is at least this large, it is guaranteed that - * @ref psa_aead_generate_nonce() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_AEAD_NONCE_LENGTH(). - */ -#define PSA_AEAD_NONCE_MAX_SIZE (13) - -/** - * @brief A sufficient output buffer size for @ref psa_aead_update(), for any of the supported key - * types and AEAD algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_aead_update() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_AEAD_UPDATE_OUTPUT_SIZE(). - * - * @param input_length Size of the input in bytes. - */ -#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \ -/* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_aead_update(). - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_aead_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 @ref PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_AEAD(@p alg) is true. - * @param input_length Size of the input in bytes. - * - * @return A sufficient output buffer size for the specified key type and algorithm. - * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ -/* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_aead_update(), for any of the supported key - * types and AEAD algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_aead_update() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_AEAD_UPDATE_OUTPUT_SIZE(). - * - * @param input_length Size of the input in bytes. - */ -#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient plaintext buffer size for @ref psa_aead_verify(), in bytes. - * - * @details If the size of the plaintext buffer is at least this large, it is guaranteed that - * @ref psa_aead_verify() will not fail due to an insufficient plaintext buffer size. The - * actual size of the output might be smaller in any given call. - * - * See also @ref PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg An AEAD algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_AEAD(@p alg) is true. - * - * @return A sufficient plaintext buffer size for the specified key type and algorithm. - * 0 if the key type or AEAD algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \ -/* implementation-defined value */ - -/** - * @brief Maximum size of a hash supported by this implementation, in bytes. - * - * See also @ref PSA_HASH_LENGTH(). - */ -#define PSA_HASH_MAX_SIZE (64) - -/** - * @brief Maximum size of a hash block supported by this implementation, in bytes. - * - * See also @ref PSA_HASH_BLOCK_LENGTH(). - */ -#if (IS_USED(MODULE_PSA_HASH_SHA3_256)) -#define PSA_HASH_MAX_BLOCK_SIZE 136 -#elif (IS_USED(MODULE_PSA_HASH_SHA_512) || \ - IS_USED(MODULE_PSA_HASH_SHA_384) || \ - IS_USED(MODULE_PSA_HASH_SHA_512_224) || \ - IS_USED(MODULE_PSA_HASH_SHA_512_256)) -#define PSA_HASH_MAX_BLOCK_SIZE 128 -#elif (IS_USED(MODULE_PSA_HASH_SHA3_384)) -#define PSA_HASH_MAX_BLOCK_SIZE 104 -#elif (IS_USED(MODULE_PSA_HASH_SHA3_512)) -#define PSA_HASH_MAX_BLOCK_SIZE 72 -#elif (IS_USED(MODULE_PSA_HASH_MD5) || \ - IS_USED(MODULE_PSA_HASH_SHA_1) || \ - IS_USED(MODULE_PSA_HASH_SHA_224) || \ - IS_USED(MODULE_PSA_HASH_SHA_256)) -#define PSA_HASH_MAX_BLOCK_SIZE 64 -#else -#define PSA_HASH_MAX_BLOCK_SIZE 0 -#endif - -/** - * @brief The input block size of a hash algorithm, in bytes. - * - * @details Hash algorithms process their input data in blocks. Hash operations will retain any - * partial blocks until they have enough input to fill the block or until the operation - * is finished. - * - * This affects the output from @ref psa_hash_suspend(). - * - * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_HASH(@p alg) is true. - * - * @return The block size in bytes for the specified hash algorithm. If the hash algorithm is not - * recognized, return 0. An implementation can return either 0 or the correct size for a - * hash algorithm that it recognizes, but does not support. - */ -#define PSA_HASH_BLOCK_LENGTH(alg) \ - ( \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 : \ - 0) - -/** - * @brief The size of the output of @ref psa_hash_compute() and @ref psa_hash_finish(), in bytes. - * - * @details This is also the hash length that @ref psa_hash_compare() and @ref psa_hash_verify() - * expect. - * - * See also @ref PSA_HASH_MAX_SIZE. - * - * @param alg A hash algorithm or an HMAC algorithm: a value of type @ref psa_algorithm_t such - * that (@ref PSA_ALG_IS_HASH(@p alg) || @ref PSA_ALG_IS_HMAC(@p alg)) is true. - * - * @return The hash length for the specified hash algorithm. - * 0 if the hash algorithm is not recognized or not supported. - */ -#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 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ - 0) - -/** - * @brief The size of the output of @ref psa_mac_compute() and @ref psa_mac_sign_finish(), - * in bytes. - * - * @details If the size of the MAC buffer is at least this large, it is guaranteed that - * @ref psa_mac_compute() and @ref psa_mac_sign_finish() will not fail due to an - * insufficient buffer size. - * - * This is also the MAC length that @ref psa_mac_verify() and @ref psa_mac_verify_finish() - * expect. - * - * See also @ref PSA_MAC_MAX_SIZE. - * - * @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: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_MAC(@p alg) is true. - * - * @return The MAC length for the specified algorithm with the specified key parameters. - * 0 if the MAC algorithm is not recognized or not supported. - * Unspecified if the key parameters are not consistent with the algorithm. - */ -#define PSA_MAC_LENGTH(key_type, key_bits, 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)) - -/** - * @brief A sufficient buffer size for storing the MAC output by @ref psa_mac_verify() and - * @ref psa_mac_verify_finish(), for any of the supported key types and MAC algorithms. - * - * @details If the size of the MAC buffer is at least this large, it is guaranteed that - * @ref psa_mac_verify() and @ref psa_mac_verify_finish() will not fail due to an - * insufficient buffer size. - * - * See also @ref PSA_MAC_LENGTH(). - */ -#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_512)) /* 64 */ -#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_384)) /* 48 */ -#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_256)) /* 32 */ -#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_224)) /* 28 */ -#elif (IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \ - IS_USED(MODULE_PSA_MAC_HMAC_SHA_1)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA_1)) /* 20 */ -#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD2) || \ - IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \ - IS_USED(MODULE_PSA_MAC_HMAC_MD5)) -#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_MD5)) /* 16 */ -#else -#define PSA_MAC_MAX_SIZE 0 -#endif - -/** - * @brief The block size of a block cipher. - * - * @note It is possible to build stream cipher algorithms on top of a block cipher, - * for example CTR mode (@ref PSA_ALG_CTR). This macro only takes the key type - * into account, so it cannot be used to determine the size of the data that - * @ref psa_cipher_update() might buffer for future processing in general. - * - * @param type A cipher key type (value of type @ref psa_key_type_t). - * - * @return The block size for a block cipher, or 1 for a stream cipher. - */ -#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type) \ - (1u << (((type) >> 8) & 7)) - -/** - * @brief The maximum block size of a block cipher supported by the implementation. - * - * @details See also @ref PSA_BLOCK_CIPHER_BLOCK_LENGTH(). - */ -#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_decrypt(), for any of the supported - * key types and cipher algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_cipher_decrypt() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_CIPHER_DECRYPT_OUTPUT_SIZE(). - * - * @param input_length Size of the input in bytes. - */ -#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \ - (input_length) - -/** - * @brief The maximum size of the output of @ref psa_cipher_decrypt(), in bytes. - * - * @details If the size of the output buffer is at least this large, it is guaranteed - * that @ref 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 @ref PSA_CIPHER_DECRYPT_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 - * @ref 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. - * 0 if the key type or cipher algorithm is not recognized, or the parameters - * are incompatible. - */ -#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (input_length - PSA_CIPHER_IV_LENGTH(key_type, alg)) - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_encrypt(), for any of the supported - * key types and cipher algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_cipher_encrypt() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(). - * - * @param input_length Size of the input in bytes. - */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ - (PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING, input_length)) - -/** - * @brief The maximum size of the output of @ref psa_cipher_encrypt(), in bytes. - * - * @details If the size of the output buffer is at least this large, it is guaranteed - * that @ref 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 @ref PSA_CIPHER_ENCRYPT_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 - * @ref 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. - * 0 if the key type or cipher algorithm is not recognized, not supported or the - * parameters are incompatible. - */ -#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ - (input_length + PSA_CIPHER_IV_LENGTH(key_type, alg)) - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_finish(), for any of the supported - * key types and cipher algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_cipher_finish() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_CIPHER_FINISH_OUTPUT_SIZE(). - */ -#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_finish(). - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_cipher_finish() will not fail due to an insufficient buffer size. - * The actual size of the output might be smaller in any given call. - * - * See also @ref PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE. - * - * @param key_type A symmetric key type that is compatible with algorithm alg. - * @param alg A cipher algorithm: a value of type psa_algorithm_t such that - * @ref PSA_ALG_IS_CIPHER(@p alg) is true. - * - * @return A sufficient output size for the specified key type and algorithm. - * 0 if the key type or cipher algorithm is not recognized, not supported or the - * parameters are incompatible. - */ -#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ -/* implementation-defined value */ - -/** - * @brief The default IV size for a cipher algorithm, in bytes. - * - * @details The IV that is generated as part of a call to @ref psa_cipher_encrypt() is always - * the default IV length for the algorithm. - * - * This macro can be used to allocate a buffer of sufficient size to - * store the IV output from @ref psa_cipher_generate_iv() when using - * a multi-part cipher operation. - * - * See also @ref PSA_CIPHER_IV_MAX_SIZE. - * - * @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 (PSA_ALG_XXX value such that - * @ref PSA_ALG_IS_CIPHER(@p alg) is true) - * - * @return The default IV size for the specified key type and algorithm. - * 0, if the algorithm does not use an IV, if key type or cipher - * algorithm are not recognized or if the parameters are not compatible. - * - */ -#define PSA_CIPHER_IV_LENGTH(key_type, alg) \ - ((PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \ - ((alg) == PSA_ALG_CBC_NO_PADDING)) ? 16 : \ - (key_type == PSA_KEY_TYPE_CHACHA20) ? 12 : 0) - -/** - * @brief A sufficient buffer size for storing the IV generated by @ref psa_cipher_generate_iv(), - * for any of the supported key types and cipher algorithms. - * - * @details If the size of the IV buffer is at least this large, it is guaranteed that - * @ref psa_cipher_generate_iv() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_CIPHER_IV_LENGTH(). - */ -#define PSA_CIPHER_IV_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_update(), - * for any of the supported key types and cipher algorithms. - * - * @details If the size of the output buffer is at least this large, - * it is guaranteed that @ref psa_cipher_update() will not fail - * due to an insufficient buffer size. - * - * See also @ref PSA_CIPHER_UPDATE_OUTPUT_SIZE(). - * - * @param input_length Size of the input in bytes. - */ -#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ -/* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_cipher_update(). - * - * @details If the size of the output buffer is at least this large, - * it is guaranteed that @ref 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 @ref PSA_CIPHER_UPDATE_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 - * @ref PSA_ALG_IS_CIPHER(alg) is true). - * @param input_length Size of the input in bytes. - * - * @return A sufficient output size for the specified key type and algorithm. - * 0 if the key type or cipher algorithm is not recognized, not supported or the parameters - * are incompatible. - */ -#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ -/* implementation-defined value */ - -/** - * @brief The size of the algorithm field that is part of the output of @ref psa_hash_suspend(), - * in bytes. - * - * @details Applications can use this value to unpack the hash suspend state that is output by - * @ref psa_hash_suspend(). - */ -#define PSA_HASH_SUSPEND_ALGORITHM_FIELD_LENGTH ((size_t)4) - -/** - * @brief The size of the hash-state field that is part of the output of @ref psa_hash_suspend(), - * in bytes. - * - * @details Applications can use this value to unpack the hash suspend state that is output by - * @ref psa_hash_suspend(). - * - * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_HASH(@p alg) is true. - * - * @return The size, in bytes, of the hash-state field of the hash suspend state for the specified - * hash algorithm. - * 0 if the hash algorithm is not recognized or not supported. - */ -#define PSA_HASH_SUSPEND_HASH_STATE_FIELD_LENGTH(alg) \ -/* specification-defined value */ - -/** - * @brief The size of the input-length field that is part of the output of - * @ref psa_hash_suspend(), in bytes. - * - * @details Applications can use this value to unpack the hash suspend state that is output - * by @ref psa_hash_suspend(). - * - * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_HASH(@p alg) is true. - * - * @return The size, in bytes, of the input-length field of the hash suspend state for the - * specified hash algorithm. - * 0 i f the hash algorithm is not recognized or not supported. - */ -#define PSA_HASH_SUSPEND_INPUT_LENGTH_FIELD_LENGTH(alg) \ -/* specification-defined value */ - -/** - * @brief A sufficient hash suspend state buffer size for @ref psa_hash_suspend(), - * for any supported hash algorithms. - * - * @details If the size of the hash state buffer is at least this large, it is guaranteed that - * @ref psa_hash_suspend() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_HASH_SUSPEND_OUTPUT_SIZE(). - */ -#define PSA_HASH_SUSPEND_OUTPUT_MAX_SIZE /* implementation-defined value */ - -/** - * @brief A sufficient hash suspend state buffer size for @ref psa_hash_suspend(), in bytes. - * - * @details If the size of the hash state buffer is at least this large, it is guaranteed that - * @ref psa_hash_suspend() will not fail due to an insufficient buffer size. The actual - * size of the output might be smaller in any given call. - * - * See also @ref PSA_HASH_SUSPEND_OUTPUT_MAX_SIZE. - * - * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that - * @ref PSA_ALG_IS_HASH(alg) is true. - * - * @return A sufficient output size for the algorithm. - * 0 if the hash algorithm is not recognized, or is not supported by - * @ref psa_hash_suspend(). - * - * For a supported hash algorithm alg, the following expression is true: - * @code - * PSA_HASH_SUSPEND_OUTPUT_SIZE(alg) == PSA_HASH_SUSPEND_ALGORITHM_FIELD_LENGTH + - * PSA_HASH_SUSPEND_INPUT_LENGTH_FIELD_LENGTH(alg) + - * PSA_HASH_SUSPEND_HASH_STATE_FIELD_LENGTH(alg) + - * PSA_HASH_BLOCK_LENGTH(alg) - 1 - * @endcode - */ -#define PSA_HASH_SUSPEND_OUTPUT_SIZE(alg) /* specification-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_asymmetric_decrypt(), - * for any of the supported key types and asymmetric encryption algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_asymmetric_decrypt() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(). - */ -#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \ -/* implementation-defined value */ - -/** - * @brief Sufficient output buffer size for @ref psa_asymmetric_decrypt(). - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_asymmetric_decrypt() will not fail due to an insufficient buffer size. - * The actual size of the output might be smaller in any given call. - * - * See also @ref PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE. - * - * @param key_type An asymmetric key type, either a key pair or a public key. - * @param key_bits The size of the key in bits. - * @param alg An asymmetric encryption algorithm: a value of type psa_algorithm_t such - * that @ref PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(@p alg) is true. - * - * @return A sufficient output buffer size for the specified asymmetric encryption algorithm - * and key parameters. - * 0 if the asymmetric encryption algorithm and key parameters are not supported. - * Unspecified if the parameters are not valid. - */ -#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ -/* implementation-defined value */ - -/** - * @brief A sufficient output buffer size for @ref psa_asymmetric_encrypt(), - * for any of the supported key types and asymmetric encryption algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_asymmetric_encrypt() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(). - */ -#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE /* implementation-defined value */ - -/** - * @brief Sufficient output buffer size for @ref psa_asymmetric_encrypt(). - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_asymmetric_encrypt() will not fail due to an insufficient buffer size. - * The actual size of the output might be smaller in any given call. - * - * See also @ref PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE. - * - * @param key_type An asymmetric key type, either a key pair or a public key. - * @param key_bits The size of the key in bits. - * @param alg An asymmetric encryption algorithm: a value of type psa_algorithm_t - * such that @ref PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(@p alg) is true. - * - * @return A sufficient output buffer size for the specified asymmetric encryption algorithm - * and key parameters. - * 0 if the asymmetric encryption algorithm and key parameters are not supported. - * Unspecified if the parameters are not valid. - */ -#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ -/* implementation-defined value */ - -/** - * @brief Maximum size of the export encoding of an ECC keypair. - * - * @details The representation of an ECC keypair follows - * https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html#key-formats - * and is dependent on the family: - * - for twisted Edwards curves: 32B - * - for Weierstrass curves: `ceiling(m/8)`-byte string, big-endian - * where m is the bit size associated with the curve. - */ -#define PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) \ - (size_t)\ - (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \ - (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_SECP_R1 ? \ - PSA_BITS_TO_BYTES(key_bits) : \ - 0)) - -/** - * @brief Sufficient output buffer size for @ref psa_export_key(). - * - * @details The following code illustrates how to allocate enough memory to export a key by - * querying the key type and size at runtime. - * - * @code - * @ref psa_key_attributes_t attributes = @ref PSA_KEY_ATTRIBUTES_INIT; - * @ref psa_status_t status; - * status = @ref psa_get_key_attributes(key, &attributes); - * if (status != @ref PSA_SUCCESS) - * handle_error(...); - * @ref psa_key_type_t key_type = @ref psa_get_key_type(&attributes); - * size_t key_bits = @ref psa_get_key_bits(&attributes); - * size_t buffer_size = @ref PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); - * @ref psa_reset_key_attributes(&attributes); - * uint8_t *buffer = malloc(buffer_size); - * if (buffer == NULL) - * handle_error(...); - * size_t buffer_length; - * status = @ref psa_export_key(key, buffer, buffer_size, &buffer_length); - * if (status != @ref PSA_SUCCESS) - * handle_error(...); - * @endcode - * - * See also @ref PSA_EXPORT_KEY_PAIR_MAX_SIZE and @ref PSA_EXPORT_PUBLIC_KEY_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 @ref psa_export_key() or @ref psa_export_public_key() will not fail - * with @ref PSA_ERROR_BUFFER_TOO_SMALL. - * 0 if the parameters are a valid combination that is not supported by the implementation. - * Unspecified if the parameters are not valid. - */ -#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type) ? \ - PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) : \ - (PSA_KEY_TYPE_IS_ECC(key_type) ? \ - PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) : \ - 0)) - -/** - * @brief Check whether the key size is a valid ECC size for key type. - * - * @param type key type of of type @ref psa_key_type_t - * @param bits Key size of type @ref psa_key_bits_t - */ -#define PSA_ECC_KEY_SIZE_IS_VALID(type, bits) \ - (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? \ - (bits == 255) : \ - (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_SECP_R1 ? \ - (bits == 128 || \ - bits == 192 || \ - bits == 224 || \ - bits == 256 || \ - bits == 384) : \ - 0)) - -/** - * @brief The maximum size of an asymmetric private key. - */ -#define PSA_MAX_PRIV_KEY_SIZE (PSA_BYTES_TO_BITS(CONFIG_PSA_MAX_KEY_SIZE)) - -/** - * @brief Sufficient buffer size for exporting any asymmetric key pair. - * - * @details This value must be a sufficient buffer size when calling @ref 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 @ref PSA_EXPORT_KEY_OUTPUT_SIZE(). - */ -#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ - IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_SECT_R1, 256)) -#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)) -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)) -#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ - (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_SECT_R1, 192)) -#else -#define PSA_EXPORT_KEY_PAIR_MAX_SIZE 0 -#endif - -/** - * @brief Maximum size of the export encoding of an ECC public key. - * - * @details The representation of an ECC public key is dependent on the family: - * - for twisted Edwards curves: 32B - * - for Weierstrass curves: - * - The byte 0x04; - * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; - * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; - * - where m is the bit size associated with the curve. - * - 1 byte + 2 * point size. - */ -#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) \ - (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \ - ((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1))) - -/** - * @brief Sufficient output buffer size for @ref psa_export_public_key(). - * - * @details 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 - * @ref psa_key_attributes_t attributes = @ref PSA_KEY_ATTRIBUTES_INIT; - * @ref psa_status_t status; - * status = @ref psa_get_key_attributes(key, &attributes); - * if (status != @ref PSA_SUCCESS) handle_error(...); - * @ref psa_key_type_t key_type = @ref psa_get_key_type(&attributes); - * size_t key_bits = @ref psa_get_key_bits(&attributes); - * size_t buffer_size = @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); - * @ref psa_reset_key_attributes(&attributes); - * uint8_t *buffer = malloc(buffer_size); - * if (buffer == NULL) handle_error(...); - * size_t buffer_length; - * status = @ref psa_export_public_key(key, buffer, buffer_size, &buffer_length); - * if (status != @ref 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 A buffer size in bytes that guarantees that @ref psa_export_public_key() will not fail - * with @ref PSA_ERROR_BUFFER_TOO_SMALL. - * 0 if the parameters are a valid combination that is not supported. - * Unspecified if the parameters are not valid, the return value is unspecified. - * If the parameters are valid and supported, return the same result as - * @ref PSA_EXPORT_KEY_OUTPUT_SIZE( - * @ref 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) \ - (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) : \ - 0) - -/** - * @brief Sufficient buffer size for exporting any asymmetric public key. - * - * @details This macro expands to a compile-time constant integer. This value is - * a sufficient buffer size when calling @ref psa_export_key() or - * @ref psa_export_public_key() to export any asymmetric public key, - * regardless of the exact key type and key size. - * - * See also @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(@p key_type, @p key_bits). - */ -#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ - IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, 256)) -#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, 192)) -#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)) -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ - (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)) -#else -#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 0 -#endif - -/** - * @brief The maximum size of an asymmetric private key buffer. If only a secure element driver is - * present, the private key will always be stored in a key slot and PSA Crypto will only - * allocate memory for an 8 Byte key slot number. - */ -#define PSA_MAX_PRIV_KEY_BUFFER_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_PRIV_KEY_SIZE)) - -/** - * @brief The maximum size of an asymmetric private key pair. - */ -#define PSA_MAX_ASYMMETRIC_KEYPAIR_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_PRIV_KEY_SIZE) + \ - PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) - -/** - * @brief The maximum size of the used key data. - */ -#if IS_USED(MODULE_PSA_ASYMMETRIC) -#define PSA_MAX_KEY_DATA_SIZE (PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) -#else -#define PSA_MAX_KEY_DATA_SIZE (CONFIG_PSA_MAX_KEY_SIZE) -#endif - -/** - * @brief The maximum size of an unstructured key. - */ -#define PSA_MAX_UNSTRUCTURED_KEY_SIZE (CONFIG_PSA_MAX_KEY_SIZE) - -/** - * @brief ECDSA signature size for a given curve bit size - * - * @note This macro returns a compile-time constant if its argument is one. - * - * @param curve_bits Curve size in bits. - * - * @return Signature size in bytes. - */ -#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \ - ((size_t)(PSA_BITS_TO_BYTES(curve_bits) * 2)) - -/** - * @brief Sufficient signature buffer size for @ref psa_sign_message() and @ref psa_sign_hash(). - * - * @details If the size of the signature buffer is at least this large, it is guaranteed that - * @ref psa_sign_message() and @ref psa_sign_hash() will not fail due to an insufficient - * buffer size. The actual size of the output might be smaller in any given call. - * - * See also @ref PSA_SIGNATURE_MAX_SIZE. - * - * @param key_type An asymmetric key type. This can be a key pair type or a public key type. - * @param key_bits The size of the key in bits. - * @param alg The signature algorithm. - * - * @return A sufficient signature buffer size for the specified asymmetric signature algorithm and - * key parameters. - * 0 if algorithm and key parameters are not supported. - * If the parameters are not valid, the return value is unspecified. - */ -#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ - (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \ - ((void)alg, 0)) +#include "aead/sizes.h" +#include "asymmetric_encryption/sizes.h" +#include "asymmetric_signature/sizes.h" +#include "cipher/sizes.h" +#include "hash/sizes.h" +#include "key/sizes.h" +#include "key/values.h" +#include "key_agreement/sizes.h" +#include "key_derivation/sizes.h" +#include "mac/sizes.h" +#include "sizes.h" #ifdef __cplusplus } diff --git a/sys/include/psa_crypto/psa/crypto_struct.h b/sys/include/psa_crypto/psa/crypto_struct.h index 7dc43827a9..8d44a80a6d 100644 --- a/sys/include/psa_crypto/psa/crypto_struct.h +++ b/sys/include/psa_crypto/psa/crypto_struct.h @@ -27,159 +27,11 @@ extern "C" { #include "crypto_sizes.h" #include "crypto_contexts.h" -#if IS_USED(MODULE_PSA_AEAD) || defined(DOXYGEN) -/** - * @brief Structure storing an AEAD operation context - * - * @note Not implemented, yet - */ -struct psa_aead_operation_s { - int dummy; /**< Not implemented, yet */ -}; - -/** - * @brief This macro returns a suitable initializer for an AEAD operation object of type - * @ref psa_aead_operation_t. - */ -#define PSA_AEAD_OPERATION_INIT { 0 } - -/** - * @brief Return an initial value for an AEAD operation object. - * - * @return psa_aead_operation_s - */ -static inline struct psa_aead_operation_s psa_aead_operation_init(void) -{ - const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT; - - return v; -} -#endif /* MODULE_PSA_AEAD */ - -#if IS_USED(MODULE_PSA_CIPHER) || defined(DOXYGEN) -/** - * @brief Structure storing a cipher operation context - */ -struct psa_cipher_operation_s { - uint8_t iv_required : 1; /**< True if algorithm requires IV */ - uint8_t iv_set : 1; /**< True if IV was already set */ - uint8_t default_iv_length; /**< Default IV length for algorithm */ - psa_algorithm_t alg; /**< Operation algorithm*/ - /** Union containing cipher contexts for the executing backend */ - union cipher_context { - psa_cipher_context_t cipher_ctx; /**< Cipher context */ -#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN) - psa_se_cipher_context_t se_ctx; /**< SE Cipher context */ -#endif - } backend_ctx; /**< Backend specific cipher context */ -}; - -/** - * @brief This macro returns a suitable initializer for a cipher operation - * object of type @ref psa_cipher_operation_t. - */ -#define PSA_CIPHER_OPERATION_INIT { 0 } - -/** - * @brief Return an initial value for a cipher operation object. - * - * @return psa_cipher_operation_s - */ -static inline struct psa_cipher_operation_s psa_cipher_operation_init(void) -{ - const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; - - return v; -} -#endif /* MODULE_PSA_CIPHER */ - -#if IS_USED(MODULE_PSA_KEY_DERIVATION) || defined(DOXYGEN) -/** - * @brief This macro returns a suitable initializer for a key derivation operation object of - * type @ref psa_key_derivation_operation_t. - */ -#define PSA_KEY_DERIVATION_OPERATION_INIT { 0 } - -/** - * @brief Structure storing a key derivation context - * - * @note Not yet implemented - */ -struct psa_key_derivation_operation_s { - int dummy; /**< Not implemented yet */ -}; - -/** - * @brief Return an initial value for a key derivation operation object. - * - * @return psa_key_derivation_operation_s - */ -static inline struct psa_key_derivation_operation_s psa_key_derivation_operation_init(void) -{ - const struct psa_key_derivation_operation_s v = PSA_KEY_DERIVATION_OPERATION_INIT; - - return v; -} -#endif /* MODULE_PSA_KEY_DERIVATION */ - -#if IS_USED(MODULE_PSA_HASH) || defined(DOXYGEN) -/** - * @brief Structure containing a hash context and algorithm - */ -struct psa_hash_operation_s { - psa_algorithm_t alg; /**< Operation algorithm */ -#if IS_USED(MODULE_PSA_HASH) - psa_hash_context_t ctx; /**< Operation hash context */ -#endif -}; - -/** - * @brief This macro returns a suitable initializer for a hash operation object of type - * @ref psa_hash_operation_t. - */ -#define PSA_HASH_OPERATION_INIT { 0 } - -/** - * @brief Return an initial value for a hash operation object. - * - * @return struct psa_hash_operation_s - */ -static inline struct psa_hash_operation_s psa_hash_operation_init(void) -{ - const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT; - - return v; -} -#endif /* MODULE_PSA_HASH */ - -#if IS_USED(MODULE_PSA_MAC) || defined(DOXYGEN) -/** - * @brief This macro returns a suitable initializer for a MAC operation object of type - * @ref psa_mac_operation_t. - */ -#define PSA_MAC_OPERATION_INIT { 0 } - -/** - * @brief Structure storing a MAC operation context - * - * @note Not yet implemented - */ -struct psa_mac_operation_s { - int dummy; /**< Not yet implemented */ -}; - -/** - * @brief Return an initial value for a MAC operation object. - * - * @return psa_mac_operation_s - */ -static inline struct psa_mac_operation_s psa_mac_operation_init(void) -{ - const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; - - return v; -} -#endif /* MODULE_PSA_MAC */ +#include "aead/types.h" +#include "cipher/types.h" +#include "hash/types.h" +#include "key_derivation/types.h" +#include "mac/types.h" #ifdef __cplusplus } diff --git a/sys/include/psa_crypto/psa/crypto_types.h b/sys/include/psa_crypto/psa/crypto_types.h index 3426049b36..1d147423b1 100644 --- a/sys/include/psa_crypto/psa/crypto_types.h +++ b/sys/include/psa_crypto/psa/crypto_types.h @@ -29,180 +29,11 @@ extern "C" { #include "psa/error.h" #include "psa/key/attributes.h" -/** - * @brief For encrypt-decrypt functions, whether the operation is an encryption - * or a decryption. - */ -typedef enum { - PSA_CRYPTO_DRIVER_DECRYPT, - PSA_CRYPTO_DRIVER_ENCRYPT -} psa_encrypt_or_decrypt_t; - -/** - * @brief The type of the state object for key derivation operations. - * - * @details Before calling any function on a key derivation operation object, the application must - * initialize it by any of the following means: - * - Set the object to all-bits-zero, for example: - * @code - * @ref psa_key_derivation_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * @endcode - * - Initialize the object to logical zero values by declaring the object as static or - * global without an explicit initializer, for example: - * @code - * static @ref psa_key_derivation_operation_t operation; - * @endcode - * - Initialize the object to the initializer @ref PSA_KEY_DERIVATION_OPERATION_INIT, - * for example: - * @code - * @ref psa_key_derivation_operation_t operation = - * @ref PSA_KEY_DERIVATION_OPERATION_INIT; - * @endcode - * - Assign the result of the function @ref psa_key_derivation_operation_init() to - * the object, for example: - * @code - * @ref psa_key_derivation_operation_t operation; - * operation = @ref psa_key_derivation_operation_init(); - * @endcode - * This is an implementation-defined type. Applications that make assumptions about the - * content of this object will result in in implementation-specific behavior, and are - * non-portable. - */ -typedef struct psa_key_derivation_operation_s psa_key_derivation_operation_t; - -/** - * @brief Encoding of the step of a key derivation. - */ -typedef uint16_t psa_key_derivation_step_t; - -/* These are all temporarily defined as some numeric type to prevent errors at compile time.*/ -/** - * @brief The type of the state object for multi-part AEAD operations. - * - * @details Before calling any function on an AEAD operation object, the application must - * initialize it by any of the following means: - * - Set the object to all-bits-zero, for example: - * @code - * @ref psa_aead_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * @endcode - * - Initialize the object to logical zero values by declaring the object as static - * or global without an explicit initializer, for example: - * @code - * static @ref psa_aead_operation_t operation; - * @endcode - * - Initialize the object to the initializer @ref PSA_AEAD_OPERATION_INIT, for example: - * @code - * @ref psa_aead_operation_t operation = @ref PSA_AEAD_OPERATION_INIT; - * @endcode - * - Assign the result of the function @ref psa_aead_operation_init() to the object, - * for example: - * @code - * @ref psa_aead_operation_t operation; - * operation = @ref psa_aead_operation_init(); - * @endcode - * - * This is an implementation-defined type. Applications that make assumptions about the - * content of this object will result in in implementation-specific behavior, and are - * non-portable. - */ -typedef struct psa_aead_operation_s psa_aead_operation_t; - -/** - * @brief The type of the state object for multi-part MAC operations. - * - * @details Before calling any function on a MAC operation object, the application must initialize - * it by any of the following means: - * - Set the object to all-bits-zero, for example: - * @code - * @ref psa_mac_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * @endcode - * - Initialize the object to logical zero values by declaring the object as static or - * global without an explicit initializer, for example: - * @code - * static @ref psa_mac_operation_t operation; - * @endcode - * - Initialize the object to the initializer @ref PSA_MAC_OPERATION_INIT, for example: - * @code - * @ref psa_mac_operation_t operation = @ref PSA_MAC_OPERATION_INIT; - * @endcode - * - Assign the result of the function @ref psa_mac_operation_init() to the object, - * for example: - * @code - * @ref psa_mac_operation_t operation; - * operation = @ref psa_mac_operation_init(); - * @endcode - * This is an implementation-defined type. Applications that make assumptions about the - * content of this object will result in in implementation-specific behavior, and are - * non-portable. - */ -typedef struct psa_mac_operation_s psa_mac_operation_t; - -/** - * @brief The type of the state data structure for multipart hash operations. - * - * @details Before calling any function on a hash operation object, the application must - * initialize it by any of the following means: - * - Set the structure to all-bits-zero, for example: - * @code - * @ref psa_hash_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * @endcode - * - Initialize the structure to logical zero values, for example: - * @code - * @ref psa_hash_operation_t operation = {0}; - * @endcode - * - Initialize the structure to the initializer @ref PSA_HASH_OPERATION_INIT, - * for example: - * @code - * @ref psa_hash_operation_t operation = @ref PSA_HASH_OPERATION_INIT; - * @endcode - * - Assign the result of the function @ref psa_hash_operation_init() - * to the structure, for example: - * @code - * @ref psa_hash_operation_t operation; - * operation = @ref psa_hash_operation_init(); - * @endcode - * - * This is an implementation-defined struct. Applications should not - * make any assumptions about the content of this structure except - * as directed by the documentation of a specific implementation. - */ -typedef struct psa_hash_operation_s psa_hash_operation_t; - -/** - * @brief The type of the state object for multi-part cipher operations. - * - * @details Before calling any function on a cipher operation object, the application must - * initialize it by any of the following means: - * - Set the object to all-bits-zero, for example: - * @code - * @ref psa_cipher_operation_t operation; - * memset(&operation, 0, sizeof(operation)); - * @endcode - * - Initialize the object to logical zero values by declaring the object as static or - * global without an explicit initializer, for example: - * @code - * static @ref psa_cipher_operation_t operation; - * @endcode - * - Initialize the object to the initializer @ref PSA_CIPHER_OPERATION_INIT, for example: - * @code - * @ref psa_cipher_operation_t operation = @ref PSA_CIPHER_OPERATION_INIT; - * @endcode - * - Assign the result of the function @ref psa_cipher_operation_init() to the object, - * for example: - * @code - * @ref psa_cipher_operation_t operation; - * operation = @ref psa_cipher_operation_init(); - * @endcode - * - * This is an implementation-defined type. Applications that make assumptions about the - * content of this object will result in in implementation-specific behavior, and are - * non-portable. - */ -typedef struct psa_cipher_operation_s psa_cipher_operation_t; +#include "aead/types.h" +#include "cipher/types.h" +#include "hash/types.h" +#include "key_derivation/types.h" +#include "mac/types.h" #ifdef __cplusplus } diff --git a/sys/include/psa_crypto/psa/crypto_values.h b/sys/include/psa_crypto/psa/crypto_values.h index 74186bfb0d..c124e7d216 100644 --- a/sys/include/psa_crypto/psa/crypto_values.h +++ b/sys/include/psa_crypto/psa/crypto_values.h @@ -35,155 +35,10 @@ extern "C" { #include "psa/aead/algorithm.h" #include "psa/key_agreement/algorithm.h" #include "psa/key_derivation/algorithm.h" +#include "psa/key_derivation/values.h" #include "psa/asymmetric_encryption/algorithm.h" #include "psa/asymmetric_signature/algorithm.h" -/** - * @brief A context for key derivation. - * - * @details This is typically a direct input. It can also be a key of type - * @ref PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_CONTEXT /* implementation-defined value */ - -/** - * @brief A cost parameter for password hashing or key stretching. - * - * @details This must be a direct input, passed to @ref psa_key_derivation_input_integer(). - */ -#define PSA_KEY_DERIVATION_INPUT_COST /* implementation-defined value */ - -/** - * @brief An information string for key derivation. - * - * @details This is typically a direct input. It can also be a key of type - * @ref PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_INFO /* implementation-defined value */ - -/** - * @brief A label for key derivation. - * - * @details This is typically a direct input. It can also be a key of type - * @ref PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_LABEL /* implementation-defined value */ - -/** - * @brief A low-entropy secret input for password hashing or key stretching. - * - * @details This is usually a key of type @ref PSA_KEY_TYPE_PASSWORD passed to - * @ref psa_key_derivation_input_key() or a direct input passed to - * @ref psa_key_derivation_input_bytes() that is a password or passphrase. It can also be - * high-entropy secret, for example, a key of type @ref PSA_KEY_TYPE_DERIVE, or the shared - * secret resulting from a key agreement. - * - * If the secret is a direct input, the derivation operation cannot be used to derive - * keys: the operation will not allow a call to @ref psa_key_derivation_output_key(). - */ -#define PSA_KEY_DERIVATION_INPUT_PASSWORD /* implementation-defined value */ - -/** - * @brief A salt for key derivation. - * - * @details This is typically a direct input. It can also be a key of type - * @ref PSA_KEY_TYPE_RAW_DATA or @ref PSA_KEY_TYPE_PEPPER. - */ -#define PSA_KEY_DERIVATION_INPUT_SALT /* implementation-defined value */ - -/** - * @brief A high-entropy secret input for key derivation. - * - * @details This is typically a key of type @ref PSA_KEY_TYPE_DERIVE passed to - * @ref psa_key_derivation_input_key(), or the shared secret resulting from a key - * agreement obtained via @ref psa_key_derivation_key_agreement(). - * - * The secret can also be a direct input passed to @ref psa_key_derivation_input_bytes(). - * In this case, the derivation operation cannot be used to derive keys: the operation - * will not allow a call to @ref psa_key_derivation_output_key(). - */ -#define PSA_KEY_DERIVATION_INPUT_SECRET /* implementation-defined value */ - -/** - * @brief A seed for key derivation. - * - * @details This is typically a direct input. It can also be a key of type - * @ref PSA_KEY_TYPE_RAW_DATA. - */ -#define PSA_KEY_DERIVATION_INPUT_SEED /* implementation-defined value */ - -/** - * @brief Use the maximum possible capacity for a key derivation operation. - * - * @details Use this value as the capacity argument when setting up a key derivation to specify - * that the operation will use the maximum possible capacity. The value of the maximum - * possible capacity depends on the key derivation algorithm. - */ -#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY \ -/* implementation-defined value */ - -/** - * @brief Sufficient output buffer size for @ref psa_raw_key_agreement(), for any of the - * supported key types and key agreement algorithms. - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_raw_key_agreement() will not fail due to an insufficient buffer size. - * - * See also @ref PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(). - */ -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ -/* implementation-defined value */ - -/** - * @brief Sufficient output buffer size for @ref psa_raw_key_agreement(). - * - * @details If the size of the output buffer is at least this large, it is guaranteed that - * @ref psa_raw_key_agreement() will not fail due to an insufficient buffer size. - * The actual size of the output might be smaller in any given call. - * - * See also @ref 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 A sufficient output buffer size for the specified key type and size. - * 0 if key type is not supported. - * If the parameters are not valid, the return value is unspecified. - */ -#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ -/* implementation-defined value */ - -/** - * @brief A sufficient signature buffer size for @ref psa_sign_message() and - * @ref psa_sign_hash(), for any of the supported key types and asymmetric signature - * algorithms. - * - * @details If the size of the signature buffer is at least this large, it is guaranteed that - * @ref psa_sign_message() and @ref psa_sign_hash() will not fail due to an insufficient - * buffer size. - * - * See also @ref PSA_SIGN_OUTPUT_SIZE(). - */ -#define PSA_SIGNATURE_MAX_SIZE /* implementation-defined value */ - -/** - * @brief This macro returns the maximum supported length of the PSK for the TLS-1.2 PSK-to-MS - * key derivation. - * - * @details This implementation-defined value specifies the maximum length for the PSK input used - * with a @ref PSA_ALG_TLS12_PSK_TO_MS() key agreement algorithm. - * - * Quoting Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) - * [RFC4279](https://tools.ietf.org/html/rfc4279.html) §5.3: - * TLS implementations supporting these cipher suites MUST support arbitrary PSK - * identities up to 128 octets in length, and arbitrary PSKs up to 64 octets in length. - * Supporting longer identities and keys is RECOMMENDED. - * - * Therefore, it is recommended that implementations define - * @ref PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE with a value greater than or equal to 64. - */ -#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE /* implementation-defined value */ - #ifdef __cplusplus } #endif diff --git a/sys/include/psa_crypto/psa/hash/sizes.h b/sys/include/psa_crypto/psa/hash/sizes.h new file mode 100644 index 0000000000..2c36ad5155 --- /dev/null +++ b/sys/include/psa_crypto/psa/hash/sizes.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Hash size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "kernel_defines.h" +#include "psa/hash/algorithm.h" + +/** + * @brief The size of the output of @ref psa_hash_compute() and @ref psa_hash_finish(), in bytes. + * + * @details This is also the hash length that @ref psa_hash_compare() and @ref psa_hash_verify() + * expect. + * + * See also @ref PSA_HASH_MAX_SIZE. + * + * @param alg A hash algorithm or an HMAC algorithm: a value of type @ref psa_algorithm_t such + * that (@ref PSA_ALG_IS_HASH(@p alg) || @ref PSA_ALG_IS_HMAC(@p alg)) is true. + * + * @return The hash length for the specified hash algorithm. + * 0 if the hash algorithm is not recognized or not supported. + */ +#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 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ + 0) + +/** + * @brief Maximum size of a hash supported by this implementation, in bytes. + * + * See also @ref PSA_HASH_LENGTH(). + */ +#define PSA_HASH_MAX_SIZE (64) + +/** + * @brief Maximum size of a hash block supported by this implementation, in bytes. + * + * See also @ref PSA_HASH_BLOCK_LENGTH(). + */ +#if (IS_USED(MODULE_PSA_HASH_SHA3_256)) +#define PSA_HASH_MAX_BLOCK_SIZE 136 +#elif (IS_USED(MODULE_PSA_HASH_SHA_512) || \ + IS_USED(MODULE_PSA_HASH_SHA_384) || \ + IS_USED(MODULE_PSA_HASH_SHA_512_224) || \ + IS_USED(MODULE_PSA_HASH_SHA_512_256)) +#define PSA_HASH_MAX_BLOCK_SIZE 128 +#elif (IS_USED(MODULE_PSA_HASH_SHA3_384)) +#define PSA_HASH_MAX_BLOCK_SIZE 104 +#elif (IS_USED(MODULE_PSA_HASH_SHA3_512)) +#define PSA_HASH_MAX_BLOCK_SIZE 72 +#elif (IS_USED(MODULE_PSA_HASH_MD5) || \ + IS_USED(MODULE_PSA_HASH_SHA_1) || \ + IS_USED(MODULE_PSA_HASH_SHA_224) || \ + IS_USED(MODULE_PSA_HASH_SHA_256)) +#define PSA_HASH_MAX_BLOCK_SIZE 64 +#else +#define PSA_HASH_MAX_BLOCK_SIZE 0 +#endif + +/** + * @brief A sufficient hash suspend state buffer size for @ref psa_hash_suspend(), in bytes. + * + * @details If the size of the hash state buffer is at least this large, it is guaranteed that + * @ref psa_hash_suspend() will not fail due to an insufficient buffer size. The actual + * size of the output might be smaller in any given call. + * + * See also @ref PSA_HASH_SUSPEND_OUTPUT_MAX_SIZE. + * + * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_HASH(alg) is true. + * + * @return A sufficient output size for the algorithm. + * 0 if the hash algorithm is not recognized, or is not supported by + * @ref psa_hash_suspend(). + * + * For a supported hash algorithm alg, the following expression is true: + * @code + * PSA_HASH_SUSPEND_OUTPUT_SIZE(alg) == PSA_HASH_SUSPEND_ALGORITHM_FIELD_LENGTH + + * PSA_HASH_SUSPEND_INPUT_LENGTH_FIELD_LENGTH(alg) + + * PSA_HASH_SUSPEND_HASH_STATE_FIELD_LENGTH(alg) + + * PSA_HASH_BLOCK_LENGTH(alg) - 1 + * @endcode + */ +#define PSA_HASH_SUSPEND_OUTPUT_SIZE(alg) /* specification-defined value */ + +/** + * @brief A sufficient hash suspend state buffer size for @ref psa_hash_suspend(), + * for any supported hash algorithms. + * + * @details If the size of the hash state buffer is at least this large, it is guaranteed that + * @ref psa_hash_suspend() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_HASH_SUSPEND_OUTPUT_SIZE(). + */ +#define PSA_HASH_SUSPEND_OUTPUT_MAX_SIZE /* implementation-defined value */ + +/** + * @brief The size of the algorithm field that is part of the output of @ref psa_hash_suspend(), + * in bytes. + * + * @details Applications can use this value to unpack the hash suspend state that is output by + * @ref psa_hash_suspend(). + */ +#define PSA_HASH_SUSPEND_ALGORITHM_FIELD_LENGTH ((size_t)4) + +/** + * @brief The size of the input-length field that is part of the output of + * @ref psa_hash_suspend(), in bytes. + * + * @details Applications can use this value to unpack the hash suspend state that is output + * by @ref psa_hash_suspend(). + * + * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_HASH(@p alg) is true. + * + * @return The size, in bytes, of the input-length field of the hash suspend state for the + * specified hash algorithm. + * 0 i f the hash algorithm is not recognized or not supported. + */ +#define PSA_HASH_SUSPEND_INPUT_LENGTH_FIELD_LENGTH(alg) \ +/* specification-defined value */ + +/** + * @brief The size of the hash-state field that is part of the output of @ref psa_hash_suspend(), + * in bytes. + * + * @details Applications can use this value to unpack the hash suspend state that is output by + * @ref psa_hash_suspend(). + * + * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_HASH(@p alg) is true. + * + * @return The size, in bytes, of the hash-state field of the hash suspend state for the specified + * hash algorithm. + * 0 if the hash algorithm is not recognized or not supported. + */ +#define PSA_HASH_SUSPEND_HASH_STATE_FIELD_LENGTH(alg) \ +/* specification-defined value */ + +/** + * @brief The input block size of a hash algorithm, in bytes. + * + * @details Hash algorithms process their input data in blocks. Hash operations will retain any + * partial blocks until they have enough input to fill the block or until the operation + * is finished. + * + * This affects the output from @ref psa_hash_suspend(). + * + * @param alg A hash algorithm: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_HASH(@p alg) is true. + * + * @return The block size in bytes for the specified hash algorithm. If the hash algorithm is not + * recognized, return 0. An implementation can return either 0 or the correct size for a + * hash algorithm that it recognizes, but does not support. + */ +#define PSA_HASH_BLOCK_LENGTH(alg) \ + ( \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 128 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 144 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 136 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 104 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 72 : \ + 0) + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/hash/types.h b/sys/include/psa_crypto/psa/hash/types.h new file mode 100644 index 0000000000..d38af5f59e --- /dev/null +++ b/sys/include/psa_crypto/psa/hash/types.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Hash type definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hashes/psa/riot_hashes.h" +#include "kernel_defines.h" +#include "psa/algorithm.h" + +#if IS_USED(MODULE_PSA_RIOT_HASHES_HMAC_SHA256) || IS_USED(MODULE_PSA_RIOT_HASHES_MD5) || \ + IS_USED(MODULE_PSA_RIOT_HASHES_SHA_1) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA_224) || \ + IS_USED(MODULE_PSA_RIOT_HASHES_SHA_256) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA_384) || \ + IS_USED(MODULE_PSA_RIOT_HASHES_SHA_512) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA_512_224) || \ + IS_USED(MODULE_PSA_RIOT_HASHES_SHA_512_256) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA3_256) || \ + IS_USED(MODULE_PSA_RIOT_HASHES_SHA3_384) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA3_512) +#include "hashes/psa/riot_hashes.h" +#endif + +#if IS_USED(MODULE_PERIPH_HASH_SHA_1) || IS_USED(MODULE_PERIPH_HASH_SHA_224) || \ + IS_USED(MODULE_PERIPH_HASH_SHA_256) || IS_USED(MODULE_PERIPH_HASH_SHA_384) || \ + IS_USED(MODULE_PERIPH_HASH_SHA_512) || IS_USED(MODULE_PERIPH_HASH_SHA_512_224) || \ + IS_USED(MODULE_PERIPH_HASH_SHA_512_256) +#include "psa_periph_hashes_ctx.h" +#endif + +/** + * @brief Structure containing the hash contexts needed by the application. + */ +typedef union { +#if IS_USED(MODULE_PSA_HASH_MD5) || defined(DOXYGEN) + psa_hashes_md5_ctx_t md5; /**< MD5 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_1) || defined(DOXYGEN) + psa_hashes_sha1_ctx_t sha1; /**< SHA-1 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_224) || defined(DOXYGEN) + psa_hashes_sha224_ctx_t sha224; /**< SHA-224 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_256) || defined(DOXYGEN) + psa_hashes_sha256_ctx_t sha256; /**< SHA-256 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_384) || defined(DOXYGEN) + psa_hashes_sha384_ctx_t sha384; /**< SHA-384 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_512) || defined(DOXYGEN) + psa_hashes_sha512_ctx_t sha512; /**< SHA-512 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA3_256) || IS_USED(MODULE_PSA_HASH_SHA3_384) \ +|| IS_USED(MODULE_PSA_HASH_SHA3_512) || defined(DOXYGEN) + psa_hashes_sha3_ctx_t sha3; /**< SHA-3 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_512_224) || defined(DOXYGEN) + psa_hashes_sha512_224_ctx_t sha512_224; /**< SHA-512/224 context */ +#endif +#if IS_USED(MODULE_PSA_HASH_SHA_512_256) || defined(DOXYGEN) + psa_hashes_sha512_256_ctx_t sha512_256; /**< SHA-512/256 context */ +#endif +} psa_hash_context_t; + +/** + * @brief Structure containing a hash context and algorithm + */ +struct psa_hash_operation_s { + psa_algorithm_t alg; /**< Operation algorithm */ +#if IS_USED(MODULE_PSA_HASH) || defined(DOXYGEN) + psa_hash_context_t ctx; /**< Operation hash context */ +#endif +}; + +/** + * @brief The type of the state data structure for multipart hash operations. + * + * @details Before calling any function on a hash operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * @code + * @ref psa_hash_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * @endcode + * - Initialize the structure to logical zero values, for example: + * @code + * @ref psa_hash_operation_t operation = {0}; + * @endcode + * - Initialize the structure to the initializer @ref PSA_HASH_OPERATION_INIT, + * for example: + * @code + * @ref psa_hash_operation_t operation = @ref PSA_HASH_OPERATION_INIT; + * @endcode + * - Assign the result of the function @ref psa_hash_operation_init() + * to the structure, for example: + * @code + * @ref psa_hash_operation_t operation; + * operation = @ref psa_hash_operation_init(); + * @endcode + * + * This is an implementation-defined struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. + */ +typedef struct psa_hash_operation_s psa_hash_operation_t; + +/** + * @brief This macro returns a suitable initializer for a hash operation object of type + * @ref psa_hash_operation_t. + */ +#define PSA_HASH_OPERATION_INIT { 0 } + +/** + * @brief Return an initial value for a hash operation object. + * + * @return struct psa_hash_operation_t + */ +static inline psa_hash_operation_t psa_hash_operation_init(void) +{ + const psa_hash_operation_t v = PSA_HASH_OPERATION_INIT; + + return v; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key/sizes.h b/sys/include/psa_crypto/psa/key/sizes.h new file mode 100644 index 0000000000..ae3f30888d --- /dev/null +++ b/sys/include/psa_crypto/psa/key/sizes.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "psa/sizes.h" +#include "type.h" + +/** + * @brief Maximum key size in bytes, determined by the build system. + * + * @details The maximum key size is set automatically, depending on + * the features chosen at compile-time. They should not be + * changed manually. + */ +#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256)) +#define CONFIG_PSA_MAX_KEY_SIZE 64 +#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ + IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519) || \ + IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || \ + IS_USED(MODULE_PSA_AEAD_AES_256_CCM) || \ + IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256) || \ + IS_USED(MODULE_PSA_CIPHER_CHACHA20)) +#define CONFIG_PSA_MAX_KEY_SIZE 32 +#elif (IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || \ + IS_USED(MODULE_PSA_AEAD_AES_192_CCM) || \ + IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) +#define CONFIG_PSA_MAX_KEY_SIZE 24 +#elif (IS_USED(MODULE_PSA_CIPHER_AES_128_CBC)) || \ + (IS_USED(MODULE_PSA_AEAD_AES_128_CCM)) || \ + (IS_USED(MODULE_PSA_CIPHER_AES_128_ECB)) +#define CONFIG_PSA_MAX_KEY_SIZE 16 +#else +#define CONFIG_PSA_MAX_KEY_SIZE 0 +#endif + +/** + * @brief Maximum size of the export encoding of an ECC keypair. + * + * @details The representation of an ECC keypair follows + * https://arm-software.github.io/psa-api/crypto/1.1/api/keys/management.html#key-formats + * and is dependent on the family: + * - for twisted Edwards curves: 32B + * - for Weierstrass curves: `ceiling(m/8)`-byte string, big-endian + * where m is the bit size associated with the curve. + */ +#define PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) \ + (size_t)\ + (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_SECP_R1 ? \ + PSA_BITS_TO_BYTES(key_bits) : \ + 0)) + +/** + * @brief Sufficient output buffer size for @ref psa_export_key(). + * + * @details The following code illustrates how to allocate enough memory to export a key by + * querying the key type and size at runtime. + * + * @code + * @ref psa_key_attributes_t attributes = @ref PSA_KEY_ATTRIBUTES_INIT; + * @ref psa_status_t status; + * status = @ref psa_get_key_attributes(key, &attributes); + * if (status != @ref PSA_SUCCESS) + * handle_error(...); + * @ref psa_key_type_t key_type = @ref psa_get_key_type(&attributes); + * size_t key_bits = @ref psa_get_key_bits(&attributes); + * size_t buffer_size = @ref PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); + * @ref psa_reset_key_attributes(&attributes); + * uint8_t *buffer = malloc(buffer_size); + * if (buffer == NULL) + * handle_error(...); + * size_t buffer_length; + * status = @ref psa_export_key(key, buffer, buffer_size, &buffer_length); + * if (status != @ref PSA_SUCCESS) + * handle_error(...); + * @endcode + * + * See also @ref PSA_EXPORT_KEY_PAIR_MAX_SIZE and @ref PSA_EXPORT_PUBLIC_KEY_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 @ref psa_export_key() or @ref psa_export_public_key() will not fail + * with @ref PSA_ERROR_BUFFER_TOO_SMALL. + * 0 if the parameters are a valid combination that is not supported by the implementation. + * Unspecified if the parameters are not valid. + */ +#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type) ? \ + PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) : \ + (PSA_KEY_TYPE_IS_ECC(key_type) ? \ + PSA_KEY_EXPORT_ECC_KEY_MAX_SIZE(key_type, key_bits) : \ + 0)) + +/** + * @brief Check whether the key size is a valid ECC size for key type. + * + * @param type key type of of type @ref psa_key_type_t + * @param bits Key size of type @ref psa_key_bits_t + */ +#define PSA_ECC_KEY_SIZE_IS_VALID(type, bits) \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? \ + (bits == 255) : \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(type) == PSA_ECC_FAMILY_SECP_R1 ? \ + (bits == 128 || \ + bits == 192 || \ + bits == 224 || \ + bits == 256 || \ + bits == 384) : \ + 0)) + +/** + * @brief The maximum size of an asymmetric private key. + */ +#define PSA_MAX_PRIV_KEY_SIZE (PSA_BYTES_TO_BITS(CONFIG_PSA_MAX_KEY_SIZE)) + +/** + * @brief Sufficient buffer size for exporting any asymmetric key pair. + * + * @details This value must be a sufficient buffer size when calling @ref 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 @ref PSA_EXPORT_KEY_OUTPUT_SIZE(). + */ +#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ + IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_SECT_R1, 256)) +#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)) +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)) +#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + (PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_ECC_FAMILY_SECT_R1, 192)) +#else +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE 0 +#endif + +/** + * @brief Maximum size of the export encoding of an ECC public key. + * + * @details The representation of an ECC public key is dependent on the family: + * - for twisted Edwards curves: 32B + * - for Weierstrass curves: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; + * - where m is the bit size associated with the curve. + * - 1 byte + 2 * point size. + */ +#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) == PSA_ECC_FAMILY_TWISTED_EDWARDS ? 32 : \ + ((size_t)(2 * PSA_BITS_TO_BYTES(key_bits) + 1))) + +/** + * @brief Sufficient output buffer size for @ref psa_export_public_key(). + * + * @details 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 + * @ref psa_key_attributes_t attributes = @ref PSA_KEY_ATTRIBUTES_INIT; + * @ref psa_status_t status; + * status = @ref psa_get_key_attributes(key, &attributes); + * if (status != @ref PSA_SUCCESS) handle_error(...); + * @ref psa_key_type_t key_type = @ref psa_get_key_type(&attributes); + * size_t key_bits = @ref psa_get_key_bits(&attributes); + * size_t buffer_size = @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); + * @ref psa_reset_key_attributes(&attributes); + * uint8_t *buffer = malloc(buffer_size); + * if (buffer == NULL) handle_error(...); + * size_t buffer_length; + * status = @ref psa_export_public_key(key, buffer, buffer_size, &buffer_length); + * if (status != @ref 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 A buffer size in bytes that guarantees that @ref psa_export_public_key() will not fail + * with @ref PSA_ERROR_BUFFER_TOO_SMALL. + * 0 if the parameters are a valid combination that is not supported. + * Unspecified if the parameters are not valid, the return value is unspecified. + * If the parameters are valid and supported, return the same result as + * @ref PSA_EXPORT_KEY_OUTPUT_SIZE( + * @ref 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) \ + (PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_type, key_bits) : \ + 0) + +/** + * @brief Sufficient buffer size for exporting any asymmetric public key. + * + * @details This macro expands to a compile-time constant integer. This value is + * a sufficient buffer size when calling @ref psa_export_key() or + * @ref psa_export_public_key() to export any asymmetric public key, + * regardless of the exact key type and key size. + * + * See also @ref PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(@p key_type, @p key_bits). + */ +#if (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1) || \ + IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256)) +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, 256)) +#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)) +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_SECT_R1, 192)) +#elif (IS_USED(MODULE_PSA_ASYMMETRIC_ECC_ED25519)) +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_ECC_FAMILY_TWISTED_EDWARDS, 255)) +#else +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE 0 +#endif + +/** + * @brief The maximum size of an asymmetric private key buffer. If only a secure element driver is + * present, the private key will always be stored in a key slot and PSA Crypto will only + * allocate memory for an 8 Byte key slot number. + */ +#define PSA_MAX_PRIV_KEY_BUFFER_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_PRIV_KEY_SIZE)) + +/** + * @brief The maximum size of an asymmetric private key pair. + */ +#define PSA_MAX_ASYMMETRIC_KEYPAIR_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_PRIV_KEY_SIZE) + \ + PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) + +/** + * @brief The maximum size of the used key data. + */ +#if IS_USED(MODULE_PSA_ASYMMETRIC) +#define PSA_MAX_KEY_DATA_SIZE (PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) +#else +#define PSA_MAX_KEY_DATA_SIZE (CONFIG_PSA_MAX_KEY_SIZE) +#endif + +/** + * @brief The maximum size of an unstructured key. + */ +#define PSA_MAX_UNSTRUCTURED_KEY_SIZE (CONFIG_PSA_MAX_KEY_SIZE) + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key/values.h b/sys/include/psa_crypto/psa/key/values.h new file mode 100644 index 0000000000..a20a449b04 --- /dev/null +++ b/sys/include/psa_crypto/psa/key/values.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key values definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Number of required allocated asymmetric key pair slots. + * + * @details These should be defined by the developer to + * fit their requirements. The default number is 0. + */ +#ifndef CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT +#define CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT 0 +#endif + +/** + * @brief Number of required allocated single key slots. + * + * @details These should be defined by the developer to + * fit their requirements. The default number is 0. + */ +#ifndef CONFIG_PSA_SINGLE_KEY_COUNT +#define CONFIG_PSA_SINGLE_KEY_COUNT 0 +#endif + +/** + * @brief Number of required allocated protected key slots. + * + * @details These should be defined by the developer to + * fit their requirements. The default number is 5. + */ +#ifndef CONFIG_PSA_PROTECTED_KEY_COUNT +#if (IS_USED(MODULE_PSA_SECURE_ELEMENT)) +#define CONFIG_PSA_PROTECTED_KEY_COUNT 5 +#else +#define CONFIG_PSA_PROTECTED_KEY_COUNT 0 +#endif +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key_agreement/sizes.h b/sys/include/psa_crypto/psa/key_agreement/sizes.h new file mode 100644 index 0000000000..2036e3d8da --- /dev/null +++ b/sys/include/psa_crypto/psa/key_agreement/sizes.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key agreement size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Sufficient output buffer size for @ref psa_raw_key_agreement(), for any of the + * supported key types and key agreement algorithms. + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_raw_key_agreement() will not fail due to an insufficient buffer size. + * + * See also @ref PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(). + */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ +/* implementation-defined value */ + +/** + * @brief Sufficient output buffer size for @ref psa_raw_key_agreement(). + * + * @details If the size of the output buffer is at least this large, it is guaranteed that + * @ref psa_raw_key_agreement() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also @ref 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 A sufficient output buffer size for the specified key type and size. + * 0 if key type is not supported. + * If the parameters are not valid, the return value is unspecified. + */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ +/* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key_derivation/sizes.h b/sys/include/psa_crypto/psa/key_derivation/sizes.h new file mode 100644 index 0000000000..b51ab14027 --- /dev/null +++ b/sys/include/psa_crypto/psa/key_derivation/sizes.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key derivation size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Use the maximum possible capacity for a key derivation operation. + * + * @details Use this value as the capacity argument when setting up a key derivation to specify + * that the operation will use the maximum possible capacity. The value of the maximum + * possible capacity depends on the key derivation algorithm. + */ +#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY \ +/* implementation-defined value */ + +/** + * @brief This macro returns the maximum supported length of the PSK for the TLS-1.2 PSK-to-MS + * key derivation. + * + * @details This implementation-defined value specifies the maximum length for the PSK input used + * with a @ref PSA_ALG_TLS12_PSK_TO_MS() key agreement algorithm. + * + * Quoting Pre-Shared Key Ciphersuites for Transport Layer Security (TLS) + * [RFC4279](https://tools.ietf.org/html/rfc4279.html) §5.3: + * TLS implementations supporting these cipher suites MUST support arbitrary PSK + * identities up to 128 octets in length, and arbitrary PSKs up to 64 octets in length. + * Supporting longer identities and keys is RECOMMENDED. + * + * Therefore, it is recommended that implementations define + * @ref PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE with a value greater than or equal to 64. + */ +#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE /* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key_derivation/types.h b/sys/include/psa_crypto/psa/key_derivation/types.h new file mode 100644 index 0000000000..5b43b7f6df --- /dev/null +++ b/sys/include/psa_crypto/psa/key_derivation/types.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key derivation type definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encoding of the step of a key derivation. + */ +typedef uint16_t psa_key_derivation_step_t; + +/** + * @brief Structure storing a key derivation context + * + * @note Not yet implemented + */ +struct psa_key_derivation_operation_s { + int dummy; /**< Not implemented yet */ +}; + +/** + * @brief The type of the state object for key derivation operations. + * + * @details Before calling any function on a key derivation operation object, the application must + * initialize it by any of the following means: + * - Set the object to all-bits-zero, for example: + * @code + * @ref psa_key_derivation_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * @endcode + * - Initialize the object to logical zero values by declaring the object as static or + * global without an explicit initializer, for example: + * @code + * static @ref psa_key_derivation_operation_t operation; + * @endcode + * - Initialize the object to the initializer @ref PSA_KEY_DERIVATION_OPERATION_INIT, + * for example: + * @code + * @ref psa_key_derivation_operation_t operation = + * @ref PSA_KEY_DERIVATION_OPERATION_INIT; + * @endcode + * - Assign the result of the function @ref psa_key_derivation_operation_init() to + * the object, for example: + * @code + * @ref psa_key_derivation_operation_t operation; + * operation = @ref psa_key_derivation_operation_init(); + * @endcode + * This is an implementation-defined type. Applications that make assumptions about the + * content of this object will result in in implementation-specific behavior, and are + * non-portable. + */ +typedef struct psa_key_derivation_operation_s psa_key_derivation_operation_t; + +/** + * @brief This macro returns a suitable initializer for a key derivation operation object of + * type @ref psa_key_derivation_operation_t. + */ +#define PSA_KEY_DERIVATION_OPERATION_INIT { 0 } + +/** + * @brief Return an initial value for a key derivation operation object. + * + * @return psa_key_derivation_operation_t + */ +static inline psa_key_derivation_operation_t psa_key_derivation_operation_init(void) +{ + const psa_key_derivation_operation_t v = PSA_KEY_DERIVATION_OPERATION_INIT; + + return v; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/key_derivation/values.h b/sys/include/psa_crypto/psa/key_derivation/values.h new file mode 100644 index 0000000000..c7103623ac --- /dev/null +++ b/sys/include/psa_crypto/psa/key_derivation/values.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief Key derivation value definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief A context for key derivation. + * + * @details This is typically a direct input. It can also be a key of type + * @ref PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_CONTEXT /* implementation-defined value */ + +/** + * @brief A cost parameter for password hashing or key stretching. + * + * @details This must be a direct input, passed to @ref psa_key_derivation_input_integer(). + */ +#define PSA_KEY_DERIVATION_INPUT_COST /* implementation-defined value */ + +/** + * @brief An information string for key derivation. + * + * @details This is typically a direct input. It can also be a key of type + * @ref PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_INFO /* implementation-defined value */ + +/** + * @brief A label for key derivation. + * + * @details This is typically a direct input. It can also be a key of type + * @ref PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_LABEL /* implementation-defined value */ + +/** + * @brief A low-entropy secret input for password hashing or key stretching. + * + * @details This is usually a key of type @ref PSA_KEY_TYPE_PASSWORD passed to + * @ref psa_key_derivation_input_key() or a direct input passed to + * @ref psa_key_derivation_input_bytes() that is a password or passphrase. It can also be + * high-entropy secret, for example, a key of type @ref PSA_KEY_TYPE_DERIVE, or the shared + * secret resulting from a key agreement. + * + * If the secret is a direct input, the derivation operation cannot be used to derive + * keys: the operation will not allow a call to @ref psa_key_derivation_output_key(). + */ +#define PSA_KEY_DERIVATION_INPUT_PASSWORD /* implementation-defined value */ + +/** + * @brief A salt for key derivation. + * + * @details This is typically a direct input. It can also be a key of type + * @ref PSA_KEY_TYPE_RAW_DATA or @ref PSA_KEY_TYPE_PEPPER. + */ +#define PSA_KEY_DERIVATION_INPUT_SALT /* implementation-defined value */ + +/** + * @brief A high-entropy secret input for key derivation. + * + * @details This is typically a key of type @ref PSA_KEY_TYPE_DERIVE passed to + * @ref psa_key_derivation_input_key(), or the shared secret resulting from a key + * agreement obtained via @ref psa_key_derivation_key_agreement(). + * + * The secret can also be a direct input passed to @ref psa_key_derivation_input_bytes(). + * In this case, the derivation operation cannot be used to derive keys: the operation + * will not allow a call to @ref psa_key_derivation_output_key(). + */ +#define PSA_KEY_DERIVATION_INPUT_SECRET /* implementation-defined value */ + +/** + * @brief A seed for key derivation. + * + * @details This is typically a direct input. It can also be a key of type + * @ref PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_SEED /* implementation-defined value */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/mac/sizes.h b/sys/include/psa_crypto/psa/mac/sizes.h new file mode 100644 index 0000000000..3e817b29ec --- /dev/null +++ b/sys/include/psa_crypto/psa/mac/sizes.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief MAC size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "kernel_defines.h" +#include "psa/algorithm.h" +#include "psa/cipher/sizes.h" +#include "psa/hash/algorithm.h" +#include "psa/hash/sizes.h" +#include "psa/mac/algorithm.h" + +/** + * @brief The size of the output of @ref psa_mac_compute() and @ref psa_mac_sign_finish(), + * in bytes. + * + * @details If the size of the MAC buffer is at least this large, it is guaranteed that + * @ref psa_mac_compute() and @ref psa_mac_sign_finish() will not fail due to an + * insufficient buffer size. + * + * This is also the MAC length that @ref psa_mac_verify() and @ref psa_mac_verify_finish() + * expect. + * + * See also @ref PSA_MAC_MAX_SIZE. + * + * @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: a value of type @ref psa_algorithm_t such that + * @ref PSA_ALG_IS_MAC(@p alg) is true. + * + * @return The MAC length for the specified algorithm with the specified key parameters. + * 0 if the MAC algorithm is not recognized or not supported. + * Unspecified if the key parameters are not consistent with the algorithm. + */ +#define PSA_MAC_LENGTH(key_type, key_bits, 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)) + +/** + * @brief A sufficient buffer size for storing the MAC output by @ref psa_mac_verify() and + * @ref psa_mac_verify_finish(), for any of the supported key types and MAC algorithms. + * + * @details If the size of the MAC buffer is at least this large, it is guaranteed that + * @ref psa_mac_verify() and @ref psa_mac_verify_finish() will not fail due to an + * insufficient buffer size. + * + * See also @ref PSA_MAC_LENGTH(). + */ +#if (IS_USED(MODULE_PSA_MAC_HMAC_SHA_512) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA3_512)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_512)) /* 64 */ +#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_384) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA3_384)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_384)) /* 48 */ +#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_256) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_256) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA3_256)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_256)) /* 32 */ +#elif (IS_USED(MODULE_PSA_MAC_HMAC_SHA_224) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA_512_224) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA3_224)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA3_224)) /* 28 */ +#elif (IS_USED(MODULE_PSA_MAC_HMAC_RIPEMD160) || \ + IS_USED(MODULE_PSA_MAC_HMAC_SHA_1)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_SHA_1)) /* 20 */ +#elif (IS_USED(MODULE_PSA_MAC_HMAC_MD2) || \ + IS_USED(MODULE_PSA_MAC_HMAC_MD4) || \ + IS_USED(MODULE_PSA_MAC_HMAC_MD5)) +#define PSA_MAC_MAX_SIZE (PSA_HASH_LENGTH(PSA_ALG_MD5)) /* 16 */ +#else +#define PSA_MAC_MAX_SIZE 0 +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/mac/types.h b/sys/include/psa_crypto/psa/mac/types.h new file mode 100644 index 0000000000..6042c6fec8 --- /dev/null +++ b/sys/include/psa_crypto/psa/mac/types.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file + * @brief MAC type definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure storing a MAC operation context + * + * @note Not yet implemented + */ +struct psa_mac_operation_s { + int dummy; /**< Not yet implemented */ +}; + +/** + * @brief The type of the state object for multi-part MAC operations. + * + * @details Before calling any function on a MAC operation object, the application must initialize + * it by any of the following means: + * - Set the object to all-bits-zero, for example: + * @code + * @ref psa_mac_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * @endcode + * - Initialize the object to logical zero values by declaring the object as static or + * global without an explicit initializer, for example: + * @code + * static @ref psa_mac_operation_t operation; + * @endcode + * - Initialize the object to the initializer @ref PSA_MAC_OPERATION_INIT, for example: + * @code + * @ref psa_mac_operation_t operation = @ref PSA_MAC_OPERATION_INIT; + * @endcode + * - Assign the result of the function @ref psa_mac_operation_init() to the object, + * for example: + * @code + * @ref psa_mac_operation_t operation; + * operation = @ref psa_mac_operation_init(); + * @endcode + * This is an implementation-defined type. Applications that make assumptions about the + * content of this object will result in in implementation-specific behavior, and are + * non-portable. + */ +typedef struct psa_mac_operation_s psa_mac_operation_t; + +/** + * @brief This macro returns a suitable initializer for a MAC operation object of type + * @ref psa_mac_operation_t. + */ +#define PSA_MAC_OPERATION_INIT { 0 } + +/** + * @brief Return an initial value for a MAC operation object. + * + * @return psa_mac_operation_t + */ +static inline psa_mac_operation_t psa_mac_operation_init(void) +{ + const psa_mac_operation_t v = PSA_MAC_OPERATION_INIT; + + return v; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/sys/include/psa_crypto/psa/sizes.h b/sys/include/psa_crypto/psa/sizes.h new file mode 100644 index 0000000000..57e9b3de5a --- /dev/null +++ b/sys/include/psa_crypto/psa/sizes.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 TU Dresden + * Copyright (C) 2021 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup sys_psa_crypto + * @{ + * + * @file sizes.h + * @brief Size definitions for the PSA Crypto API + * + * @author Armin Wolf + * @author Lena Boeckmann + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Functions to convert bits to bytes + * + * @param bits + * + * @return Number of bytes contained in bits + */ +#define PSA_BITS_TO_BYTES(bits) (size_t)(((bits) + 7) / 8) + +/** + * @brief Functions to convert bytes to bits + * + * @param bytes + * + * @return Number of bits contained in bytes + */ +#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8) + +#ifdef __cplusplus +} +#endif + +/** @} */