diff --git a/include/psa/crypto.h b/include/psa/crypto.h index c58d22ae4..fa8045cf4 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -53,272 +53,18 @@ typedef _unsigned_integral_type_ psa_key_handle_t; extern "C" { #endif -/** \defgroup basic Basic definitions +/* The file "crypto_types.h" declares types that encode errors, + * algorithms, key types, policies, etc. */ +#include "crypto_types.h" + +/* The file "crypto_values.h" declares macros to build and analyze values + * of integral types defined in "crypto_types.h". */ +#include "crypto_values.h" + +/** \defgroup initialization Library initialization * @{ */ -#if defined(PSA_SUCCESS) -/* If PSA_SUCCESS is defined, assume that PSA crypto is being used - * together with PSA IPC, which also defines the identifier - * PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case; - * the other error code names don't clash. Also define psa_status_t as - * an alias for the type used by PSA IPC. This is a temporary hack - * until we unify error reporting in PSA IPC and PSA crypto. - * - * Note that psa_defs.h must be included before this header! - */ -typedef psa_error_t psa_status_t; - -#else /* defined(PSA_SUCCESS) */ - -/** - * \brief Function return status. - * - * This is either #PSA_SUCCESS (which is zero), indicating success, - * or a nonzero value indicating that an error occurred. Errors are - * encoded as one of the \c PSA_ERROR_xxx values defined here. - */ -typedef int32_t psa_status_t; - -/** The action was completed successfully. */ -#define PSA_SUCCESS ((psa_status_t)0) - -#endif /* !defined(PSA_SUCCESS) */ - -/** An error occurred that does not correspond to any defined - * failure cause. - * - * Implementations may use this error code if none of the other standard - * error codes are applicable. */ -#define PSA_ERROR_UNKNOWN_ERROR ((psa_status_t)1) - -/** The requested operation or a parameter is not supported - * by this implementation. - * - * Implementations should return this error code when an enumeration - * parameter such as a key type, algorithm, etc. is not recognized. - * If a combination of parameters is recognized and identified as - * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */ -#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)2) - -/** The requested action is denied by a policy. - * - * Implementations should return this error code when the parameters - * are recognized as valid and supported, and a policy explicitly - * denies the requested operation. - * - * If a subset of the parameters of a function call identify a - * forbidden operation, and another subset of the parameters are - * not valid or not supported, it is unspecified whether the function - * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or - * #PSA_ERROR_INVALID_ARGUMENT. */ -#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)3) - -/** An output buffer is too small. - * - * Applications can call the \c PSA_xxx_SIZE macro listed in the function - * description to determine a sufficient buffer size. - * - * Implementations should preferably return this error code only - * in cases when performing the operation with a larger output - * buffer would succeed. However implementations may return this - * error if a function has invalid or unsupported parameters in addition - * to the parameters that determine the necessary output buffer size. */ -#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)4) - -/** A slot is occupied, but must be empty to carry out the - * requested action. - * - * If a handle is invalid, it does not designate an occupied slot. - * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. - */ -#define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5) - -/** A slot is empty, but must be occupied to carry out the - * requested action. - * - * If a handle is invalid, it does not designate an empty slot. - * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. - */ -#define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6) - -/** The requested action cannot be performed in the current state. - * - * Multipart operations return this error when one of the - * functions is called out of sequence. Refer to the function - * descriptions for permitted sequencing of functions. - * - * Implementations shall not return this error code to indicate - * that a key slot is occupied when it needs to be free or vice versa, - * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT - * as applicable. */ -#define PSA_ERROR_BAD_STATE ((psa_status_t)7) - -/** The parameters passed to the function are invalid. - * - * Implementations may return this error any time a parameter or - * combination of parameters are recognized as invalid. - * - * Implementations shall not return this error code to indicate - * that a key slot is occupied when it needs to be free or vice versa, - * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT - * as applicable. - * - * Implementation shall not return this error code to indicate that a - * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE - * instead. - */ -#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8) - -/** There is not enough runtime memory. - * - * If the action is carried out across multiple security realms, this - * error can refer to available memory in any of the security realms. */ -#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)9) - -/** There is not enough persistent storage. - * - * Functions that modify the key storage return this error code if - * there is insufficient storage space on the host media. In addition, - * many functions that do not otherwise access storage may return this - * error code if the implementation requires a mandatory log entry for - * the requested action and the log storage space is full. */ -#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)10) - -/** There was a communication failure inside the implementation. - * - * This can indicate a communication failure between the application - * and an external cryptoprocessor or between the cryptoprocessor and - * an external volatile or persistent memory. A communication failure - * may be transient or permanent depending on the cause. - * - * \warning If a function returns this error, it is undetermined - * whether the requested action has completed or not. Implementations - * should return #PSA_SUCCESS on successful completion whenver - * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE - * if the requested action was completed successfully in an external - * cryptoprocessor but there was a breakdown of communication before - * the cryptoprocessor could report the status to the application. - */ -#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11) - -/** There was a storage failure that may have led to data loss. - * - * This error indicates that some persistent storage is corrupted. - * It should not be used for a corruption of volatile memory - * (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error - * between the cryptoprocessor and its external storage (use - * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is - * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE). - * - * Note that a storage failure does not indicate that any data that was - * previously read is invalid. However this previously read data may no - * longer be readable from storage. - * - * When a storage failure occurs, it is no longer possible to ensure - * the global integrity of the keystore. Depending on the global - * integrity guarantees offered by the implementation, access to other - * data may or may not fail even if the data is still readable but - * its integrity canont be guaranteed. - * - * Implementations should only use this error code to report a - * permanent storage corruption. However application writers should - * keep in mind that transient errors while reading the storage may be - * reported using this error code. */ -#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)12) - -/** A hardware failure was detected. - * - * A hardware failure may be transient or permanent depending on the - * cause. */ -#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)13) - -/** A tampering attempt was detected. - * - * If an application receives this error code, there is no guarantee - * that previously accessed or computed data was correct and remains - * confidential. Applications should not perform any security function - * and should enter a safe failure state. - * - * Implementations may return this error code if they detect an invalid - * state that cannot happen during normal operation and that indicates - * that the implementation's security guarantees no longer hold. Depending - * on the implementation architecture and on its security and safety goals, - * the implementation may forcibly terminate the application. - * - * This error code is intended as a last resort when a security breach - * is detected and it is unsure whether the keystore data is still - * protected. Implementations shall only return this error code - * to report an alarm from a tampering detector, to indicate that - * the confidentiality of stored data can no longer be guaranteed, - * or to indicate that the integrity of previously returned data is now - * considered compromised. Implementations shall not use this error code - * to indicate a hardware failure that merely makes it impossible to - * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE, - * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE, - * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code - * instead). - * - * This error indicates an attack against the application. Implementations - * shall not return this error code as a consequence of the behavior of - * the application itself. */ -#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)14) - -/** There is not enough entropy to generate random data needed - * for the requested action. - * - * This error indicates a failure of a hardware random generator. - * Application writers should note that this error can be returned not - * only by functions whose purpose is to generate random data, such - * as key, IV or nonce generation, but also by functions that execute - * an algorithm with a randomized result, as well as functions that - * use randomization of intermediate computations as a countermeasure - * to certain attacks. - * - * Implementations should avoid returning this error after psa_crypto_init() - * has succeeded. Implementations should generate sufficient - * entropy during initialization and subsequently use a cryptographically - * secure pseudorandom generator (PRNG). However implementations may return - * this error at any time if a policy requires the PRNG to be reseeded - * during normal operation. */ -#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)15) - -/** The signature, MAC or hash is incorrect. - * - * Verification functions return this error if the verification - * calculations completed successfully, and the value to be verified - * was determined to be incorrect. - * - * If the value to verify has an invalid size, implementations may return - * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */ -#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)16) - -/** The decrypted padding is incorrect. - * - * \warning In some protocols, when decrypting data, it is essential that - * the behavior of the application does not depend on whether the padding - * is correct, down to precise timing. Applications should prefer - * protocols that use authenticated encryption rather than plain - * encryption. If the application must perform a decryption of - * unauthenticated data, the application writer should take care not - * to reveal whether the padding is invalid. - * - * Implementations should strive to make valid and invalid padding - * as close as possible to indistinguishable to an external observer. - * In particular, the timing of a decryption operation should not - * depend on the validity of the padding. */ -#define PSA_ERROR_INVALID_PADDING ((psa_status_t)17) - -/** The generator has insufficient capacity left. - * - * Once a function returns this error, attempts to read from the - * generator will always return this error. */ -#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18) - -/** The key handle is not valid. - */ -#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)19) - /** * \brief Library initialization. * @@ -345,1094 +91,12 @@ typedef int32_t psa_status_t; */ psa_status_t psa_crypto_init(void); -#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8) -#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8) - -/**@}*/ - -/** \defgroup crypto_types Key and algorithm types - * @{ - */ - -/** \brief Encoding of a key type. - */ -typedef uint32_t psa_key_type_t; - -/** An invalid key type value. - * - * Zero is not the encoding of any key type. - */ -#define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x00000000) - -/** Vendor-defined flag - * - * Key types defined by this standard will never have the - * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types - * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should - * respect the bitwise structure used by standard encodings whenever practical. - */ -#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000) - -#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x70000000) -#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x40000000) -#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t)0x50000000) -#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t)0x60000000) -#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t)0x70000000) - -#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t)0x10000000) - -/** Whether a key type is vendor-defined. */ -#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \ - (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0) - -/** Whether a key type is an unstructured array of bytes. - * - * This encompasses both symmetric keys and non-key data. - */ -#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK & ~(psa_key_type_t)0x10000000) == \ - PSA_KEY_TYPE_CATEGORY_SYMMETRIC) - -/** Whether a key type is asymmetric: either a key pair or a public key. */ -#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ - & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) == \ - PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) -/** Whether a key type is the public part of a key pair. */ -#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) -/** Whether a key type is a key pair containing a private part and a public - * part. */ -#define PSA_KEY_TYPE_IS_KEYPAIR(type) \ - (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR) -/** The key pair type corresponding to a public key type. - * - * You may also pass a key pair type as \p type, it will be left unchanged. - * - * \param type A public key type or key pair type. - * - * \return The corresponding key pair type. - * If \p type is not a public key or a key pair, - * the return value is undefined. - */ -#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \ - ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) -/** The public key type corresponding to a key pair type. - * - * You may also pass a key pair type as \p type, it will be left unchanged. - * - * \param type A public key type or key pair type. - * - * \return The corresponding public key type. - * If \p type is not a public key or a key pair, - * the return value is undefined. - */ -#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \ - ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) - -/** Raw data. - * - * A "key" of this type cannot be used for any cryptographic operation. - * Applications may use this type to store arbitrary data in the keystore. */ -#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x50000001) - -/** HMAC key. - * - * The key policy determines which underlying hash algorithm the key can be - * used for. - * - * HMAC keys should generally have the same size as the underlying hash. - * This size can be calculated with #PSA_HASH_SIZE(\c alg) where - * \c alg is the HMAC algorithm or the underlying hash algorithm. */ -#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x51000000) - -/** A secret for key derivation. - * - * The key policy determines which key derivation algorithm the key - * can be used for. - */ -#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000) - -/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher. - * - * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or - * 32 bytes (AES-256). - */ -#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x40000001) - -/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). - * - * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or - * 24 bytes (3-key 3DES). - * - * Note that single DES and 2-key 3DES are weak and strongly - * deprecated and should only be used to decrypt legacy data. 3-key 3DES - * is weak and deprecated and should only be used in legacy protocols. - */ -#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002) - -/** Key for an cipher, AEAD or MAC algorithm based on the - * Camellia block cipher. */ -#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003) - -/** Key for the RC4 stream cipher. - * - * Note that RC4 is weak and deprecated and should only be used in - * legacy protocols. */ -#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004) - -/** RSA public key. */ -#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000) -/** RSA key pair (private and public key). */ -#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000) -/** Whether a key type is an RSA key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_RSA(type) \ - (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY) - -/** DSA public key. */ -#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000) -/** DSA key pair (private and public key). */ -#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000) -/** Whether a key type is an DSA key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_DSA(type) \ - (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY) - -#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000) -#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000) -#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff) -/** Elliptic curve key pair. */ -#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \ - (PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve)) -/** Elliptic curve public key. */ -#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \ - (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve)) - -/** Whether a key type is an elliptic curve key (pair or public-only). */ -#define PSA_KEY_TYPE_IS_ECC(type) \ - ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \ - ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) -#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \ - (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ - PSA_KEY_TYPE_ECC_KEYPAIR_BASE) -#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \ - (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ - PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) - -/** The type of PSA elliptic curve identifiers. */ -typedef uint16_t psa_ecc_curve_t; -/** Extract the curve from an elliptic curve key type. */ -#define PSA_KEY_TYPE_GET_CURVE(type) \ - ((psa_ecc_curve_t) (PSA_KEY_TYPE_IS_ECC(type) ? \ - ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \ - 0)) - -/* The encoding of curve identifiers is currently aligned with the - * TLS Supported Groups Registry (formerly known as the - * TLS EC Named Curve Registry) - * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 - * The values are defined by RFC 8422 and RFC 7027. */ -#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x0001) -#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x0002) -#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x0003) -#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x0004) -#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x0005) -#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x0006) -#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x0007) -#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x0008) -#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x0009) -#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x000a) -#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x000b) -#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x000c) -#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x000d) -#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x000e) -#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x000f) -#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x0010) -#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x0011) -#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x0012) -#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x0013) -#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x0014) -#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x0015) -#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x0016) -#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x0017) -#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x0018) -#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x0019) -#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a) -#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b) -#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c) -#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d) -#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e) - -/** The block size of a block cipher. - * - * \param type A cipher key type (value of type #psa_key_type_t). - * - * \return The block size for a block cipher, or 1 for a stream cipher. - * The return value is undefined if \p type is not a supported - * cipher key type. - * - * \note It is possible to build stream cipher algorithms on top of a block - * cipher, for example CTR mode (#PSA_ALG_CTR). - * This macro only takes the key type into account, so it cannot be - * used to determine the size of the data that #psa_cipher_update() - * might buffer for future processing in general. - * - * \note This macro returns a compile-time constant if its argument is one. - * - * \warning This macro may evaluate its argument multiple times. - */ -#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \ - ( \ - (type) == PSA_KEY_TYPE_AES ? 16 : \ - (type) == PSA_KEY_TYPE_DES ? 8 : \ - (type) == PSA_KEY_TYPE_CAMELLIA ? 16 : \ - (type) == PSA_KEY_TYPE_ARC4 ? 1 : \ - 0) - -/** \brief Encoding of a cryptographic algorithm. - * - * For algorithms that can be applied to multiple key types, this type - * does not encode the key type. For example, for symmetric ciphers - * based on a block cipher, #psa_algorithm_t encodes the block cipher - * mode and the padding mode while the block cipher itself is encoded - * via #psa_key_type_t. - */ -typedef uint32_t psa_algorithm_t; - -#define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000) -#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000) -#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000) -#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000) -#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000) -#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000) -#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000) -#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000) -#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000) -#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000) -#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000) - -#define PSA_ALG_IS_VENDOR_DEFINED(alg) \ - (((alg) & PSA_ALG_VENDOR_FLAG) != 0) - -/** Whether the specified algorithm is a hash algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a hash algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_HASH(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH) - -/** Whether the specified algorithm is a MAC algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a MAC algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_MAC(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) - -/** Whether the specified algorithm is a symmetric cipher algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_CIPHER(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER) - -/** Whether the specified algorithm is an authenticated encryption - * with associated data (AEAD) algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an AEAD algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_AEAD(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) - -/** Whether the specified algorithm is a public-key signature algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a public-key signature algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_SIGN(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN) - -/** Whether the specified algorithm is a public-key encryption algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a public-key encryption algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) - -#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000) -/** Whether the specified algorithm is a key agreement algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key agreement algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \ - PSA_ALG_CATEGORY_KEY_AGREEMENT) - -/** Whether the specified algorithm is a key derivation algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key derivation algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_KEY_DERIVATION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) - -/** Whether the specified algorithm is a key selection algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a key selection algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_KEY_SELECTION(alg) \ - (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION) - -#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) -#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) -#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) -#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003) -#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004) -#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005) -/** SHA2-224 */ -#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008) -/** SHA2-256 */ -#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x01000009) -/** SHA2-384 */ -#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0100000a) -/** SHA2-512 */ -#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0100000b) -/** SHA2-512/224 */ -#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0100000c) -/** SHA2-512/256 */ -#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0100000d) -/** SHA3-224 */ -#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x01000010) -/** SHA3-256 */ -#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x01000011) -/** SHA3-384 */ -#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x01000012) -/** SHA3-512 */ -#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x01000013) - -#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000) -#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x02800000) -/** Macro to build an HMAC algorithm. - * - * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HMAC algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HMAC(hash_alg) \ - (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_HMAC_GET_HASH(hmac_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is an HMAC algorithm. - * - * HMAC is a family of MAC algorithms that are based on a hash function. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is an HMAC algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_HMAC(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ - PSA_ALG_HMAC_BASE) - -/* In the encoding of a MAC algorithm, the bits corresponding to - * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is - * truncated. As an exception, the value 0 means the untruncated algorithm, - * whatever its length is. The length is encoded in 6 bits, so it can - * reach up to 63; the largest MAC is 64 bytes so its trivial truncation - * to full length is correctly encoded as 0 and any non-trivial truncation - * is correctly encoded as a value between 1 and 63. */ -#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x00003f00) -#define PSA_MAC_TRUNCATION_OFFSET 8 - -/** Macro to build a truncated MAC algorithm. - * - * A truncated MAC algorithm is identical to the corresponding MAC - * algorithm except that the MAC value for the truncated algorithm - * consists of only the first \p mac_length bytes of the MAC value - * for the untruncated algorithm. - * - * \note This macro may allow constructing algorithm identifiers that - * are not valid, either because the specified length is larger - * than the untruncated MAC or because the specified length is - * smaller than permitted by the implementation. - * - * \note It is implementation-defined whether a truncated MAC that - * is truncated to the same length as the MAC of the untruncated - * algorithm is considered identical to the untruncated algorithm - * for policy comparison purposes. - * - * \param alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) - * is true). This may be a truncated or untruncated - * MAC algorithm. - * \param mac_length Desired length of the truncated MAC in bytes. - * This must be at most the full length of the MAC - * and must be at least an implementation-specified - * minimum. The implementation-specified minimum - * shall not be zero. - * - * \return The corresponding MAC algorithm with the specified - * length. - * \return Unspecified if \p alg is not a supported - * MAC algorithm or if \p mac_length is too small or - * too large for the specified MAC algorithm. - */ -#define PSA_ALG_TRUNCATED_MAC(alg, mac_length) \ - (((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \ - ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK)) - -/** Macro to build the base MAC algorithm corresponding to a truncated - * MAC algorithm. - * - * \param alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) - * is true). This may be a truncated or untruncated - * MAC algorithm. - * - * \return The corresponding base MAC algorithm. - * \return Unspecified if \p alg is not a supported - * MAC algorithm. - */ -#define PSA_ALG_FULL_LENGTH_MAC(alg) \ - ((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) - -/** Length to which a MAC algorithm is truncated. - * - * \param alg A MAC algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) - * is true). - * - * \return Length of the truncated MAC in bytes. - * \return 0 if \p alg is a non-truncated MAC algorithm. - * \return Unspecified if \p alg is not a supported - * MAC algorithm. - */ -#define PSA_MAC_TRUNCATED_LENGTH(alg) \ - (((alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) - -#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000) -#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001) -#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002) -#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003) - -/** Whether the specified algorithm is a MAC algorithm based on a block cipher. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier. - */ -#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ - PSA_ALG_CIPHER_MAC_BASE) - -#define PSA_ALG_CIPHER_STREAM_FLAG ((psa_algorithm_t)0x00800000) -#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000) - -/** Whether the specified algorithm is a stream cipher. - * - * A stream cipher is a symmetric cipher that encrypts or decrypts messages - * by applying a bitwise-xor with a stream of bytes that is generated - * from a key. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \p alg is not a supported - * algorithm identifier or if it is not a symmetric cipher algorithm. - */ -#define PSA_ALG_IS_STREAM_CIPHER(alg) \ - (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \ - (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG)) - -/** The ARC4 stream cipher algorithm. - */ -#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001) - -/** The CTR stream cipher mode. - * - * CTR is a stream cipher which is built from a block cipher. - * The underlying block cipher is determined by the key type. - * For example, to use AES-128-CTR, use this algorithm with - * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes). - */ -#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001) - -#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002) - -#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003) - -/** The XTS cipher mode. - * - * XTS is a cipher mode which is built from a block cipher. It requires at - * least one full block of input, but beyond this minimum the input - * does not need to be a whole number of blocks. - */ -#define PSA_ALG_XTS ((psa_algorithm_t)0x044000ff) - -/** The CBC block cipher chaining mode, with no padding. - * - * The underlying block cipher is determined by the key type. - * - * This symmetric cipher mode can only be used with messages whose lengths - * are whole number of blocks for the chosen block cipher. - */ -#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t)0x04600100) - -/** The CBC block cipher chaining mode with PKCS#7 padding. - * - * The underlying block cipher is determined by the key type. - * - * This is the padding method defined by PKCS#7 (RFC 2315) §10.3. - */ -#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101) - -#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001) -#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002) - -/* In the encoding of a AEAD algorithm, the bits corresponding to - * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag. - * The constants for default lengths follow this encoding. - */ -#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x00003f00) -#define PSA_AEAD_TAG_LENGTH_OFFSET 8 - -/** Macro to build a shortened AEAD algorithm. - * - * A shortened AEAD algorithm is similar to the corresponding AEAD - * algorithm, but has an authentication tag that consists of fewer bytes. - * Depending on the algorithm, the tag length may affect the calculation - * of the ciphertext. - * - * \param alg A AEAD algorithm identifier (value of type - * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg) - * is true). - * \param tag_length Desired length of the authentication tag in bytes. - * - * \return The corresponding AEAD algorithm with the specified - * length. - * \return Unspecified if \p alg is not a supported - * AEAD algorithm or if \p tag_length is not valid - * for the specified AEAD algorithm. - */ -#define PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, tag_length) \ - (((alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \ - ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ - PSA_ALG_AEAD_TAG_LENGTH_MASK)) - -/** Calculate the corresponding AEAD algorithm with the default tag length. - * - * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return The corresponding AEAD algorithm with the default tag length - * for that algorithm. - */ -#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) \ - ( \ - PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_CCM) \ - PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_GCM) \ - 0) -#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, ref) \ - PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, 0) == \ - PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \ - ref : - -#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000) -/** RSA PKCS#1 v1.5 signature with hashing. - * - * This is the signature scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSASSA-PKCS1-v1_5. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding RSA PKCS#1 v1.5 signature algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \ - (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Raw PKCS#1 v1.5 signature. - * - * The input to this algorithm is the DigestInfo structure used by - * RFC 8017 (PKCS#1: RSA Cryptography Specifications), §9.2 - * steps 3–6. - */ -#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE -#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE) - -#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x10030000) -/** RSA PSS signature with hashing. - * - * This is the signature scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSASSA-PSS, with the message generation function MGF1, and with - * a salt length equal to the length of the hash. The specified - * hash algorithm is used to hash the input message, to create the - * salted hash, and for the mask generation. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding RSA PSS signature algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_PSS(hash_alg) \ - (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_RSA_PSS(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) - -#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000) -/** DSA signature with hashing. - * - * This is the signature scheme defined by FIPS 186-4, - * with a random per-message secret number (*k*). - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding DSA signature algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_DSA(hash_alg) \ - (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000) -#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000) -#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \ - (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_DSA(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \ - PSA_ALG_DSA_BASE) -#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \ - (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0) -#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \ - (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg)) -#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \ - (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg)) - -#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000) -/** ECDSA signature with hashing. - * - * This is the ECDSA signature scheme defined by ANSI X9.62, - * with a random per-message secret number (*k*). - * - * The representation of the signature as a byte string consists of - * the concatentation of the signature values *r* and *s*. Each of - * *r* and *s* is encoded as an *N*-octet string, where *N* is the length - * of the base point of the curve in octets. Each value is represented - * in big-endian order (most significant octet first). - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding ECDSA signature algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_ECDSA(hash_alg) \ - (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** ECDSA signature without hashing. - * - * This is the same signature scheme as #PSA_ALG_ECDSA(), but - * without specifying a hash algorithm. This algorithm may only be - * used to sign or verify a sequence of bytes that should be an - * already-calculated hash. Note that the input is padded with - * zeros on the left or truncated on the left as required to fit - * the curve size. - */ -#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE -#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t)0x10070000) -/** Deterministic ECDSA signature with hashing. - * - * This is the deterministic ECDSA signature scheme defined by RFC 6979. - * - * The representation of a signature is the same as with #PSA_ALG_ECDSA(). - * - * Note that when this algorithm is used for verification, signatures - * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the - * same private key are accepted. In other words, - * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from - * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding deterministic ECDSA signature - * algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \ - (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_ECDSA(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \ - PSA_ALG_ECDSA_BASE) -#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \ - (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0) -#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \ - (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) -#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \ - (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) - -/** Get the hash used by a hash-and-sign signature algorithm. - * - * A hash-and-sign algorithm is a signature algorithm which is - * composed of two phases: first a hashing phase which does not use - * the key and produces a hash of the input message, then a signing - * phase which only uses the hash and the key and not the message - * itself. - * - * \param alg A signature algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_SIGN(\p alg) is true). - * - * \return The underlying hash algorithm if \p alg is a hash-and-sign - * algorithm. - * \return 0 if \p alg is a signature algorithm that does not - * follow the hash-and-sign structure. - * \return Unspecified if \p alg is not a signature algorithm or - * if it is not supported by the implementation. - */ -#define PSA_ALG_SIGN_GET_HASH(alg) \ - (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ - PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ? \ - ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 : \ - ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ - 0) - -/** RSA PKCS#1 v1.5 encryption. - */ -#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t)0x12020000) - -#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x12030000) -/** RSA OAEP encryption. - * - * This is the encryption scheme defined by RFC 8017 - * (PKCS#1: RSA Cryptography Specifications) under the name - * RSAES-OAEP, with the message generation function MGF1. - * - * \param hash_alg The hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true) to use - * for MGF1. - * - * \return The corresponding RSA OAEP signature algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_RSA_OAEP(hash_alg) \ - (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -#define PSA_ALG_IS_RSA_OAEP(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE) -#define PSA_ALG_RSA_OAEP_GET_HASH(alg) \ - (PSA_ALG_IS_RSA_OAEP(alg) ? \ - ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ - 0) - -#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100) -/** Macro to build an HKDF algorithm. - * - * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding HKDF algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_HKDF(hash_alg) \ - (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) -/** Whether the specified algorithm is an HKDF algorithm. - * - * HKDF is a family of key derivation algorithms that are based on a hash - * function and the HMAC construction. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an HKDF algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_HKDF(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE) -#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200) -/** Macro to build a TLS-1.2 PRF algorithm. - * - * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, - * specified in Section 5 of RFC 5246. It is based on HMAC and can be - * used with either SHA-256 or SHA-384. - * - * For the application to TLS-1.2, the salt and label arguments passed - * to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246, - * respectively. For example, for TLS key expansion, the salt is the - * concatenation of ServerHello.Random + ClientHello.Random, - * while the label is "key expansion". - * - * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the - * TLS 1.2 PRF using HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding TLS-1.2 PRF algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_TLS12_PRF(hash_alg) \ - (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is a TLS-1.2 PRF algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_TLS12_PRF(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE) -#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300) -/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. - * - * In a pure-PSK handshake in TLS 1.2, the master secret is derived - * from the PreSharedKey (PSK) through the application of padding - * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5). - * The latter is based on HMAC and can be used with either SHA-256 - * or SHA-384. - * - * For the application to TLS-1.2, the salt passed to psa_key_derivation() - * (and forwarded to the TLS-1.2 PRF) is the concatenation of the - * ClientHello.Random + ServerHello.Random, while the label is "master secret" - * or "extended master secret". - * - * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the - * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256. - * - * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p hash_alg) is true). - * - * \return The corresponding TLS-1.2 PSK to MS algorithm. - * \return Unspecified if \p alg is not a supported - * hash algorithm. - */ -#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \ - (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) - -/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key derivation algorithm identifier. - */ -#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) \ - (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE) -#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ - (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) - -#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff) - -/** Use a shared secret as is. - * - * Specify this algorithm as the selection component of a key agreement - * to use the raw result of the key agreement as key material. - * - * \warning The raw result of a key agreement algorithm such as finite-field - * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should - * not be used directly as key material. It can however be used as the secret - * input in a key derivation algorithm. - */ -#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001) - -#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \ - (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION) - -#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \ - ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK) - -#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000) -/** The Diffie-Hellman key agreement algorithm. - * - * This algorithm combines the finite-field Diffie-Hellman (DH) key - * agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement, - * to produce a shared secret from a private key and the peer's - * public key, with a key selection or key derivation algorithm to produce - * one or more shared keys and other shared cryptographic material. - * - * The shared secret produced by key agreement and passed as input to the - * derivation or selection algorithm \p kdf_alg is the shared secret - * `g^{ab}` in big-endian format. - * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p` - * in bits. - * - * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) - * or a key selection algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true). - * - * \return The Diffie-Hellman algorithm with the specified - * selection or derivation algorithm. - */ -#define PSA_ALG_FFDH(kdf_alg) \ - (PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) -/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. - * - * This includes every supported key selection or key agreement algorithm - * for the output of the Diffie-Hellman calculation. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key agreement algorithm identifier. - */ -#define PSA_ALG_IS_FFDH(alg) \ - (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE) - -#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000) -/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm. - * - * This algorithm combines the elliptic curve Diffie-Hellman key - * agreement to produce a shared secret from a private key and the peer's - * public key, with a key selection or key derivation algorithm to produce - * one or more shared keys and other shared cryptographic material. - * - * The shared secret produced by key agreement and passed as input to the - * derivation or selection algorithm \p kdf_alg is the x-coordinate of - * the shared secret point. It is always `ceiling(m / 8)` bytes long where - * `m` is the bit size associated with the curve, i.e. the bit size of the - * order of the curve's coordinate field. When `m` is not a multiple of 8, - * the byte containing the most significant bit of the shared secret - * is padded with zero bits. The byte order is either little-endian - * or big-endian depending on the curve type. - * - * - For Montgomery curves (curve types `PSA_ECC_CURVE_CURVEXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in little-endian byte order. - * The bit size is 448 for Curve448 and 255 for Curve25519. - * - For Weierstrass curves over prime fields (curve types - * `PSA_ECC_CURVE_SECPXXX` and `PSA_ECC_CURVE_BRAINPOOL_PXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in big-endian byte order. - * The bit size is `m = ceiling(log_2(p))` for the field `F_p`. - * - For Weierstrass curves over binary fields (curve types - * `PSA_ECC_CURVE_SECTXXX`), - * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` - * in big-endian byte order. - * The bit size is `m` for the field `F_{2^m}`. - * - * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) - * or a selection algorithm (\c PSA_ALG_XXX value such - * that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true). - * - * \return The Diffie-Hellman algorithm with the specified - * selection or derivation algorithm. - */ -#define PSA_ALG_ECDH(kdf_alg) \ - (PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) -/** Whether the specified algorithm is an elliptic curve Diffie-Hellman - * algorithm. - * - * This includes every supported key selection or key agreement algorithm - * for the output of the Diffie-Hellman calculation. - * - * \param alg An algorithm identifier (value of type #psa_algorithm_t). - * - * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm, - * 0 otherwise. - * This macro may return either 0 or 1 if \c alg is not a supported - * key agreement algorithm identifier. - */ -#define PSA_ALG_IS_ECDH(alg) \ - (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE) - /**@}*/ /** \defgroup key_management Key management * @{ */ -/** Encoding of key lifetimes. - */ -typedef uint32_t psa_key_lifetime_t; - -/** Encoding of identifiers of persistent keys. - */ -typedef uint32_t psa_key_id_t; - -/** A volatile key only exists as long as the handle to it is not closed. - * The key material is guaranteed to be erased on a power reset. - */ -#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000) - -/** The default storage area for persistent keys. - * - * A persistent key remains in storage until it is explicitly destroyed or - * until the corresponding storage area is wiped. This specification does - * not define any mechanism to wipe a storage area, but implementations may - * provide their own mechanism (for example to perform a factory reset, - * to prepare for device refurbishment, or to uninstall an application). - * - * This lifetime value is the default storage area for the calling - * application. Implementations may offer other storage areas designated - * by other lifetime values as implementation-specific extensions. - */ -#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) - /** \brief Retrieve the lifetime of an open key. * * \param handle Handle to query. @@ -1906,68 +570,6 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, * @{ */ -/** \brief Encoding of permitted usage on a key. */ -typedef uint32_t psa_key_usage_t; - -/** Whether the key may be exported. - * - * A public key or the public part of a key pair may always be exported - * regardless of the value of this permission flag. - * - * If a key does not have export permission, implementations shall not - * allow the key to be exported in plain form from the cryptoprocessor, - * whether through psa_export_key() or through a proprietary interface. - * The key may however be exportable in a wrapped form, i.e. in a form - * where it is encrypted by another key. - */ -#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001) - -/** Whether the key may be used to encrypt a message. - * - * This flag allows the key to be used for a symmetric encryption operation, - * for an AEAD encryption-and-authentication operation, - * or for an asymmetric encryption operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the public key. - */ -#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t)0x00000100) - -/** Whether the key may be used to decrypt a message. - * - * This flag allows the key to be used for a symmetric decryption operation, - * for an AEAD decryption-and-verification operation, - * or for an asymmetric decryption operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the private key. - */ -#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t)0x00000200) - -/** Whether the key may be used to sign a message. - * - * This flag allows the key to be used for a MAC calculation operation - * or for an asymmetric signature operation, - * if otherwise permitted by the key's type and policy. - * - * For a key pair, this concerns the private key. - */ -#define PSA_KEY_USAGE_SIGN ((psa_key_usage_t)0x00000400) - -/** Whether the key may be used to verify a message signature. - * - * This flag allows the key to be used for a MAC verification operation - * or for an asymmetric signature verification operation, - * if otherwise permitted by by the key's type and policy. - * - * For a key pair, this concerns the public key. - */ -#define PSA_KEY_USAGE_VERIFY ((psa_key_usage_t)0x00000800) - -/** Whether the key may be used to derive other keys. - */ -#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00001000) - /** The type of the key policy data structure. * * This is an implementation-defined \c struct. Applications should not @@ -2075,39 +677,6 @@ psa_status_t psa_get_key_policy(psa_key_handle_t handle, * as directed by the documentation of a specific implementation. */ typedef struct psa_hash_operation_s psa_hash_operation_t; -/** The size of the output of psa_hash_finish(), in bytes. - * - * This is also the hash size that psa_hash_verify() expects. - * - * \param alg A hash algorithm (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm - * (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a - * hash algorithm). - * - * \return The hash size for the specified hash algorithm. - * If the hash algorithm is not recognized, return 0. - * An implementation may return either 0 or the correct size - * for a hash algorithm that it recognizes, but does not support. - */ -#define PSA_HASH_SIZE(alg) \ - ( \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \ - PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ - 0) - /** Start a multipart hash operation. * * The sequence of operations to calculate a hash (message digest) @@ -2828,26 +1397,6 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * @{ */ -/** The tag size for an AEAD algorithm, in bytes. - * - * \param alg An AEAD algorithm - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(\p alg) is true). - * - * \return The tag size for the specified algorithm. - * If the AEAD algorithm does not have an identified - * tag that can be distinguished from the rest of - * the ciphertext, return 0. - * If the AEAD algorithm is not recognized, return 0. - * An implementation may return either 0 or a - * correct size for an AEAD algorithm that it - * recognizes, but does not support. - */ -#define PSA_AEAD_TAG_LENGTH(alg) \ - (PSA_ALG_IS_AEAD(alg) ? \ - (((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \ - 0) - /** Process an authenticated encryption operation. * * \param handle Handle to the key to use for the operation. @@ -2970,17 +1519,6 @@ psa_status_t psa_aead_decrypt(psa_key_handle_t handle, * @{ */ -/** - * \brief ECDSA signature size for a given curve bit size - * - * \param curve_bits Curve size in bits. - * \return Signature size in bytes. - * - * \note This macro returns a compile-time constant if its argument is one. - */ -#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \ - (PSA_BITS_TO_BYTES(curve_bits) * 2) - /** * \brief Sign a hash or short message with a private key. * @@ -3070,11 +1608,6 @@ psa_status_t psa_asymmetric_verify(psa_key_handle_t handle, const uint8_t *signature, size_t signature_length); -#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \ - (PSA_ALG_IS_RSA_OAEP(alg) ? \ - 2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ - 11 /*PKCS#1v1.5*/) - /** * \brief Encrypt a short message with a public key. * diff --git a/include/psa/crypto_accel_driver.h b/include/psa/crypto_accel_driver.h new file mode 100644 index 000000000..b752fed88 --- /dev/null +++ b/include/psa/crypto_accel_driver.h @@ -0,0 +1,796 @@ +/** + * \file psa/crypto_accel_driver.h + * \brief PSA cryptography accelerator driver module + * + * This header declares types and function signatures for cryptography + * drivers that access key material directly. This is meant for + * on-chip cryptography accelerators. + * + * This file is part of the PSA Crypto Driver Model, containing functions for + * driver developers to implement to enable hardware to be called in a + * standardized way by a PSA Cryptographic API implementation. The functions + * comprising the driver model, which driver authors implement, are not + * intended to be called by application developers. + */ + +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PSA_CRYPTO_ACCEL_DRIVER_H +#define PSA_CRYPTO_ACCEL_DRIVER_H + +#include "crypto_driver_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup driver_digest Message Digests + * + * Generation and authentication of Message Digests (aka hashes) must be done + * in parts using the following sequence: + * - `psa_drv_hash_setup_t` + * - `psa_drv_hash_update_t` + * - ... + * - `psa_drv_hash_finish_t` + * + * If a previously started Message Digest operation needs to be terminated + * before the `psa_drv_hash_finish_t` operation is complete, it should be aborted + * by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated + * resources not being freed or in other undefined behavior. + */ +/**@{*/ + +/** \brief The hardware-specific hash context structure + * + * The contents of this structure are implementation dependent and are + * therefore not described here + */ +typedef struct psa_drv_hash_context_s psa_drv_hash_context_t; + +/** \brief The function prototype for the start operation of a hash (message + * digest) operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_hash__setup + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying hash function + * + * \param[in,out] p_context A structure that will contain the + * hardware-specific hash context + * + * \retval PSA_SUCCESS Success. + */ +typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context); + +/** \brief The function prototype for the update operation of a hash (message + * digest) operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_hash__update + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm + * + * \param[in,out] p_context A hardware-specific structure for the + * previously-established hash operation to be + * continued + * \param[in] p_input A buffer containing the message to be appended + * to the hash operation + * \param[in] input_length The size in bytes of the input message buffer + */ +typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context, + const uint8_t *p_input, + size_t input_length); + +/** \brief The prototype for the finish operation of a hash (message digest) + * operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_hash__finish + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started hash operation to be + * fiinished + * \param[out] p_output A buffer where the generated digest will be + * placed + * \param[in] output_size The size in bytes of the buffer that has been + * allocated for the `p_output` buffer + * \param[out] p_output_length The number of bytes placed in `p_output` after + * success + * + * \retval PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** \brief The function prototype for the abort operation of a hash (message + * digest) operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_hash__abort + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm + * + * \param[in,out] p_context A hardware-specific structure for the previously + * started hash operation to be aborted + */ +typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context); + +/**@}*/ + +/** \defgroup transparent_mac Transparent Message Authentication Code + * Generation and authentication of Message Authentication Codes (MACs) using + * transparent keys can be done either as a single function call (via the + * `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t` + * functions), or in parts using the following sequence: + * - `psa_drv_mac_transparent_setup_t` + * - `psa_drv_mac_transparent_update_t` + * - `psa_drv_mac_transparent_update_t` + * - ... + * - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t` + * + * If a previously started Transparent MAC operation needs to be terminated, it + * should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may + * result in allocated resources not being freed or in other undefined + * behavior. + * + */ +/**@{*/ + +/** \brief The hardware-specific transparent-key MAC context structure + * + * The contents of this structure are implementation dependent and are + * therefore not described here. + */ +typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t; + +/** \brief The function prototype for the setup operation of a + * transparent-key MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___setup + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT` + * is the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in,out] p_context A structure that will contain the + * hardware-specific MAC context + * \param[in] p_key A buffer containing the cleartext key material + * to be used in the operation + * \param[in] key_length The size in bytes of the key material + * + * \retval PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context, + const uint8_t *p_key, + size_t key_length); + +/** \brief The function prototype for the update operation of a + * transparent-key MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___update + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` + * is the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously-established MAC operation to be + * continued + * \param[in] p_input A buffer containing the message to be appended + * to the MAC operation + * \param[in] input_length The size in bytes of the input message buffer + */ +typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context, + const uint8_t *p_input, + size_t input_length); + +/** \brief The function prototype for the finish operation of a + * transparent-key MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___finish + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is + * the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started MAC operation to be + * finished + * \param[out] p_mac A buffer where the generated MAC will be placed + * \param[in] mac_length The size in bytes of the buffer that has been + * allocated for the `p_mac` buffer + * + * \retval PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context, + uint8_t *p_mac, + size_t mac_length); + +/** \brief The function prototype for the finish and verify operation of a + * transparent-key MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___finish_verify + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is + * the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started MAC operation to be + * verified and finished + * \param[in] p_mac A buffer containing the MAC that will be used + * for verification + * \param[in] mac_length The size in bytes of the data in the `p_mac` + * buffer + * + * \retval PSA_SUCCESS + * The operation completed successfully and the comparison matched + */ +typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context, + const uint8_t *p_mac, + size_t mac_length); + +/** \brief The function prototype for the abort operation for a previously + * started transparent-key MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___abort + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is + * the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started MAC operation to be + * aborted + * + */ +typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context); + +/** \brief The function prototype for a one-shot operation of a transparent-key + * MAC operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent__ + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is + * the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in] p_input A buffer containing the data to be MACed + * \param[in] input_length The length in bytes of the `p_input` data + * \param[in] p_key A buffer containing the key material to be used + * for the MAC operation + * \param[in] key_length The length in bytes of the `p_key` data + * \param[in] alg The algorithm to be performed + * \param[out] p_mac The buffer where the resulting MAC will be placed + * upon success + * \param[in] mac_length The length in bytes of the `p_mac` buffer + */ +typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input, + size_t input_length, + const uint8_t *p_key, + size_t key_length, + psa_algorithm_t alg, + uint8_t *p_mac, + size_t mac_length); + +/** \brief The function prototype for a one-shot operation of a transparent-key + * MAC Verify operation + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_mac_transparent___verify + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is + * the specific variant of a MAC operation (such as HMAC or CMAC) + * + * \param[in] p_input A buffer containing the data to be MACed + * \param[in] input_length The length in bytes of the `p_input` data + * \param[in] p_key A buffer containing the key material to be used + * for the MAC operation + * \param[in] key_length The length in bytes of the `p_key` data + * \param[in] alg The algorithm to be performed + * \param[in] p_mac The MAC data to be compared + * \param[in] mac_length The length in bytes of the `p_mac` buffer + * + * \retval PSA_SUCCESS + * The operation completed successfully and the comparison matched + */ +typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input, + size_t input_length, + const uint8_t *p_key, + size_t key_length, + psa_algorithm_t alg, + const uint8_t *p_mac, + size_t mac_length); +/**@}*/ + +/** \defgroup transparent_cipher Transparent Block Cipher + * Encryption and Decryption using transparent keys in block modes other than + * ECB must be done in multiple parts, using the following flow: + * - `psa_drv_cipher_transparent_setup_t` + * - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode) + * - `psa_drv_cipher_transparent_update_t` + * - ... + * - `psa_drv_cipher_transparent_finish_t` + + * If a previously started Transparent Cipher operation needs to be terminated, + * it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do + * so may result in allocated resources not being freed or in other undefined + * behavior. + */ +/**@{*/ + +/** \brief The hardware-specific transparent-key Cipher context structure + * + * The contents of this structure are implementation dependent and are + * therefore not described here. + */ +typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t; + +/** \brief The function prototype for the setup operation of transparent-key + * block cipher operations. + * Functions that implement the prototype should be named in the following + * conventions: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_setup__ + * ~~~~~~~~~~~~~ + * Where + * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) + * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) + * or for stream ciphers: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_setup_ + * ~~~~~~~~~~~~~ + * Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4) + * + * \param[in,out] p_context A structure that will contain the + * hardware-specific cipher context + * \param[in] direction Indicates if the operation is an encrypt or a + * decrypt + * \param[in] p_key_data A buffer containing the cleartext key material + * to be used in the operation + * \param[in] key_data_size The size in bytes of the key material + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context, + psa_encrypt_or_decrypt_t direction, + const uint8_t *p_key_data, + size_t key_data_size); + +/** \brief The function prototype for the set initialization vector operation + * of transparent-key block cipher operations + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_set_iv__ + * ~~~~~~~~~~~~~ + * Where + * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) + * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) + * + * \param[in,out] p_context A structure that contains the previously setup + * hardware-specific cipher context + * \param[in] p_iv A buffer containing the initialization vecotr + * \param[in] iv_length The size in bytes of the contents of `p_iv` + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context, + const uint8_t *p_iv, + size_t iv_length); + +/** \brief The function prototype for the update operation of transparent-key + * block cipher operations. + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_update__ + * ~~~~~~~~~~~~~ + * Where + * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) + * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started cipher operation + * \param[in] p_input A buffer containing the data to be + * encrypted or decrypted + * \param[in] input_size The size in bytes of the `p_input` buffer + * \param[out] p_output A caller-allocated buffer where the + * generated output will be placed + * \param[in] output_size The size in bytes of the `p_output` buffer + * \param[out] p_output_length After completion, will contain the number + * of bytes placed in the `p_output` buffer + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context, + const uint8_t *p_input, + size_t input_size, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** \brief The function prototype for the finish operation of transparent-key + * block cipher operations. + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_finish__ + * ~~~~~~~~~~~~~ + * Where + * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) + * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started cipher operation + * \param[out] p_output A caller-allocated buffer where the generated + * output will be placed + * \param[in] output_size The size in bytes of the `p_output` buffer + * \param[out] p_output_length After completion, will contain the number of + * bytes placed in the `p_output` buffer + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** \brief The function prototype for the abort operation of transparent-key + * block cipher operations. + * + * Functions that implement the following prototype should be named in the + * following convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_cipher_transparent_abort__ + * ~~~~~~~~~~~~~ + * Where + * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) + * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) + * + * \param[in,out] p_context A hardware-specific structure for the + * previously started cipher operation + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context); + +/**@}*/ + +/** \defgroup aead_transparent AEAD Transparent + * + * Authenticated Encryption with Additional Data (AEAD) operations with + * transparent keys must be done in one function call. While this creates a + * burden for implementers as there must be sufficient space in memory for the + * entire message, it prevents decrypted data from being made available before + * the authentication operation is complete and the data is known to be + * authentic. + */ +/**@{*/ + +/** Process an authenticated encryption operation using an opaque key. + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_aead__encrypt + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the AEAD algorithm + * + * \param[in] p_key A pointer to the key material + * \param[in] key_length The size in bytes of the key material + * \param[in] alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(`alg`) is true) + * \param[in] nonce Nonce or IV to use + * \param[in] nonce_length Size of the `nonce` buffer in bytes + * \param[in] additional_data Additional data that will be MACed + * but not encrypted. + * \param[in] additional_data_length Size of `additional_data` in bytes + * \param[in] plaintext Data that will be MACed and + * encrypted. + * \param[in] plaintext_length Size of `plaintext` in bytes + * \param[out] ciphertext Output buffer for the authenticated and + * encrypted data. The additional data is + * not part of this output. For algorithms + * where the encrypted data and the + * authentication tag are defined as + * separate outputs, the authentication + * tag is appended to the encrypted data. + * \param[in] ciphertext_size Size of the `ciphertext` buffer in + * bytes + * This must be at least + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`, + * `plaintext_length`). + * \param[out] ciphertext_length On success, the size of the output in + * the `ciphertext` buffer + * + * \retval #PSA_SUCCESS + + */ +typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key, + size_t key_length, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *plaintext, + size_t plaintext_length, + uint8_t *ciphertext, + size_t ciphertext_size, + size_t *ciphertext_length); + +/** Process an authenticated decryption operation using an opaque key. + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_aead__decrypt + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the AEAD algorithm + * \param[in] p_key A pointer to the key material + * \param[in] key_length The size in bytes of the key material + * \param[in] alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(`alg`) is true) + * \param[in] nonce Nonce or IV to use + * \param[in] nonce_length Size of the `nonce` buffer in bytes + * \param[in] additional_data Additional data that has been MACed + * but not encrypted + * \param[in] additional_data_length Size of `additional_data` in bytes + * \param[in] ciphertext Data that has been MACed and + * encrypted + * For algorithms where the encrypted data + * and the authentication tag are defined + * as separate inputs, the buffer must + * contain the encrypted data followed by + * the authentication tag. + * \param[in] ciphertext_length Size of `ciphertext` in bytes + * \param[out] plaintext Output buffer for the decrypted data + * \param[in] plaintext_size Size of the `plaintext` buffer in + * bytes + * This must be at least + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`, + * `ciphertext_length`). + * \param[out] plaintext_length On success, the size of the output + * in the \b plaintext buffer + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key, + size_t key_length, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *ciphertext, + size_t ciphertext_length, + uint8_t *plaintext, + size_t plaintext_size, + size_t *plaintext_length); + +/**@}*/ + +/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography + * + * Since the amount of data that can (or should) be encrypted or signed using + * asymmetric keys is limited by the key size, asymmetric key operations using + * transparent keys must be done in single function calls. + */ +/**@{*/ + + +/** + * \brief A function that signs a hash or short message with a transparent + * asymmetric private key + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_asymmetric__sign + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the signing algorithm + * + * \param[in] p_key A buffer containing the private key + * material + * \param[in] key_size The size in bytes of the `p_key` data + * \param[in] alg A signature algorithm that is compatible + * with the type of `p_key` + * \param[in] p_hash The hash or message to sign + * \param[in] hash_length Size of the `p_hash` buffer in bytes + * \param[out] p_signature Buffer where the signature is to be written + * \param[in] signature_size Size of the `p_signature` buffer in bytes + * \param[out] p_signature_length On success, the number of bytes + * that make up the returned signature value + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key, + size_t key_size, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + uint8_t *p_signature, + size_t signature_size, + size_t *p_signature_length); + +/** + * \brief A function that verifies the signature a hash or short message using + * a transparent asymmetric public key + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_asymmetric__verify + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the signing algorithm + * + * \param[in] p_key A buffer containing the public key material + * \param[in] key_size The size in bytes of the `p_key` data + * \param[in] alg A signature algorithm that is compatible with + * the type of `key` + * \param[in] p_hash The hash or message whose signature is to be + * verified + * \param[in] hash_length Size of the `p_hash` buffer in bytes + * \param[in] p_signature Buffer containing the signature to verify + * \param[in] signature_length Size of the `p_signature` buffer in bytes + * + * \retval PSA_SUCCESS + * The signature is valid. + */ +typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key, + size_t key_size, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + const uint8_t *p_signature, + size_t signature_length); + +/** + * \brief A function that encrypts a short message with a transparent + * asymmetric public key + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_asymmetric__encrypt + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the encryption algorithm + * + * \param[in] p_key A buffer containing the public key material + * \param[in] key_size The size in bytes of the `p_key` data + * \param[in] alg An asymmetric encryption algorithm that is + * compatible with the type of `key` + * \param[in] p_input The message to encrypt + * \param[in] input_length Size of the `p_input` buffer in bytes + * \param[in] p_salt A salt or label, if supported by the + * encryption algorithm + * If the algorithm does not support a + * salt, pass `NULL` + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass `NULL`. + * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param[in] salt_length Size of the `p_salt` buffer in bytes + * If `p_salt` is `NULL`, pass 0. + * \param[out] p_output Buffer where the encrypted message is to + * be written + * \param[in] output_size Size of the `p_output` buffer in bytes + * \param[out] p_output_length On success, the number of bytes + * that make up the returned output + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key, + size_t key_size, + psa_algorithm_t alg, + const uint8_t *p_input, + size_t input_length, + const uint8_t *p_salt, + size_t salt_length, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** + * \brief Decrypt a short message with a transparent asymmetric private key + * + * Functions that implement the prototype should be named in the following + * convention: + * ~~~~~~~~~~~~~{.c} + * psa_drv_asymmetric__decrypt + * ~~~~~~~~~~~~~ + * Where `ALGO` is the name of the encryption algorithm + * + * \param[in] p_key A buffer containing the private key material + * \param[in] key_size The size in bytes of the `p_key` data + * \param[in] alg An asymmetric encryption algorithm that is + * compatible with the type of `key` + * \param[in] p_input The message to decrypt + * \param[in] input_length Size of the `p_input` buffer in bytes + * \param[in] p_salt A salt or label, if supported by the + * encryption algorithm + * If the algorithm does not support a + * salt, pass `NULL`. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass `NULL`. + * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported + * \param[in] salt_length Size of the `p_salt` buffer in bytes + * If `p_salt` is `NULL`, pass 0 + * \param[out] p_output Buffer where the decrypted message is to + * be written + * \param[in] output_size Size of the `p_output` buffer in bytes + * \param[out] p_output_length On success, the number of bytes + * that make up the returned output + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key, + size_t key_size, + psa_algorithm_t alg, + const uint8_t *p_input, + size_t input_length, + const uint8_t *p_salt, + size_t salt_length, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_ACCEL_DRIVER_H */ diff --git a/include/psa/crypto_driver_common.h b/include/psa/crypto_driver_common.h new file mode 100644 index 000000000..6f1a5d5d9 --- /dev/null +++ b/include/psa/crypto_driver_common.h @@ -0,0 +1,54 @@ +/** + * \file psa/crypto_driver_common.h + * \brief Definitions for all PSA crypto drivers + * + * This file contains common definitions shared by all PSA crypto drivers. + * Do not include it directly: instead, include the header file(s) for + * the type(s) of driver that you are implementing. For example, if + * you are writing a driver for a chip that provides both a hardware + * random generator and an accelerator for some cryptographic algorithms, + * include `psa/crypto_entropy_driver.h` and `psa/crypto_accel_driver.h`. + * + * This file is part of the PSA Crypto Driver Model, containing functions for + * driver developers to implement to enable hardware to be called in a + * standardized way by a PSA Cryptographic API implementation. The functions + * comprising the driver model, which driver authors implement, are not + * intended to be called by application developers. + */ + +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PSA_CRYPTO_DRIVER_COMMON_H +#define PSA_CRYPTO_DRIVER_COMMON_H + +#include +#include + +/* Include type definitions (psa_status_t, psa_algorithm_t, + * psa_key_type_t, etc.) and macros to build and analyze values + * of these types. */ +#include "crypto_types.h" +#include "crypto_values.h" + +/** For encrypt-decrypt functions, whether the operation is an encryption + * or a decryption. */ +typedef enum { + PSA_CRYPTO_DRIVER_DECRYPT, + PSA_CRYPTO_DRIVER_ENCRYPT +} psa_encrypt_or_decrypt_t; + +#endif /* PSA_CRYPTO_DRIVER_COMMON_H */ diff --git a/include/psa/crypto_entropy_driver.h b/include/psa/crypto_entropy_driver.h new file mode 100644 index 000000000..f5e383e6c --- /dev/null +++ b/include/psa/crypto_entropy_driver.h @@ -0,0 +1,111 @@ +/** + * \file psa/crypto_entropy_driver.h + * \brief PSA entropy source driver module + * + * This header declares types and function signatures for entropy sources. + * + * This file is part of the PSA Crypto Driver Model, containing functions for + * driver developers to implement to enable hardware to be called in a + * standardized way by a PSA Cryptographic API implementation. The functions + * comprising the driver model, which driver authors implement, are not + * intended to be called by application developers. + */ + +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PSA_CRYPTO_ENTROPY_DRIVER_H +#define PSA_CRYPTO_ENTROPY_DRIVER_H + +#include "crypto_driver_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup driver_rng Entropy Generation + */ +/**@{*/ + +/** \brief A hardware-specific structure for a entropy providing hardware + */ +typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t; + +/** \brief Initialize an entropy driver + * + * + * \param[in,out] p_context A hardware-specific structure + * containing any context information for + * the implementation + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context); + +/** \brief Get a specified number of bits from the entropy source + * + * It retrives `buffer_size` bytes of data from the entropy source. The entropy + * source will always fill the provided buffer to its full size, however, most + * entropy sources have biases, and the actual amount of entropy contained in + * the buffer will be less than the number of bytes. + * The driver will return the actual number of bytes of entropy placed in the + * buffer in `p_received_entropy_bytes`. + * A PSA Crypto API implementation will likely feed the output of this function + * into a Digital Random Bit Generator (DRBG), and typically has a minimum + * amount of entropy that it needs. + * To accomplish this, the PSA Crypto implementation should be designed to call + * this function multiple times until it has received the required amount of + * entropy from the entropy source. + * + * \param[in,out] p_context A hardware-specific structure + * containing any context information + * for the implementation + * \param[out] p_buffer A caller-allocated buffer for the + * retrieved entropy to be placed in + * \param[in] buffer_size The allocated size of `p_buffer` + * \param[out] p_received_entropy_bits The amount of entropy (in bits) + * actually provided in `p_buffer` + * + * \retval PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context, + uint8_t *p_buffer, + uint32_t buffer_size, + uint32_t *p_received_entropy_bits); + +/** + * \brief A struct containing all of the function pointers needed to interface + * to an entropy source + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup. + * + * If one of the functions is not implemented, it should be set to NULL. + */ +typedef struct { + /** Function that performs initialization for the entropy source */ + psa_drv_entropy_init_t *p_init; + /** Function that performs the get_bits operation for the entropy source + */ + psa_drv_entropy_get_bits_t *p_get_bits; +} psa_drv_entropy_t; +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_ENTROPY_DRIVER_H */ diff --git a/include/psa/crypto_driver.h b/include/psa/crypto_se_driver.h similarity index 52% rename from include/psa/crypto_driver.h rename to include/psa/crypto_se_driver.h index a52ecc427..057866445 100644 --- a/include/psa/crypto_driver.h +++ b/include/psa/crypto_se_driver.h @@ -1,8 +1,14 @@ /** - * \file psa/crypto_driver.h - * \brief Platform Security Architecture cryptographic driver module + * \file psa/crypto_se_driver.h + * \brief PSA external cryptoprocessor driver module * - * This file describes the PSA Crypto Driver Model, containing functions for + * This header declares types and function signatures for cryptography + * drivers that access key material via opaque references. This is + * meant for cryptoprocessors that have a separate key storage from the + * space in which the PSA Crypto implementation runs, typically secure + * elements. + * + * This file is part of the PSA Crypto Driver Model, containing functions for * driver developers to implement to enable hardware to be called in a * standardized way by a PSA Cryptographic API implementation. The functions * comprising the driver model, which driver authors implement, are not @@ -25,29 +31,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef PSA_CRYPTO_DRIVER_H -#define PSA_CRYPTO_DRIVER_H +#ifndef PSA_CRYPTO_SE_DRIVER_H +#define PSA_CRYPTO_SE_DRIVER_H -#include -#include +#include "crypto_driver_common.h" #ifdef __cplusplus extern "C" { #endif -/** The following types are redefinitions from the psa/crypto.h file. - * It is intended that these will be moved to a new common header file to - * avoid duplication. They are included here for expediency in publication. - */ -typedef uint32_t psa_status_t; -typedef uint32_t psa_algorithm_t; -typedef uint8_t psa_encrypt_or_decrypt_t; +/** An internal designation of a key slot between the core part of the + * PSA Crypto implementation and the driver. The meaning of this value + * is driver-dependent. */ typedef uint32_t psa_key_slot_t; -typedef uint32_t psa_key_type_t; -typedef uint32_t psa_key_usage_t; - -#define PSA_CRYPTO_DRIVER_ENCRYPT 1 -#define PSA_CRYPTO_DRIVER_DECRYPT 0 /** \defgroup opaque_mac Opaque Message Authentication Code * Generation and authentication of Message Authentication Codes (MACs) using @@ -239,208 +235,6 @@ typedef struct { } psa_drv_mac_opaque_t; /**@}*/ -/** \defgroup transparent_mac Transparent Message Authentication Code - * Generation and authentication of Message Authentication Codes (MACs) using - * transparent keys can be done either as a single function call (via the - * `psa_drv_mac_transparent_generate_t` or `psa_drv_mac_transparent_verify_t` - * functions), or in parts using the following sequence: - * - `psa_drv_mac_transparent_setup_t` - * - `psa_drv_mac_transparent_update_t` - * - `psa_drv_mac_transparent_update_t` - * - ... - * - `psa_drv_mac_transparent_finish_t` or `psa_drv_mac_transparent_finish_verify_t` - * - * If a previously started Transparent MAC operation needs to be terminated, it - * should be done so by the `psa_drv_mac_transparent_abort_t`. Failure to do so may - * result in allocated resources not being freed or in other undefined - * behavior. - * - */ -/**@{*/ - -/** \brief The hardware-specific transparent-key MAC context structure - * - * The contents of this structure are implementation dependent and are - * therefore not described here. - */ -typedef struct psa_drv_mac_transparent_context_s psa_drv_mac_transparent_context_t; - -/** \brief The function prototype for the setup operation of a - * transparent-key MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___setup - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying primitive, and `MAC_VARIANT` - * is the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in,out] p_context A structure that will contain the - * hardware-specific MAC context - * \param[in] p_key A buffer containing the cleartext key material - * to be used in the operation - * \param[in] key_length The size in bytes of the key material - * - * \retval PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_mac_transparent_setup_t)(psa_drv_mac_transparent_context_t *p_context, - const uint8_t *p_key, - size_t key_length); - -/** \brief The function prototype for the update operation of a - * transparent-key MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___update - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` - * is the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously-established MAC operation to be - * continued - * \param[in] p_input A buffer containing the message to be appended - * to the MAC operation - * \param[in] input_length The size in bytes of the input message buffer - */ -typedef psa_status_t (*psa_drv_mac_transparent_update_t)(psa_drv_mac_transparent_context_t *p_context, - const uint8_t *p_input, - size_t input_length); - -/** \brief The function prototype for the finish operation of a - * transparent-key MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___finish - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is - * the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started MAC operation to be - * finished - * \param[out] p_mac A buffer where the generated MAC will be placed - * \param[in] mac_length The size in bytes of the buffer that has been - * allocated for the `p_mac` buffer - * - * \retval PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_mac_transparent_finish_t)(psa_drv_mac_transparent_context_t *p_context, - uint8_t *p_mac, - size_t mac_length); - -/** \brief The function prototype for the finish and verify operation of a - * transparent-key MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___finish_verify - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is - * the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started MAC operation to be - * verified and finished - * \param[in] p_mac A buffer containing the MAC that will be used - * for verification - * \param[in] mac_length The size in bytes of the data in the `p_mac` - * buffer - * - * \retval PSA_SUCCESS - * The operation completed successfully and the comparison matched - */ -typedef psa_status_t (*psa_drv_mac_transparent_finish_verify_t)(psa_drv_mac_transparent_context_t *p_context, - const uint8_t *p_mac, - size_t mac_length); - -/** \brief The function prototype for the abort operation for a previously - * started transparent-key MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___abort - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is - * the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started MAC operation to be - * aborted - * - */ -typedef psa_status_t (*psa_drv_mac_transparent_abort_t)(psa_drv_mac_transparent_context_t *p_context); - -/** \brief The function prototype for a one-shot operation of a transparent-key - * MAC operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent__ - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is - * the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in] p_input A buffer containing the data to be MACed - * \param[in] input_length The length in bytes of the `p_input` data - * \param[in] p_key A buffer containing the key material to be used - * for the MAC operation - * \param[in] key_length The length in bytes of the `p_key` data - * \param[in] alg The algorithm to be performed - * \param[out] p_mac The buffer where the resulting MAC will be placed - * upon success - * \param[in] mac_length The length in bytes of the `p_mac` buffer - */ -typedef psa_status_t (*psa_drv_mac_transparent_t)(const uint8_t *p_input, - size_t input_length, - const uint8_t *p_key, - size_t key_length, - psa_algorithm_t alg, - uint8_t *p_mac, - size_t mac_length); - -/** \brief The function prototype for a one-shot operation of a transparent-key - * MAC Verify operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_mac_transparent___verify - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm, and `MAC_VARIANT` is - * the specific variant of a MAC operation (such as HMAC or CMAC) - * - * \param[in] p_input A buffer containing the data to be MACed - * \param[in] input_length The length in bytes of the `p_input` data - * \param[in] p_key A buffer containing the key material to be used - * for the MAC operation - * \param[in] key_length The length in bytes of the `p_key` data - * \param[in] alg The algorithm to be performed - * \param[in] p_mac The MAC data to be compared - * \param[in] mac_length The length in bytes of the `p_mac` buffer - * - * \retval PSA_SUCCESS - * The operation completed successfully and the comparison matched - */ -typedef psa_status_t (*psa_drv_mac_transparent_verify_t)(const uint8_t *p_input, - size_t input_length, - const uint8_t *p_key, - size_t key_length, - psa_algorithm_t alg, - const uint8_t *p_mac, - size_t mac_length); -/**@}*/ - /** \defgroup opaque_cipher Opaque Symmetric Ciphers * * Encryption and Decryption using opaque keys in block modes other than ECB @@ -618,269 +412,6 @@ typedef struct { /**@}*/ -/** \defgroup transparent_cipher Transparent Block Cipher - * Encryption and Decryption using transparent keys in block modes other than - * ECB must be done in multiple parts, using the following flow: - * - `psa_drv_cipher_transparent_setup_t` - * - `psa_drv_cipher_transparent_set_iv_t` (optional depending upon block mode) - * - `psa_drv_cipher_transparent_update_t` - * - ... - * - `psa_drv_cipher_transparent_finish_t` - - * If a previously started Transparent Cipher operation needs to be terminated, - * it should be done so by the `psa_drv_cipher_transparent_abort_t`. Failure to do - * so may result in allocated resources not being freed or in other undefined - * behavior. - */ -/**@{*/ - -/** \brief The hardware-specific transparent-key Cipher context structure - * - * The contents of this structure are implementation dependent and are - * therefore not described here. - */ -typedef struct psa_drv_cipher_transparent_context_s psa_drv_cipher_transparent_context_t; - -/** \brief The function prototype for the setup operation of transparent-key - * block cipher operations. - * Functions that implement the prototype should be named in the following - * conventions: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_setup__ - * ~~~~~~~~~~~~~ - * Where - * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) - * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) - * or for stream ciphers: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_setup_ - * ~~~~~~~~~~~~~ - * Where `CIPHER_NAME` is the name of a stream cipher (i.e. RC4) - * - * \param[in,out] p_context A structure that will contain the - * hardware-specific cipher context - * \param[in] direction Indicates if the operation is an encrypt or a - * decrypt - * \param[in] p_key_data A buffer containing the cleartext key material - * to be used in the operation - * \param[in] key_data_size The size in bytes of the key material - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_cipher_transparent_setup_t)(psa_drv_cipher_transparent_context_t *p_context, - psa_encrypt_or_decrypt_t direction, - const uint8_t *p_key_data, - size_t key_data_size); - -/** \brief The function prototype for the set initialization vector operation - * of transparent-key block cipher operations - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_set_iv__ - * ~~~~~~~~~~~~~ - * Where - * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) - * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) - * - * \param[in,out] p_context A structure that contains the previously setup - * hardware-specific cipher context - * \param[in] p_iv A buffer containing the initialization vecotr - * \param[in] iv_length The size in bytes of the contents of `p_iv` - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_cipher_transparent_set_iv_t)(psa_drv_cipher_transparent_context_t *p_context, - const uint8_t *p_iv, - size_t iv_length); - -/** \brief The function prototype for the update operation of transparent-key - * block cipher operations. - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_update__ - * ~~~~~~~~~~~~~ - * Where - * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) - * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started cipher operation - * \param[in] p_input A buffer containing the data to be - * encrypted or decrypted - * \param[in] input_size The size in bytes of the `p_input` buffer - * \param[out] p_output A caller-allocated buffer where the - * generated output will be placed - * \param[in] output_size The size in bytes of the `p_output` buffer - * \param[out] p_output_length After completion, will contain the number - * of bytes placed in the `p_output` buffer - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_cipher_transparent_update_t)(psa_drv_cipher_transparent_context_t *p_context, - const uint8_t *p_input, - size_t input_size, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** \brief The function prototype for the finish operation of transparent-key - * block cipher operations. - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_finish__ - * ~~~~~~~~~~~~~ - * Where - * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) - * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started cipher operation - * \param[out] p_output A caller-allocated buffer where the generated - * output will be placed - * \param[in] output_size The size in bytes of the `p_output` buffer - * \param[out] p_output_length After completion, will contain the number of - * bytes placed in the `p_output` buffer - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_cipher_transparent_finish_t)(psa_drv_cipher_transparent_context_t *p_context, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** \brief The function prototype for the abort operation of transparent-key - * block cipher operations. - * - * Functions that implement the following prototype should be named in the - * following convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_cipher_transparent_abort__ - * ~~~~~~~~~~~~~ - * Where - * - `CIPHER_NAME` is the name of the underlying block cipher (i.e. AES or DES) - * - `MODE` is the block mode of the cipher operation (i.e. CBC or CTR) - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started cipher operation - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_cipher_transparent_abort_t)(psa_drv_cipher_transparent_context_t *p_context); - -/**@}*/ - -/** \defgroup driver_digest Message Digests - * - * Generation and authentication of Message Digests (aka hashes) must be done - * in parts using the following sequence: - * - `psa_drv_hash_setup_t` - * - `psa_drv_hash_update_t` - * - ... - * - `psa_drv_hash_finish_t` - * - * If a previously started Message Digest operation needs to be terminated - * before the `psa_drv_hash_finish_t` operation is complete, it should be aborted - * by the `psa_drv_hash_abort_t`. Failure to do so may result in allocated - * resources not being freed or in other undefined behavior. - */ -/**@{*/ - -/** \brief The hardware-specific hash context structure - * - * The contents of this structure are implementation dependent and are - * therefore not described here - */ -typedef struct psa_drv_hash_context_s psa_drv_hash_context_t; - -/** \brief The function prototype for the start operation of a hash (message - * digest) operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_hash__setup - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying hash function - * - * \param[in,out] p_context A structure that will contain the - * hardware-specific hash context - * - * \retval PSA_SUCCESS Success. - */ -typedef psa_status_t (*psa_drv_hash_setup_t)(psa_drv_hash_context_t *p_context); - -/** \brief The function prototype for the update operation of a hash (message - * digest) operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_hash__update - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm - * - * \param[in,out] p_context A hardware-specific structure for the - * previously-established hash operation to be - * continued - * \param[in] p_input A buffer containing the message to be appended - * to the hash operation - * \param[in] input_length The size in bytes of the input message buffer - */ -typedef psa_status_t (*psa_drv_hash_update_t)(psa_drv_hash_context_t *p_context, - const uint8_t *p_input, - size_t input_length); - -/** \brief The prototype for the finish operation of a hash (message digest) - * operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_hash__finish - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm - * - * \param[in,out] p_context A hardware-specific structure for the - * previously started hash operation to be - * fiinished - * \param[out] p_output A buffer where the generated digest will be - * placed - * \param[in] output_size The size in bytes of the buffer that has been - * allocated for the `p_output` buffer - * \param[out] p_output_length The number of bytes placed in `p_output` after - * success - * - * \retval PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_hash_finish_t)(psa_drv_hash_context_t *p_context, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** \brief The function prototype for the abort operation of a hash (message - * digest) operation - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_hash__abort - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the underlying algorithm - * - * \param[in,out] p_context A hardware-specific structure for the previously - * started hash operation to be aborted - */ -typedef void (*psa_drv_hash_abort_t)(psa_drv_hash_context_t *p_context); - -/**@}*/ - - /** \defgroup opaque_asymmetric Opaque Asymmetric Cryptography * * Since the amount of data that can (or should) be encrypted or signed using @@ -1033,176 +564,6 @@ typedef struct { /**@}*/ -/** \defgroup transparent_asymmetric Transparent Asymmetric Cryptography - * - * Since the amount of data that can (or should) be encrypted or signed using - * asymmetric keys is limited by the key size, asymmetric key operations using - * transparent keys must be done in single function calls. - */ -/**@{*/ - - -/** - * \brief A function that signs a hash or short message with a transparent - * asymmetric private key - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_asymmetric__sign - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the signing algorithm - * - * \param[in] p_key A buffer containing the private key - * material - * \param[in] key_size The size in bytes of the `p_key` data - * \param[in] alg A signature algorithm that is compatible - * with the type of `p_key` - * \param[in] p_hash The hash or message to sign - * \param[in] hash_length Size of the `p_hash` buffer in bytes - * \param[out] p_signature Buffer where the signature is to be written - * \param[in] signature_size Size of the `p_signature` buffer in bytes - * \param[out] p_signature_length On success, the number of bytes - * that make up the returned signature value - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_asymmetric_transparent_sign_t)(const uint8_t *p_key, - size_t key_size, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - uint8_t *p_signature, - size_t signature_size, - size_t *p_signature_length); - -/** - * \brief A function that verifies the signature a hash or short message using - * a transparent asymmetric public key - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_asymmetric__verify - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the signing algorithm - * - * \param[in] p_key A buffer containing the public key material - * \param[in] key_size The size in bytes of the `p_key` data - * \param[in] alg A signature algorithm that is compatible with - * the type of `key` - * \param[in] p_hash The hash or message whose signature is to be - * verified - * \param[in] hash_length Size of the `p_hash` buffer in bytes - * \param[in] p_signature Buffer containing the signature to verify - * \param[in] signature_length Size of the `p_signature` buffer in bytes - * - * \retval PSA_SUCCESS - * The signature is valid. - */ -typedef psa_status_t (*psa_drv_asymmetric_transparent_verify_t)(const uint8_t *p_key, - size_t key_size, - psa_algorithm_t alg, - const uint8_t *p_hash, - size_t hash_length, - const uint8_t *p_signature, - size_t signature_length); - -/** - * \brief A function that encrypts a short message with a transparent - * asymmetric public key - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_asymmetric__encrypt - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the encryption algorithm - * - * \param[in] p_key A buffer containing the public key material - * \param[in] key_size The size in bytes of the `p_key` data - * \param[in] alg An asymmetric encryption algorithm that is - * compatible with the type of `key` - * \param[in] p_input The message to encrypt - * \param[in] input_length Size of the `p_input` buffer in bytes - * \param[in] p_salt A salt or label, if supported by the - * encryption algorithm - * If the algorithm does not support a - * salt, pass `NULL` - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass `NULL`. - * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported. - * \param[in] salt_length Size of the `p_salt` buffer in bytes - * If `p_salt` is `NULL`, pass 0. - * \param[out] p_output Buffer where the encrypted message is to - * be written - * \param[in] output_size Size of the `p_output` buffer in bytes - * \param[out] p_output_length On success, the number of bytes - * that make up the returned output - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_asymmetric_transparent_encrypt_t)(const uint8_t *p_key, - size_t key_size, - psa_algorithm_t alg, - const uint8_t *p_input, - size_t input_length, - const uint8_t *p_salt, - size_t salt_length, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/** - * \brief Decrypt a short message with a transparent asymmetric private key - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_asymmetric__decrypt - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the encryption algorithm - * - * \param[in] p_key A buffer containing the private key material - * \param[in] key_size The size in bytes of the `p_key` data - * \param[in] alg An asymmetric encryption algorithm that is - * compatible with the type of `key` - * \param[in] p_input The message to decrypt - * \param[in] input_length Size of the `p_input` buffer in bytes - * \param[in] p_salt A salt or label, if supported by the - * encryption algorithm - * If the algorithm does not support a - * salt, pass `NULL`. - * If the algorithm supports an optional - * salt and you do not want to pass a salt, - * pass `NULL`. - * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is - * supported - * \param[in] salt_length Size of the `p_salt` buffer in bytes - * If `p_salt` is `NULL`, pass 0 - * \param[out] p_output Buffer where the decrypted message is to - * be written - * \param[in] output_size Size of the `p_output` buffer in bytes - * \param[out] p_output_length On success, the number of bytes - * that make up the returned output - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_asymmetric_transparent_decrypt_t)(const uint8_t *p_key, - size_t key_size, - psa_algorithm_t alg, - const uint8_t *p_input, - size_t input_length, - const uint8_t *p_salt, - size_t salt_length, - uint8_t *p_output, - size_t output_size, - size_t *p_output_length); - -/**@}*/ - /** \defgroup aead_opaque AEAD Opaque * Authenticated Encryption with Additional Data (AEAD) operations with opaque * keys must be done in one function call. While this creates a burden for @@ -1310,192 +671,6 @@ typedef struct { } psa_drv_aead_opaque_t; /**@}*/ -/** \defgroup aead_transparent AEAD Transparent - * - * Authenticated Encryption with Additional Data (AEAD) operations with - * transparent keys must be done in one function call. While this creates a - * burden for implementers as there must be sufficient space in memory for the - * entire message, it prevents decrypted data from being made available before - * the authentication operation is complete and the data is known to be - * authentic. - */ -/**@{*/ - -/** Process an authenticated encryption operation using an opaque key. - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_aead__encrypt - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the AEAD algorithm - * - * \param[in] p_key A pointer to the key material - * \param[in] key_length The size in bytes of the key material - * \param[in] alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(`alg`) is true) - * \param[in] nonce Nonce or IV to use - * \param[in] nonce_length Size of the `nonce` buffer in bytes - * \param[in] additional_data Additional data that will be MACed - * but not encrypted. - * \param[in] additional_data_length Size of `additional_data` in bytes - * \param[in] plaintext Data that will be MACed and - * encrypted. - * \param[in] plaintext_length Size of `plaintext` in bytes - * \param[out] ciphertext Output buffer for the authenticated and - * encrypted data. The additional data is - * not part of this output. For algorithms - * where the encrypted data and the - * authentication tag are defined as - * separate outputs, the authentication - * tag is appended to the encrypted data. - * \param[in] ciphertext_size Size of the `ciphertext` buffer in - * bytes - * This must be at least - * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(`alg`, - * `plaintext_length`). - * \param[out] ciphertext_length On success, the size of the output in - * the `ciphertext` buffer - * - * \retval #PSA_SUCCESS - - */ -typedef psa_status_t (*psa_drv_aead_transparent_encrypt_t)(const uint8_t *p_key, - size_t key_length, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *plaintext, - size_t plaintext_length, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length); - -/** Process an authenticated decryption operation using an opaque key. - * - * Functions that implement the prototype should be named in the following - * convention: - * ~~~~~~~~~~~~~{.c} - * psa_drv_aead__decrypt - * ~~~~~~~~~~~~~ - * Where `ALGO` is the name of the AEAD algorithm - * \param[in] p_key A pointer to the key material - * \param[in] key_length The size in bytes of the key material - * \param[in] alg The AEAD algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_AEAD(`alg`) is true) - * \param[in] nonce Nonce or IV to use - * \param[in] nonce_length Size of the `nonce` buffer in bytes - * \param[in] additional_data Additional data that has been MACed - * but not encrypted - * \param[in] additional_data_length Size of `additional_data` in bytes - * \param[in] ciphertext Data that has been MACed and - * encrypted - * For algorithms where the encrypted data - * and the authentication tag are defined - * as separate inputs, the buffer must - * contain the encrypted data followed by - * the authentication tag. - * \param[in] ciphertext_length Size of `ciphertext` in bytes - * \param[out] plaintext Output buffer for the decrypted data - * \param[in] plaintext_size Size of the `plaintext` buffer in - * bytes - * This must be at least - * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(`alg`, - * `ciphertext_length`). - * \param[out] plaintext_length On success, the size of the output - * in the \b plaintext buffer - * - * \retval #PSA_SUCCESS - * Success. - */ -typedef psa_status_t (*psa_drv_aead_transparent_decrypt_t)(const uint8_t *p_key, - size_t key_length, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length); - -/**@}*/ - - -/** \defgroup driver_rng Entropy Generation - */ -/**@{*/ - -/** \brief A hardware-specific structure for a entropy providing hardware - */ -typedef struct psa_drv_entropy_context_s psa_drv_entropy_context_t; - -/** \brief Initialize an entropy driver - * - * - * \param[in,out] p_context A hardware-specific structure - * containing any context information for - * the implementation - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_entropy_init_t)(psa_drv_entropy_context_t *p_context); - -/** \brief Get a specified number of bits from the entropy source - * - * It retrives `buffer_size` bytes of data from the entropy source. The entropy - * source will always fill the provided buffer to its full size, however, most - * entropy sources have biases, and the actual amount of entropy contained in - * the buffer will be less than the number of bytes. - * The driver will return the actual number of bytes of entropy placed in the - * buffer in `p_received_entropy_bytes`. - * A PSA Crypto API implementation will likely feed the output of this function - * into a Digital Random Bit Generator (DRBG), and typically has a minimum - * amount of entropy that it needs. - * To accomplish this, the PSA Crypto implementation should be designed to call - * this function multiple times until it has received the required amount of - * entropy from the entropy source. - * - * \param[in,out] p_context A hardware-specific structure - * containing any context information - * for the implementation - * \param[out] p_buffer A caller-allocated buffer for the - * retrieved entropy to be placed in - * \param[in] buffer_size The allocated size of `p_buffer` - * \param[out] p_received_entropy_bits The amount of entropy (in bits) - * actually provided in `p_buffer` - * - * \retval PSA_SUCCESS - */ -typedef psa_status_t (*psa_drv_entropy_get_bits_t)(psa_drv_entropy_context_t *p_context, - uint8_t *p_buffer, - uint32_t buffer_size, - uint32_t *p_received_entropy_bits); - -/** - * \brief A struct containing all of the function pointers needed to interface - * to an entropy source - * - * PSA Crypto API implementations should populate instances of the table as - * appropriate upon startup. - * - * If one of the functions is not implemented, it should be set to NULL. - */ -typedef struct { - /** Function that performs initialization for the entropy source */ - psa_drv_entropy_init_t *p_init; - /** Function that performs the get_bits operation for the entropy source - */ - psa_drv_entropy_get_bits_t *p_get_bits; -} psa_drv_entropy_t; -/**@}*/ - /** \defgroup driver_key_management Key Management * Currently, key management is limited to importing keys in the clear, * destroying keys, and exporting keys in the clear. @@ -1784,4 +959,4 @@ typedef struct { } #endif -#endif /* PSA_CRYPTO_DRIVER_H */ +#endif /* PSA_CRYPTO_SE_DRIVER_H */ diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index 7e1795673..5ad695a39 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -50,6 +50,42 @@ #include MBEDTLS_CONFIG_FILE #endif +#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8) +#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8) + +/** The size of the output of psa_hash_finish(), in bytes. + * + * This is also the hash size that psa_hash_verify() expects. + * + * \param alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p alg) is true), or an HMAC algorithm + * (#PSA_ALG_HMAC(\c hash_alg) where \c hash_alg is a + * hash algorithm). + * + * \return The hash size for the specified hash algorithm. + * If the hash algorithm is not recognized, return 0. + * An implementation may return either 0 or the correct size + * for a hash algorithm that it recognizes, but does not support. + */ +#define PSA_HASH_SIZE(alg) \ + ( \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ + 0) + /** \def PSA_HASH_MAX_SIZE * * Maximum size of a hash. @@ -84,6 +120,26 @@ */ #define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE +/** The tag size for an AEAD algorithm, in bytes. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The tag size for the specified algorithm. + * If the AEAD algorithm does not have an identified + * tag that can be distinguished from the rest of + * the ciphertext, return 0. + * If the AEAD algorithm is not recognized, return 0. + * An implementation may return either 0 or a + * correct size for an AEAD algorithm that it + * recognizes, but does not support. + */ +#define PSA_AEAD_TAG_LENGTH(alg) \ + (PSA_ALG_IS_AEAD(alg) ? \ + (((alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> PSA_AEAD_TAG_LENGTH_OFFSET) : \ + 0) + /* The maximum size of an RSA key on this implementation, in bits. * This is a vendor-specific macro. * @@ -236,6 +292,22 @@ (plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \ 0) +#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \ + (PSA_ALG_IS_RSA_OAEP(alg) ? \ + 2 * PSA_HASH_FINAL_SIZE(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ + 11 /*PKCS#1v1.5*/) + +/** + * \brief ECDSA signature size for a given curve bit size + * + * \param curve_bits Curve size in bits. + * \return Signature size in bytes. + * + * \note This macro returns a compile-time constant if its argument is one. + */ +#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \ + (PSA_BITS_TO_BYTES(curve_bits) * 2) + /** Safe signature buffer size for psa_asymmetric_sign(). * * This macro returns a safe buffer size for a signature using a key diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h new file mode 100644 index 000000000..9b44d6aef --- /dev/null +++ b/include/psa/crypto_types.h @@ -0,0 +1,101 @@ +/** + * \file psa/crypto_types.h + * + * \brief PSA cryptography module: type aliases. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. Drivers must include the appropriate driver + * header file. + * + * This file contains portable definitions of integral types for properties + * of cryptographic keys, designations of cryptographic algorithms, and + * error codes returned by the library. + * + * This header file does not declare any function. + */ +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef PSA_CRYPTO_TYPES_H +#define PSA_CRYPTO_TYPES_H + +#include + +/** \defgroup error Error codes + * @{ + */ + +/** + * \brief Function return status. + * + * This is either #PSA_SUCCESS (which is zero), indicating success, + * or a nonzero value indicating that an error occurred. Errors are + * encoded as one of the \c PSA_ERROR_xxx values defined here. + */ +typedef int32_t psa_status_t; + +/**@}*/ + +/** \defgroup crypto_types Key and algorithm types + * @{ + */ + +/** \brief Encoding of a key type. + */ +typedef uint32_t psa_key_type_t; + +/** The type of PSA elliptic curve identifiers. */ +typedef uint16_t psa_ecc_curve_t; + +/** \brief Encoding of a cryptographic algorithm. + * + * For algorithms that can be applied to multiple key types, this type + * does not encode the key type. For example, for symmetric ciphers + * based on a block cipher, #psa_algorithm_t encodes the block cipher + * mode and the padding mode while the block cipher itself is encoded + * via #psa_key_type_t. + */ +typedef uint32_t psa_algorithm_t; + +/**@}*/ + +/** \defgroup key_lifetimes Key lifetimes + * @{ + */ + +/** Encoding of key lifetimes. + */ +typedef uint32_t psa_key_lifetime_t; + +/** Encoding of identifiers of persistent keys. + */ +typedef uint32_t psa_key_id_t; + +/**@}*/ + +/** \defgroup policy Key policies + * @{ + */ + +/** \brief Encoding of permitted usage on a key. */ +typedef uint32_t psa_key_usage_t; + +/**@}*/ + +#endif /* PSA_CRYPTO_TYPES_H */ diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h new file mode 100644 index 000000000..4d25835be --- /dev/null +++ b/include/psa/crypto_values.h @@ -0,0 +1,1420 @@ +/** + * \file psa/crypto_values.h + * + * \brief PSA cryptography module: macros to build and analyze integer values. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. Drivers must include the appropriate driver + * header file. + * + * This file contains portable definitions of macros to build and analyze + * values of integral types that encode properties of cryptographic keys, + * designations of cryptographic algorithms, and error codes returned by + * the library. + * + * This header file only defines preprocessor macros. + */ +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef PSA_CRYPTO_VALUES_H +#define PSA_CRYPTO_VALUES_H + +/** \defgroup error Error codes + * @{ + */ + +#if !defined(PSA_SUCCESS) +/* If PSA_SUCCESS is defined, assume that PSA crypto is being used + * together with PSA IPC, which also defines the identifier + * PSA_SUCCESS. We must not define PSA_SUCCESS ourselves in that case; + * the other error code names don't clash. This is a temporary hack + * until we unify error reporting in PSA IPC and PSA crypto. + * + * Note that psa_defs.h must be included before this header! + */ +/** The action was completed successfully. */ +#define PSA_SUCCESS ((psa_status_t)0) +#endif /* !defined(PSA_SUCCESS) */ + +/** An error occurred that does not correspond to any defined + * failure cause. + * + * Implementations may use this error code if none of the other standard + * error codes are applicable. */ +#define PSA_ERROR_UNKNOWN_ERROR ((psa_status_t)1) + +/** The requested operation or a parameter is not supported + * by this implementation. + * + * Implementations should return this error code when an enumeration + * parameter such as a key type, algorithm, etc. is not recognized. + * If a combination of parameters is recognized and identified as + * not valid, return #PSA_ERROR_INVALID_ARGUMENT instead. */ +#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)2) + +/** The requested action is denied by a policy. + * + * Implementations should return this error code when the parameters + * are recognized as valid and supported, and a policy explicitly + * denies the requested operation. + * + * If a subset of the parameters of a function call identify a + * forbidden operation, and another subset of the parameters are + * not valid or not supported, it is unspecified whether the function + * returns #PSA_ERROR_NOT_PERMITTED, #PSA_ERROR_NOT_SUPPORTED or + * #PSA_ERROR_INVALID_ARGUMENT. */ +#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)3) + +/** An output buffer is too small. + * + * Applications can call the \c PSA_xxx_SIZE macro listed in the function + * description to determine a sufficient buffer size. + * + * Implementations should preferably return this error code only + * in cases when performing the operation with a larger output + * buffer would succeed. However implementations may return this + * error if a function has invalid or unsupported parameters in addition + * to the parameters that determine the necessary output buffer size. */ +#define PSA_ERROR_BUFFER_TOO_SMALL ((psa_status_t)4) + +/** A slot is occupied, but must be empty to carry out the + * requested action. + * + * If a handle is invalid, it does not designate an occupied slot. + * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. + */ +#define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5) + +/** A slot is empty, but must be occupied to carry out the + * requested action. + * + * If a handle is invalid, it does not designate an empty slot. + * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. + */ +#define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6) + +/** The requested action cannot be performed in the current state. + * + * Multipart operations return this error when one of the + * functions is called out of sequence. Refer to the function + * descriptions for permitted sequencing of functions. + * + * Implementations shall not return this error code to indicate + * that a key slot is occupied when it needs to be free or vice versa, + * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT + * as applicable. */ +#define PSA_ERROR_BAD_STATE ((psa_status_t)7) + +/** The parameters passed to the function are invalid. + * + * Implementations may return this error any time a parameter or + * combination of parameters are recognized as invalid. + * + * Implementations shall not return this error code to indicate + * that a key slot is occupied when it needs to be free or vice versa, + * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT + * as applicable. + * + * Implementation shall not return this error code to indicate that a + * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * instead. + */ +#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8) + +/** There is not enough runtime memory. + * + * If the action is carried out across multiple security realms, this + * error can refer to available memory in any of the security realms. */ +#define PSA_ERROR_INSUFFICIENT_MEMORY ((psa_status_t)9) + +/** There is not enough persistent storage. + * + * Functions that modify the key storage return this error code if + * there is insufficient storage space on the host media. In addition, + * many functions that do not otherwise access storage may return this + * error code if the implementation requires a mandatory log entry for + * the requested action and the log storage space is full. */ +#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)10) + +/** There was a communication failure inside the implementation. + * + * This can indicate a communication failure between the application + * and an external cryptoprocessor or between the cryptoprocessor and + * an external volatile or persistent memory. A communication failure + * may be transient or permanent depending on the cause. + * + * \warning If a function returns this error, it is undetermined + * whether the requested action has completed or not. Implementations + * should return #PSA_SUCCESS on successful completion whenver + * possible, however functions may return #PSA_ERROR_COMMUNICATION_FAILURE + * if the requested action was completed successfully in an external + * cryptoprocessor but there was a breakdown of communication before + * the cryptoprocessor could report the status to the application. + */ +#define PSA_ERROR_COMMUNICATION_FAILURE ((psa_status_t)11) + +/** There was a storage failure that may have led to data loss. + * + * This error indicates that some persistent storage is corrupted. + * It should not be used for a corruption of volatile memory + * (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error + * between the cryptoprocessor and its external storage (use + * #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is + * in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE). + * + * Note that a storage failure does not indicate that any data that was + * previously read is invalid. However this previously read data may no + * longer be readable from storage. + * + * When a storage failure occurs, it is no longer possible to ensure + * the global integrity of the keystore. Depending on the global + * integrity guarantees offered by the implementation, access to other + * data may or may not fail even if the data is still readable but + * its integrity canont be guaranteed. + * + * Implementations should only use this error code to report a + * permanent storage corruption. However application writers should + * keep in mind that transient errors while reading the storage may be + * reported using this error code. */ +#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)12) + +/** A hardware failure was detected. + * + * A hardware failure may be transient or permanent depending on the + * cause. */ +#define PSA_ERROR_HARDWARE_FAILURE ((psa_status_t)13) + +/** A tampering attempt was detected. + * + * If an application receives this error code, there is no guarantee + * that previously accessed or computed data was correct and remains + * confidential. Applications should not perform any security function + * and should enter a safe failure state. + * + * Implementations may return this error code if they detect an invalid + * state that cannot happen during normal operation and that indicates + * that the implementation's security guarantees no longer hold. Depending + * on the implementation architecture and on its security and safety goals, + * the implementation may forcibly terminate the application. + * + * This error code is intended as a last resort when a security breach + * is detected and it is unsure whether the keystore data is still + * protected. Implementations shall only return this error code + * to report an alarm from a tampering detector, to indicate that + * the confidentiality of stored data can no longer be guaranteed, + * or to indicate that the integrity of previously returned data is now + * considered compromised. Implementations shall not use this error code + * to indicate a hardware failure that merely makes it impossible to + * perform the requested operation (use #PSA_ERROR_COMMUNICATION_FAILURE, + * #PSA_ERROR_STORAGE_FAILURE, #PSA_ERROR_HARDWARE_FAILURE, + * #PSA_ERROR_INSUFFICIENT_ENTROPY or other applicable error code + * instead). + * + * This error indicates an attack against the application. Implementations + * shall not return this error code as a consequence of the behavior of + * the application itself. */ +#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)14) + +/** There is not enough entropy to generate random data needed + * for the requested action. + * + * This error indicates a failure of a hardware random generator. + * Application writers should note that this error can be returned not + * only by functions whose purpose is to generate random data, such + * as key, IV or nonce generation, but also by functions that execute + * an algorithm with a randomized result, as well as functions that + * use randomization of intermediate computations as a countermeasure + * to certain attacks. + * + * Implementations should avoid returning this error after psa_crypto_init() + * has succeeded. Implementations should generate sufficient + * entropy during initialization and subsequently use a cryptographically + * secure pseudorandom generator (PRNG). However implementations may return + * this error at any time if a policy requires the PRNG to be reseeded + * during normal operation. */ +#define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)15) + +/** The signature, MAC or hash is incorrect. + * + * Verification functions return this error if the verification + * calculations completed successfully, and the value to be verified + * was determined to be incorrect. + * + * If the value to verify has an invalid size, implementations may return + * either #PSA_ERROR_INVALID_ARGUMENT or #PSA_ERROR_INVALID_SIGNATURE. */ +#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)16) + +/** The decrypted padding is incorrect. + * + * \warning In some protocols, when decrypting data, it is essential that + * the behavior of the application does not depend on whether the padding + * is correct, down to precise timing. Applications should prefer + * protocols that use authenticated encryption rather than plain + * encryption. If the application must perform a decryption of + * unauthenticated data, the application writer should take care not + * to reveal whether the padding is invalid. + * + * Implementations should strive to make valid and invalid padding + * as close as possible to indistinguishable to an external observer. + * In particular, the timing of a decryption operation should not + * depend on the validity of the padding. */ +#define PSA_ERROR_INVALID_PADDING ((psa_status_t)17) + +/** The generator has insufficient capacity left. + * + * Once a function returns this error, attempts to read from the + * generator will always return this error. */ +#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18) + +/** The key handle is not valid. + */ +#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)19) + +/**@}*/ + +/** \defgroup crypto_types Key and algorithm types + * @{ + */ + +/** An invalid key type value. + * + * Zero is not the encoding of any key type. + */ +#define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x00000000) + +/** Vendor-defined flag + * + * Key types defined by this standard will never have the + * #PSA_KEY_TYPE_VENDOR_FLAG bit set. Vendors who define additional key types + * must use an encoding with the #PSA_KEY_TYPE_VENDOR_FLAG bit set and should + * respect the bitwise structure used by standard encodings whenever practical. + */ +#define PSA_KEY_TYPE_VENDOR_FLAG ((psa_key_type_t)0x80000000) + +#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x70000000) +#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x40000000) +#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t)0x50000000) +#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t)0x60000000) +#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t)0x70000000) + +#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t)0x10000000) + +/** Whether a key type is vendor-defined. */ +#define PSA_KEY_TYPE_IS_VENDOR_DEFINED(type) \ + (((type) & PSA_KEY_TYPE_VENDOR_FLAG) != 0) + +/** Whether a key type is an unstructured array of bytes. + * + * This encompasses both symmetric keys and non-key data. + */ +#define PSA_KEY_TYPE_IS_UNSTRUCTURED(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK & ~(psa_key_type_t)0x10000000) == \ + PSA_KEY_TYPE_CATEGORY_SYMMETRIC) + +/** Whether a key type is asymmetric: either a key pair or a public key. */ +#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ + & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) == \ + PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) +/** Whether a key type is the public part of a key pair. */ +#define PSA_KEY_TYPE_IS_PUBLIC_KEY(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY) +/** Whether a key type is a key pair containing a private part and a public + * part. */ +#define PSA_KEY_TYPE_IS_KEYPAIR(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR) +/** The key pair type corresponding to a public key type. + * + * You may also pass a key pair type as \p type, it will be left unchanged. + * + * \param type A public key type or key pair type. + * + * \return The corresponding key pair type. + * If \p type is not a public key or a key pair, + * the return value is undefined. + */ +#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \ + ((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) +/** The public key type corresponding to a key pair type. + * + * You may also pass a key pair type as \p type, it will be left unchanged. + * + * \param type A public key type or key pair type. + * + * \return The corresponding public key type. + * If \p type is not a public key or a key pair, + * the return value is undefined. + */ +#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \ + ((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR) + +/** Raw data. + * + * A "key" of this type cannot be used for any cryptographic operation. + * Applications may use this type to store arbitrary data in the keystore. */ +#define PSA_KEY_TYPE_RAW_DATA ((psa_key_type_t)0x50000001) + +/** HMAC key. + * + * The key policy determines which underlying hash algorithm the key can be + * used for. + * + * HMAC keys should generally have the same size as the underlying hash. + * This size can be calculated with #PSA_HASH_SIZE(\c alg) where + * \c alg is the HMAC algorithm or the underlying hash algorithm. */ +#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x51000000) + +/** A secret for key derivation. + * + * The key policy determines which key derivation algorithm the key + * can be used for. + */ +#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000) + +/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher. + * + * The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or + * 32 bytes (AES-256). + */ +#define PSA_KEY_TYPE_AES ((psa_key_type_t)0x40000001) + +/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). + * + * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or + * 24 bytes (3-key 3DES). + * + * Note that single DES and 2-key 3DES are weak and strongly + * deprecated and should only be used to decrypt legacy data. 3-key 3DES + * is weak and deprecated and should only be used in legacy protocols. + */ +#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002) + +/** Key for an cipher, AEAD or MAC algorithm based on the + * Camellia block cipher. */ +#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003) + +/** Key for the RC4 stream cipher. + * + * Note that RC4 is weak and deprecated and should only be used in + * legacy protocols. */ +#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004) + +/** RSA public key. */ +#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000) +/** RSA key pair (private and public key). */ +#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000) +/** Whether a key type is an RSA key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_RSA(type) \ + (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY) + +/** DSA public key. */ +#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000) +/** DSA key pair (private and public key). */ +#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000) +/** Whether a key type is an DSA key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_DSA(type) \ + (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY) + +#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000) +#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000) +#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff) +/** Elliptic curve key pair. */ +#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \ + (PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve)) +/** Elliptic curve public key. */ +#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \ + (PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve)) + +/** Whether a key type is an elliptic curve key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_ECC(type) \ + ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \ + ~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) +/** Whether a key type is an elliptic curve key pair. */ +#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \ + (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ + PSA_KEY_TYPE_ECC_KEYPAIR_BASE) +/** Whether a key type is an elliptic curve public key. */ +#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \ + (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ + PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE) + +/** Extract the curve from an elliptic curve key type. */ +#define PSA_KEY_TYPE_GET_CURVE(type) \ + ((psa_ecc_curve_t) (PSA_KEY_TYPE_IS_ECC(type) ? \ + ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \ + 0)) + +/* The encoding of curve identifiers is currently aligned with the + * TLS Supported Groups Registry (formerly known as the + * TLS EC Named Curve Registry) + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + * The values are defined by RFC 8422 and RFC 7027. */ +#define PSA_ECC_CURVE_SECT163K1 ((psa_ecc_curve_t) 0x0001) +#define PSA_ECC_CURVE_SECT163R1 ((psa_ecc_curve_t) 0x0002) +#define PSA_ECC_CURVE_SECT163R2 ((psa_ecc_curve_t) 0x0003) +#define PSA_ECC_CURVE_SECT193R1 ((psa_ecc_curve_t) 0x0004) +#define PSA_ECC_CURVE_SECT193R2 ((psa_ecc_curve_t) 0x0005) +#define PSA_ECC_CURVE_SECT233K1 ((psa_ecc_curve_t) 0x0006) +#define PSA_ECC_CURVE_SECT233R1 ((psa_ecc_curve_t) 0x0007) +#define PSA_ECC_CURVE_SECT239K1 ((psa_ecc_curve_t) 0x0008) +#define PSA_ECC_CURVE_SECT283K1 ((psa_ecc_curve_t) 0x0009) +#define PSA_ECC_CURVE_SECT283R1 ((psa_ecc_curve_t) 0x000a) +#define PSA_ECC_CURVE_SECT409K1 ((psa_ecc_curve_t) 0x000b) +#define PSA_ECC_CURVE_SECT409R1 ((psa_ecc_curve_t) 0x000c) +#define PSA_ECC_CURVE_SECT571K1 ((psa_ecc_curve_t) 0x000d) +#define PSA_ECC_CURVE_SECT571R1 ((psa_ecc_curve_t) 0x000e) +#define PSA_ECC_CURVE_SECP160K1 ((psa_ecc_curve_t) 0x000f) +#define PSA_ECC_CURVE_SECP160R1 ((psa_ecc_curve_t) 0x0010) +#define PSA_ECC_CURVE_SECP160R2 ((psa_ecc_curve_t) 0x0011) +#define PSA_ECC_CURVE_SECP192K1 ((psa_ecc_curve_t) 0x0012) +#define PSA_ECC_CURVE_SECP192R1 ((psa_ecc_curve_t) 0x0013) +#define PSA_ECC_CURVE_SECP224K1 ((psa_ecc_curve_t) 0x0014) +#define PSA_ECC_CURVE_SECP224R1 ((psa_ecc_curve_t) 0x0015) +#define PSA_ECC_CURVE_SECP256K1 ((psa_ecc_curve_t) 0x0016) +#define PSA_ECC_CURVE_SECP256R1 ((psa_ecc_curve_t) 0x0017) +#define PSA_ECC_CURVE_SECP384R1 ((psa_ecc_curve_t) 0x0018) +#define PSA_ECC_CURVE_SECP521R1 ((psa_ecc_curve_t) 0x0019) +#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a) +#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b) +#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c) +#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d) +#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e) + +/** The block size of a block cipher. + * + * \param type A cipher key type (value of type #psa_key_type_t). + * + * \return The block size for a block cipher, or 1 for a stream cipher. + * The return value is undefined if \p type is not a supported + * cipher key type. + * + * \note It is possible to build stream cipher algorithms on top of a block + * cipher, for example CTR mode (#PSA_ALG_CTR). + * This macro only takes the key type into account, so it cannot be + * used to determine the size of the data that #psa_cipher_update() + * might buffer for future processing in general. + * + * \note This macro returns a compile-time constant if its argument is one. + * + * \warning This macro may evaluate its argument multiple times. + */ +#define PSA_BLOCK_CIPHER_BLOCK_SIZE(type) \ + ( \ + (type) == PSA_KEY_TYPE_AES ? 16 : \ + (type) == PSA_KEY_TYPE_DES ? 8 : \ + (type) == PSA_KEY_TYPE_CAMELLIA ? 16 : \ + (type) == PSA_KEY_TYPE_ARC4 ? 1 : \ + 0) + +#define PSA_ALG_VENDOR_FLAG ((psa_algorithm_t)0x80000000) +#define PSA_ALG_CATEGORY_MASK ((psa_algorithm_t)0x7f000000) +#define PSA_ALG_CATEGORY_HASH ((psa_algorithm_t)0x01000000) +#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x02000000) +#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000) +#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000) +#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000) +#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000) +#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000) +#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000) +#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000) + +#define PSA_ALG_IS_VENDOR_DEFINED(alg) \ + (((alg) & PSA_ALG_VENDOR_FLAG) != 0) + +/** Whether the specified algorithm is a hash algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a hash algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_HASH(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_HASH) + +/** Whether the specified algorithm is a MAC algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a MAC algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_MAC(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_MAC) + +/** Whether the specified algorithm is a symmetric cipher algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a symmetric cipher algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_CIPHER(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_CIPHER) + +/** Whether the specified algorithm is an authenticated encryption + * with associated data (AEAD) algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an AEAD algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_AEAD(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_AEAD) + +/** Whether the specified algorithm is a public-key signature algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a public-key signature algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_SIGN(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_SIGN) + +/** Whether the specified algorithm is a public-key encryption algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a public-key encryption algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION) + +#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000) +/** Whether the specified algorithm is a key agreement algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key agreement algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_KEY_AGREEMENT(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \ + PSA_ALG_CATEGORY_KEY_AGREEMENT) + +/** Whether the specified algorithm is a key derivation algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key derivation algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_KEY_DERIVATION(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION) + +/** Whether the specified algorithm is a key selection algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a key selection algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_KEY_SELECTION(alg) \ + (((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION) + +#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) +#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001) +#define PSA_ALG_MD4 ((psa_algorithm_t)0x01000002) +#define PSA_ALG_MD5 ((psa_algorithm_t)0x01000003) +#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x01000004) +#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x01000005) +/** SHA2-224 */ +#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x01000008) +/** SHA2-256 */ +#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x01000009) +/** SHA2-384 */ +#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0100000a) +/** SHA2-512 */ +#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0100000b) +/** SHA2-512/224 */ +#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0100000c) +/** SHA2-512/256 */ +#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0100000d) +/** SHA3-224 */ +#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x01000010) +/** SHA3-256 */ +#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x01000011) +/** SHA3-384 */ +#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x01000012) +/** SHA3-512 */ +#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x01000013) + +#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000) +#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x02800000) +/** Macro to build an HMAC algorithm. + * + * For example, #PSA_ALG_HMAC(#PSA_ALG_SHA_256) is HMAC-SHA-256. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding HMAC algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_HMAC(hash_alg) \ + (PSA_ALG_HMAC_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +#define PSA_ALG_HMAC_GET_HASH(hmac_alg) \ + (PSA_ALG_CATEGORY_HASH | ((hmac_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is an HMAC algorithm. + * + * HMAC is a family of MAC algorithms that are based on a hash function. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an HMAC algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_HMAC(alg) \ + (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ + PSA_ALG_HMAC_BASE) + +/* In the encoding of a MAC algorithm, the bits corresponding to + * PSA_ALG_MAC_TRUNCATION_MASK encode the length to which the MAC is + * truncated. As an exception, the value 0 means the untruncated algorithm, + * whatever its length is. The length is encoded in 6 bits, so it can + * reach up to 63; the largest MAC is 64 bytes so its trivial truncation + * to full length is correctly encoded as 0 and any non-trivial truncation + * is correctly encoded as a value between 1 and 63. */ +#define PSA_ALG_MAC_TRUNCATION_MASK ((psa_algorithm_t)0x00003f00) +#define PSA_MAC_TRUNCATION_OFFSET 8 + +/** Macro to build a truncated MAC algorithm. + * + * A truncated MAC algorithm is identical to the corresponding MAC + * algorithm except that the MAC value for the truncated algorithm + * consists of only the first \p mac_length bytes of the MAC value + * for the untruncated algorithm. + * + * \note This macro may allow constructing algorithm identifiers that + * are not valid, either because the specified length is larger + * than the untruncated MAC or because the specified length is + * smaller than permitted by the implementation. + * + * \note It is implementation-defined whether a truncated MAC that + * is truncated to the same length as the MAC of the untruncated + * algorithm is considered identical to the untruncated algorithm + * for policy comparison purposes. + * + * \param alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * is true). This may be a truncated or untruncated + * MAC algorithm. + * \param mac_length Desired length of the truncated MAC in bytes. + * This must be at most the full length of the MAC + * and must be at least an implementation-specified + * minimum. The implementation-specified minimum + * shall not be zero. + * + * \return The corresponding MAC algorithm with the specified + * length. + * \return Unspecified if \p alg is not a supported + * MAC algorithm or if \p mac_length is too small or + * too large for the specified MAC algorithm. + */ +#define PSA_ALG_TRUNCATED_MAC(alg, mac_length) \ + (((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) | \ + ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK)) + +/** Macro to build the base MAC algorithm corresponding to a truncated + * MAC algorithm. + * + * \param alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * is true). This may be a truncated or untruncated + * MAC algorithm. + * + * \return The corresponding base MAC algorithm. + * \return Unspecified if \p alg is not a supported + * MAC algorithm. + */ +#define PSA_ALG_FULL_LENGTH_MAC(alg) \ + ((alg) & ~PSA_ALG_MAC_TRUNCATION_MASK) + +/** Length to which a MAC algorithm is truncated. + * + * \param alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p alg) + * is true). + * + * \return Length of the truncated MAC in bytes. + * \return 0 if \p alg is a non-truncated MAC algorithm. + * \return Unspecified if \p alg is not a supported + * MAC algorithm. + */ +#define PSA_MAC_TRUNCATED_LENGTH(alg) \ + (((alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) + +#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000) +#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001) +#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002) +#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003) + +/** Whether the specified algorithm is a MAC algorithm based on a block cipher. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a MAC algorithm based on a block cipher, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) \ + (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_MAC_SUBCATEGORY_MASK)) == \ + PSA_ALG_CIPHER_MAC_BASE) + +#define PSA_ALG_CIPHER_STREAM_FLAG ((psa_algorithm_t)0x00800000) +#define PSA_ALG_CIPHER_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000) + +/** Whether the specified algorithm is a stream cipher. + * + * A stream cipher is a symmetric cipher that encrypts or decrypts messages + * by applying a bitwise-xor with a stream of bytes that is generated + * from a key. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a stream cipher algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \p alg is not a supported + * algorithm identifier or if it is not a symmetric cipher algorithm. + */ +#define PSA_ALG_IS_STREAM_CIPHER(alg) \ + (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_CIPHER_STREAM_FLAG)) == \ + (PSA_ALG_CATEGORY_CIPHER | PSA_ALG_CIPHER_STREAM_FLAG)) + +/** The ARC4 stream cipher algorithm. + */ +#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001) + +/** The CTR stream cipher mode. + * + * CTR is a stream cipher which is built from a block cipher. + * The underlying block cipher is determined by the key type. + * For example, to use AES-128-CTR, use this algorithm with + * a key of type #PSA_KEY_TYPE_AES and a length of 128 bits (16 bytes). + */ +#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001) + +#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002) + +#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003) + +/** The XTS cipher mode. + * + * XTS is a cipher mode which is built from a block cipher. It requires at + * least one full block of input, but beyond this minimum the input + * does not need to be a whole number of blocks. + */ +#define PSA_ALG_XTS ((psa_algorithm_t)0x044000ff) + +/** The CBC block cipher chaining mode, with no padding. + * + * The underlying block cipher is determined by the key type. + * + * This symmetric cipher mode can only be used with messages whose lengths + * are whole number of blocks for the chosen block cipher. + */ +#define PSA_ALG_CBC_NO_PADDING ((psa_algorithm_t)0x04600100) + +/** The CBC block cipher chaining mode with PKCS#7 padding. + * + * The underlying block cipher is determined by the key type. + * + * This is the padding method defined by PKCS#7 (RFC 2315) §10.3. + */ +#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101) + +#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001) +#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002) + +/* In the encoding of a AEAD algorithm, the bits corresponding to + * PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag. + * The constants for default lengths follow this encoding. + */ +#define PSA_ALG_AEAD_TAG_LENGTH_MASK ((psa_algorithm_t)0x00003f00) +#define PSA_AEAD_TAG_LENGTH_OFFSET 8 + +/** Macro to build a shortened AEAD algorithm. + * + * A shortened AEAD algorithm is similar to the corresponding AEAD + * algorithm, but has an authentication tag that consists of fewer bytes. + * Depending on the algorithm, the tag length may affect the calculation + * of the ciphertext. + * + * \param alg A AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p alg) + * is true). + * \param tag_length Desired length of the authentication tag in bytes. + * + * \return The corresponding AEAD algorithm with the specified + * length. + * \return Unspecified if \p alg is not a supported + * AEAD algorithm or if \p tag_length is not valid + * for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, tag_length) \ + (((alg) & ~PSA_ALG_AEAD_TAG_LENGTH_MASK) | \ + ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ + PSA_ALG_AEAD_TAG_LENGTH_MASK)) + +/** Calculate the corresponding AEAD algorithm with the default tag length. + * + * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The corresponding AEAD algorithm with the default tag length + * for that algorithm. + */ +#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH(alg) \ + ( \ + PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_CCM) \ + PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, PSA_ALG_GCM) \ + 0) +#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(alg, ref) \ + PSA_ALG_AEAD_WITH_TAG_LENGTH(alg, 0) == \ + PSA_ALG_AEAD_WITH_TAG_LENGTH(ref, 0) ? \ + ref : + +#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x10020000) +/** RSA PKCS#1 v1.5 signature with hashing. + * + * This is the signature scheme defined by RFC 8017 + * (PKCS#1: RSA Cryptography Specifications) under the name + * RSASSA-PKCS1-v1_5. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding RSA PKCS#1 v1.5 signature algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \ + (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +/** Raw PKCS#1 v1.5 signature. + * + * The input to this algorithm is the DigestInfo structure used by + * RFC 8017 (PKCS#1: RSA Cryptography Specifications), §9.2 + * steps 3–6. + */ +#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE +#define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE) + +#define PSA_ALG_RSA_PSS_BASE ((psa_algorithm_t)0x10030000) +/** RSA PSS signature with hashing. + * + * This is the signature scheme defined by RFC 8017 + * (PKCS#1: RSA Cryptography Specifications) under the name + * RSASSA-PSS, with the message generation function MGF1, and with + * a salt length equal to the length of the hash. The specified + * hash algorithm is used to hash the input message, to create the + * salted hash, and for the mask generation. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding RSA PSS signature algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_RSA_PSS(hash_alg) \ + (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_RSA_PSS(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE) + +#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000) +/** DSA signature with hashing. + * + * This is the signature scheme defined by FIPS 186-4, + * with a random per-message secret number (*k*). + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding DSA signature algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_DSA(hash_alg) \ + (PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000) +#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000) +#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \ + (PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_DSA(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \ + PSA_ALG_DSA_BASE) +#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \ + (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0) +#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \ + (PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg)) +#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \ + (PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg)) + +#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000) +/** ECDSA signature with hashing. + * + * This is the ECDSA signature scheme defined by ANSI X9.62, + * with a random per-message secret number (*k*). + * + * The representation of the signature as a byte string consists of + * the concatentation of the signature values *r* and *s*. Each of + * *r* and *s* is encoded as an *N*-octet string, where *N* is the length + * of the base point of the curve in octets. Each value is represented + * in big-endian order (most significant octet first). + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding ECDSA signature algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_ECDSA(hash_alg) \ + (PSA_ALG_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +/** ECDSA signature without hashing. + * + * This is the same signature scheme as #PSA_ALG_ECDSA(), but + * without specifying a hash algorithm. This algorithm may only be + * used to sign or verify a sequence of bytes that should be an + * already-calculated hash. Note that the input is padded with + * zeros on the left or truncated on the left as required to fit + * the curve size. + */ +#define PSA_ALG_ECDSA_ANY PSA_ALG_ECDSA_BASE +#define PSA_ALG_DETERMINISTIC_ECDSA_BASE ((psa_algorithm_t)0x10070000) +/** Deterministic ECDSA signature with hashing. + * + * This is the deterministic ECDSA signature scheme defined by RFC 6979. + * + * The representation of a signature is the same as with #PSA_ALG_ECDSA(). + * + * Note that when this algorithm is used for verification, signatures + * made with randomized ECDSA (#PSA_ALG_ECDSA(\p hash_alg)) with the + * same private key are accepted. In other words, + * #PSA_ALG_DETERMINISTIC_ECDSA(\p hash_alg) differs from + * #PSA_ALG_ECDSA(\p hash_alg) only for signature, not for verification. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding deterministic ECDSA signature + * algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \ + (PSA_ALG_DETERMINISTIC_ECDSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_ECDSA(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \ + PSA_ALG_ECDSA_BASE) +#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \ + (((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0) +#define PSA_ALG_IS_DETERMINISTIC_ECDSA(alg) \ + (PSA_ALG_IS_ECDSA(alg) && PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) +#define PSA_ALG_IS_RANDOMIZED_ECDSA(alg) \ + (PSA_ALG_IS_ECDSA(alg) && !PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) + +/** Get the hash used by a hash-and-sign signature algorithm. + * + * A hash-and-sign algorithm is a signature algorithm which is + * composed of two phases: first a hashing phase which does not use + * the key and produces a hash of the input message, then a signing + * phase which only uses the hash and the key and not the message + * itself. + * + * \param alg A signature algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_SIGN(\p alg) is true). + * + * \return The underlying hash algorithm if \p alg is a hash-and-sign + * algorithm. + * \return 0 if \p alg is a signature algorithm that does not + * follow the hash-and-sign structure. + * \return Unspecified if \p alg is not a signature algorithm or + * if it is not supported by the implementation. + */ +#define PSA_ALG_SIGN_GET_HASH(alg) \ + (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ + PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg) ? \ + ((alg) & PSA_ALG_HASH_MASK) == 0 ? /*"raw" algorithm*/ 0 : \ + ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ + 0) + +/** RSA PKCS#1 v1.5 encryption. + */ +#define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t)0x12020000) + +#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x12030000) +/** RSA OAEP encryption. + * + * This is the encryption scheme defined by RFC 8017 + * (PKCS#1: RSA Cryptography Specifications) under the name + * RSAES-OAEP, with the message generation function MGF1. + * + * \param hash_alg The hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true) to use + * for MGF1. + * + * \return The corresponding RSA OAEP signature algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_RSA_OAEP(hash_alg) \ + (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +#define PSA_ALG_IS_RSA_OAEP(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE) +#define PSA_ALG_RSA_OAEP_GET_HASH(alg) \ + (PSA_ALG_IS_RSA_OAEP(alg) ? \ + ((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \ + 0) + +#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100) +/** Macro to build an HKDF algorithm. + * + * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding HKDF algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_HKDF(hash_alg) \ + (PSA_ALG_HKDF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) +/** Whether the specified algorithm is an HKDF algorithm. + * + * HKDF is a family of key derivation algorithms that are based on a hash + * function and the HMAC construction. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is an HKDF algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_HKDF(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HKDF_BASE) +#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \ + (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) + +#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200) +/** Macro to build a TLS-1.2 PRF algorithm. + * + * TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule, + * specified in Section 5 of RFC 5246. It is based on HMAC and can be + * used with either SHA-256 or SHA-384. + * + * For the application to TLS-1.2, the salt and label arguments passed + * to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246, + * respectively. For example, for TLS key expansion, the salt is the + * concatenation of ServerHello.Random + ClientHello.Random, + * while the label is "key expansion". + * + * For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the + * TLS 1.2 PRF using HMAC-SHA-256. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding TLS-1.2 PRF algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_TLS12_PRF(hash_alg) \ + (PSA_ALG_TLS12_PRF_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is a TLS-1.2 PRF algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a TLS-1.2 PRF algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_TLS12_PRF(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PRF_BASE) +#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \ + (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) + +#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300) +/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm. + * + * In a pure-PSK handshake in TLS 1.2, the master secret is derived + * from the PreSharedKey (PSK) through the application of padding + * (RFC 4279, Section 2) and the TLS-1.2 PRF (RFC 5246, Section 5). + * The latter is based on HMAC and can be used with either SHA-256 + * or SHA-384. + * + * For the application to TLS-1.2, the salt passed to psa_key_derivation() + * (and forwarded to the TLS-1.2 PRF) is the concatenation of the + * ClientHello.Random + ServerHello.Random, while the label is "master secret" + * or "extended master secret". + * + * For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the + * TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * + * \return The corresponding TLS-1.2 PSK to MS algorithm. + * \return Unspecified if \p alg is not a supported + * hash algorithm. + */ +#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \ + (PSA_ALG_TLS12_PSK_TO_MS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK)) + +/** Whether the specified algorithm is a TLS-1.2 PSK to MS algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a TLS-1.2 PSK to MS algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key derivation algorithm identifier. + */ +#define PSA_ALG_IS_TLS12_PSK_TO_MS(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_TLS12_PSK_TO_MS_BASE) +#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \ + (PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK)) + +#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff) + +/** Use a shared secret as is. + * + * Specify this algorithm as the selection component of a key agreement + * to use the raw result of the key agreement as key material. + * + * \warning The raw result of a key agreement algorithm such as finite-field + * Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should + * not be used directly as key material. It can however be used as the secret + * input in a key derivation algorithm. + */ +#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001) + +#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \ + (((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION) + +#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \ + ((alg) & ~PSA_ALG_KEY_DERIVATION_MASK) + +#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000) +/** The Diffie-Hellman key agreement algorithm. + * + * This algorithm combines the finite-field Diffie-Hellman (DH) key + * agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement, + * to produce a shared secret from a private key and the peer's + * public key, with a key selection or key derivation algorithm to produce + * one or more shared keys and other shared cryptographic material. + * + * The shared secret produced by key agreement and passed as input to the + * derivation or selection algorithm \p kdf_alg is the shared secret + * `g^{ab}` in big-endian format. + * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p` + * in bits. + * + * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) + * or a key selection algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true). + * + * \return The Diffie-Hellman algorithm with the specified + * selection or derivation algorithm. + */ +#define PSA_ALG_FFDH(kdf_alg) \ + (PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) +/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. + * + * This includes every supported key selection or key agreement algorithm + * for the output of the Diffie-Hellman calculation. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a finite field Diffie-Hellman algorithm, 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key agreement algorithm identifier. + */ +#define PSA_ALG_IS_FFDH(alg) \ + (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE) + +#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000) +/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm. + * + * This algorithm combines the elliptic curve Diffie-Hellman key + * agreement to produce a shared secret from a private key and the peer's + * public key, with a key selection or key derivation algorithm to produce + * one or more shared keys and other shared cryptographic material. + * + * The shared secret produced by key agreement and passed as input to the + * derivation or selection algorithm \p kdf_alg is the x-coordinate of + * the shared secret point. It is always `ceiling(m / 8)` bytes long where + * `m` is the bit size associated with the curve, i.e. the bit size of the + * order of the curve's coordinate field. When `m` is not a multiple of 8, + * the byte containing the most significant bit of the shared secret + * is padded with zero bits. The byte order is either little-endian + * or big-endian depending on the curve type. + * + * - For Montgomery curves (curve types `PSA_ECC_CURVE_CURVEXXX`), + * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` + * in little-endian byte order. + * The bit size is 448 for Curve448 and 255 for Curve25519. + * - For Weierstrass curves over prime fields (curve types + * `PSA_ECC_CURVE_SECPXXX` and `PSA_ECC_CURVE_BRAINPOOL_PXXX`), + * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` + * in big-endian byte order. + * The bit size is `m = ceiling(log_2(p))` for the field `F_p`. + * - For Weierstrass curves over binary fields (curve types + * `PSA_ECC_CURVE_SECTXXX`), + * the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A` + * in big-endian byte order. + * The bit size is `m` for the field `F_{2^m}`. + * + * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true) + * or a selection algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true). + * + * \return The Diffie-Hellman algorithm with the specified + * selection or derivation algorithm. + */ +#define PSA_ALG_ECDH(kdf_alg) \ + (PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK)) +/** Whether the specified algorithm is an elliptic curve Diffie-Hellman + * algorithm. + * + * This includes every supported key selection or key agreement algorithm + * for the output of the Diffie-Hellman calculation. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is an elliptic curve Diffie-Hellman algorithm, + * 0 otherwise. + * This macro may return either 0 or 1 if \c alg is not a supported + * key agreement algorithm identifier. + */ +#define PSA_ALG_IS_ECDH(alg) \ + (PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE) + +/**@}*/ + +/** \defgroup key_lifetimes Key lifetimes + * @{ + */ + +/** A volatile key only exists as long as the handle to it is not closed. + * The key material is guaranteed to be erased on a power reset. + */ +#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000) + +/** The default storage area for persistent keys. + * + * A persistent key remains in storage until it is explicitly destroyed or + * until the corresponding storage area is wiped. This specification does + * not define any mechanism to wipe a storage area, but implementations may + * provide their own mechanism (for example to perform a factory reset, + * to prepare for device refurbishment, or to uninstall an application). + * + * This lifetime value is the default storage area for the calling + * application. Implementations may offer other storage areas designated + * by other lifetime values as implementation-specific extensions. + */ +#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) + +/**@}*/ + +/** \defgroup policy Key policies + * @{ + */ + +/** Whether the key may be exported. + * + * A public key or the public part of a key pair may always be exported + * regardless of the value of this permission flag. + * + * If a key does not have export permission, implementations shall not + * allow the key to be exported in plain form from the cryptoprocessor, + * whether through psa_export_key() or through a proprietary interface. + * The key may however be exportable in a wrapped form, i.e. in a form + * where it is encrypted by another key. + */ +#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001) + +/** Whether the key may be used to encrypt a message. + * + * This flag allows the key to be used for a symmetric encryption operation, + * for an AEAD encryption-and-authentication operation, + * or for an asymmetric encryption operation, + * if otherwise permitted by the key's type and policy. + * + * For a key pair, this concerns the public key. + */ +#define PSA_KEY_USAGE_ENCRYPT ((psa_key_usage_t)0x00000100) + +/** Whether the key may be used to decrypt a message. + * + * This flag allows the key to be used for a symmetric decryption operation, + * for an AEAD decryption-and-verification operation, + * or for an asymmetric decryption operation, + * if otherwise permitted by the key's type and policy. + * + * For a key pair, this concerns the private key. + */ +#define PSA_KEY_USAGE_DECRYPT ((psa_key_usage_t)0x00000200) + +/** Whether the key may be used to sign a message. + * + * This flag allows the key to be used for a MAC calculation operation + * or for an asymmetric signature operation, + * if otherwise permitted by the key's type and policy. + * + * For a key pair, this concerns the private key. + */ +#define PSA_KEY_USAGE_SIGN ((psa_key_usage_t)0x00000400) + +/** Whether the key may be used to verify a message signature. + * + * This flag allows the key to be used for a MAC verification operation + * or for an asymmetric signature verification operation, + * if otherwise permitted by by the key's type and policy. + * + * For a key pair, this concerns the public key. + */ +#define PSA_KEY_USAGE_VERIFY ((psa_key_usage_t)0x00000800) + +/** Whether the key may be used to derive other keys. + */ +#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00001000) + +/**@}*/ + +#endif /* PSA_CRYPTO_VALUES_H */ diff --git a/programs/Makefile b/programs/Makefile index f3627c906..2792b0913 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -103,7 +103,7 @@ EXTRA_GENERATED += psa/psa_constant_names_generated.c endif psa/psa_constant_names$(EXEXT): psa/psa_constant_names_generated.c -psa/psa_constant_names_generated.c: ../scripts/generate_psa_constants.py ../include/psa/crypto.h +psa/psa_constant_names_generated.c: ../scripts/generate_psa_constants.py ../include/psa/crypto_values.h ../scripts/generate_psa_constants.py aes/aescrypt2$(EXEXT): aes/aescrypt2.c $(DEP) diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py index 7e4420b69..3e4e88b77 100755 --- a/scripts/generate_psa_constants.py +++ b/scripts/generate_psa_constants.py @@ -285,5 +285,5 @@ def generate_psa_constants(header_file_name, output_file_name): if __name__ == '__main__': if not os.path.isdir('programs') and os.path.isdir('../programs'): os.chdir('..') - generate_psa_constants('include/psa/crypto.h', + generate_psa_constants('include/psa/crypto_values.h', 'programs/psa/psa_constant_names_generated.c') diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 366b97e55..23d5c2c72 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -226,11 +226,16 @@ - + + + + + +