diff options
author | Adam Harrison <adamdharrison@gmail.com> | 2022-11-26 16:20:59 -0500 |
---|---|---|
committer | Adam Harrison <adamdharrison@gmail.com> | 2022-11-29 18:39:46 -0500 |
commit | fc0c4ed9a3103e0e6534311923668879fc8e0875 (patch) | |
tree | 6e7723c3f45d39f06c243d9c18a3c038da948793 /lib/mbedtls-2.27.0/include/psa | |
parent | 3836606e2b735ba7b2dc0f580231843660587fb4 (diff) | |
download | lite-xl-plugin-manager-curl-removal.tar.gz lite-xl-plugin-manager-curl-removal.zip |
Removed openssl, and curl, and added mbedded tls.curl-removal
Almost fully removed curl, needs more testing.
Fixed most issues, now trying to cross compile.
Fix?
Sigh.
Diffstat (limited to 'lib/mbedtls-2.27.0/include/psa')
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto.h | 3951 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_builtin_composites.h | 92 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_builtin_primitives.h | 149 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_compat.h | 528 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_config.h | 128 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_driver_common.h | 53 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_composites.h | 62 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_primitives.h | 69 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_extra.h | 818 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_platform.h | 111 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_se_driver.h | 1395 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_sizes.h | 1135 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_struct.h | 478 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_types.h | 383 | ||||
-rw-r--r-- | lib/mbedtls-2.27.0/include/psa/crypto_values.h | 2218 |
15 files changed, 11570 insertions, 0 deletions
diff --git a/lib/mbedtls-2.27.0/include/psa/crypto.h b/lib/mbedtls-2.27.0/include/psa/crypto.h new file mode 100644 index 0000000..17bebf3 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto.h @@ -0,0 +1,3951 @@ +/** + * \file psa/crypto.h + * \brief Platform Security Architecture cryptography module + */ +/* + * Copyright The Mbed TLS Contributors + * 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_H +#define PSA_CRYPTO_H + +#include "crypto_platform.h" + +#include <stddef.h> + +#ifdef __DOXYGEN_ONLY__ +/* This __DOXYGEN_ONLY__ block contains mock definitions for things that + * must be defined in the crypto_platform.h header. These mock definitions + * are present in this file as a convenience to generate pretty-printed + * documentation that includes those definitions. */ + +/** \defgroup platform Implementation-specific definitions + * @{ + */ + +/**@}*/ +#endif /* __DOXYGEN_ONLY__ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* The file "crypto_types.h" declares types that encode errors, + * algorithms, key types, policies, etc. */ +#include "crypto_types.h" + +/** \defgroup version API version + * @{ + */ + +/** + * The major version of this implementation of the PSA Crypto API + */ +#define PSA_CRYPTO_API_VERSION_MAJOR 1 + +/** + * The minor version of this implementation of the PSA Crypto API + */ +#define PSA_CRYPTO_API_VERSION_MINOR 0 + +/**@}*/ + +/* 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 + * @{ + */ + +/** + * \brief Library initialization. + * + * Applications must call this function before calling any other + * function in this module. + * + * Applications may call this function more than once. Once a call + * succeeds, subsequent calls are guaranteed to succeed. + * + * If the application calls other functions before calling psa_crypto_init(), + * the behavior is undefined. Implementations are encouraged to either perform + * the operation as if the library had been initialized or to return + * #PSA_ERROR_BAD_STATE or some other applicable error. In particular, + * implementations should not return a success status if the lack of + * initialization may have security implications, for example due to improper + * seeding of the random number generator. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + */ +psa_status_t psa_crypto_init(void); + +/**@}*/ + +/** \addtogroup attributes + * @{ + */ + +/** \def PSA_KEY_ATTRIBUTES_INIT + * + * This macro returns a suitable initializer for a key attribute structure + * of type #psa_key_attributes_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_KEY_ATTRIBUTES_INIT {0} +#endif + +/** Return an initial value for a key attributes structure. + */ +static psa_key_attributes_t psa_key_attributes_init(void); + +/** Declare a key as persistent and set its key identifier. + * + * If the attribute structure currently declares the key as volatile (which + * is the default content of an attribute structure), this function sets + * the lifetime attribute to #PSA_KEY_LIFETIME_PERSISTENT. + * + * This function does not access storage, it merely stores the given + * value in the structure. + * The persistent key will be written to storage when the attribute + * structure is passed to a key creation function such as + * psa_import_key(), psa_generate_key(), + * psa_key_derivation_output_key() or psa_copy_key(). + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param key The persistent identifier for the key. + */ +static void psa_set_key_id( psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t key ); + +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +/** Set the owner identifier of a key. + * + * When key identifiers encode key owner identifiers, psa_set_key_id() does + * not allow to define in key attributes the owner of volatile keys as + * psa_set_key_id() enforces the key to be persistent. + * + * This function allows to set in key attributes the owner identifier of a + * key. It is intended to be used for volatile keys. For persistent keys, + * it is recommended to use the PSA Cryptography API psa_set_key_id() to define + * the owner of a key. + * + * \param[out] attributes The attribute structure to write to. + * \param owner_id The key owner identifier. + */ +static void mbedtls_set_key_owner_id( psa_key_attributes_t *attributes, + mbedtls_key_owner_id_t owner_id ); +#endif + +/** Set the location of a persistent key. + * + * To make a key persistent, you must give it a persistent key identifier + * with psa_set_key_id(). By default, a key that has a persistent identifier + * is stored in the default storage area identifier by + * #PSA_KEY_LIFETIME_PERSISTENT. Call this function to choose a storage + * area, or to explicitly declare the key as volatile. + * + * This function does not access storage, it merely stores the given + * value in the structure. + * The persistent key will be written to storage when the attribute + * structure is passed to a key creation function such as + * psa_import_key(), psa_generate_key(), + * psa_key_derivation_output_key() or psa_copy_key(). + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param lifetime The lifetime for the key. + * If this is #PSA_KEY_LIFETIME_VOLATILE, the + * key will be volatile, and the key identifier + * attribute is reset to 0. + */ +static void psa_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime); + +/** Retrieve the key identifier from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The persistent identifier stored in the attribute structure. + * This value is unspecified if the attribute structure declares + * the key as volatile. + */ +static mbedtls_svc_key_id_t psa_get_key_id( + const psa_key_attributes_t *attributes); + +/** Retrieve the lifetime from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The lifetime value stored in the attribute structure. + */ +static psa_key_lifetime_t psa_get_key_lifetime( + const psa_key_attributes_t *attributes); + +/** Declare usage flags for a key. + * + * Usage flags are part of a key's usage policy. They encode what + * kind of operations are permitted on the key. For more details, + * refer to the documentation of the type #psa_key_usage_t. + * + * This function overwrites any usage flags + * previously set in \p attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param usage_flags The usage flags to write. + */ +static void psa_set_key_usage_flags(psa_key_attributes_t *attributes, + psa_key_usage_t usage_flags); + +/** Retrieve the usage flags from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The usage flags stored in the attribute structure. + */ +static psa_key_usage_t psa_get_key_usage_flags( + const psa_key_attributes_t *attributes); + +/** Declare the permitted algorithm policy for a key. + * + * The permitted algorithm policy of a key encodes which algorithm or + * algorithms are permitted to be used with this key. The following + * algorithm policies are supported: + * - 0 does not allow any cryptographic operation with the key. The key + * may be used for non-cryptographic actions such as exporting (if + * permitted by the usage flags). + * - An algorithm value permits this particular algorithm. + * - An algorithm wildcard built from #PSA_ALG_ANY_HASH allows the specified + * signature scheme with any hash algorithm. + * - An algorithm built from #PSA_ALG_AT_LEAST_THIS_LENGTH_MAC allows + * any MAC algorithm from the same base class (e.g. CMAC) which + * generates/verifies a MAC length greater than or equal to the length + * encoded in the wildcard algorithm. + * - An algorithm built from #PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG + * allows any AEAD algorithm from the same base class (e.g. CCM) which + * generates/verifies a tag length greater than or equal to the length + * encoded in the wildcard algorithm. + * + * This function overwrites any algorithm policy + * previously set in \p attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param alg The permitted algorithm policy to write. + */ +static void psa_set_key_algorithm(psa_key_attributes_t *attributes, + psa_algorithm_t alg); + + +/** Retrieve the algorithm policy from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The algorithm stored in the attribute structure. + */ +static psa_algorithm_t psa_get_key_algorithm( + const psa_key_attributes_t *attributes); + +/** Declare the type of a key. + * + * This function overwrites any key type + * previously set in \p attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param type The key type to write. + * If this is 0, the key type in \p attributes + * becomes unspecified. + */ +static void psa_set_key_type(psa_key_attributes_t *attributes, + psa_key_type_t type); + + +/** Declare the size of a key. + * + * This function overwrites any key size previously set in \p attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate each of its arguments exactly once. + * + * \param[out] attributes The attribute structure to write to. + * \param bits The key size in bits. + * If this is 0, the key size in \p attributes + * becomes unspecified. Keys of size 0 are + * not supported. + */ +static void psa_set_key_bits(psa_key_attributes_t *attributes, + size_t bits); + +/** Retrieve the key type from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The key type stored in the attribute structure. + */ +static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes); + +/** Retrieve the key size from key attributes. + * + * This function may be declared as `static` (i.e. without external + * linkage). This function may be provided as a function-like macro, + * but in this case it must evaluate its argument exactly once. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The key size stored in the attribute structure, in bits. + */ +static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); + +/** Retrieve the attributes of a key. + * + * This function first resets the attribute structure as with + * psa_reset_key_attributes(). It then copies the attributes of + * the given key into the given attribute structure. + * + * \note This function may allocate memory or other resources. + * Once you have called this function on an attribute structure, + * you must call psa_reset_key_attributes() to free these resources. + * + * \param[in] key Identifier of the key to query. + * \param[in,out] attributes On success, the attributes of the key. + * On failure, equivalent to a + * freshly-initialized structure. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_get_key_attributes(mbedtls_svc_key_id_t key, + psa_key_attributes_t *attributes); + +/** Reset a key attribute structure to a freshly initialized state. + * + * You must initialize the attribute structure as described in the + * documentation of the type #psa_key_attributes_t before calling this + * function. Once the structure has been initialized, you may call this + * function at any time. + * + * This function frees any auxiliary resources that the structure + * may contain. + * + * \param[in,out] attributes The attribute structure to reset. + */ +void psa_reset_key_attributes(psa_key_attributes_t *attributes); + +/**@}*/ + +/** \defgroup key_management Key management + * @{ + */ + +/** Remove non-essential copies of key material from memory. + * + * If the key identifier designates a volatile key, this functions does not do + * anything and returns successfully. + * + * If the key identifier designates a persistent key, then this function will + * free all resources associated with the key in volatile memory. The key + * data in persistent storage is not affected and the key can still be used. + * + * \param key Identifier of the key to purge. + * + * \retval #PSA_SUCCESS + * The key material will have been removed from memory if it is not + * currently required. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not a valid key identifier. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); + +/** Make a copy of a key. + * + * Copy key material from one location to another. + * + * This function is primarily useful to copy a key from one location + * to another, since it populates a key using the material from + * another key which may have a different lifetime. + * + * This function may be used to share a key with a different party, + * subject to implementation-defined restrictions on key sharing. + * + * The policy on the source key must have the usage flag + * #PSA_KEY_USAGE_COPY set. + * This flag is sufficient to permit the copy if the key has the lifetime + * #PSA_KEY_LIFETIME_VOLATILE or #PSA_KEY_LIFETIME_PERSISTENT. + * Some secure elements do not provide a way to copy a key without + * making it extractable from the secure element. If a key is located + * in such a secure element, then the key must have both usage flags + * #PSA_KEY_USAGE_COPY and #PSA_KEY_USAGE_EXPORT in order to make + * a copy of the key outside the secure element. + * + * The resulting key may only be used in a way that conforms to + * both the policy of the original key and the policy specified in + * the \p attributes parameter: + * - The usage flags on the resulting key are the bitwise-and of the + * usage flags on the source policy and the usage flags in \p attributes. + * - If both allow the same algorithm or wildcard-based + * algorithm policy, the resulting key has the same algorithm policy. + * - If either of the policies allows an algorithm and the other policy + * allows a wildcard-based algorithm policy that includes this algorithm, + * the resulting key allows the same algorithm. + * - If the policies do not allow any algorithm in common, this function + * fails with the status #PSA_ERROR_INVALID_ARGUMENT. + * + * The effect of this function on implementation-defined attributes is + * implementation-defined. + * + * \param source_key The key to copy. It must allow the usage + * #PSA_KEY_USAGE_COPY. If a private or secret key is + * being copied outside of a secure element it must + * also allow #PSA_KEY_USAGE_EXPORT. + * \param[in] attributes The attributes for the new key. + * They are used as follows: + * - The key type and size may be 0. If either is + * nonzero, it must match the corresponding + * attribute of the source key. + * - The key location (the lifetime and, for + * persistent keys, the key identifier) is + * used directly. + * - The policy constraints (usage flags and + * algorithm policy) are combined from + * the source key and \p attributes so that + * both sets of restrictions apply, as + * described in the documentation of this function. + * \param[out] target_key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \p source_key is invalid. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The lifetime or identifier in \p attributes are invalid. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The policy constraints on the source and specified in + * \p attributes are incompatible. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p attributes specifies a key type or key size + * which does not match the attributes of the source key. + * \retval #PSA_ERROR_NOT_PERMITTED + * The source key does not have the #PSA_KEY_USAGE_COPY usage flag. + * \retval #PSA_ERROR_NOT_PERMITTED + * The source key is not exportable and its lifetime does not + * allow copying it to the target's lifetime. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_copy_key(mbedtls_svc_key_id_t source_key, + const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *target_key); + + +/** + * \brief Destroy a key. + * + * This function destroys a key from both volatile + * memory and, if applicable, non-volatile storage. Implementations shall + * make a best effort to ensure that that the key material cannot be recovered. + * + * This function also erases any metadata such as policies and frees + * resources associated with the key. + * + * If a key is currently in use in a multipart operation, then destroying the + * key will cause the multipart operation to fail. + * + * \param key Identifier of the key to erase. If this is \c 0, do nothing and + * return #PSA_SUCCESS. + * + * \retval #PSA_SUCCESS + * \p key was a valid identifier and the key material that it + * referred to has been erased. Alternatively, \p key is \c 0. + * \retval #PSA_ERROR_NOT_PERMITTED + * The key cannot be erased because it is + * read-only, either due to a policy or due to physical restrictions. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p key is not a valid identifier nor \c 0. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * There was an failure in communication with the cryptoprocessor. + * The key material may still be present in the cryptoprocessor. + * \retval #PSA_ERROR_DATA_INVALID + * This error is typically a result of either storage corruption on a + * cleartext storage backend, or an attempt to read data that was + * written by an incompatible version of the library. + * \retval #PSA_ERROR_STORAGE_FAILURE + * The storage is corrupted. Implementations shall make a best effort + * to erase key material even in this stage, however applications + * should be aware that it may be impossible to guarantee that the + * key material is not recoverable in such cases. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * An unexpected condition which is not a storage corruption or + * a communication failure occurred. The cryptoprocessor may have + * been compromised. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); + +/**@}*/ + +/** \defgroup import_export Key import and export + * @{ + */ + +/** + * \brief Import a key in binary format. + * + * This function supports any output from psa_export_key(). Refer to the + * documentation of psa_export_public_key() for the format of public keys + * and to the documentation of psa_export_key() for the format for + * other key types. + * + * The key data determines the key size. The attributes may optionally + * specify a key size; in this case it must match the size determined + * from the key data. A key size of 0 in \p attributes indicates that + * the key size is solely determined by the key data. + * + * Implementations must reject an attempt to import a key of size 0. + * + * This specification supports a single format for each key type. + * Implementations may support other formats as long as the standard + * format is supported. Implementations that support other formats + * should ensure that the formats are clearly unambiguous so as to + * minimize the risk that an invalid input is accidentally interpreted + * according to a different format. + * + * \param[in] attributes The attributes for the new key. + * The key size is always determined from the + * \p data buffer. + * If the key size in \p attributes is nonzero, + * it must be equal to the size from \p data. + * \param[out] key On success, an identifier to the newly created key. + * For persistent keys, this is the key identifier + * defined in \p attributes. + * \c 0 on failure. + * \param[in] data Buffer containing the key data. The content of this + * buffer is interpreted according to the type declared + * in \p attributes. + * All implementations must support at least the format + * described in the documentation + * of psa_export_key() or psa_export_public_key() for + * the chosen type. Implementations may allow other + * formats, but should be conservative: implementations + * should err on the side of rejecting content if it + * may be erroneous (e.g. wrong type or truncated data). + * \param data_length Size of the \p data buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular persistent location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key attributes, as a whole, are invalid. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key data is not correctly formatted. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size in \p attributes is nonzero and does not match the size + * of the key data. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + mbedtls_svc_key_id_t *key); + + + +/** + * \brief Export a key in binary format. + * + * The output of this function can be passed to psa_import_key() to + * create an equivalent object. + * + * If the implementation of psa_import_key() supports other formats + * beyond the format specified here, the output from psa_export_key() + * must use the representation specified here, not the original + * representation. + * + * For standard key types, the output format is as follows: + * + * - For symmetric keys (including MAC keys), the format is the + * raw bytes of the key. + * - For DES, the key data consists of 8 bytes. The parity bits must be + * correct. + * - For Triple-DES, the format is the concatenation of the + * two or three DES keys. + * - For RSA key pairs (#PSA_KEY_TYPE_RSA_KEY_PAIR), the format + * is the non-encrypted DER encoding of the representation defined by + * PKCS\#1 (RFC 8017) as `RSAPrivateKey`, version 0. + * ``` + * RSAPrivateKey ::= SEQUENCE { + * version INTEGER, -- must be 0 + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * } + * ``` + * - For elliptic curve key pairs (key types for which + * #PSA_KEY_TYPE_IS_ECC_KEY_PAIR is true), the format is + * a representation of the private value as a `ceiling(m/8)`-byte string + * where `m` is the bit size associated with the curve, i.e. the bit size + * of the order of the curve's coordinate field. This byte string is + * in little-endian order for Montgomery curves (curve types + * `PSA_ECC_FAMILY_CURVEXXX`), and in big-endian order for Weierstrass + * curves (curve types `PSA_ECC_FAMILY_SECTXXX`, `PSA_ECC_FAMILY_SECPXXX` + * and `PSA_ECC_FAMILY_BRAINPOOL_PXXX`). + * For Weierstrass curves, this is the content of the `privateKey` field of + * the `ECPrivateKey` format defined by RFC 5915. For Montgomery curves, + * the format is defined by RFC 7748, and output is masked according to §5. + * For twisted Edwards curves, the private key is as defined by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). + * - For Diffie-Hellman key exchange key pairs (key types for which + * #PSA_KEY_TYPE_IS_DH_KEY_PAIR is true), the + * format is the representation of the private key `x` as a big-endian byte + * string. The length of the byte string is the private key size in bytes + * (leading zeroes are not stripped). + * - For public keys (key types for which #PSA_KEY_TYPE_IS_PUBLIC_KEY is + * true), the format is the same as for psa_export_public_key(). + * + * The policy on the key must have the usage flag #PSA_KEY_USAGE_EXPORT set. + * + * \param key Identifier of the key to export. It must allow the + * usage #PSA_KEY_USAGE_EXPORT, unless it is a public + * key. + * \param[out] data Buffer where the key data is to be written. + * \param data_size Size of the \p data buffer in bytes. + * \param[out] data_length On success, the number of bytes + * that make up the key data. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_EXPORT flag. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p data buffer is too small. You can determine a + * sufficient buffer size by calling + * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) + * where \c type is the key type + * and \c bits is the key size in bits. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_export_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length); + +/** + * \brief Export a public key or the public part of a key pair in binary format. + * + * The output of this function can be passed to psa_import_key() to + * create an object that is equivalent to the public key. + * + * This specification supports a single format for each key type. + * Implementations may support other formats as long as the standard + * format is supported. Implementations that support other formats + * should ensure that the formats are clearly unambiguous so as to + * minimize the risk that an invalid input is accidentally interpreted + * according to a different format. + * + * For standard key types, the output format is as follows: + * - For RSA public keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY), the DER encoding of + * the representation defined by RFC 3279 §2.3.1 as `RSAPublicKey`. + * ``` + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + * ``` + * - For elliptic curve keys on a twisted Edwards curve (key types for which + * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true and #PSA_KEY_TYPE_ECC_GET_FAMILY + * returns #PSA_ECC_FAMILY_TWISTED_EDWARDS), the public key is as defined + * by RFC 8032 + * (a 32-byte string for Edwards25519, a 57-byte string for Edwards448). + * - For other elliptic curve public keys (key types for which + * #PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY is true), the format is the uncompressed + * representation defined by SEC1 §2.3.3 as the content of an ECPoint. + * Let `m` be the bit size associated with the curve, i.e. the bit size of + * `q` for a curve over `F_q`. The representation consists of: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian. + * - For Diffie-Hellman key exchange public keys (key types for which + * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true), + * the format is the representation of the public key `y = g^x mod p` as a + * big-endian byte string. The length of the byte string is the length of the + * base prime `p` in bytes. + * + * Exporting a public key object or the public part of a key pair is + * always permitted, regardless of the key's usage flags. + * + * \param key Identifier of the key to export. + * \param[out] data Buffer where the key data is to be written. + * \param data_size Size of the \p data buffer in bytes. + * \param[out] data_length On success, the number of bytes + * that make up the key data. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is neither a public key nor a key pair. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p data buffer is too small. You can determine a + * sufficient buffer size by calling + * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) + * where \c type is the key type + * and \c bits is the key size in bits. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, + uint8_t *data, + size_t data_size, + size_t *data_length); + + + +/**@}*/ + +/** \defgroup hash Message digests + * @{ + */ + +/** Calculate the hash (digest) of a message. + * + * \note To verify the hash of a message against an + * expected value, use psa_hash_compare() instead. + * + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * \param[in] input Buffer containing the message to hash. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] hash Buffer where the hash is to be written. + * \param hash_size Size of the \p hash buffer in bytes. + * \param[out] hash_length On success, the number of bytes + * that make up the hash value. This is always + * #PSA_HASH_LENGTH(\p alg). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p hash_size is too small + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_compute(psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +/** Calculate the hash (digest) of a message and compare it with a + * reference value. + * + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * \param[in] input Buffer containing the message to hash. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] hash Buffer containing the expected hash value. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected hash is identical to the actual hash of the input. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The hash of the message was calculated successfully, but it + * differs from the expected hash. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p input_length or \p hash_length do not match the hash size for \p alg + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_compare(psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *hash, + size_t hash_length); + +/** The type of the state data structure for multipart hash operations. + * + * Before calling any function on a hash operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_hash_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_hash_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_HASH_OPERATION_INIT, + * for example: + * \code + * psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_hash_operation_init() + * to the structure, for example: + * \code + * psa_hash_operation_t operation; + * operation = psa_hash_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. */ +typedef struct psa_hash_operation_s psa_hash_operation_t; + +/** \def PSA_HASH_OPERATION_INIT + * + * This macro returns a suitable initializer for a hash operation object + * of type #psa_hash_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_HASH_OPERATION_INIT {0} +#endif + +/** Return an initial value for a hash operation object. + */ +static psa_hash_operation_t psa_hash_operation_init(void); + +/** Set up a multipart hash operation. + * + * The sequence of operations to calculate a hash (message digest) + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_hash_operation_t, e.g. #PSA_HASH_OPERATION_INIT. + * -# Call psa_hash_setup() to specify the algorithm. + * -# Call psa_hash_update() zero, one or more times, passing a fragment + * of the message each time. The hash that is calculated is the hash + * of the concatenation of these messages in order. + * -# To calculate the hash, call psa_hash_finish(). + * To compare the hash with an expected value, call psa_hash_verify(). + * + * If an error occurs at any step after a call to psa_hash_setup(), the + * operation will need to be reset by a call to psa_hash_abort(). The + * application may call psa_hash_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_hash_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_hash_finish() or psa_hash_verify(). + * - A call to psa_hash_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_hash_operation_t and not yet in use. + * \param alg The hash algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_HASH(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not a supported hash algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p alg is not a hash algorithm. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_setup(psa_hash_operation_t *operation, + psa_algorithm_t alg); + +/** Add a message fragment to a multipart hash operation. + * + * The application must call psa_hash_setup() before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \param[in,out] operation Active hash operation. + * \param[in] input Buffer containing the message fragment to hash. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it muct be active). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_update(psa_hash_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Finish the calculation of the hash of a message. + * + * The application must call psa_hash_setup() before calling this function. + * This function calculates the hash of the message formed by concatenating + * the inputs passed to preceding calls to psa_hash_update(). + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \warning Applications should not call this function if they expect + * a specific value for the hash. Call psa_hash_verify() instead. + * Beware that comparing integrity or authenticity data such as + * hash values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the hashed data which could allow an attacker to guess + * a valid hash and thereby bypass security controls. + * + * \param[in,out] operation Active hash operation. + * \param[out] hash Buffer where the hash is to be written. + * \param hash_size Size of the \p hash buffer in bytes. + * \param[out] hash_length On success, the number of bytes + * that make up the hash value. This is always + * #PSA_HASH_LENGTH(\c alg) where \c alg is the + * hash algorithm that is calculated. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p hash buffer is too small. You can determine a + * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) + * where \c alg is the hash algorithm that is calculated. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_finish(psa_hash_operation_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +/** Finish the calculation of the hash of a message and compare it with + * an expected value. + * + * The application must call psa_hash_setup() before calling this function. + * This function calculates the hash of the message formed by concatenating + * the inputs passed to preceding calls to psa_hash_update(). It then + * compares the calculated hash with the expected hash passed as a + * parameter to this function. + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_hash_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual hash and the expected hash is performed + * in constant time. + * + * \param[in,out] operation Active hash operation. + * \param[in] hash Buffer containing the expected hash value. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected hash is identical to the actual hash of the message. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The hash of the message was calculated successfully, but it + * differs from the expected hash. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_verify(psa_hash_operation_t *operation, + const uint8_t *hash, + size_t hash_length); + +/** Abort a hash operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_hash_setup() again. + * + * You may call this function any time after the operation object has + * been initialized by one of the methods described in #psa_hash_operation_t. + * + * In particular, calling psa_hash_abort() after the operation has been + * terminated by a call to psa_hash_abort(), psa_hash_finish() or + * psa_hash_verify() is safe and has no effect. + * + * \param[in,out] operation Initialized hash operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_abort(psa_hash_operation_t *operation); + +/** Clone a hash operation. + * + * This function copies the state of an ongoing hash operation to + * a new operation object. In other words, this function is equivalent + * to calling psa_hash_setup() on \p target_operation with the same + * algorithm that \p source_operation was set up for, then + * psa_hash_update() on \p target_operation with the same input that + * that was passed to \p source_operation. After this function returns, the + * two objects are independent, i.e. subsequent calls involving one of + * the objects do not affect the other object. + * + * \param[in] source_operation The active hash operation to clone. + * \param[in,out] target_operation The operation object to set up. + * It must be initialized but not active. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BAD_STATE + * The \p source_operation state is not valid (it must be active). + * \retval #PSA_ERROR_BAD_STATE + * The \p target_operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, + psa_hash_operation_t *target_operation); + +/**@}*/ + +/** \defgroup MAC Message authentication codes + * @{ + */ + +/** Calculate the MAC (message authentication code) of a message. + * + * \note To verify the MAC of a message against an + * expected value, use psa_mac_verify() instead. + * Beware that comparing integrity or authenticity data such as + * MAC values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the MAC value which could allow an attacker to guess + * a valid MAC and thereby bypass security controls. + * + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * \param[in] input Buffer containing the input message. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p mac_size is too small + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +/** Calculate the MAC of a message and compare it with a reference value. + * + * \param key Identifier of the key to use for the operation. It + * must allow the usage PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * \param[in] input Buffer containing the input message. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] mac Buffer containing the expected MAC value. + * \param mac_length Size of the \p mac buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected MAC is identical to the actual MAC of the input. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The MAC of the message was calculated successfully, but it + * differs from the expected value. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *mac, + size_t mac_length); + +/** The type of the state data structure for multipart MAC operations. + * + * Before calling any function on a MAC operation object, the application must + * initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_mac_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_mac_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_MAC_OPERATION_INIT, + * for example: + * \code + * psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_mac_operation_init() + * to the structure, for example: + * \code + * psa_mac_operation_t operation; + * operation = psa_mac_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. */ +typedef struct psa_mac_operation_s psa_mac_operation_t; + +/** \def PSA_MAC_OPERATION_INIT + * + * This macro returns a suitable initializer for a MAC operation object of type + * #psa_mac_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_MAC_OPERATION_INIT {0} +#endif + +/** Return an initial value for a MAC operation object. + */ +static psa_mac_operation_t psa_mac_operation_init(void); + +/** Set up a multipart MAC calculation operation. + * + * This function sets up the calculation of the MAC + * (message authentication code) of a byte string. + * To verify the MAC of a message against an + * expected value, use psa_mac_verify_setup() instead. + * + * The sequence of operations to calculate a MAC is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. + * -# Call psa_mac_sign_setup() to specify the algorithm and key. + * -# Call psa_mac_update() zero, one or more times, passing a fragment + * of the message each time. The MAC that is calculated is the MAC + * of the concatenation of these messages in order. + * -# At the end of the message, call psa_mac_sign_finish() to finish + * calculating the MAC value and retrieve it. + * + * If an error occurs at any step after a call to psa_mac_sign_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_mac_sign_setup(), the application must + * eventually terminate the operation through one of the following methods: + * - A successful call to psa_mac_sign_finish(). + * - A call to psa_mac_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage PSA_KEY_USAGE_SIGN_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set up a multipart MAC verification operation. + * + * This function sets up the verification of the MAC + * (message authentication code) of a byte string against an expected value. + * + * The sequence of operations to verify a MAC is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_mac_operation_t, e.g. #PSA_MAC_OPERATION_INIT. + * -# Call psa_mac_verify_setup() to specify the algorithm and key. + * -# Call psa_mac_update() zero, one or more times, passing a fragment + * of the message each time. The MAC that is calculated is the MAC + * of the concatenation of these messages in order. + * -# At the end of the message, call psa_mac_verify_finish() to finish + * calculating the actual MAC of the message and verify it against + * the expected value. + * + * If an error occurs at any step after a call to psa_mac_verify_setup(), the + * operation will need to be reset by a call to psa_mac_abort(). The + * application may call psa_mac_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_mac_verify_setup(), the application must + * eventually terminate the operation through one of the following methods: + * - A successful call to psa_mac_verify_finish(). + * - A call to psa_mac_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_mac_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. It + * must remain valid until the operation terminates. + * It must allow the usage + * PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c key is not compatible with \c alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a MAC algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * The key could not be retrieved from storage + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Add a message fragment to a multipart MAC operation. + * + * The application must call psa_mac_sign_setup() or psa_mac_verify_setup() + * before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \param[in,out] operation Active MAC operation. + * \param[in] input Buffer containing the message fragment to add to + * the MAC calculation. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_update(psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Finish the calculation of the MAC of a message. + * + * The application must call psa_mac_sign_setup() before calling this function. + * This function calculates the MAC of the message formed by concatenating + * the inputs passed to preceding calls to psa_mac_update(). + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \warning Applications should not call this function if they expect + * a specific value for the MAC. Call psa_mac_verify_finish() instead. + * Beware that comparing integrity or authenticity data such as + * MAC values with a function such as \c memcmp is risky + * because the time taken by the comparison may leak information + * about the MAC value which could allow an attacker to guess + * a valid MAC and thereby bypass security controls. + * + * \param[in,out] operation Active MAC operation. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. This is always + * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of the key and \c alg is the + * MAC algorithm that is calculated. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac sign + * operation). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p mac buffer is too small. You can determine a + * sufficient buffer size by calling PSA_MAC_LENGTH(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +/** Finish the calculation of the MAC of a message and compare it with + * an expected value. + * + * The application must call psa_mac_verify_setup() before calling this function. + * This function calculates the MAC of the message formed by concatenating + * the inputs passed to preceding calls to psa_mac_update(). It then + * compares the calculated MAC with the expected MAC passed as a + * parameter to this function. + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual MAC and the expected MAC is performed + * in constant time. + * + * \param[in,out] operation Active MAC operation. + * \param[in] mac Buffer containing the expected MAC value. + * \param mac_length Size of the \p mac buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected MAC is identical to the actual MAC of the message. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The MAC of the message was calculated successfully, but it + * differs from the expected MAC. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac verify + * operation). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length); + +/** Abort a MAC operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_mac_sign_setup() or psa_mac_verify_setup() again. + * + * You may call this function any time after the operation object has + * been initialized by one of the methods described in #psa_mac_operation_t. + * + * In particular, calling psa_mac_abort() after the operation has been + * terminated by a call to psa_mac_abort(), psa_mac_sign_finish() or + * psa_mac_verify_finish() is safe and has no effect. + * + * \param[in,out] operation Initialized MAC operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_mac_abort(psa_mac_operation_t *operation); + +/**@}*/ + +/** \defgroup cipher Symmetric ciphers + * @{ + */ + +/** Encrypt a message using a symmetric cipher. + * + * This function encrypts a message with a random IV (initialization + * vector). Use the multipart operation interface with a + * #psa_cipher_operation_t object to provide other forms of IV. + * + * \param key Identifier of the key to use for the operation. + * It must allow the usage #PSA_KEY_USAGE_ENCRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param[in] input Buffer containing the message to encrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * The output contains the IV followed by + * the ciphertext proper. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Decrypt a message using a symmetric cipher. + * + * This function decrypts a message encrypted with a symmetric cipher. + * + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param[in] input Buffer containing the message to decrypt. + * This consists of the IV followed by the + * ciphertext proper. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the plaintext is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** The type of the state data structure for multipart cipher operations. + * + * Before calling any function on a cipher operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_cipher_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_cipher_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_CIPHER_OPERATION_INIT, + * for example: + * \code + * psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_cipher_operation_init() + * to the structure, for example: + * \code + * psa_cipher_operation_t operation; + * operation = psa_cipher_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. */ +typedef struct psa_cipher_operation_s psa_cipher_operation_t; + +/** \def PSA_CIPHER_OPERATION_INIT + * + * This macro returns a suitable initializer for a cipher operation object of + * type #psa_cipher_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_CIPHER_OPERATION_INIT {0} +#endif + +/** Return an initial value for a cipher operation object. + */ +static psa_cipher_operation_t psa_cipher_operation_init(void); + +/** Set the key for a multipart symmetric encryption operation. + * + * The sequence of operations to encrypt a message with a symmetric cipher + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * #PSA_CIPHER_OPERATION_INIT. + * -# Call psa_cipher_encrypt_setup() to specify the algorithm and key. + * -# Call either psa_cipher_generate_iv() or psa_cipher_set_iv() to + * generate or set the IV (initialization vector). You should use + * psa_cipher_generate_iv() unless the protocol you are implementing + * requires a specific IV value. + * -# Call psa_cipher_update() zero, one or more times, passing a fragment + * of the message each time. + * -# Call psa_cipher_finish(). + * + * If an error occurs at any step after a call to psa_cipher_encrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_cipher_encrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set the key for a multipart symmetric decryption operation. + * + * The sequence of operations to decrypt a message with a symmetric cipher + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_cipher_operation_t, e.g. + * #PSA_CIPHER_OPERATION_INIT. + * -# Call psa_cipher_decrypt_setup() to specify the algorithm and key. + * -# Call psa_cipher_set_iv() with the IV (initialization vector) for the + * decryption. If the IV is prepended to the ciphertext, you can call + * psa_cipher_update() on a buffer containing the IV followed by the + * beginning of the message. + * -# Call psa_cipher_update() zero, one or more times, passing a fragment + * of the message each time. + * -# Call psa_cipher_finish(). + * + * If an error occurs at any step after a call to psa_cipher_decrypt_setup(), + * the operation will need to be reset by a call to psa_cipher_abort(). The + * application may call psa_cipher_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_cipher_decrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_cipher_finish(). + * - A call to psa_cipher_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not a cipher algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Generate an IV for a symmetric encryption operation. + * + * This function generates a random IV (initialization vector), nonce + * or initial counter value for the encryption operation as appropriate + * for the chosen algorithm, key type and key size. + * + * The application must call psa_cipher_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[out] iv Buffer where the generated IV is to be written. + * \param iv_size Size of the \p iv buffer in bytes. + * \param[out] iv_length On success, the number of bytes of the + * generated IV. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with no IV set). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p iv buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, + uint8_t *iv, + size_t iv_size, + size_t *iv_length); + +/** Set the IV for a symmetric encryption or decryption operation. + * + * This function sets the IV (initialization vector), nonce + * or initial counter value for the encryption or decryption operation. + * + * The application must call psa_cipher_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \note When encrypting, applications should use psa_cipher_generate_iv() + * instead of this function, unless implementing a protocol that requires + * a non-random IV. + * + * \param[in,out] operation Active cipher operation. + * \param[in] iv Buffer containing the IV to use. + * \param iv_length Size of the IV in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active cipher + * encrypt operation, with no IV set). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size of \p iv is not acceptable for the chosen algorithm, + * or the chosen algorithm does not use an IV. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, + const uint8_t *iv, + size_t iv_length); + +/** Encrypt or decrypt a message fragment in an active cipher operation. + * + * Before calling this function, you must: + * 1. Call either psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup(). + * The choice of setup function determines whether this function + * encrypts or decrypts its input. + * 2. If the algorithm requires an IV, call psa_cipher_generate_iv() + * (recommended when encrypting) or psa_cipher_set_iv(). + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[in] input Buffer containing the message fragment to + * encrypt or decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Finish encrypting or decrypting a message in a cipher operation. + * + * The application must call psa_cipher_encrypt_setup() or + * psa_cipher_decrypt_setup() before calling this function. The choice + * of setup function determines whether this function encrypts or + * decrypts its input. + * + * This function finishes the encryption or decryption of the message + * formed by concatenating the inputs passed to preceding calls to + * psa_cipher_update(). + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_cipher_abort(). + * + * \param[in,out] operation Active cipher operation. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input size passed to this operation is not valid for + * this particular algorithm. For example, the algorithm is a based + * on block cipher and requires a whole number of blocks, but the + * total input size is not a multiple of the block size. + * \retval #PSA_ERROR_INVALID_PADDING + * This is a decryption operation for an algorithm that includes + * padding, and the ciphertext does not contain valid padding. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with an IV set + * if required for the algorithm). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Abort a cipher operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_cipher_encrypt_setup() or psa_cipher_decrypt_setup() again. + * + * You may call this function any time after the operation object has + * been initialized as described in #psa_cipher_operation_t. + * + * In particular, calling psa_cipher_abort() after the operation has been + * terminated by a call to psa_cipher_abort() or psa_cipher_finish() + * is safe and has no effect. + * + * \param[in,out] operation Initialized cipher operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); + +/**@}*/ + +/** \defgroup aead Authenticated encryption with associated data (AEAD) + * @{ + */ + +/** Process an authenticated encryption operation. + * + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the \p nonce buffer in bytes. + * \param[in] additional_data Additional data that will be authenticated + * but not encrypted. + * \param additional_data_length Size of \p additional_data in bytes. + * \param[in] plaintext Data that will be authenticated and + * encrypted. + * \param plaintext_length Size of \p 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 ciphertext_size Size of the \p ciphertext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p plaintext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p + * plaintext_length) evaluates to the maximum + * ciphertext size of any supported AEAD + * encryption. + * \param[out] ciphertext_length On success, the size of the output + * in the \p ciphertext buffer. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p ciphertext_size is too small. + * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p plaintext_length) or + * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to + * determine the required buffer size. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, + 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. + * + * \param key Identifier of the key to use for the + * operation. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the \p nonce buffer in bytes. + * \param[in] additional_data Additional data that has been authenticated + * but not encrypted. + * \param additional_data_length Size of \p additional_data in bytes. + * \param[in] ciphertext Data that has been authenticated and + * encrypted. For algorithms where the + * encrypted data and the authentication tag + * are defined as separate inputs, the buffer + * must contain the encrypted data followed + * by the authentication tag. + * \param ciphertext_length Size of \p ciphertext in bytes. + * \param[out] plaintext Output buffer for the decrypted data. + * \param plaintext_size Size of the \p plaintext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, + * \p alg, \p ciphertext_length) where + * \c key_type is the type of \p key. + * - #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p + * ciphertext_length) evaluates to the maximum + * plaintext size of any supported AEAD + * decryption. + * \param[out] plaintext_length On success, the size of the output + * in the \p plaintext buffer. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The ciphertext is not authentic. + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p plaintext_size is too small. + * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, + * \p ciphertext_length) or + * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used + * to determine the required buffer size. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, + 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); + +/** The type of the state data structure for multipart AEAD operations. + * + * Before calling any function on an AEAD operation object, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_aead_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_aead_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_AEAD_OPERATION_INIT, + * for example: + * \code + * psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_aead_operation_init() + * to the structure, for example: + * \code + * psa_aead_operation_t operation; + * operation = psa_aead_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. */ +typedef struct psa_aead_operation_s psa_aead_operation_t; + +/** \def PSA_AEAD_OPERATION_INIT + * + * This macro returns a suitable initializer for an AEAD operation object of + * type #psa_aead_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_AEAD_OPERATION_INIT {0} +#endif + +/** Return an initial value for an AEAD operation object. + */ +static psa_aead_operation_t psa_aead_operation_init(void); + +/** Set the key for a multipart authenticated encryption operation. + * + * The sequence of operations to encrypt a message with authentication + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_aead_operation_t, e.g. + * #PSA_AEAD_OPERATION_INIT. + * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. + * -# If needed, call psa_aead_set_lengths() to specify the length of the + * inputs to the subsequent calls to psa_aead_update_ad() and + * psa_aead_update(). See the documentation of psa_aead_set_lengths() + * for details. + * -# Call either psa_aead_generate_nonce() or psa_aead_set_nonce() to + * generate or set the nonce. You should use + * psa_aead_generate_nonce() unless the protocol you are implementing + * requires a specific nonce value. + * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment + * of the non-encrypted additional authenticated data each time. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the message to encrypt each time. + * -# Call psa_aead_finish(). + * + * If an error occurs at any step after a call to psa_aead_encrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_aead_encrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_aead_finish(). + * - A call to psa_aead_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_aead_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Set the key for a multipart authenticated decryption operation. + * + * The sequence of operations to decrypt a message with authentication + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Initialize the operation object with one of the methods described in the + * documentation for #psa_aead_operation_t, e.g. + * #PSA_AEAD_OPERATION_INIT. + * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. + * -# If needed, call psa_aead_set_lengths() to specify the length of the + * inputs to the subsequent calls to psa_aead_update_ad() and + * psa_aead_update(). See the documentation of psa_aead_set_lengths() + * for details. + * -# Call psa_aead_set_nonce() with the nonce for the decryption. + * -# Call psa_aead_update_ad() zero, one or more times, passing a fragment + * of the non-encrypted additional authenticated data each time. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the ciphertext to decrypt each time. + * -# Call psa_aead_verify(). + * + * If an error occurs at any step after a call to psa_aead_decrypt_setup(), + * the operation will need to be reset by a call to psa_aead_abort(). The + * application may call psa_aead_abort() at any time after the operation + * has been initialized. + * + * After a successful call to psa_aead_decrypt_setup(), the application must + * eventually terminate the operation. The following events terminate an + * operation: + * - A successful call to psa_aead_verify(). + * - A call to psa_aead_abort(). + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_aead_operation_t and not yet in use. + * \param key Identifier of the key to use for the operation. + * It must remain valid until the operation + * terminates. It must allow the usage + * #PSA_KEY_USAGE_DECRYPT. + * \param alg The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported or is not an AEAD algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg); + +/** Generate a random nonce for an authenticated encryption operation. + * + * This function generates a random nonce for the authenticated encryption + * operation with an appropriate size for the chosen algorithm, key type + * and key size. + * + * The application must call psa_aead_encrypt_setup() before + * calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param[out] nonce Buffer where the generated nonce is to be + * written. + * \param nonce_size Size of the \p nonce buffer in bytes. + * \param[out] nonce_length On success, the number of bytes of the + * generated nonce. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active aead encrypt + * operation, with no nonce set). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p nonce buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, + uint8_t *nonce, + size_t nonce_size, + size_t *nonce_length); + +/** Set the nonce for an authenticated encryption or decryption operation. + * + * This function sets the nonce for the authenticated + * encryption or decryption operation. + * + * The application must call psa_aead_encrypt_setup() or + * psa_aead_decrypt_setup() before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \note When encrypting, applications should use psa_aead_generate_nonce() + * instead of this function, unless implementing a protocol that requires + * a non-random IV. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] nonce Buffer containing the nonce to use. + * \param nonce_length Size of the nonce in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, with no nonce + * set). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size of \p nonce is not acceptable for the chosen algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, + const uint8_t *nonce, + size_t nonce_length); + +/** Declare the lengths of the message and additional data for AEAD. + * + * The application must call this function before calling + * psa_aead_update_ad() or psa_aead_update() if the algorithm for + * the operation requires it. If the algorithm does not require it, + * calling this function is optional, but if this function is called + * then the implementation must enforce the lengths. + * + * You may call this function before or after setting the nonce with + * psa_aead_set_nonce() or psa_aead_generate_nonce(). + * + * - For #PSA_ALG_CCM, calling this function is required. + * - For the other AEAD algorithms defined in this specification, calling + * this function is not required. + * - For vendor-defined algorithm, refer to the vendor documentation. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param ad_length Size of the non-encrypted additional + * authenticated data in bytes. + * \param plaintext_length Size of the plaintext to encrypt in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, and + * psa_aead_update_ad() and psa_aead_update() must not have been + * called yet). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * At least one of the lengths is not acceptable for the chosen + * algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, + size_t ad_length, + size_t plaintext_length); + +/** Pass additional data to an active AEAD operation. + * + * Additional data is authenticated, but not encrypted. + * + * You may call this function multiple times to pass successive fragments + * of the additional data. You may not call this function after passing + * data to encrypt or decrypt with psa_aead_update(). + * + * Before calling this function, you must: + * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). + * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, + * there is no guarantee that the input is valid. Therefore, until + * you have called psa_aead_verify() and it has returned #PSA_SUCCESS, + * treat the input as untrusted and prepare to undo any action that + * depends on the input if psa_aead_verify() returns an error status. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] input Buffer containing the fragment of + * additional data. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, have a nonce + * set, have lengths set if required by the algorithm, and + * psa_aead_update() must not have been called yet). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input length overflows the additional data length that + * was previously specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length); + +/** Encrypt or decrypt a message fragment in an active AEAD operation. + * + * Before calling this function, you must: + * 1. Call either psa_aead_encrypt_setup() or psa_aead_decrypt_setup(). + * The choice of setup function determines whether this function + * encrypts or decrypts its input. + * 2. Set the nonce with psa_aead_generate_nonce() or psa_aead_set_nonce(). + * 3. Call psa_aead_update_ad() to pass all the additional data. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \warning When decrypting, until psa_aead_verify() has returned #PSA_SUCCESS, + * there is no guarantee that the input is valid. Therefore, until + * you have called psa_aead_verify() and it has returned #PSA_SUCCESS: + * - Do not use the output in any way other than storing it in a + * confidential location. If you take any action that depends + * on the tentative decrypted data, this action will need to be + * undone if the input turns out not to be valid. Furthermore, + * if an adversary can observe that this action took place + * (for example through timing), they may be able to use this + * fact as an oracle to decrypt any message encrypted with the + * same key. + * - In particular, do not copy the output anywhere but to a + * memory or storage space that you have exclusive access to. + * + * This function does not require the input to be aligned to any + * particular block boundary. If the implementation can only process + * a whole block at a time, it must consume all the input provided, but + * it may delay the end of the corresponding output until a subsequent + * call to psa_aead_update(), psa_aead_finish() or psa_aead_verify() + * provides sufficient input. The amount of data that can be delayed + * in this way is bounded by #PSA_AEAD_UPDATE_OUTPUT_SIZE. + * + * \param[in,out] operation Active AEAD operation. + * \param[in] input Buffer containing the message fragment to + * encrypt or decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * \param output_size Size of the \p output buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, + * \c alg, \p input_length) where + * \c key_type is the type of key and \c alg is + * the algorithm that were used to set up the + * operation. + * - #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p + * input_length) evaluates to the maximum + * output size of any supported AEAD + * algorithm. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active, have a nonce + * set, and have lengths set if required by the algorithm). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * #PSA_AEAD_UPDATE_OUTPUT_SIZE(\c key_type, \c alg, \p input_length) or + * #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length) can be used to + * determine the required buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input length overflows the plaintext length that + * was previously specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_update(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** Finish encrypting a message in an AEAD operation. + * + * The operation must have been set up with psa_aead_encrypt_setup(). + * + * This function finishes the authentication of the additional data + * formed by concatenating the inputs passed to preceding calls to + * psa_aead_update_ad() with the plaintext formed by concatenating the + * inputs passed to preceding calls to psa_aead_update(). + * + * This function has two output buffers: + * - \p ciphertext contains trailing ciphertext that was buffered from + * preceding calls to psa_aead_update(). + * - \p tag contains the authentication tag. + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \param[in,out] operation Active AEAD operation. + * \param[out] ciphertext Buffer where the last part of the ciphertext + * is to be written. + * \param ciphertext_size Size of the \p ciphertext buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. + * \param[out] ciphertext_length On success, the number of bytes of + * returned ciphertext. + * \param[out] tag Buffer where the authentication tag is + * to be written. + * \param tag_size Size of the \p tag buffer in bytes. + * This must be appropriate for the selected + * algorithm and key: + * - The exact tag size is #PSA_AEAD_TAG_LENGTH(\c + * key_type, \c key_bits, \c alg) where + * \c key_type and \c key_bits are the type and + * bit-size of the key, and \c alg is the + * algorithm that were used in the call to + * psa_aead_encrypt_setup(). + * - #PSA_AEAD_TAG_MAX_SIZE evaluates to the + * maximum tag size of any supported AEAD + * algorithm. + * \param[out] tag_length On success, the number of bytes + * that make up the returned tag. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active encryption + * operation with a nonce set). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p ciphertext or \p tag buffer is too small. + * #PSA_AEAD_FINISH_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE can be used to determine the + * required \p ciphertext buffer size. #PSA_AEAD_TAG_LENGTH(\c key_type, + * \c key_bits, \c alg) or #PSA_AEAD_TAG_MAX_SIZE can be used to + * determine the required \p tag buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update() so far is + * less than the plaintext length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_finish(psa_aead_operation_t *operation, + uint8_t *ciphertext, + size_t ciphertext_size, + size_t *ciphertext_length, + uint8_t *tag, + size_t tag_size, + size_t *tag_length); + +/** Finish authenticating and decrypting a message in an AEAD operation. + * + * The operation must have been set up with psa_aead_decrypt_setup(). + * + * This function finishes the authenticated decryption of the message + * components: + * + * - The additional data consisting of the concatenation of the inputs + * passed to preceding calls to psa_aead_update_ad(). + * - The ciphertext consisting of the concatenation of the inputs passed to + * preceding calls to psa_aead_update(). + * - The tag passed to this function call. + * + * If the authentication tag is correct, this function outputs any remaining + * plaintext and reports success. If the authentication tag is not correct, + * this function returns #PSA_ERROR_INVALID_SIGNATURE. + * + * When this function returns successfuly, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_aead_abort(). + * + * \note Implementations shall make the best effort to ensure that the + * comparison between the actual tag and the expected tag is performed + * in constant time. + * + * \param[in,out] operation Active AEAD operation. + * \param[out] plaintext Buffer where the last part of the plaintext + * is to be written. This is the remaining data + * from previous calls to psa_aead_update() + * that could not be processed until the end + * of the input. + * \param plaintext_size Size of the \p plaintext buffer in bytes. + * This must be appropriate for the selected algorithm and key: + * - A sufficient output size is + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, + * \c alg) where \c key_type is the type of key + * and \c alg is the algorithm that were used to + * set up the operation. + * - #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE evaluates to + * the maximum output size of any supported AEAD + * algorithm. + * \param[out] plaintext_length On success, the number of bytes of + * returned plaintext. + * \param[in] tag Buffer containing the authentication tag. + * \param tag_length Size of the \p tag buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculations were successful, but the authentication tag is + * not correct. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active decryption + * operation with a nonce set). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p plaintext buffer is too small. + * #PSA_AEAD_VERIFY_OUTPUT_SIZE(\c key_type, \c alg) or + * #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE can be used to determine the + * required buffer size. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update_ad() so far is + * less than the additional data length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total length of input to psa_aead_update() so far is + * less than the plaintext length that was previously + * specified with psa_aead_set_lengths(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_verify(psa_aead_operation_t *operation, + uint8_t *plaintext, + size_t plaintext_size, + size_t *plaintext_length, + const uint8_t *tag, + size_t tag_length); + +/** Abort an AEAD operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * psa_aead_encrypt_setup() or psa_aead_decrypt_setup() again. + * + * You may call this function any time after the operation object has + * been initialized as described in #psa_aead_operation_t. + * + * In particular, calling psa_aead_abort() after the operation has been + * terminated by a call to psa_aead_abort(), psa_aead_finish() or + * psa_aead_verify() is safe and has no effect. + * + * \param[in,out] operation Initialized AEAD operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_aead_abort(psa_aead_operation_t *operation); + +/**@}*/ + +/** \defgroup asymmetric Asymmetric cryptography + * @{ + */ + +/** + * \brief Sign a message with a private key. For hash-and-sign algorithms, + * this includes the hashing step. + * + * \note To perform a multi-part hash-and-sign signature algorithm, first use + * a multi-part hash operation and then pass the resulting hash to + * psa_sign_hash(). PSA_ALG_GET_HASH(\p alg) can be used to determine the + * hash algorithm to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The input message to sign. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] signature Buffer where the signature is to be written. + * \param[in] signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key: + * - The required signature size is + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of key. + * - #PSA_SIGNATURE_MAX_SIZE evaluates to the + * maximum signature size of any supported + * signature algorithm. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_message( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t * input, + size_t input_length, + uint8_t * signature, + size_t signature_size, + size_t * signature_length ); + +/** \brief Verify the signature of a message with a public key, using + * a hash-and-sign verification algorithm. + * + * \note To perform a multi-part hash-and-sign signature verification + * algorithm, first use a multi-part hash operation to hash the message + * and then pass the resulting hash to psa_verify_hash(). + * PSA_ALG_GET_HASH(\p alg) can be used to determine the hash algorithm + * to use. + * + * \param[in] key Identifier of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. The key must allow the usage + * #PSA_KEY_USAGE_VERIFY_MESSAGE. + * \param[in] alg An asymmetric signature algorithm (PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_MESSAGE(\p alg) + * is true), that is compatible with the type of + * \p key. + * \param[in] input The message whose signature is to be verified. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] signature Buffer containing the signature to verify. + * \param[in] signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, + * or it does not permit the requested algorithm. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed signature + * is not a valid signature. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_message( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t * input, + size_t input_length, + const uint8_t * signature, + size_t signature_length ); + +/** + * \brief Sign a hash or short message with a private key. + * + * Note that to perform a hash-and-sign signature algorithm, you must + * first calculate the hash by calling psa_hash_setup(), psa_hash_update() + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash + * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) + * to determine the hash algorithm to use. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_HASH. + * \param alg A signature algorithm that is compatible with + * the type of \p key. + * \param[in] hash The hash or message to sign. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[out] signature Buffer where the signature is to be written. + * \param signature_size Size of the \p signature buffer in bytes. + * \param[out] signature_length On success, the number of bytes + * that make up the returned signature value. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length); + +/** + * \brief Verify the signature of a hash or short message using a public key. + * + * Note that to perform a hash-and-sign signature algorithm, you must + * first calculate the hash by calling psa_hash_setup(), psa_hash_update() + * and psa_hash_finish(), or alternatively by calling psa_hash_compute(). + * Then pass the resulting hash as the \p hash + * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) + * to determine the hash algorithm to use. + * + * \param key Identifier of the key to use for the operation. It + * must be a public key or an asymmetric key pair. The + * key must allow the usage + * #PSA_KEY_USAGE_VERIFY_HASH. + * \param alg A signature algorithm that is compatible with + * the type of \p key. + * \param[in] hash The hash or message whose signature is to be + * verified. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * The signature is valid. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was perfomed successfully, but the passed + * signature is not a valid signature. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + const uint8_t *signature, + size_t signature_length); + +/** + * \brief Encrypt a short message with a public key. + * + * \param key Identifer of the key to use for the operation. + * It must be a public key or an asymmetric key + * pair. It must allow the usage + * #PSA_KEY_USAGE_ENCRYPT. + * \param alg An asymmetric encryption algorithm that is + * compatible with the type of \p key. + * \param[in] input The message to encrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[in] salt A salt or label, if supported by the + * encryption algorithm. + * If the algorithm does not support a + * salt, pass \c NULL. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass \c NULL. + * + * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param salt_length Size of the \p salt buffer in bytes. + * If \p salt is \c NULL, pass 0. + * \param[out] output Buffer where the encrypted message is to + * be written. + * \param output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *salt, + size_t salt_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/** + * \brief Decrypt a short message with a private key. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. It must + * allow the usage #PSA_KEY_USAGE_DECRYPT. + * \param alg An asymmetric encryption algorithm that is + * compatible with the type of \p key. + * \param[in] input The message to decrypt. + * \param input_length Size of the \p input buffer in bytes. + * \param[in] salt A salt or label, if supported by the + * encryption algorithm. + * If the algorithm does not support a + * salt, pass \c NULL. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass \c NULL. + * + * - For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param salt_length Size of the \p salt buffer in bytes. + * If \p salt is \c NULL, pass 0. + * \param[out] output Buffer where the decrypted message is to + * be written. + * \param output_size Size of the \c output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_INVALID_PADDING + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *salt, + size_t salt_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/**@}*/ + +/** \defgroup key_derivation Key derivation and pseudorandom generation + * @{ + */ + +/** The type of the state data structure for key derivation operations. + * + * Before calling any function on a key derivation operation object, the + * application must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_key_derivation_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_key_derivation_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_KEY_DERIVATION_OPERATION_INIT, + * for example: + * \code + * psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; + * \endcode + * - Assign the result of the function psa_key_derivation_operation_init() + * to the structure, for example: + * \code + * psa_key_derivation_operation_t operation; + * operation = psa_key_derivation_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. + */ +typedef struct psa_key_derivation_s psa_key_derivation_operation_t; + +/** \def PSA_KEY_DERIVATION_OPERATION_INIT + * + * This macro returns a suitable initializer for a key derivation operation + * object of type #psa_key_derivation_operation_t. + */ +#ifdef __DOXYGEN_ONLY__ +/* This is an example definition for documentation purposes. + * Implementations should define a suitable value in `crypto_struct.h`. + */ +#define PSA_KEY_DERIVATION_OPERATION_INIT {0} +#endif + +/** Return an initial value for a key derivation operation object. + */ +static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); + +/** Set up a key derivation operation. + * + * A key derivation algorithm takes some inputs and uses them to generate + * a byte stream in a deterministic way. + * This byte stream can be used to produce keys and other + * cryptographic material. + * + * To derive a key: + * -# Start with an initialized object of type #psa_key_derivation_operation_t. + * -# Call psa_key_derivation_setup() to select the algorithm. + * -# Provide the inputs for the key derivation by calling + * psa_key_derivation_input_bytes() or psa_key_derivation_input_key() + * as appropriate. Which inputs are needed, in what order, and whether + * they may be keys and if so of what type depends on the algorithm. + * -# Optionally set the operation's maximum capacity with + * psa_key_derivation_set_capacity(). You may do this before, in the middle + * of or after providing inputs. For some algorithms, this step is mandatory + * because the output depends on the maximum capacity. + * -# To derive a key, call psa_key_derivation_output_key(). + * To derive a byte string for a different purpose, call + * psa_key_derivation_output_bytes(). + * Successive calls to these functions use successive output bytes + * calculated by the key derivation algorithm. + * -# Clean up the key derivation operation object with + * psa_key_derivation_abort(). + * + * If this function returns an error, the key derivation operation object is + * not changed. + * + * If an error occurs at any step after a call to psa_key_derivation_setup(), + * the operation will need to be reset by a call to psa_key_derivation_abort(). + * + * Implementations must reject an attempt to derive a key of size 0. + * + * \param[in,out] operation The key derivation operation object + * to set up. It must + * have been initialized but not set up yet. + * \param alg The key derivation algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c alg is not a key derivation algorithm. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a key derivation algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_setup( + psa_key_derivation_operation_t *operation, + psa_algorithm_t alg); + +/** Retrieve the current capacity of a key derivation operation. + * + * The capacity of a key derivation is the maximum number of bytes that it can + * return. When you get *N* bytes of output from a key derivation operation, + * this reduces its capacity by *N*. + * + * \param[in] operation The operation to query. + * \param[out] capacity On success, the capacity of the operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *operation, + size_t *capacity); + +/** Set the maximum capacity of a key derivation operation. + * + * The capacity of a key derivation operation is the maximum number of bytes + * that the key derivation operation can return from this point onwards. + * + * \param[in,out] operation The key derivation operation object to modify. + * \param capacity The new capacity of the operation. + * It must be less or equal to the operation's + * current capacity. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p capacity is larger than the operation's current capacity. + * In this case, the operation object remains valid and its capacity + * remains unchanged. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *operation, + size_t capacity); + +/** Use the maximum possible capacity for a key derivation operation. + * + * Use this value as the capacity argument when setting up a key derivation + * to indicate that the operation should have the maximum possible capacity. + * The value of the maximum possible capacity depends on the key derivation + * algorithm. + */ +#define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ((size_t)(-1)) + +/** Provide an input for key derivation or key agreement. + * + * Which inputs are required and in what order depends on the algorithm. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function passes direct inputs, which is usually correct for + * non-secret inputs. To pass a secret input, which should be in a key + * object, call psa_key_derivation_input_key() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param[in] data Input data to use. + * \param data_length Size of the \p data buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step does not allow direct inputs. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + const uint8_t *data, + size_t data_length); + +/** Provide an input for key derivation in the form of a key. + * + * Which inputs are required and in what order depends on the algorithm. + * Refer to the documentation of each key derivation or key agreement + * algorithm for information. + * + * This function obtains input from a key object, which is usually correct for + * secret inputs or for non-secret personalization strings kept in the key + * store. To pass a non-secret parameter which is not in the key store, + * call psa_key_derivation_input_bytes() instead of this function. + * Refer to the documentation of individual step types + * (`PSA_KEY_DERIVATION_INPUT_xxx` values of type ::psa_key_derivation_step_t) + * for more information. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() and must not + * have produced any output yet. + * \param step Which step the input data is for. + * \param key Identifier of the key. It must have an + * appropriate type for step and must allow the + * usage #PSA_KEY_USAGE_DERIVE. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step is not compatible with the operation's algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step does not allow key inputs of the given type + * or does not allow key inputs at all. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this input \p step. + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_input_key( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t key); + +/** Perform a key agreement and use the shared secret as input to a key + * derivation. + * + * A key agreement algorithm takes two inputs: a private key \p private_key + * a public key \p peer_key. + * The result of this function is passed as input to a key derivation. + * The output of this key derivation can be extracted by reading from the + * resulting operation to produce keys and other cryptographic material. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to use. + * It must have been set up with + * psa_key_derivation_setup() with a + * key agreement and derivation algorithm + * \c alg (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_KEY_AGREEMENT(\c alg) is true + * and #PSA_ALG_IS_RAW_KEY_AGREEMENT(\c alg) + * is false). + * The operation must be ready for an + * input of the type given by \p step. + * \param step Which step the input data is for. + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. + * \param[in] peer_key Public key of the peer. The peer key must be in the + * same format that psa_import_key() accepts for the + * public key type corresponding to the type of + * private_key. That is, this function performs the + * equivalent of + * #psa_import_key(..., + * `peer_key`, `peer_key_length`) where + * with key attributes indicating the public key + * type corresponding to the type of `private_key`. + * For example, for EC keys, this means that peer_key + * is interpreted as a point on the curve that the + * private key is on. The standard formats for public + * keys are documented in the documentation of + * psa_export_public_key(). + * \param peer_key_length Size of \p peer_key in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid for this key agreement \p step. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c private_key is not compatible with \c alg, + * or \p peer_key is not valid for \c alg or not compatible with + * \c private_key. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \c alg is not supported or is not a key derivation algorithm. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \c step does not allow an input resulting from a key agreement. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *operation, + psa_key_derivation_step_t step, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, + size_t peer_key_length); + +/** Read some data from a key derivation operation. + * + * This function calculates output bytes from a key derivation algorithm and + * return those bytes. + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads the requested number of bytes from the + * stream. + * The operation's capacity decreases by the number of bytes read. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * \param[in,out] operation The key derivation operation object to read from. + * \param[out] output Buffer where the output will be written. + * \param output_length Number of bytes to output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * The operation's capacity was less than + * \p output_length bytes. Note that in this case, + * no output is written to the output buffer. + * The operation's capacity is set to 0, thus + * subsequent calls to this function will not + * succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *operation, + uint8_t *output, + size_t output_length); + +/** Derive a key from an ongoing key derivation operation. + * + * This function calculates output bytes from a key derivation algorithm + * and uses those bytes to generate a key deterministically. + * The key's location, usage policy, type and size are taken from + * \p attributes. + * + * If you view the key derivation's output as a stream of bytes, this + * function destructively reads as many bytes as required from the + * stream. + * The operation's capacity decreases by the number of bytes read. + * + * If this function returns an error status other than + * #PSA_ERROR_INSUFFICIENT_DATA, the operation enters an error + * state and must be aborted by calling psa_key_derivation_abort(). + * + * How much output is produced and consumed from the operation, and how + * the key is derived, depends on the key type and on the key size + * (denoted \c bits below): + * + * - For key types for which the key is an arbitrary sequence of bytes + * of a given size, this function is functionally equivalent to + * calling #psa_key_derivation_output_bytes + * and passing the resulting output to #psa_import_key. + * However, this function has a security benefit: + * if the implementation provides an isolation boundary then + * the key material is not exposed outside the isolation boundary. + * As a consequence, for these key types, this function always consumes + * exactly (\c bits / 8) bytes from the operation. + * The following key types defined in this specification follow this scheme: + * + * - #PSA_KEY_TYPE_AES; + * - #PSA_KEY_TYPE_ARC4; + * - #PSA_KEY_TYPE_CAMELLIA; + * - #PSA_KEY_TYPE_DERIVE; + * - #PSA_KEY_TYPE_HMAC. + * + * - For ECC keys on a Montgomery elliptic curve + * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a + * Montgomery curve), this function always draws a byte string whose + * length is determined by the curve, and sets the mandatory bits + * accordingly. That is: + * + * - Curve25519 (#PSA_ECC_FAMILY_MONTGOMERY, 255 bits): draw a 32-byte + * string and process it as specified in RFC 7748 §5. + * - Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte + * string and process it as specified in RFC 7748 §5. + * + * - For key types for which the key is represented by a single sequence of + * \c bits bits with constraints as to which bit sequences are acceptable, + * this function draws a byte string of length (\c bits / 8) bytes rounded + * up to the nearest whole number of bytes. If the resulting byte string + * is acceptable, it becomes the key, otherwise the drawn bytes are discarded. + * This process is repeated until an acceptable byte string is drawn. + * The byte string drawn from the operation is interpreted as specified + * for the output produced by psa_export_key(). + * The following key types defined in this specification follow this scheme: + * + * - #PSA_KEY_TYPE_DES. + * Force-set the parity bits, but discard forbidden weak keys. + * For 2-key and 3-key triple-DES, the three keys are generated + * successively (for example, for 3-key triple-DES, + * if the first 8 bytes specify a weak key and the next 8 bytes do not, + * discard the first 8 bytes, use the next 8 bytes as the first key, + * and continue reading output from the operation to derive the other + * two keys). + * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group) + * where \c group designates any Diffie-Hellman group) and + * ECC keys on a Weierstrass elliptic curve + * (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a + * Weierstrass curve). + * For these key types, interpret the byte string as integer + * in big-endian order. Discard it if it is not in the range + * [0, *N* - 2] where *N* is the boundary of the private key domain + * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, + * or the order of the curve's base point for ECC). + * Add 1 to the resulting integer and use this as the private key *x*. + * This method allows compliance to NIST standards, specifically + * the methods titled "key-pair generation by testing candidates" + * in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, + * in FIPS 186-4 §B.1.2 for DSA, and + * in NIST SP 800-56A §5.6.1.2.2 or + * FIPS 186-4 §B.4.2 for elliptic curve keys. + * + * - For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR, + * the way in which the operation output is consumed is + * implementation-defined. + * + * In all cases, the data that is read is discarded from the operation. + * The operation's capacity is decreased by the number of bytes read. + * + * For algorithms that take an input step #PSA_KEY_DERIVATION_INPUT_SECRET, + * the input to that step must be provided with psa_key_derivation_input_key(). + * Future versions of this specification may include additional restrictions + * on the derived key based on the attributes and strength of the secret key. + * + * \param[in] attributes The attributes for the new key. + * \param[in,out] operation The key derivation operation object to read from. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * There was not enough data to create the desired key. + * Note that in this case, no output is written to the output buffer. + * The operation's capacity is set to 0, thus subsequent calls to + * this function will not succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The provided key attributes are not valid for the operation. + * \retval #PSA_ERROR_NOT_PERMITTED + * The #PSA_KEY_DERIVATION_INPUT_SECRET input was not provided through + * a key. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_key( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + mbedtls_svc_key_id_t *key); + +/** Abort a key derivation operation. + * + * Aborting an operation frees all associated resources except for the \c + * operation structure itself. Once aborted, the operation object can be reused + * for another operation by calling psa_key_derivation_setup() again. + * + * This function may be called at any time after the operation + * object has been initialized as described in #psa_key_derivation_operation_t. + * + * In particular, it is valid to call psa_key_derivation_abort() twice, or to + * call psa_key_derivation_abort() on an operation that has not been set up. + * + * \param[in,out] operation The operation to abort. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_abort( + psa_key_derivation_operation_t *operation); + +/** Perform a key agreement and return the raw shared secret. + * + * \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 should instead be passed as + * input to a key derivation algorithm. To chain a key agreement with + * a key derivation, use psa_key_derivation_key_agreement() and other + * functions from the key derivation interface. + * + * \param alg The key agreement algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_RAW_KEY_AGREEMENT(\p alg) + * is true). + * \param private_key Identifier of the private key to use. It must + * allow the usage #PSA_KEY_USAGE_DERIVE. + * \param[in] peer_key Public key of the peer. It must be + * in the same format that psa_import_key() + * accepts. The standard formats for public + * keys are documented in the documentation + * of psa_export_public_key(). + * \param peer_key_length Size of \p peer_key in bytes. + * \param[out] output Buffer where the decrypted message is to + * be written. + * \param output_size Size of the \c output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p alg is not a key agreement algorithm + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p private_key is not compatible with \p alg, + * or \p peer_key is not valid for \p alg or not compatible with + * \p private_key. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p output_size is too small + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not a supported key agreement algorithm. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, + mbedtls_svc_key_id_t private_key, + const uint8_t *peer_key, + size_t peer_key_length, + uint8_t *output, + size_t output_size, + size_t *output_length); + +/**@}*/ + +/** \defgroup random Random generation + * @{ + */ + +/** + * \brief Generate random bytes. + * + * \warning This function **can** fail! Callers MUST check the return status + * and MUST NOT use the content of the output buffer if the return + * status is not #PSA_SUCCESS. + * + * \note To generate a key, use psa_generate_key() instead. + * + * \param[out] output Output buffer for the generated data. + * \param output_size Number of bytes to generate and output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_random(uint8_t *output, + size_t output_size); + +/** + * \brief Generate a key or key pair. + * + * The key is generated randomly. + * Its location, usage policy, type and size are taken from \p attributes. + * + * Implementations must reject an attempt to generate a key of size 0. + * + * The following type-specific considerations apply: + * - For RSA keys (#PSA_KEY_TYPE_RSA_KEY_PAIR), + * the public exponent is 65537. + * The modulus is a product of two probabilistic primes + * between 2^{n-1} and 2^n where n is the bit size specified in the + * attributes. + * + * \param[in] attributes The attributes for the new key. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +/* The file "crypto_sizes.h" contains definitions for size calculation + * macros whose definitions are implementation-specific. */ +#include "crypto_sizes.h" + +/* The file "crypto_struct.h" contains definitions for + * implementation-specific structs that are declared above. */ +#include "crypto_struct.h" + +/* The file "crypto_extra.h" contains vendor-specific definitions. This + * can include vendor-defined algorithms, extra functions, etc. */ +#include "crypto_extra.h" + +#endif /* PSA_CRYPTO_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_builtin_composites.h b/lib/mbedtls-2.27.0/include/psa/crypto_builtin_composites.h new file mode 100644 index 0000000..1d11b00 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_builtin_composites.h @@ -0,0 +1,92 @@ +/* + * Context structure declaration of the Mbed TLS software-based PSA drivers + * called through the PSA Crypto driver dispatch layer. + * This file contains the context structures of those algorithms which need to + * rely on other algorithms, i.e. are 'composite' algorithms. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the Mbed TLS software-based PSA drivers. The + * definition of these objects are then used by crypto_struct.h to define the + * implementation-defined types of PSA multi-part state objects. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_BUILTIN_COMPOSITES_H +#define PSA_CRYPTO_BUILTIN_COMPOSITES_H + +#include <psa/crypto_driver_common.h> + +/* + * MAC multi-part operation definitions. + */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_MAC +#endif + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) +typedef struct +{ + /** The HMAC algorithm in use */ + psa_algorithm_t alg; + /** The hash context. */ + struct psa_hash_operation_s hash_ctx; + /** The HMAC part of the context. */ + uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; +} mbedtls_psa_hmac_operation_t; + +#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, PSA_HASH_OPERATION_INIT, {0}} +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ + +#include "mbedtls/cmac.h" + +typedef struct +{ + psa_algorithm_t alg; + union + { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_psa_hmac_operation_t hmac; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_cipher_context_t cmac; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ + } ctx; +} mbedtls_psa_mac_operation_t; + +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, {0}} + +/* + * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. + */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + +typedef mbedtls_psa_mac_operation_t mbedtls_transparent_test_driver_mac_operation_t; +typedef mbedtls_psa_mac_operation_t mbedtls_opaque_test_driver_mac_operation_t; + +#define MBEDTLS_TRANSPARENT_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT +#define MBEDTLS_OPAQUE_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_builtin_primitives.h b/lib/mbedtls-2.27.0/include/psa/crypto_builtin_primitives.h new file mode 100644 index 0000000..d7a69e5 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_builtin_primitives.h @@ -0,0 +1,149 @@ +/* + * Context structure declaration of the Mbed TLS software-based PSA drivers + * called through the PSA Crypto driver dispatch layer. + * This file contains the context structures of those algorithms which do not + * rely on other algorithms, i.e. are 'primitive' algorithms. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the Mbed TLS software-based PSA drivers. The + * definition of these objects are then used by crypto_struct.h to define the + * implementation-defined types of PSA multi-part state objects. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_BUILTIN_PRIMITIVES_H +#define PSA_CRYPTO_BUILTIN_PRIMITIVES_H + +#include <psa/crypto_driver_common.h> + +/* + * Hash multi-part operation definitions. + */ + +#include "mbedtls/md2.h" +#include "mbedtls/md4.h" +#include "mbedtls/md5.h" +#include "mbedtls/ripemd160.h" +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) +#define MBEDTLS_PSA_BUILTIN_HASH +#endif + +typedef struct +{ + psa_algorithm_t alg; + union + { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(MBEDTLS_MD2_C) + mbedtls_md2_context md2; +#endif +#if defined(MBEDTLS_MD4_C) + mbedtls_md4_context md4; +#endif +#if defined(MBEDTLS_MD5_C) + mbedtls_md5_context md5; +#endif +#if defined(MBEDTLS_RIPEMD160_C) + mbedtls_ripemd160_context ripemd160; +#endif +#if defined(MBEDTLS_SHA1_C) + mbedtls_sha1_context sha1; +#endif +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_context sha256; +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_context sha512; +#endif + } ctx; +} mbedtls_psa_hash_operation_t; + +#define MBEDTLS_PSA_HASH_OPERATION_INIT {0, {0}} + +/* + * Cipher multi-part operation definitions. + */ + +#include "mbedtls/cipher.h" + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_XTS) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) +#define MBEDTLS_PSA_BUILTIN_CIPHER 1 +#endif + +typedef struct { + /* Context structure for the Mbed TLS cipher implementation. */ + psa_algorithm_t alg; + uint8_t iv_length; + uint8_t block_length; + union { + unsigned int dummy; + mbedtls_cipher_context_t cipher; + } ctx; +} mbedtls_psa_cipher_operation_t; + +#define MBEDTLS_PSA_CIPHER_OPERATION_INIT {0, 0, 0, {0}} + +/* + * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. + */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + +typedef mbedtls_psa_hash_operation_t mbedtls_transparent_test_driver_hash_operation_t; + +#define MBEDTLS_TRANSPARENT_TEST_DRIVER_HASH_OPERATION_INIT MBEDTLS_PSA_HASH_OPERATION_INIT + +typedef mbedtls_psa_cipher_operation_t + mbedtls_transparent_test_driver_cipher_operation_t; + +typedef struct { + unsigned int initialised : 1; + mbedtls_transparent_test_driver_cipher_operation_t ctx; +} mbedtls_opaque_test_driver_cipher_operation_t; + +#define MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT \ + MBEDTLS_PSA_CIPHER_OPERATION_INIT + +#define MBEDTLS_OPAQUE_TEST_DRIVER_CIPHER_OPERATION_INIT \ + { 0, MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT } + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* PSA_CRYPTO_BUILTIN_PRIMITIVES_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_compat.h b/lib/mbedtls-2.27.0/include/psa/crypto_compat.h new file mode 100644 index 0000000..09ac488 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_compat.h @@ -0,0 +1,528 @@ +/** + * \file psa/crypto_compat.h + * + * \brief PSA cryptography module: Backward compatibility aliases + * + * This header declares alternative names for macro and functions. + * New application code should not use these names. + * These names may be removed in a future version of Mbed Crypto. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_COMPAT_H +#define PSA_CRYPTO_COMPAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * To support both openless APIs and psa_open_key() temporarily, define + * psa_key_handle_t to be equal to mbedtls_svc_key_id_t. Do not mark the + * type and its utility macros and functions deprecated yet. This will be done + * in a subsequent phase. + */ +typedef mbedtls_svc_key_id_t psa_key_handle_t; + +#define PSA_KEY_HANDLE_INIT MBEDTLS_SVC_KEY_ID_INIT + +/** Check whether an handle is null. + * + * \param handle Handle + * + * \return Non-zero if the handle is null, zero otherwise. + */ +static inline int psa_key_handle_is_null( psa_key_handle_t handle ) +{ + return( mbedtls_svc_key_id_is_null( handle ) ); +} + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) + +/* + * Mechanism for declaring deprecated values + */ +#if defined(MBEDTLS_DEPRECATED_WARNING) && !defined(MBEDTLS_PSA_DEPRECATED) +#define MBEDTLS_PSA_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_PSA_DEPRECATED +#endif + +typedef MBEDTLS_PSA_DEPRECATED size_t mbedtls_deprecated_size_t; +typedef MBEDTLS_PSA_DEPRECATED psa_status_t mbedtls_deprecated_psa_status_t; +typedef MBEDTLS_PSA_DEPRECATED psa_key_usage_t mbedtls_deprecated_psa_key_usage_t; +typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t mbedtls_deprecated_psa_ecc_family_t; +typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t mbedtls_deprecated_psa_dh_family_t; +typedef MBEDTLS_PSA_DEPRECATED psa_ecc_family_t psa_ecc_curve_t; +typedef MBEDTLS_PSA_DEPRECATED psa_dh_family_t psa_dh_group_t; +typedef MBEDTLS_PSA_DEPRECATED psa_algorithm_t mbedtls_deprecated_psa_algorithm_t; + +#define PSA_KEY_TYPE_GET_CURVE PSA_KEY_TYPE_ECC_GET_FAMILY +#define PSA_KEY_TYPE_GET_GROUP PSA_KEY_TYPE_DH_GET_FAMILY + +#define MBEDTLS_DEPRECATED_CONSTANT( type, value ) \ + ( (mbedtls_deprecated_##type) ( value ) ) + +/* + * Deprecated PSA Crypto error code definitions (PSA Crypto API <= 1.0 beta2) + */ +#define PSA_ERROR_UNKNOWN_ERROR \ + MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_GENERIC_ERROR ) +#define PSA_ERROR_OCCUPIED_SLOT \ + MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_ALREADY_EXISTS ) +#define PSA_ERROR_EMPTY_SLOT \ + MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_DOES_NOT_EXIST ) +#define PSA_ERROR_INSUFFICIENT_CAPACITY \ + MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_INSUFFICIENT_DATA ) +#define PSA_ERROR_TAMPERING_DETECTED \ + MBEDTLS_DEPRECATED_CONSTANT( psa_status_t, PSA_ERROR_CORRUPTION_DETECTED ) + +/* + * Deprecated PSA Crypto numerical encodings (PSA Crypto API <= 1.0 beta3) + */ +#define PSA_KEY_USAGE_SIGN \ + MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_SIGN_HASH ) +#define PSA_KEY_USAGE_VERIFY \ + MBEDTLS_DEPRECATED_CONSTANT( psa_key_usage_t, PSA_KEY_USAGE_VERIFY_HASH ) + +/* + * Deprecated PSA Crypto size calculation macros (PSA Crypto API <= 1.0 beta3) + */ +#define PSA_ASYMMETRIC_SIGNATURE_MAX_SIZE \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGNATURE_MAX_SIZE ) +#define PSA_ASYMMETRIC_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_SIGN_OUTPUT_SIZE( key_type, key_bits, alg ) ) +#define PSA_KEY_EXPORT_MAX_SIZE( key_type, key_bits ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) ) +#define PSA_BLOCK_CIPHER_BLOCK_SIZE( type ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_LENGTH( type ) ) +#define PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE ) +#define PSA_HASH_SIZE( alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_HASH_LENGTH( alg ) ) +#define PSA_MAC_FINAL_SIZE( key_type, key_bits, alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_MAC_LENGTH( key_type, key_bits, alg ) ) +#define PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE ) + +/* + * Deprecated PSA Crypto function names (PSA Crypto API <= 1.0 beta3) + */ +MBEDTLS_PSA_DEPRECATED static inline psa_status_t psa_asymmetric_sign( psa_key_handle_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + uint8_t *signature, + size_t signature_size, + size_t *signature_length ) +{ + return psa_sign_hash( key, alg, hash, hash_length, signature, signature_size, signature_length ); +} + +MBEDTLS_PSA_DEPRECATED static inline psa_status_t psa_asymmetric_verify( psa_key_handle_t key, + psa_algorithm_t alg, + const uint8_t *hash, + size_t hash_length, + const uint8_t *signature, + size_t signature_length ) +{ + return psa_verify_hash( key, alg, hash, hash_length, signature, signature_length ); +} + +/* + * Size-specific elliptic curve families. + */ +#define PSA_ECC_CURVE_SECP160K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) +#define PSA_ECC_CURVE_SECP192K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) +#define PSA_ECC_CURVE_SECP224K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) +#define PSA_ECC_CURVE_SECP256K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) +#define PSA_ECC_CURVE_SECP160R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP192R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP224R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP256R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP384R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP521R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP160R2 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R2 ) +#define PSA_ECC_CURVE_SECT163K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT233K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT239K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT283K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT409K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT571K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT163R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT193R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT233R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT283R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT409R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT571R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT163R2 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) +#define PSA_ECC_CURVE_SECT193R2 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) +#define PSA_ECC_CURVE_BRAINPOOL_P256R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) +#define PSA_ECC_CURVE_BRAINPOOL_P384R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) +#define PSA_ECC_CURVE_BRAINPOOL_P512R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) +#define PSA_ECC_CURVE_CURVE25519 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) +#define PSA_ECC_CURVE_CURVE448 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) + +/* + * Curves that changed name due to PSA specification. + */ +#define PSA_ECC_CURVE_SECP_K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_K1 ) +#define PSA_ECC_CURVE_SECP_R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R1 ) +#define PSA_ECC_CURVE_SECP_R2 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECP_R2 ) +#define PSA_ECC_CURVE_SECT_K1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_K1 ) +#define PSA_ECC_CURVE_SECT_R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R1 ) +#define PSA_ECC_CURVE_SECT_R2 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_SECT_R2 ) +#define PSA_ECC_CURVE_BRAINPOOL_P_R1 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_BRAINPOOL_P_R1 ) +#define PSA_ECC_CURVE_MONTGOMERY \ + MBEDTLS_DEPRECATED_CONSTANT( psa_ecc_family_t, PSA_ECC_FAMILY_MONTGOMERY ) + +/* + * Finite-field Diffie-Hellman families. + */ +#define PSA_DH_GROUP_FFDHE2048 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) +#define PSA_DH_GROUP_FFDHE3072 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) +#define PSA_DH_GROUP_FFDHE4096 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) +#define PSA_DH_GROUP_FFDHE6144 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) +#define PSA_DH_GROUP_FFDHE8192 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) + +/* + * Diffie-Hellman families that changed name due to PSA specification. + */ +#define PSA_DH_GROUP_RFC7919 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_RFC7919 ) +#define PSA_DH_GROUP_CUSTOM \ + MBEDTLS_DEPRECATED_CONSTANT( psa_dh_family_t, PSA_DH_FAMILY_CUSTOM ) + +/* + * Deprecated PSA Crypto stream cipher algorithms (PSA Crypto API <= 1.0 beta3) + */ +#define PSA_ALG_ARC4 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_STREAM_CIPHER ) +#define PSA_ALG_CHACHA20 \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_STREAM_CIPHER ) + +/* + * Renamed AEAD tag length macros (PSA Crypto API <= 1.0 beta3) + */ +#define PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH( aead_alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG( aead_alg ) ) +#define PSA_ALG_AEAD_WITH_TAG_LENGTH( aead_alg, tag_length ) \ + MBEDTLS_DEPRECATED_CONSTANT( psa_algorithm_t, PSA_ALG_AEAD_WITH_SHORTENED_TAG( aead_alg, tag_length ) ) + +/* + * Deprecated PSA AEAD output size macros (PSA Crypto API <= 1.0 beta3) + */ + +/** 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. + */ +#define PSA_AEAD_TAG_LENGTH_1_ARG( alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD( alg ) ? \ + PSA_ALG_AEAD_GET_TAG_LENGTH( alg ) : \ + 0 ) + +/** The maximum size of the output of psa_aead_encrypt(), in bytes. + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_aead_encrypt() will not fail due to an + * insufficient buffer size. Depending on the algorithm, the actual size of + * the ciphertext may be smaller. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param plaintext_length Size of the plaintext in bytes. + * + * \return The AEAD ciphertext size for the specified + * algorithm. + * If the AEAD algorithm is not recognized, return 0. + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE_2_ARG( alg, plaintext_length ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD( alg ) ? \ + (plaintext_length) + PSA_ALG_AEAD_GET_TAG_LENGTH( alg ) : \ + 0 ) + +/** The maximum size of the output of psa_aead_decrypt(), in bytes. + * + * If the size of the plaintext buffer is at least this large, it is + * guaranteed that psa_aead_decrypt() will not fail due to an + * insufficient buffer size. Depending on the algorithm, the actual size of + * the plaintext may be smaller. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param ciphertext_length Size of the plaintext in bytes. + * + * \return The AEAD ciphertext size for the specified + * algorithm. + * If the AEAD algorithm is not recognized, return 0. + */ +#define PSA_AEAD_DECRYPT_OUTPUT_SIZE_2_ARG( alg, ciphertext_length ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD( alg ) && \ + (ciphertext_length) > PSA_ALG_AEAD_GET_TAG_LENGTH( alg ) ? \ + (ciphertext_length) - PSA_ALG_AEAD_GET_TAG_LENGTH( alg ) : \ + 0 ) + +/** A sufficient output buffer size for psa_aead_update(). + * + * If the size of the output buffer is at least this large, it is + * guaranteed that psa_aead_update() will not fail due to an + * insufficient buffer size. The actual size of the output may be smaller + * in any given call. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output buffer size for the specified + * algorithm. + * If the AEAD algorithm is not recognized, return 0. + */ +/* For all the AEAD modes defined in this specification, it is possible + * to emit output without delay. However, hardware may not always be + * capable of this. So for modes based on a block cipher, allow the + * implementation to delay the output until it has a full block. */ +#define PSA_AEAD_UPDATE_OUTPUT_SIZE_2_ARG( alg, input_length ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER( alg ) ? \ + PSA_ROUND_UP_TO_MULTIPLE( PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length) ) : \ + (input_length) ) + +/** A sufficient ciphertext buffer size for psa_aead_finish(). + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_aead_finish() will not fail due to an + * insufficient ciphertext buffer size. The actual size of the output may + * be smaller in any given call. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return A sufficient ciphertext buffer size for the + * specified algorithm. + * If the AEAD algorithm is not recognized, return 0. + */ +#define PSA_AEAD_FINISH_OUTPUT_SIZE_1_ARG( alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER( alg ) ? \ + PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \ + 0 ) + +/** A sufficient plaintext buffer size for psa_aead_verify(). + * + * If the size of the plaintext buffer is at least this large, it is + * guaranteed that psa_aead_verify() will not fail due to an + * insufficient plaintext buffer size. The actual size of the output may + * be smaller in any given call. + * + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return A sufficient plaintext buffer size for the + * specified algorithm. + * If the AEAD algorithm is not recognized, return 0. + */ +#define PSA_AEAD_VERIFY_OUTPUT_SIZE_1_ARG( alg ) \ + MBEDTLS_DEPRECATED_CONSTANT( size_t, \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER( alg ) ? \ + PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE : \ + 0 ) + +#endif /* MBEDTLS_DEPRECATED_REMOVED */ + +/** Open a handle to an existing persistent key. + * + * Open a handle to a persistent key. A key is persistent if it was created + * with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE. A persistent key + * always has a nonzero key identifier, set with psa_set_key_id() when + * creating the key. Implementations may provide additional pre-provisioned + * keys that can be opened with psa_open_key(). Such keys have an application + * key identifier in the vendor range, as documented in the description of + * #psa_key_id_t. + * + * The application must eventually close the handle with psa_close_key() or + * psa_destroy_key() to release associated resources. If the application dies + * without calling one of these functions, the implementation should perform + * the equivalent of a call to psa_close_key(). + * + * Some implementations permit an application to open the same key multiple + * times. If this is successful, each call to psa_open_key() will return a + * different key handle. + * + * \note This API is not part of the PSA Cryptography API Release 1.0.0 + * specification. It was defined in the 1.0 Beta 3 version of the + * specification but was removed in the 1.0.0 released version. This API is + * kept for the time being to not break applications relying on it. It is not + * deprecated yet but will be in the near future. + * + * \note Applications that rely on opening a key multiple times will not be + * portable to implementations that only permit a single key handle to be + * opened. See also :ref:\`key-handles\`. + * + * + * \param key The persistent identifier of the key. + * \param[out] handle On success, a handle to the key. + * + * \retval #PSA_SUCCESS + * Success. The application can now use the value of `*handle` + * to access the key. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * The implementation does not have sufficient resources to open the + * key. This can be due to reaching an implementation limit on the + * number of open keys, the number of open key handles, or available + * memory. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * There is no persistent key with key identifier \p key. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p key is not a valid persistent key identifier. + * \retval #PSA_ERROR_NOT_PERMITTED + * The specified key exists, but the application does not have the + * permission to access it. Note that this specification does not + * define any way to create such a key, but it may be possible + * through implementation-specific means. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_open_key( mbedtls_svc_key_id_t key, + psa_key_handle_t *handle ); + +/** Close a key handle. + * + * If the handle designates a volatile key, this will destroy the key material + * and free all associated resources, just like psa_destroy_key(). + * + * If this is the last open handle to a persistent key, then closing the handle + * will free all resources associated with the key in volatile memory. The key + * data in persistent storage is not affected and can be opened again later + * with a call to psa_open_key(). + * + * Closing the key handle makes the handle invalid, and the key handle + * must not be used again by the application. + * + * \note This API is not part of the PSA Cryptography API Release 1.0.0 + * specification. It was defined in the 1.0 Beta 3 version of the + * specification but was removed in the 1.0.0 released version. This API is + * kept for the time being to not break applications relying on it. It is not + * deprecated yet but will be in the near future. + * + * \note If the key handle was used to set up an active + * :ref:\`multipart operation <multipart-operations>\`, then closing the + * key handle can cause the multipart operation to fail. Applications should + * maintain the key handle until after the multipart operation has finished. + * + * \param handle The key handle to close. + * If this is \c 0, do nothing and return \c PSA_SUCCESS. + * + * \retval #PSA_SUCCESS + * \p handle was a valid handle or \c 0. It is now closed. + * \retval #PSA_ERROR_INVALID_HANDLE + * \p handle is not a valid handle nor \c 0. + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_close_key(psa_key_handle_t handle); + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_COMPAT_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_config.h b/lib/mbedtls-2.27.0/include/psa/crypto_config.h new file mode 100644 index 0000000..246e894 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_config.h @@ -0,0 +1,128 @@ +/** + * \file psa/crypto_config.h + * \brief PSA crypto configuration options (set of defines) + * + */ +#if defined(MBEDTLS_PSA_CRYPTO_CONFIG) +/** + * When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled in config.h, + * this file determines which cryptographic mechanisms are enabled + * through the PSA Cryptography API (\c psa_xxx() functions). + * + * To enable a cryptographic mechanism, uncomment the definition of + * the corresponding \c PSA_WANT_xxx preprocessor symbol. + * To disable a cryptographic mechanism, comment out the definition of + * the corresponding \c PSA_WANT_xxx preprocessor symbol. + * The names of cryptographic mechanisms correspond to values + * defined in psa/crypto_values.h, with the prefix \c PSA_WANT_ instead + * of \c PSA_. + * + * Note that many cryptographic mechanisms involve two symbols: one for + * the key type (\c PSA_WANT_KEY_TYPE_xxx) and one for the algorithm + * (\c PSA_WANT_ALG_xxx). Mechanisms with additional parameters may involve + * additional symbols. + */ +#else +/** + * When \c MBEDTLS_PSA_CRYPTO_CONFIG is disabled in config.h, + * this file is not used, and cryptographic mechanisms are supported + * through the PSA API if and only if they are supported through the + * mbedtls_xxx API. + */ +#endif +/* + * Copyright The Mbed TLS Contributors + * 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_CONFIG_H +#define PSA_CRYPTO_CONFIG_H + +/* + * CBC-MAC is not yet supported via the PSA API in Mbed TLS. + */ +//#define PSA_WANT_ALG_CBC_MAC 1 +#define PSA_WANT_ALG_CBC_NO_PADDING 1 +#define PSA_WANT_ALG_CBC_PKCS7 1 +#define PSA_WANT_ALG_CCM 1 +#define PSA_WANT_ALG_CMAC 1 +#define PSA_WANT_ALG_CFB 1 +#define PSA_WANT_ALG_CHACHA20_POLY1305 1 +#define PSA_WANT_ALG_CMAC 1 +#define PSA_WANT_ALG_CTR 1 +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1 +#define PSA_WANT_ALG_ECB_NO_PADDING 1 +#define PSA_WANT_ALG_ECDH 1 +#define PSA_WANT_ALG_ECDSA 1 +#define PSA_WANT_ALG_GCM 1 +#define PSA_WANT_ALG_HKDF 1 +#define PSA_WANT_ALG_HMAC 1 +#define PSA_WANT_ALG_MD2 1 +#define PSA_WANT_ALG_MD4 1 +#define PSA_WANT_ALG_MD5 1 +#define PSA_WANT_ALG_OFB 1 +#define PSA_WANT_ALG_RIPEMD160 1 +#define PSA_WANT_ALG_RSA_OAEP 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT 1 +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN 1 +#define PSA_WANT_ALG_RSA_PSS 1 +#define PSA_WANT_ALG_SHA_1 1 +#define PSA_WANT_ALG_SHA_224 1 +#define PSA_WANT_ALG_SHA_256 1 +#define PSA_WANT_ALG_SHA_384 1 +#define PSA_WANT_ALG_SHA_512 1 +#define PSA_WANT_ALG_STREAM_CIPHER 1 +#define PSA_WANT_ALG_TLS12_PRF 1 +#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1 +#define PSA_WANT_ALG_XTS 1 + +#define PSA_WANT_ECC_BRAINPOOL_P_R1_256 1 +#define PSA_WANT_ECC_BRAINPOOL_P_R1_384 1 +#define PSA_WANT_ECC_BRAINPOOL_P_R1_512 1 +#define PSA_WANT_ECC_MONTGOMERY_255 1 +/* + * Curve448 is not yet supported via the PSA API in Mbed TLS + * (https://github.com/ARMmbed/mbedtls/issues/4249). Thus, do not enable it by + * default. + */ +//#define PSA_WANT_ECC_MONTGOMERY_448 1 +#define PSA_WANT_ECC_SECP_K1_192 1 +/* + * SECP224K1 is buggy via the PSA API in Mbed TLS + * (https://github.com/ARMmbed/mbedtls/issues/3541). Thus, do not enable it by + * default. + */ +//#define PSA_WANT_ECC_SECP_K1_224 1 +#define PSA_WANT_ECC_SECP_K1_256 1 +#define PSA_WANT_ECC_SECP_R1_192 1 +#define PSA_WANT_ECC_SECP_R1_224 1 +#define PSA_WANT_ECC_SECP_R1_256 1 +#define PSA_WANT_ECC_SECP_R1_384 1 +#define PSA_WANT_ECC_SECP_R1_521 1 + +#define PSA_WANT_KEY_TYPE_DERIVE 1 +#define PSA_WANT_KEY_TYPE_HMAC 1 +#define PSA_WANT_KEY_TYPE_AES 1 +#define PSA_WANT_KEY_TYPE_ARC4 1 +#define PSA_WANT_KEY_TYPE_CAMELLIA 1 +#define PSA_WANT_KEY_TYPE_CHACHA20 1 +#define PSA_WANT_KEY_TYPE_DES 1 +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1 +#define PSA_WANT_KEY_TYPE_RAW_DATA 1 +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR 1 +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY 1 + +#endif /* PSA_CRYPTO_CONFIG_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_driver_common.h b/lib/mbedtls-2.27.0/include/psa/crypto_driver_common.h new file mode 100644 index 0000000..1b6f322 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_driver_common.h @@ -0,0 +1,53 @@ +/** + * \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 dynamically registered driver for a secure element, + * include `psa/crypto_se_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 The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PSA_CRYPTO_DRIVER_COMMON_H +#define PSA_CRYPTO_DRIVER_COMMON_H + +#include <stddef.h> +#include <stdint.h> + +/* Include type definitions (psa_status_t, psa_algorithm_t, + * psa_key_type_t, etc.) and macros to build and analyze values + * of these types. */ +#include "crypto_types.h" +#include "crypto_values.h" + +/** For encrypt-decrypt functions, whether the operation is an encryption + * or a decryption. */ +typedef enum { + PSA_CRYPTO_DRIVER_DECRYPT, + PSA_CRYPTO_DRIVER_ENCRYPT +} psa_encrypt_or_decrypt_t; + +#endif /* PSA_CRYPTO_DRIVER_COMMON_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_composites.h b/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_composites.h new file mode 100644 index 0000000..239fdcb --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_composites.h @@ -0,0 +1,62 @@ +/* + * Declaration of context structures for use with the PSA driver wrapper + * interface. This file contains the context structures for 'composite' + * operations, i.e. those operations which need to make use of other operations + * from the primitives (crypto_driver_contexts_primitives.h) + * + * Warning: This file will be auto-generated in the future. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the PSA drivers included in the cryptographic + * library. The definition of these objects are then used by crypto_struct.h + * to define the implementation-defined types of PSA multi-part state objects. + */ +/* Copyright The Mbed TLS Contributors + * 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_CONTEXTS_COMPOSITES_H +#define PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H + +#include "psa/crypto_driver_common.h" + +/* Include the context structure definitions for those drivers that were + * declared during the autogeneration process. */ + +/* Include the context structure definitions for the Mbed TLS software drivers */ +#include "psa/crypto_builtin_composites.h" + +/* Define the context to be used for an operation that is executed through the + * PSA Driver wrapper layer as the union of all possible driver's contexts. + * + * The union members are the driver's context structures, and the member names + * are formatted as `'drivername'_ctx`. This allows for procedural generation + * of both this file and the content of psa_crypto_driver_wrappers.c */ + +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_mac_operation_t mbedtls_ctx; +#if defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_transparent_test_driver_mac_operation_t transparent_test_driver_ctx; + mbedtls_opaque_test_driver_mac_operation_t opaque_test_driver_ctx; +#endif +} psa_driver_mac_context_t; + +#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ +/* End of automatically generated file. */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_primitives.h b/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_primitives.h new file mode 100644 index 0000000..104d4bd --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_driver_contexts_primitives.h @@ -0,0 +1,69 @@ +/* + * Declaration of context structures for use with the PSA driver wrapper + * interface. This file contains the context structures for 'primitive' + * operations, i.e. those operations which do not rely on other contexts. + * + * Warning: This file will be auto-generated in the future. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the PSA drivers included in the cryptographic + * library. The definition of these objects are then used by crypto_struct.h + * to define the implementation-defined types of PSA multi-part state objects. + */ +/* Copyright The Mbed TLS Contributors + * 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_CONTEXTS_PRIMITIVES_H +#define PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H + +#include "psa/crypto_driver_common.h" + +/* Include the context structure definitions for those drivers that were + * declared during the autogeneration process. */ + +/* Include the context structure definitions for the Mbed TLS software drivers */ +#include "psa/crypto_builtin_primitives.h" + +/* Define the context to be used for an operation that is executed through the + * PSA Driver wrapper layer as the union of all possible driver's contexts. + * + * The union members are the driver's context structures, and the member names + * are formatted as `'drivername'_ctx`. This allows for procedural generation + * of both this file and the content of psa_crypto_driver_wrappers.c */ + +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_hash_operation_t mbedtls_ctx; +#if defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_transparent_test_driver_hash_operation_t test_driver_ctx; +#endif +} psa_driver_hash_context_t; + +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_cipher_operation_t mbedtls_ctx; +#if defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_transparent_test_driver_cipher_operation_t transparent_test_driver_ctx; + mbedtls_opaque_test_driver_cipher_operation_t opaque_test_driver_ctx; +#endif +} psa_driver_cipher_context_t; + +#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H */ +/* End of automatically generated file. */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_extra.h b/lib/mbedtls-2.27.0/include/psa/crypto_extra.h new file mode 100644 index 0000000..1310bb5 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_extra.h @@ -0,0 +1,818 @@ +/** + * \file psa/crypto_extra.h + * + * \brief PSA cryptography module: Mbed TLS vendor extensions + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * This file is reserved for vendor-specific definitions. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_EXTRA_H +#define PSA_CRYPTO_EXTRA_H + +#include "mbedtls/platform_util.h" + +#include "crypto_compat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* UID for secure storage seed */ +#define PSA_CRYPTO_ITS_RANDOM_SEED_UID 0xFFFFFF52 + +/* See config.h for definition */ +#if !defined(MBEDTLS_PSA_KEY_SLOT_COUNT) +#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 +#endif + +/** \addtogroup attributes + * @{ + */ + +/** \brief Declare the enrollment algorithm for a key. + * + * An operation on a key may indifferently use the algorithm set with + * psa_set_key_algorithm() or with this function. + * + * \param[out] attributes The attribute structure to write to. + * \param alg2 A second algorithm that the key may be used + * for, in addition to the algorithm set with + * psa_set_key_algorithm(). + * + * \warning Setting an enrollment algorithm is not recommended, because + * using the same key with different algorithms can allow some + * attacks based on arithmetic relations between different + * computations made with the same key, or can escalate harmless + * side channels into exploitable ones. Use this function only + * if it is necessary to support a protocol for which it has been + * verified that the usage of the key with multiple algorithms + * is safe. + */ +static inline void psa_set_key_enrollment_algorithm( + psa_key_attributes_t *attributes, + psa_algorithm_t alg2) +{ + attributes->core.policy.alg2 = alg2; +} + +/** Retrieve the enrollment algorithm policy from key attributes. + * + * \param[in] attributes The key attribute structure to query. + * + * \return The enrollment algorithm stored in the attribute structure. + */ +static inline psa_algorithm_t psa_get_key_enrollment_algorithm( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.policy.alg2 ); +} + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + +/** Retrieve the slot number where a key is stored. + * + * A slot number is only defined for keys that are stored in a secure + * element. + * + * This information is only useful if the secure element is not entirely + * managed through the PSA Cryptography API. It is up to the secure + * element driver to decide how PSA slot numbers map to any other interface + * that the secure element may have. + * + * \param[in] attributes The key attribute structure to query. + * \param[out] slot_number On success, the slot number containing the key. + * + * \retval #PSA_SUCCESS + * The key is located in a secure element, and \p *slot_number + * indicates the slot number that contains it. + * \retval #PSA_ERROR_NOT_PERMITTED + * The caller is not permitted to query the slot number. + * Mbed Crypto currently does not return this error. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is not located in a secure element. + */ +psa_status_t psa_get_key_slot_number( + const psa_key_attributes_t *attributes, + psa_key_slot_number_t *slot_number ); + +/** Choose the slot number where a key is stored. + * + * This function declares a slot number in the specified attribute + * structure. + * + * A slot number is only meaningful for keys that are stored in a secure + * element. It is up to the secure element driver to decide how PSA slot + * numbers map to any other interface that the secure element may have. + * + * \note Setting a slot number in key attributes for a key creation can + * cause the following errors when creating the key: + * - #PSA_ERROR_NOT_SUPPORTED if the selected secure element does + * not support choosing a specific slot number. + * - #PSA_ERROR_NOT_PERMITTED if the caller is not permitted to + * choose slot numbers in general or to choose this specific slot. + * - #PSA_ERROR_INVALID_ARGUMENT if the chosen slot number is not + * valid in general or not valid for this specific key. + * - #PSA_ERROR_ALREADY_EXISTS if there is already a key in the + * selected slot. + * + * \param[out] attributes The attribute structure to write to. + * \param slot_number The slot number to set. + */ +static inline void psa_set_key_slot_number( + psa_key_attributes_t *attributes, + psa_key_slot_number_t slot_number ) +{ + attributes->core.flags |= MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; + attributes->slot_number = slot_number; +} + +/** Remove the slot number attribute from a key attribute structure. + * + * This function undoes the action of psa_set_key_slot_number(). + * + * \param[out] attributes The attribute structure to write to. + */ +static inline void psa_clear_key_slot_number( + psa_key_attributes_t *attributes ) +{ + attributes->core.flags &= ~MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER; +} + +/** Register a key that is already present in a secure element. + * + * The key must be located in a secure element designated by the + * lifetime field in \p attributes, in the slot set with + * psa_set_key_slot_number() in the attribute structure. + * This function makes the key available through the key identifier + * specified in \p attributes. + * + * \param[in] attributes The attributes of the existing key. + * + * \retval #PSA_SUCCESS + * The key was successfully registered. + * Note that depending on the design of the driver, this may or may + * not guarantee that a key actually exists in the designated slot + * and is compatible with the specified attributes. + * \retval #PSA_ERROR_ALREADY_EXISTS + * There is already a key with the identifier specified in + * \p attributes. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The secure element driver for the specified lifetime does not + * support registering a key. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The identifier in \p attributes is invalid, namely the identifier is + * not in the user range. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p attributes specifies a lifetime which is not located + * in a secure element. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * No slot number is specified in \p attributes, + * or the specified slot number is not valid. + * \retval #PSA_ERROR_NOT_PERMITTED + * The caller is not authorized to register the specified key slot. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t mbedtls_psa_register_se_key( + const psa_key_attributes_t *attributes); + +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + +/**@}*/ + +/** + * \brief Library deinitialization. + * + * This function clears all data associated with the PSA layer, + * including the whole key store. + * + * This is an Mbed TLS extension. + */ +void mbedtls_psa_crypto_free( void ); + +/** \brief Statistics about + * resource consumption related to the PSA keystore. + * + * \note The content of this structure is not part of the stable API and ABI + * of Mbed Crypto and may change arbitrarily from version to version. + */ +typedef struct mbedtls_psa_stats_s +{ + /** Number of slots containing key material for a volatile key. */ + size_t volatile_slots; + /** Number of slots containing key material for a key which is in + * internal persistent storage. */ + size_t persistent_slots; + /** Number of slots containing a reference to a key in a + * secure element. */ + size_t external_slots; + /** Number of slots which are occupied, but do not contain + * key material yet. */ + size_t half_filled_slots; + /** Number of slots that contain cache data. */ + size_t cache_slots; + /** Number of slots that are not used for anything. */ + size_t empty_slots; + /** Number of slots that are locked. */ + size_t locked_slots; + /** Largest key id value among open keys in internal persistent storage. */ + psa_key_id_t max_open_internal_key_id; + /** Largest key id value among open keys in secure elements. */ + psa_key_id_t max_open_external_key_id; +} mbedtls_psa_stats_t; + +/** \brief Get statistics about + * resource consumption related to the PSA keystore. + * + * \note When Mbed Crypto is built as part of a service, with isolation + * between the application and the keystore, the service may or + * may not expose this function. + */ +void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ); + +/** + * \brief Inject an initial entropy seed for the random generator into + * secure storage. + * + * This function injects data to be used as a seed for the random generator + * used by the PSA Crypto implementation. On devices that lack a trusted + * entropy source (preferably a hardware random number generator), + * the Mbed PSA Crypto implementation uses this value to seed its + * random generator. + * + * On devices without a trusted entropy source, this function must be + * called exactly once in the lifetime of the device. On devices with + * a trusted entropy source, calling this function is optional. + * In all cases, this function may only be called before calling any + * other function in the PSA Crypto API, including psa_crypto_init(). + * + * When this function returns successfully, it populates a file in + * persistent storage. Once the file has been created, this function + * can no longer succeed. + * + * If any error occurs, this function does not change the system state. + * You can call this function again after correcting the reason for the + * error if possible. + * + * \warning This function **can** fail! Callers MUST check the return status. + * + * \warning If you use this function, you should use it as part of a + * factory provisioning process. The value of the injected seed + * is critical to the security of the device. It must be + * *secret*, *unpredictable* and (statistically) *unique per device*. + * You should be generate it randomly using a cryptographically + * secure random generator seeded from trusted entropy sources. + * You should transmit it securely to the device and ensure + * that its value is not leaked or stored anywhere beyond the + * needs of transmitting it from the point of generation to + * the call of this function, and erase all copies of the value + * once this function returns. + * + * This is an Mbed TLS extension. + * + * \note This function is only available on the following platforms: + * * If the compile-time option MBEDTLS_PSA_INJECT_ENTROPY is enabled. + * Note that you must provide compatible implementations of + * mbedtls_nv_seed_read and mbedtls_nv_seed_write. + * * In a client-server integration of PSA Cryptography, on the client side, + * if the server supports this feature. + * \param[in] seed Buffer containing the seed value to inject. + * \param[in] seed_size Size of the \p seed buffer. + * The size of the seed in bytes must be greater + * or equal to both #MBEDTLS_ENTROPY_MIN_PLATFORM + * and #MBEDTLS_ENTROPY_BLOCK_SIZE. + * It must be less or equal to + * #MBEDTLS_ENTROPY_MAX_SEED_SIZE. + * + * \retval #PSA_SUCCESS + * The seed value was injected successfully. The random generator + * of the PSA Crypto implementation is now ready for use. + * You may now call psa_crypto_init() and use the PSA Crypto + * implementation. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p seed_size is out of range. + * \retval #PSA_ERROR_STORAGE_FAILURE + * There was a failure reading or writing from storage. + * \retval #PSA_ERROR_NOT_PERMITTED + * The library has already been initialized. It is no longer + * possible to call this function. + */ +psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, + size_t seed_size); + +/** \addtogroup crypto_types + * @{ + */ + +/** DSA public key. + * + * The import and export format is the + * representation of the public key `y = g^x mod p` as a big-endian byte + * string. The length of the byte string is the length of the base prime `p` + * in bytes. + */ +#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x4002) + +/** DSA key pair (private and public key). + * + * The import and export format is the + * representation of the private key `x` as a big-endian byte string. The + * length of the byte string is the private key size in bytes (leading zeroes + * are not stripped). + * + * Determinstic DSA key derivation with psa_generate_derived_key follows + * FIPS 186-4 §B.1.2: interpret the byte string as integer + * in big-endian order. Discard it if it is not in the range + * [0, *N* - 2] where *N* is the boundary of the private key domain + * (the prime *p* for Diffie-Hellman, the subprime *q* for DSA, + * or the order of the curve's base point for ECC). + * Add 1 to the resulting integer and use this as the private key *x*. + * + */ +#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t)0x7002) + +/** 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_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY) + +#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x06000400) +/** 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). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding DSA signature algorithm. + * \return Unspecified if \p hash_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)0x06000500) +#define PSA_ALG_DSA_DETERMINISTIC_FLAG PSA_ALG_ECDSA_DETERMINISTIC_FLAG +/** Deterministic DSA signature with hashing. + * + * This is the deterministic variant defined by RFC 6979 of + * the signature scheme defined by FIPS 186-4. + * + * \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_HASH(\p hash_alg) is true). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding DSA signature algorithm. + * \return Unspecified if \p hash_alg is not a supported + * hash algorithm. + */ +#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)) + + +/* We need to expand the sample definition of this macro from + * the API definition. */ +#undef PSA_ALG_IS_VENDOR_HASH_AND_SIGN +#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) \ + PSA_ALG_IS_DSA(alg) + +/**@}*/ + +/** \addtogroup attributes + * @{ + */ + +/** Custom Diffie-Hellman group. + * + * For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or + * #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM), the group data comes + * from domain parameters set by psa_set_key_domain_parameters(). + */ +#define PSA_DH_FAMILY_CUSTOM ((psa_dh_family_t) 0x7e) + + +/** + * \brief Set domain parameters for a key. + * + * Some key types require additional domain parameters in addition to + * the key type identifier and the key size. Use this function instead + * of psa_set_key_type() when you need to specify domain parameters. + * + * The format for the required domain parameters varies based on the key type. + * + * - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR), + * the domain parameter data consists of the public exponent, + * represented as a big-endian integer with no leading zeros. + * This information is used when generating an RSA key pair. + * When importing a key, the public exponent is read from the imported + * key data and the exponent recorded in the attribute structure is ignored. + * As an exception, the public exponent 65537 is represented by an empty + * byte string. + * - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR), + * the `Dss-Parms` format as defined by RFC 3279 §2.3.2. + * ``` + * Dss-Parms ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER + * } + * ``` + * - For Diffie-Hellman key exchange keys + * (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_FAMILY_CUSTOM) or + * #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_FAMILY_CUSTOM)), the + * `DomainParameters` format as defined by RFC 3279 §2.3.3. + * ``` + * DomainParameters ::= SEQUENCE { + * p INTEGER, -- odd prime, p=jq +1 + * g INTEGER, -- generator, g + * q INTEGER, -- factor of p-1 + * j INTEGER OPTIONAL, -- subgroup factor + * validationParms ValidationParms OPTIONAL + * } + * ValidationParms ::= SEQUENCE { + * seed BIT STRING, + * pgenCounter INTEGER + * } + * ``` + * + * \note This function may allocate memory or other resources. + * Once you have called this function on an attribute structure, + * you must call psa_reset_key_attributes() to free these resources. + * + * \note This is an experimental extension to the interface. It may change + * in future versions of the library. + * + * \param[in,out] attributes Attribute structure where the specified domain + * parameters will be stored. + * If this function fails, the content of + * \p attributes is not modified. + * \param type Key type (a \c PSA_KEY_TYPE_XXX value). + * \param[in] data Buffer containing the key domain parameters. + * The content of this buffer is interpreted + * according to \p type as described above. + * \param data_length Size of the \p data buffer in bytes. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, + psa_key_type_t type, + const uint8_t *data, + size_t data_length); + +/** + * \brief Get domain parameters for a key. + * + * Get the domain parameters for a key with this function, if any. The format + * of the domain parameters written to \p data is specified in the + * documentation for psa_set_key_domain_parameters(). + * + * \note This is an experimental extension to the interface. It may change + * in future versions of the library. + * + * \param[in] attributes The key attribute structure to query. + * \param[out] data On success, the key domain parameters. + * \param data_size Size of the \p data buffer in bytes. + * The buffer is guaranteed to be large + * enough if its size in bytes is at least + * the value given by + * PSA_KEY_DOMAIN_PARAMETERS_SIZE(). + * \param[out] data_length On success, the number of bytes + * that make up the key domain parameters data. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + */ +psa_status_t psa_get_key_domain_parameters( + const psa_key_attributes_t *attributes, + uint8_t *data, + size_t data_size, + size_t *data_length); + +/** Safe output buffer size for psa_get_key_domain_parameters(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * \warning This function may call its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \note This is an experimental extension to the interface. It may change + * in future versions of the library. + * + * \param key_type A supported key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_get_key_domain_parameters() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported + * by the implementation, this macro shall return either a + * sensible size or 0. + * If the parameters are not valid, the + * return value is unspecified. + */ +#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \ + PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \ + 0) +#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \ + (4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/) +#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \ + (4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/) + +/**@}*/ + +/** \defgroup psa_tls_helpers TLS helper functions + * @{ + */ + +#if defined(MBEDTLS_ECP_C) +#include <mbedtls/ecp.h> + +/** Convert an ECC curve identifier from the Mbed TLS encoding to PSA. + * + * \note This function is provided solely for the convenience of + * Mbed TLS and may be removed at any time without notice. + * + * \param grpid An Mbed TLS elliptic curve identifier + * (`MBEDTLS_ECP_DP_xxx`). + * \param[out] bits On success, the bit size of the curve. + * + * \return The corresponding PSA elliptic curve identifier + * (`PSA_ECC_FAMILY_xxx`). + * \return \c 0 on failure (\p grpid is not recognized). + */ +static inline psa_ecc_family_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid, + size_t *bits ) +{ + switch( grpid ) + { + case MBEDTLS_ECP_DP_SECP192R1: + *bits = 192; + return( PSA_ECC_FAMILY_SECP_R1 ); + case MBEDTLS_ECP_DP_SECP224R1: + *bits = 224; + return( PSA_ECC_FAMILY_SECP_R1 ); + case MBEDTLS_ECP_DP_SECP256R1: + *bits = 256; + return( PSA_ECC_FAMILY_SECP_R1 ); + case MBEDTLS_ECP_DP_SECP384R1: + *bits = 384; + return( PSA_ECC_FAMILY_SECP_R1 ); + case MBEDTLS_ECP_DP_SECP521R1: + *bits = 521; + return( PSA_ECC_FAMILY_SECP_R1 ); + case MBEDTLS_ECP_DP_BP256R1: + *bits = 256; + return( PSA_ECC_FAMILY_BRAINPOOL_P_R1 ); + case MBEDTLS_ECP_DP_BP384R1: + *bits = 384; + return( PSA_ECC_FAMILY_BRAINPOOL_P_R1 ); + case MBEDTLS_ECP_DP_BP512R1: + *bits = 512; + return( PSA_ECC_FAMILY_BRAINPOOL_P_R1 ); + case MBEDTLS_ECP_DP_CURVE25519: + *bits = 255; + return( PSA_ECC_FAMILY_MONTGOMERY ); + case MBEDTLS_ECP_DP_SECP192K1: + *bits = 192; + return( PSA_ECC_FAMILY_SECP_K1 ); + case MBEDTLS_ECP_DP_SECP224K1: + *bits = 224; + return( PSA_ECC_FAMILY_SECP_K1 ); + case MBEDTLS_ECP_DP_SECP256K1: + *bits = 256; + return( PSA_ECC_FAMILY_SECP_K1 ); + case MBEDTLS_ECP_DP_CURVE448: + *bits = 448; + return( PSA_ECC_FAMILY_MONTGOMERY ); + default: + *bits = 0; + return( 0 ); + } +} + +/** Convert an ECC curve identifier from the PSA encoding to Mbed TLS. + * + * \note This function is provided solely for the convenience of + * Mbed TLS and may be removed at any time without notice. + * + * \param curve A PSA elliptic curve identifier + * (`PSA_ECC_FAMILY_xxx`). + * \param bits The bit-length of a private key on \p curve. + * \param bits_is_sloppy If true, \p bits may be the bit-length rounded up + * to the nearest multiple of 8. This allows the caller + * to infer the exact curve from the length of a key + * which is supplied as a byte string. + * + * \return The corresponding Mbed TLS elliptic curve identifier + * (`MBEDTLS_ECP_DP_xxx`). + * \return #MBEDTLS_ECP_DP_NONE if \c curve is not recognized. + * \return #MBEDTLS_ECP_DP_NONE if \p bits is not + * correct for \p curve. + */ +mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_family_t curve, + size_t bits, + int bits_is_sloppy ); +#endif /* MBEDTLS_ECP_C */ + +/**@}*/ + +/** \defgroup psa_external_rng External random generator + * @{ + */ + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +/** External random generator function, implemented by the platform. + * + * When the compile-time option #MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG is enabled, + * this function replaces Mbed TLS's entropy and DRBG modules for all + * random generation triggered via PSA crypto interfaces. + * + * \note This random generator must deliver random numbers with cryptographic + * quality and high performance. It must supply unpredictable numbers + * with a uniform distribution. The implementation of this function + * is responsible for ensuring that the random generator is seeded + * with sufficient entropy. If you have a hardware TRNG which is slow + * or delivers non-uniform output, declare it as an entropy source + * with mbedtls_entropy_add_source() instead of enabling this option. + * + * \param[in,out] context Pointer to the random generator context. + * This is all-bits-zero on the first call + * and preserved between successive calls. + * \param[out] output Output buffer. On success, this buffer + * contains random data with a uniform + * distribution. + * \param output_size The size of the \p output buffer in bytes. + * \param[out] output_length On success, set this value to \p output_size. + * + * \retval #PSA_SUCCESS + * Success. The output buffer contains \p output_size bytes of + * cryptographic-quality random data, and \c *output_length is + * set to \p output_size. + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * The random generator requires extra entropy and there is no + * way to obtain entropy under current environment conditions. + * This error should not happen under normal circumstances since + * this function is responsible for obtaining as much entropy as + * it needs. However implementations of this function may return + * #PSA_ERROR_INSUFFICIENT_ENTROPY if there is no way to obtain + * entropy without blocking indefinitely. + * \retval #PSA_ERROR_HARDWARE_FAILURE + * A failure of the random generator hardware that isn't covered + * by #PSA_ERROR_INSUFFICIENT_ENTROPY. + */ +psa_status_t mbedtls_psa_external_get_random( + mbedtls_psa_external_random_context_t *context, + uint8_t *output, size_t output_size, size_t *output_length ); +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + +/**@}*/ + +/** \defgroup psa_builtin_keys Built-in keys + * @{ + */ + +/** The minimum value for a key identifier that is built into the + * implementation. + * + * The range of key identifiers from #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + * to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX within the range from + * #PSA_KEY_ID_VENDOR_MIN and #PSA_KEY_ID_VENDOR_MAX and must not intersect + * with any other set of implementation-chosen key identifiers. + * + * This value is part of the library's ABI since changing it would invalidate + * the values of built-in key identifiers in applications. + */ +#define MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ((psa_key_id_t)0x7fff0000) + +/** The maximum value for a key identifier that is built into the + * implementation. + * + * See #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN for more information. + */ +#define MBEDTLS_PSA_KEY_ID_BUILTIN_MAX ((psa_key_id_t)0x7fffefff) + +/** A slot number identifying a key in a driver. + * + * Values of this type are used to identify built-in keys. + */ +typedef uint64_t psa_drv_slot_number_t; + +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +/** Test whether a key identifier belongs to the builtin key range. + * + * \param key_id Key identifier to test. + * + * \retval 1 + * The key identifier is a builtin key identifier. + * \retval 0 + * The key identifier is not a builtin key identifier. + */ +static inline int psa_key_id_is_builtin( psa_key_id_t key_id ) +{ + return( ( key_id >= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ) && + ( key_id <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX ) ); +} + +/** Platform function to obtain the location and slot number of a built-in key. + * + * An application-specific implementation of this function must be provided if + * #MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled. This would typically be provided + * as part of a platform's system image. + * + * #MBEDTLS_SVC_KEY_ID_GET_KEY_ID(\p key_id) needs to be in the range from + * #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX. + * + * In a multi-application configuration + * (\c MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER is defined), + * this function should check that #MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(\p key_id) + * is allowed to use the given key. + * + * \param key_id The key ID for which to retrieve the + * location and slot attributes. + * \param[out] lifetime On success, the lifetime associated with the key + * corresponding to \p key_id. Lifetime is a + * combination of which driver contains the key, + * and with what persistence level the key is + * intended to be used. If the platform + * implementation does not contain specific + * information about the intended key persistence + * level, the persistence level may be reported as + * #PSA_KEY_PERSISTENCE_DEFAULT. + * \param[out] slot_number On success, the slot number known to the driver + * registered at the lifetime location reported + * through \p lifetime which corresponds to the + * requested built-in key. + * + * \retval #PSA_SUCCESS + * The requested key identifier designates a built-in key. + * In a multi-application configuration, the requested owner + * is allowed to access it. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * The requested key identifier is not a built-in key which is known + * to this function. If a key exists in the key storage with this + * identifier, the data from the storage will be used. + * \return (any other error) + * Any other error is propagated to the function that requested the key. + * Common errors include: + * - #PSA_ERROR_NOT_PERMITTED: the key exists but the requested owner + * is not allowed to access it. + */ +psa_status_t mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t key_id, + psa_key_lifetime_t *lifetime, + psa_drv_slot_number_t *slot_number ); +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_EXTRA_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_platform.h b/lib/mbedtls-2.27.0/include/psa/crypto_platform.h new file mode 100644 index 0000000..66f4687 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_platform.h @@ -0,0 +1,111 @@ +/** + * \file psa/crypto_platform.h + * + * \brief PSA cryptography module: Mbed TLS platform definitions + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * This file contains platform-dependent type definitions. + * + * In implementations with isolation between the application and the + * cryptography module, implementers should take care to ensure that + * the definitions that are exposed to applications match what the + * module implements. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_PLATFORM_H +#define PSA_CRYPTO_PLATFORM_H + +/* Include the Mbed TLS configuration file, the way Mbed TLS does it + * in each of its header files. */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +/* Translate between classic MBEDTLS_xxx feature symbols and PSA_xxx + * feature symbols. */ +#include "mbedtls/config_psa.h" + +/* PSA requires several types which C99 provides in stdint.h. */ +#include <stdint.h> + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + +/* Building for the PSA Crypto service on a PSA platform, a key owner is a PSA + * partition identifier. + * + * The function psa_its_identifier_of_slot() in psa_crypto_storage.c that + * translates a key identifier to a key storage file name assumes that + * mbedtls_key_owner_id_t is an 32 bits integer. This function thus needs + * reworking if mbedtls_key_owner_id_t is not defined as a 32 bits integer + * here anymore. + */ +typedef int32_t mbedtls_key_owner_id_t; + +/** Compare two key owner identifiers. + * + * \param id1 First key owner identifier. + * \param id2 Second key owner identifier. + * + * \return Non-zero if the two key owner identifiers are equal, zero otherwise. + */ +static inline int mbedtls_key_owner_id_equal( mbedtls_key_owner_id_t id1, + mbedtls_key_owner_id_t id2 ) +{ + return( id1 == id2 ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ + +/* + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is being built for SPM + * (Secure Partition Manager) integration which separates the code into two + * parts: NSPE (Non-Secure Processing Environment) and SPE (Secure Processing + * Environment). When building for the SPE, an additional header file should be + * included. + */ +#if defined(MBEDTLS_PSA_CRYPTO_SPM) +#define PSA_CRYPTO_SECURE 1 +#include "crypto_spe.h" +#endif // MBEDTLS_PSA_CRYPTO_SPM + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) +/** The type of the context passed to mbedtls_psa_external_get_random(). + * + * Mbed TLS initializes the context to all-bits-zero before calling + * mbedtls_psa_external_get_random() for the first time. + * + * The definition of this type in the Mbed TLS source code is for + * demonstration purposes. Implementers of mbedtls_psa_external_get_random() + * are expected to replace it with a custom definition. + */ +typedef struct { + uintptr_t opaque[2]; +} mbedtls_psa_external_random_context_t; +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + +#endif /* PSA_CRYPTO_PLATFORM_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_se_driver.h b/lib/mbedtls-2.27.0/include/psa/crypto_se_driver.h new file mode 100644 index 0000000..1dc8f9b --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_se_driver.h @@ -0,0 +1,1395 @@ +/** + * \file psa/crypto_se_driver.h + * \brief PSA external cryptoprocessor driver module + * + * This header declares types and function signatures for cryptography + * drivers that access key material via opaque references. + * This is meant for cryptoprocessors that have a separate key storage from the + * space in which the PSA Crypto implementation runs, typically secure + * elements (SEs). + * + * This file is part of the PSA Crypto Driver HAL (hardware abstraction layer), + * containing functions for driver developers to implement to enable hardware + * to be called in a standardized way by a PSA Cryptography API + * implementation. The functions comprising the driver HAL, which driver + * authors implement, are not intended to be called by application developers. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef PSA_CRYPTO_SE_DRIVER_H +#define PSA_CRYPTO_SE_DRIVER_H + +#include "crypto_driver_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup se_init Secure element driver initialization + */ +/**@{*/ + +/** \brief Driver context structure + * + * Driver functions receive a pointer to this structure. + * Each registered driver has one instance of this structure. + * + * Implementations must include the fields specified here and + * may include other fields. + */ +typedef struct { + /** A read-only pointer to the driver's persistent data. + * + * Drivers typically use this persistent data to keep track of + * which slot numbers are available. This is only a guideline: + * drivers may use the persistent data for any purpose, keeping + * in mind the restrictions on when the persistent data is saved + * to storage: the persistent data is only saved after calling + * certain functions that receive a writable pointer to the + * persistent data. + * + * The core allocates a memory buffer for the persistent data. + * The pointer is guaranteed to be suitably aligned for any data type, + * like a pointer returned by `malloc` (but the core can use any + * method to allocate the buffer, not necessarily `malloc`). + * + * The size of this buffer is in the \c persistent_data_size field of + * this structure. + * + * Before the driver is initialized for the first time, the content of + * the persistent data is all-bits-zero. After a driver upgrade, if the + * size of the persistent data has increased, the original data is padded + * on the right with zeros; if the size has decreased, the original data + * is truncated to the new size. + * + * This pointer is to read-only data. Only a few driver functions are + * allowed to modify the persistent data. These functions receive a + * writable pointer. These functions are: + * - psa_drv_se_t::p_init + * - psa_drv_se_key_management_t::p_allocate + * - psa_drv_se_key_management_t::p_destroy + * + * The PSA Cryptography core saves the persistent data from one + * session to the next. It does this before returning from API functions + * that call a driver method that is allowed to modify the persistent + * data, specifically: + * - psa_crypto_init() causes a call to psa_drv_se_t::p_init, and may call + * psa_drv_se_key_management_t::p_destroy to complete an action + * that was interrupted by a power failure. + * - Key creation functions cause a call to + * psa_drv_se_key_management_t::p_allocate, and may cause a call to + * psa_drv_se_key_management_t::p_destroy in case an error occurs. + * - psa_destroy_key() causes a call to + * psa_drv_se_key_management_t::p_destroy. + */ + const void *const persistent_data; + + /** The size of \c persistent_data in bytes. + * + * This is always equal to the value of the `persistent_data_size` field + * of the ::psa_drv_se_t structure when the driver is registered. + */ + const size_t persistent_data_size; + + /** Driver transient data. + * + * The core initializes this value to 0 and does not read or modify it + * afterwards. The driver may store whatever it wants in this field. + */ + uintptr_t transient_data; +} psa_drv_se_context_t; + +/** \brief A driver initialization function. + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] persistent_data A pointer to the persistent data + * that allows writing. + * \param location The location value for which this driver + * is registered. The driver will be invoked + * for all keys whose lifetime is in this + * location. + * + * \retval #PSA_SUCCESS + * The driver is operational. + * The core will update the persistent data in storage. + * \return + * Any other return value prevents the driver from being used in + * this session. + * The core will NOT update the persistent data in storage. + */ +typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context, + void *persistent_data, + psa_key_location_t location); + +#if defined(__DOXYGEN_ONLY__) || !defined(MBEDTLS_PSA_CRYPTO_SE_C) +/* Mbed Crypto with secure element support enabled defines this type in + * crypto_types.h because it is also visible to applications through an + * implementation-specific extension. + * For the PSA Cryptography specification, this type is only visible + * via crypto_se_driver.h. */ +/** 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 uint64_t psa_key_slot_number_t; +#endif /* __DOXYGEN_ONLY__ || !MBEDTLS_PSA_CRYPTO_SE_C */ + +/**@}*/ + +/** \defgroup se_mac Secure Element Message Authentication Codes + * Generation and authentication of Message Authentication Codes (MACs) using + * a secure element can be done either as a single function call (via the + * `psa_drv_se_mac_generate_t` or `psa_drv_se_mac_verify_t` functions), or in + * parts using the following sequence: + * - `psa_drv_se_mac_setup_t` + * - `psa_drv_se_mac_update_t` + * - `psa_drv_se_mac_update_t` + * - ... + * - `psa_drv_se_mac_finish_t` or `psa_drv_se_mac_finish_verify_t` + * + * If a previously started secure element MAC operation needs to be terminated, + * it should be done so by the `psa_drv_se_mac_abort_t`. Failure to do so may + * result in allocated resources not being freed or in other undefined + * behavior. + */ +/**@{*/ +/** \brief A function that starts a secure element MAC operation for a PSA + * Crypto Driver implementation + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] op_context A structure that will contain the + * hardware-specific MAC context + * \param[in] key_slot The slot of the key to be used for the + * operation + * \param[in] algorithm The algorithm to be used to underly the MAC + * operation + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context, + void *op_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t algorithm); + +/** \brief A function that continues a previously started secure element MAC + * operation + * + * \param[in,out] op_context A hardware-specific structure for the + * previously-established MAC operation to be + * updated + * \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_se_mac_update_t)(void *op_context, + const uint8_t *p_input, + size_t input_length); + +/** \brief a function that completes a previously started secure element MAC + * operation by returning the resulting MAC. + * + * \param[in,out] op_context A hardware-specific structure for the + * previously started MAC operation to be + * finished + * \param[out] p_mac A buffer where the generated MAC will be + * placed + * \param[in] mac_size The size in bytes of the buffer that has been + * allocated for the `output` buffer + * \param[out] p_mac_length After completion, will contain the number of + * bytes placed in the `p_mac` buffer + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context, + uint8_t *p_mac, + size_t mac_size, + size_t *p_mac_length); + +/** \brief A function that completes a previously started secure element MAC + * operation by comparing the resulting MAC against a provided value + * + * \param[in,out] op_context A hardware-specific structure for the previously + * started MAC operation to be fiinished + * \param[in] p_mac The MAC value against which the resulting MAC + * will be compared against + * \param[in] mac_length The size in bytes of the value stored in `p_mac` + * + * \retval #PSA_SUCCESS + * The operation completed successfully and the MACs matched each + * other + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The operation completed successfully, but the calculated MAC did + * not match the provided MAC + */ +typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *op_context, + const uint8_t *p_mac, + size_t mac_length); + +/** \brief A function that aborts a previous started secure element MAC + * operation + * + * \param[in,out] op_context A hardware-specific structure for the previously + * started MAC operation to be aborted + */ +typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context); + +/** \brief A function that performs a secure element MAC operation in one + * command and returns the calculated MAC + * + * \param[in,out] drv_context The driver context structure. + * \param[in] p_input A buffer containing the message to be MACed + * \param[in] input_length The size in bytes of `p_input` + * \param[in] key_slot The slot of the key to be used + * \param[in] alg The algorithm to be used to underlie the MAC + * operation + * \param[out] p_mac A buffer where the generated MAC will be + * placed + * \param[in] mac_size The size in bytes of the `p_mac` buffer + * \param[out] p_mac_length After completion, will contain the number of + * bytes placed in the `output` buffer + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context, + const uint8_t *p_input, + size_t input_length, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + uint8_t *p_mac, + size_t mac_size, + size_t *p_mac_length); + +/** \brief A function that performs a secure element MAC operation in one + * command and compares the resulting MAC against a provided value + * + * \param[in,out] drv_context The driver context structure. + * \param[in] p_input A buffer containing the message to be MACed + * \param[in] input_length The size in bytes of `input` + * \param[in] key_slot The slot of the key to be used + * \param[in] alg The algorithm to be used to underlie the MAC + * operation + * \param[in] p_mac The MAC value against which the resulting MAC will + * be compared against + * \param[in] mac_length The size in bytes of `mac` + * + * \retval #PSA_SUCCESS + * The operation completed successfully and the MACs matched each + * other + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The operation completed successfully, but the calculated MAC did + * not match the provided MAC + */ +typedef psa_status_t (*psa_drv_se_mac_verify_t)(psa_drv_se_context_t *drv_context, + const uint8_t *p_input, + size_t input_length, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_mac, + size_t mac_length); + +/** \brief A struct containing all of the function pointers needed to + * perform secure element MAC operations + * + * PSA Crypto API implementations should populate the table as appropriate + * upon startup. + * + * If one of the functions is not implemented (such as + * `psa_drv_se_mac_generate_t`), it should be set to NULL. + * + * Driver implementers should ensure that they implement all of the functions + * that make sense for their hardware, and that they provide a full solution + * (for example, if they support `p_setup`, they should also support + * `p_update` and at least one of `p_finish` or `p_finish_verify`). + * + */ +typedef struct { + /**The size in bytes of the hardware-specific secure element MAC context + * structure + */ + size_t context_size; + /** Function that performs a MAC setup operation + */ + psa_drv_se_mac_setup_t p_setup; + /** Function that performs a MAC update operation + */ + psa_drv_se_mac_update_t p_update; + /** Function that completes a MAC operation + */ + psa_drv_se_mac_finish_t p_finish; + /** Function that completes a MAC operation with a verify check + */ + psa_drv_se_mac_finish_verify_t p_finish_verify; + /** Function that aborts a previoustly started MAC operation + */ + psa_drv_se_mac_abort_t p_abort; + /** Function that performs a MAC operation in one call + */ + psa_drv_se_mac_generate_t p_mac; + /** Function that performs a MAC and verify operation in one call + */ + psa_drv_se_mac_verify_t p_mac_verify; +} psa_drv_se_mac_t; +/**@}*/ + +/** \defgroup se_cipher Secure Element Symmetric Ciphers + * + * Encryption and Decryption using secure element keys in block modes other + * than ECB must be done in multiple parts, using the following flow: + * - `psa_drv_se_cipher_setup_t` + * - `psa_drv_se_cipher_set_iv_t` (optional depending upon block mode) + * - `psa_drv_se_cipher_update_t` + * - `psa_drv_se_cipher_update_t` + * - ... + * - `psa_drv_se_cipher_finish_t` + * + * If a previously started secure element Cipher operation needs to be + * terminated, it should be done so by the `psa_drv_se_cipher_abort_t`. Failure + * to do so may result in allocated resources not being freed or in other + * undefined behavior. + * + * In situations where a PSA Cryptographic API implementation is using a block + * mode not-supported by the underlying hardware or driver, it can construct + * the block mode itself, while calling the `psa_drv_se_cipher_ecb_t` function + * for the cipher operations. + */ +/**@{*/ + +/** \brief A function that provides the cipher setup function for a + * secure element driver + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] op_context A structure that will contain the + * hardware-specific cipher context. + * \param[in] key_slot The slot of the key to be used for the + * operation + * \param[in] algorithm The algorithm to be used in the cipher + * operation + * \param[in] direction Indicates whether the operation is an encrypt + * or decrypt + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED + */ +typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context, + void *op_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t algorithm, + psa_encrypt_or_decrypt_t direction); + +/** \brief A function that sets the initialization vector (if + * necessary) for an secure element cipher operation + * + * Rationale: The `psa_se_cipher_*` operation in the PSA Cryptographic API has + * two IV functions: one to set the IV, and one to generate it internally. The + * generate function is not necessary for the drivers to implement as the PSA + * Crypto implementation can do the generation using its RNG features. + * + * \param[in,out] op_context A structure that contains the previously set up + * hardware-specific cipher context + * \param[in] p_iv A buffer containing the initialization vector + * \param[in] iv_length The size (in bytes) of the `p_iv` buffer + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, + const uint8_t *p_iv, + size_t iv_length); + +/** \brief A function that continues a previously started secure element cipher + * operation + * + * \param[in,out] op_context A hardware-specific structure for the + * previously started cipher operation + * \param[in] p_input A buffer containing the data to be + * encrypted/decrypted + * \param[in] input_size The size in bytes of the buffer pointed to + * by `p_input` + * \param[out] p_output The caller-allocated buffer where the + * output will be placed + * \param[in] output_size The allocated size in bytes of the + * `p_output` buffer + * \param[out] p_output_length After completion, will contain the number + * of bytes placed in the `p_output` buffer + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, + const uint8_t *p_input, + size_t input_size, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** \brief A function that completes a previously started secure element cipher + * operation + * + * \param[in,out] op_context A hardware-specific structure for the + * previously started cipher operation + * \param[out] p_output The caller-allocated buffer where the output + * will be placed + * \param[in] output_size The allocated size in bytes of the `p_output` + * buffer + * \param[out] p_output_length After completion, will contain the number of + * bytes placed in the `p_output` buffer + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** \brief A function that aborts a previously started secure element cipher + * operation + * + * \param[in,out] op_context A hardware-specific structure for the + * previously started cipher operation + */ +typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context); + +/** \brief A function that performs the ECB block mode for secure element + * cipher operations + * + * Note: this function should only be used with implementations that do not + * provide a needed higher-level operation. + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot The slot of the key to be used for the operation + * \param[in] algorithm The algorithm to be used in the cipher operation + * \param[in] direction Indicates whether the operation is an encrypt or + * decrypt + * \param[in] p_input A buffer containing the data to be + * encrypted/decrypted + * \param[in] input_size The size in bytes of the buffer pointed to by + * `p_input` + * \param[out] p_output The caller-allocated buffer where the output + * will be placed + * \param[in] output_size The allocated size in bytes of the `p_output` + * buffer + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED + */ +typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t algorithm, + psa_encrypt_or_decrypt_t direction, + const uint8_t *p_input, + size_t input_size, + uint8_t *p_output, + size_t output_size); + +/** + * \brief A struct containing all of the function pointers needed to implement + * cipher operations using secure elements. + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup or at build time. + * + * If one of the functions is not implemented (such as + * `psa_drv_se_cipher_ecb_t`), it should be set to NULL. + */ +typedef struct { + /** The size in bytes of the hardware-specific secure element cipher + * context structure + */ + size_t context_size; + /** Function that performs a cipher setup operation */ + psa_drv_se_cipher_setup_t p_setup; + /** Function that sets a cipher IV (if necessary) */ + psa_drv_se_cipher_set_iv_t p_set_iv; + /** Function that performs a cipher update operation */ + psa_drv_se_cipher_update_t p_update; + /** Function that completes a cipher operation */ + psa_drv_se_cipher_finish_t p_finish; + /** Function that aborts a cipher operation */ + psa_drv_se_cipher_abort_t p_abort; + /** Function that performs ECB mode for a cipher operation + * (Danger: ECB mode should not be used directly by clients of the PSA + * Crypto Client API) + */ + psa_drv_se_cipher_ecb_t p_ecb; +} psa_drv_se_cipher_t; + +/**@}*/ + +/** \defgroup se_asymmetric Secure Element 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 + * keys in a secure element must be done in single function calls. + */ +/**@{*/ + +/** + * \brief A function that signs a hash or short message with a private key in + * a secure element + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Key slot of an asymmetric key pair + * \param[in] alg A signature algorithm that is compatible + * with the type of `key` + * \param[in] p_hash The hash to sign + * \param[in] hash_length Size of the `p_hash` buffer in bytes + * \param[out] p_signature Buffer where the signature is to be written + * \param[in] signature_size Size of the `p_signature` buffer in bytes + * \param[out] p_signature_length On success, the number of bytes + * that make up the returned signature value + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + uint8_t *p_signature, + size_t signature_size, + size_t *p_signature_length); + +/** + * \brief A function that verifies the signature a hash or short message using + * an asymmetric public key in a secure element + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Key slot of a public key or an asymmetric key + * pair + * \param[in] alg A signature algorithm that is compatible with + * the type of `key` + * \param[in] p_hash The hash whose signature is to be verified + * \param[in] hash_length Size of the `p_hash` buffer in bytes + * \param[in] p_signature Buffer containing the signature to verify + * \param[in] signature_length Size of the `p_signature` buffer in bytes + * + * \retval #PSA_SUCCESS + * The signature is valid. + */ +typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_hash, + size_t hash_length, + const uint8_t *p_signature, + size_t signature_length); + +/** + * \brief A function that encrypts a short message with an asymmetric public + * key in a secure element + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Key slot of a public key or an asymmetric key + * pair + * \param[in] alg An asymmetric encryption algorithm that is + * compatible with the type of `key` + * \param[in] p_input The message to encrypt + * \param[in] input_length Size of the `p_input` buffer in bytes + * \param[in] p_salt A salt or label, if supported by the + * encryption algorithm + * If the algorithm does not support a + * salt, pass `NULL`. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass `NULL`. + * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param[in] salt_length Size of the `p_salt` buffer in bytes + * If `p_salt` is `NULL`, pass 0. + * \param[out] p_output Buffer where the encrypted message is to + * be written + * \param[in] output_size Size of the `p_output` buffer in bytes + * \param[out] p_output_length On success, the number of bytes that make up + * the returned output + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_input, + size_t input_length, + const uint8_t *p_salt, + size_t salt_length, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** + * \brief A function that decrypts a short message with an asymmetric private + * key in a secure element. + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Key slot of an asymmetric key pair + * \param[in] alg An asymmetric encryption algorithm that is + * compatible with the type of `key` + * \param[in] p_input The message to decrypt + * \param[in] input_length Size of the `p_input` buffer in bytes + * \param[in] p_salt A salt or label, if supported by the + * encryption algorithm + * If the algorithm does not support a + * salt, pass `NULL`. + * If the algorithm supports an optional + * salt and you do not want to pass a salt, + * pass `NULL`. + * For #PSA_ALG_RSA_PKCS1V15_CRYPT, no salt is + * supported. + * \param[in] salt_length Size of the `p_salt` buffer in bytes + * If `p_salt` is `NULL`, pass 0. + * \param[out] p_output Buffer where the decrypted message is to + * be written + * \param[in] output_size Size of the `p_output` buffer in bytes + * \param[out] p_output_length On success, the number of bytes + * that make up the returned output + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t alg, + const uint8_t *p_input, + size_t input_length, + const uint8_t *p_salt, + size_t salt_length, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** + * \brief A struct containing all of the function pointers needed to implement + * asymmetric cryptographic operations using secure elements. + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup or at build time. + * + * If one of the functions is not implemented, it should be set to NULL. + */ +typedef struct { + /** Function that performs an asymmetric sign operation */ + psa_drv_se_asymmetric_sign_t p_sign; + /** Function that performs an asymmetric verify operation */ + psa_drv_se_asymmetric_verify_t p_verify; + /** Function that performs an asymmetric encrypt operation */ + psa_drv_se_asymmetric_encrypt_t p_encrypt; + /** Function that performs an asymmetric decrypt operation */ + psa_drv_se_asymmetric_decrypt_t p_decrypt; +} psa_drv_se_asymmetric_t; + +/**@}*/ + +/** \defgroup se_aead Secure Element Authenticated Encryption with Additional Data + * Authenticated Encryption with Additional Data (AEAD) operations with secure + * elements must be done in one function call. While this creates a burden for + * implementers as there must be sufficient space in memory for the entire + * message, it prevents decrypted data from being made available before the + * authentication operation is complete and the data is known to be authentic. + */ +/**@{*/ + +/** \brief A function that performs a secure element authenticated encryption + * operation + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Slot containing the key to use. + * \param[in] algorithm The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(`alg`) is true) + * \param[in] p_nonce Nonce or IV to use + * \param[in] nonce_length Size of the `p_nonce` buffer in bytes + * \param[in] p_additional_data Additional data that will be + * authenticated but not encrypted + * \param[in] additional_data_length Size of `p_additional_data` in bytes + * \param[in] p_plaintext Data that will be authenticated and + * encrypted + * \param[in] plaintext_length Size of `p_plaintext` in bytes + * \param[out] p_ciphertext Output buffer for the authenticated and + * encrypted data. The additional data is + * not part of this output. For algorithms + * where the encrypted data and the + * authentication tag are defined as + * separate outputs, the authentication + * tag is appended to the encrypted data. + * \param[in] ciphertext_size Size of the `p_ciphertext` buffer in + * bytes + * \param[out] p_ciphertext_length On success, the size of the output in + * the `p_ciphertext` buffer + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t algorithm, + const uint8_t *p_nonce, + size_t nonce_length, + const uint8_t *p_additional_data, + size_t additional_data_length, + const uint8_t *p_plaintext, + size_t plaintext_length, + uint8_t *p_ciphertext, + size_t ciphertext_size, + size_t *p_ciphertext_length); + +/** A function that peforms a secure element authenticated decryption operation + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key_slot Slot containing the key to use + * \param[in] algorithm The AEAD algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(`alg`) is true) + * \param[in] p_nonce Nonce or IV to use + * \param[in] nonce_length Size of the `p_nonce` buffer in bytes + * \param[in] p_additional_data Additional data that has been + * authenticated but not encrypted + * \param[in] additional_data_length Size of `p_additional_data` in bytes + * \param[in] p_ciphertext Data that has been authenticated and + * encrypted. + * For algorithms where the encrypted data + * and the authentication tag are defined + * as separate inputs, the buffer must + * contain the encrypted data followed by + * the authentication tag. + * \param[in] ciphertext_length Size of `p_ciphertext` in bytes + * \param[out] p_plaintext Output buffer for the decrypted data + * \param[in] plaintext_size Size of the `p_plaintext` buffer in + * bytes + * \param[out] p_plaintext_length On success, the size of the output in + * the `p_plaintext` buffer + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + psa_algorithm_t algorithm, + const uint8_t *p_nonce, + size_t nonce_length, + const uint8_t *p_additional_data, + size_t additional_data_length, + const uint8_t *p_ciphertext, + size_t ciphertext_length, + uint8_t *p_plaintext, + size_t plaintext_size, + size_t *p_plaintext_length); + +/** + * \brief A struct containing all of the function pointers needed to implement + * secure element Authenticated Encryption with Additional Data operations + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup. + * + * If one of the functions is not implemented, it should be set to NULL. + */ +typedef struct { + /** Function that performs the AEAD encrypt operation */ + psa_drv_se_aead_encrypt_t p_encrypt; + /** Function that performs the AEAD decrypt operation */ + psa_drv_se_aead_decrypt_t p_decrypt; +} psa_drv_se_aead_t; +/**@}*/ + +/** \defgroup se_key_management Secure Element Key Management + * Currently, key management is limited to importing keys in the clear, + * destroying keys, and exporting keys in the clear. + * Whether a key may be exported is determined by the key policies in place + * on the key slot. + */ +/**@{*/ + +/** An enumeration indicating how a key is created. + */ +typedef enum +{ + PSA_KEY_CREATION_IMPORT, /**< During psa_import_key() */ + PSA_KEY_CREATION_GENERATE, /**< During psa_generate_key() */ + PSA_KEY_CREATION_DERIVE, /**< During psa_key_derivation_output_key() */ + PSA_KEY_CREATION_COPY, /**< During psa_copy_key() */ + +#ifndef __DOXYGEN_ONLY__ + /** A key is being registered with mbedtls_psa_register_se_key(). + * + * The core only passes this value to + * psa_drv_se_key_management_t::p_validate_slot_number, not to + * psa_drv_se_key_management_t::p_allocate. The call to + * `p_validate_slot_number` is not followed by any other call to the + * driver: the key is considered successfully registered if the call to + * `p_validate_slot_number` succeeds, or if `p_validate_slot_number` is + * null. + * + * With this creation method, the driver must return #PSA_SUCCESS if + * the given attributes are compatible with the existing key in the slot, + * and #PSA_ERROR_DOES_NOT_EXIST if the driver can determine that there + * is no key with the specified slot number. + * + * This is an Mbed Crypto extension. + */ + PSA_KEY_CREATION_REGISTER, +#endif +} psa_key_creation_method_t; + +/** \brief A function that allocates a slot for a key. + * + * To create a key in a specific slot in a secure element, the core + * first calls this function to determine a valid slot number, + * then calls a function to create the key material in that slot. + * In nominal conditions (that is, if no error occurs), + * the effect of a call to a key creation function in the PSA Cryptography + * API with a lifetime that places the key in a secure element is the + * following: + * -# The core calls psa_drv_se_key_management_t::p_allocate + * (or in some implementations + * psa_drv_se_key_management_t::p_validate_slot_number). The driver + * selects (or validates) a suitable slot number given the key attributes + * and the state of the secure element. + * -# The core calls a key creation function in the driver. + * + * The key creation functions in the PSA Cryptography API are: + * - psa_import_key(), which causes + * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_IMPORT + * then a call to psa_drv_se_key_management_t::p_import. + * - psa_generate_key(), which causes + * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_GENERATE + * then a call to psa_drv_se_key_management_t::p_import. + * - psa_key_derivation_output_key(), which causes + * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_DERIVE + * then a call to psa_drv_se_key_derivation_t::p_derive. + * - psa_copy_key(), which causes + * a call to `p_allocate` with \p method = #PSA_KEY_CREATION_COPY + * then a call to psa_drv_se_key_management_t::p_export. + * + * In case of errors, other behaviors are possible. + * - If the PSA Cryptography subsystem dies after the first step, + * for example because the device has lost power abruptly, + * the second step may never happen, or may happen after a reset + * and re-initialization. Alternatively, after a reset and + * re-initialization, the core may call + * psa_drv_se_key_management_t::p_destroy on the slot number that + * was allocated (or validated) instead of calling a key creation function. + * - If an error occurs, the core may call + * psa_drv_se_key_management_t::p_destroy on the slot number that + * was allocated (or validated) instead of calling a key creation function. + * + * Errors and system resets also have an impact on the driver's persistent + * data. If a reset happens before the overall key creation process is + * completed (before or after the second step above), it is unspecified + * whether the persistent data after the reset is identical to what it + * was before or after the call to `p_allocate` (or `p_validate_slot_number`). + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] persistent_data A pointer to the persistent data + * that allows writing. + * \param[in] attributes Attributes of the key. + * \param method The way in which the key is being created. + * \param[out] key_slot Slot where the key will be stored. + * This must be a valid slot for a key of the + * chosen type. It must be unoccupied. + * + * \retval #PSA_SUCCESS + * Success. + * The core will record \c *key_slot as the key slot where the key + * is stored and will update the persistent data in storage. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + */ +typedef psa_status_t (*psa_drv_se_allocate_key_t)( + psa_drv_se_context_t *drv_context, + void *persistent_data, + const psa_key_attributes_t *attributes, + psa_key_creation_method_t method, + psa_key_slot_number_t *key_slot); + +/** \brief A function that determines whether a slot number is valid + * for a key. + * + * To create a key in a specific slot in a secure element, the core + * first calls this function to validate the choice of slot number, + * then calls a function to create the key material in that slot. + * See the documentation of #psa_drv_se_allocate_key_t for more details. + * + * As of the PSA Cryptography API specification version 1.0, there is no way + * for applications to trigger a call to this function. However some + * implementations offer the capability to create or declare a key in + * a specific slot via implementation-specific means, generally for the + * sake of initial device provisioning or onboarding. Such a mechanism may + * be added to a future version of the PSA Cryptography API specification. + * + * This function may update the driver's persistent data through + * \p persistent_data. The core will save the updated persistent data at the + * end of the key creation process. See the description of + * ::psa_drv_se_allocate_key_t for more information. + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] persistent_data A pointer to the persistent data + * that allows writing. + * \param[in] attributes Attributes of the key. + * \param method The way in which the key is being created. + * \param[in] key_slot Slot where the key is to be stored. + * + * \retval #PSA_SUCCESS + * The given slot number is valid for a key with the given + * attributes. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The given slot number is not valid for a key with the + * given attributes. This includes the case where the slot + * number is not valid at all. + * \retval #PSA_ERROR_ALREADY_EXISTS + * There is already a key with the specified slot number. + * Drivers may choose to return this error from the key + * creation function instead. + */ +typedef psa_status_t (*psa_drv_se_validate_slot_number_t)( + psa_drv_se_context_t *drv_context, + void *persistent_data, + const psa_key_attributes_t *attributes, + psa_key_creation_method_t method, + psa_key_slot_number_t key_slot); + +/** \brief A function that imports a key into a secure element in binary format + * + * This function can support any output from psa_export_key(). Refer to the + * documentation of psa_export_key() for the format for each key type. + * + * \param[in,out] drv_context The driver context structure. + * \param key_slot Slot where the key will be stored. + * This must be a valid slot for a key of the + * chosen type. It must be unoccupied. + * \param[in] attributes The key attributes, including the lifetime, + * the key type and the usage policy. + * Drivers should not access the key size stored + * in the attributes: it may not match the + * data passed in \p data. + * Drivers can call psa_get_key_lifetime(), + * psa_get_key_type(), + * psa_get_key_usage_flags() and + * psa_get_key_algorithm() to access this + * information. + * \param[in] data Buffer containing the key data. + * \param[in] data_length Size of the \p data buffer in bytes. + * \param[out] bits On success, the key size in bits. The driver + * must determine this value after parsing the + * key according to the key type. + * This value is not used if the function fails. + * + * \retval #PSA_SUCCESS + * Success. + */ +typedef psa_status_t (*psa_drv_se_import_key_t)( + psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + size_t *bits); + +/** + * \brief A function that destroys a secure element key and restore the slot to + * its default state + * + * This function destroys the content of the key from a secure element. + * Implementations shall make a best effort to ensure that any previous content + * of the slot is unrecoverable. + * + * This function returns the specified slot to its default state. + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] persistent_data A pointer to the persistent data + * that allows writing. + * \param key_slot The key slot to erase. + * + * \retval #PSA_SUCCESS + * The slot's content, if any, has been erased. + */ +typedef psa_status_t (*psa_drv_se_destroy_key_t)( + psa_drv_se_context_t *drv_context, + void *persistent_data, + psa_key_slot_number_t key_slot); + +/** + * \brief A function that exports a secure element key in binary format + * + * The output of this function can be passed to psa_import_key() to + * create an equivalent object. + * + * If a key is created with `psa_import_key()` and then exported with + * this function, it is not guaranteed that the resulting data is + * identical: the implementation may choose a different representation + * of the same key if the format permits it. + * + * This function should generate output in the same format that + * `psa_export_key()` does. Refer to the + * documentation of `psa_export_key()` for the format for each key type. + * + * \param[in,out] drv_context The driver context structure. + * \param[in] key Slot whose content is to be exported. This must + * be an occupied key slot. + * \param[out] p_data Buffer where the key data is to be written. + * \param[in] data_size Size of the `p_data` buffer in bytes. + * \param[out] p_data_length On success, the number of bytes + * that make up the key data. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_DOES_NOT_EXIST + * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key, + uint8_t *p_data, + size_t data_size, + size_t *p_data_length); + +/** + * \brief A function that generates a symmetric or asymmetric key on a secure + * element + * + * If the key type \c type recorded in \p attributes + * is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\c type) = 1), + * the driver may export the public key at the time of generation, + * in the format documented for psa_export_public_key() by writing it + * to the \p pubkey buffer. + * This is optional, intended for secure elements that output the + * public key at generation time and that cannot export the public key + * later. Drivers that do not need this feature should leave + * \p *pubkey_length set to 0 and should + * implement the psa_drv_key_management_t::p_export_public function. + * Some implementations do not support this feature, in which case + * \p pubkey is \c NULL and \p pubkey_size is 0. + * + * \param[in,out] drv_context The driver context structure. + * \param key_slot Slot where the key will be stored. + * This must be a valid slot for a key of the + * chosen type. It must be unoccupied. + * \param[in] attributes The key attributes, including the lifetime, + * the key type and size, and the usage policy. + * Drivers can call psa_get_key_lifetime(), + * psa_get_key_type(), psa_get_key_bits(), + * psa_get_key_usage_flags() and + * psa_get_key_algorithm() to access this + * information. + * \param[out] pubkey A buffer where the driver can write the + * public key, when generating an asymmetric + * key pair. + * This is \c NULL when generating a symmetric + * key or if the core does not support + * exporting the public key at generation time. + * \param pubkey_size The size of the `pubkey` buffer in bytes. + * This is 0 when generating a symmetric + * key or if the core does not support + * exporting the public key at generation time. + * \param[out] pubkey_length On entry, this is always 0. + * On success, the number of bytes written to + * \p pubkey. If this is 0 or unchanged on return, + * the core will not read the \p pubkey buffer, + * and will instead call the driver's + * psa_drv_key_management_t::p_export_public + * function to export the public key when needed. + */ +typedef psa_status_t (*psa_drv_se_generate_key_t)( + psa_drv_se_context_t *drv_context, + psa_key_slot_number_t key_slot, + const psa_key_attributes_t *attributes, + uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length); + +/** + * \brief A struct containing all of the function pointers needed to for secure + * element key management + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup or at build time. + * + * If one of the functions is not implemented, it should be set to NULL. + */ +typedef struct { + /** Function that allocates a slot for a key. */ + psa_drv_se_allocate_key_t p_allocate; + /** Function that checks the validity of a slot for a key. */ + psa_drv_se_validate_slot_number_t p_validate_slot_number; + /** Function that performs a key import operation */ + psa_drv_se_import_key_t p_import; + /** Function that performs a generation */ + psa_drv_se_generate_key_t p_generate; + /** Function that performs a key destroy operation */ + psa_drv_se_destroy_key_t p_destroy; + /** Function that performs a key export operation */ + psa_drv_se_export_key_t p_export; + /** Function that performs a public key export operation */ + psa_drv_se_export_key_t p_export_public; +} psa_drv_se_key_management_t; + +/**@}*/ + +/** \defgroup driver_derivation Secure Element Key Derivation and Agreement + * Key derivation is the process of generating new key material using an + * existing key and additional parameters, iterating through a basic + * cryptographic function, such as a hash. + * Key agreement is a part of cryptographic protocols that allows two parties + * to agree on the same key value, but starting from different original key + * material. + * The flows are similar, and the PSA Crypto Driver Model uses the same functions + * for both of the flows. + * + * There are two different final functions for the flows, + * `psa_drv_se_key_derivation_derive` and `psa_drv_se_key_derivation_export`. + * `psa_drv_se_key_derivation_derive` is used when the key material should be + * placed in a slot on the hardware and not exposed to the caller. + * `psa_drv_se_key_derivation_export` is used when the key material should be + * returned to the PSA Cryptographic API implementation. + * + * Different key derivation algorithms require a different number of inputs. + * Instead of having an API that takes as input variable length arrays, which + * can be problemmatic to manage on embedded platforms, the inputs are passed + * to the driver via a function, `psa_drv_se_key_derivation_collateral`, that + * is called multiple times with different `collateral_id`s. Thus, for a key + * derivation algorithm that required 3 parameter inputs, the flow would look + * something like: + * ~~~~~~~~~~~~~{.c} + * psa_drv_se_key_derivation_setup(kdf_algorithm, source_key, dest_key_size_bytes); + * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_0, + * p_collateral_0, + * collateral_0_size); + * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_1, + * p_collateral_1, + * collateral_1_size); + * psa_drv_se_key_derivation_collateral(kdf_algorithm_collateral_id_2, + * p_collateral_2, + * collateral_2_size); + * psa_drv_se_key_derivation_derive(); + * ~~~~~~~~~~~~~ + * + * key agreement example: + * ~~~~~~~~~~~~~{.c} + * psa_drv_se_key_derivation_setup(alg, source_key. dest_key_size_bytes); + * psa_drv_se_key_derivation_collateral(DHE_PUBKEY, p_pubkey, pubkey_size); + * psa_drv_se_key_derivation_export(p_session_key, + * session_key_size, + * &session_key_length); + * ~~~~~~~~~~~~~ + */ +/**@{*/ + +/** \brief A function that Sets up a secure element key derivation operation by + * specifying the algorithm and the source key sot + * + * \param[in,out] drv_context The driver context structure. + * \param[in,out] op_context A hardware-specific structure containing any + * context information for the implementation + * \param[in] kdf_alg The algorithm to be used for the key derivation + * \param[in] source_key The key to be used as the source material for + * the key derivation + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context, + void *op_context, + psa_algorithm_t kdf_alg, + psa_key_slot_number_t source_key); + +/** \brief A function that provides collateral (parameters) needed for a secure + * element key derivation or key agreement operation + * + * Since many key derivation algorithms require multiple parameters, it is + * expected that this function may be called multiple times for the same + * operation, each with a different algorithm-specific `collateral_id` + * + * \param[in,out] op_context A hardware-specific structure containing any + * context information for the implementation + * \param[in] collateral_id An ID for the collateral being provided + * \param[in] p_collateral A buffer containing the collateral data + * \param[in] collateral_size The size in bytes of the collateral + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, + uint32_t collateral_id, + const uint8_t *p_collateral, + size_t collateral_size); + +/** \brief A function that performs the final secure element key derivation + * step and place the generated key material in a slot + * + * \param[in,out] op_context A hardware-specific structure containing any + * context information for the implementation + * \param[in] dest_key The slot where the generated key material + * should be placed + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, + psa_key_slot_number_t dest_key); + +/** \brief A function that performs the final step of a secure element key + * agreement and place the generated key material in a buffer + * + * \param[out] p_output Buffer in which to place the generated key + * material + * \param[in] output_size The size in bytes of `p_output` + * \param[out] p_output_length Upon success, contains the number of bytes of + * key material placed in `p_output` + * + * \retval #PSA_SUCCESS + */ +typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context, + uint8_t *p_output, + size_t output_size, + size_t *p_output_length); + +/** + * \brief A struct containing all of the function pointers needed to for secure + * element key derivation and agreement + * + * PSA Crypto API implementations should populate instances of the table as + * appropriate upon startup. + * + * If one of the functions is not implemented, it should be set to NULL. + */ +typedef struct { + /** The driver-specific size of the key derivation context */ + size_t context_size; + /** Function that performs a key derivation setup */ + psa_drv_se_key_derivation_setup_t p_setup; + /** Function that sets key derivation collateral */ + psa_drv_se_key_derivation_collateral_t p_collateral; + /** Function that performs a final key derivation step */ + psa_drv_se_key_derivation_derive_t p_derive; + /** Function that perforsm a final key derivation or agreement and + * exports the key */ + psa_drv_se_key_derivation_export_t p_export; +} psa_drv_se_key_derivation_t; + +/**@}*/ + +/** \defgroup se_registration Secure element driver registration + */ +/**@{*/ + +/** A structure containing pointers to all the entry points of a + * secure element driver. + * + * Future versions of this specification may add extra substructures at + * the end of this structure. + */ +typedef struct { + /** The version of the driver HAL that this driver implements. + * This is a protection against loading driver binaries built against + * a different version of this specification. + * Use #PSA_DRV_SE_HAL_VERSION. + */ + uint32_t hal_version; + + /** The size of the driver's persistent data in bytes. + * + * This can be 0 if the driver does not need persistent data. + * + * See the documentation of psa_drv_se_context_t::persistent_data + * for more information about why and how a driver can use + * persistent data. + */ + size_t persistent_data_size; + + /** The driver initialization function. + * + * This function is called once during the initialization of the + * PSA Cryptography subsystem, before any other function of the + * driver is called. If this function returns a failure status, + * the driver will be unusable, at least until the next system reset. + * + * If this field is \c NULL, it is equivalent to a function that does + * nothing and returns #PSA_SUCCESS. + */ + psa_drv_se_init_t p_init; + + const psa_drv_se_key_management_t *key_management; + const psa_drv_se_mac_t *mac; + const psa_drv_se_cipher_t *cipher; + const psa_drv_se_aead_t *aead; + const psa_drv_se_asymmetric_t *asymmetric; + const psa_drv_se_key_derivation_t *derivation; +} psa_drv_se_t; + +/** The current version of the secure element driver HAL. + */ +/* 0.0.0 patchlevel 5 */ +#define PSA_DRV_SE_HAL_VERSION 0x00000005 + +/** Register an external cryptoprocessor (secure element) driver. + * + * This function is only intended to be used by driver code, not by + * application code. In implementations with separation between the + * PSA cryptography module and applications, this function should + * only be available to callers that run in the same memory space as + * the cryptography module, and should not be exposed to applications + * running in a different memory space. + * + * This function may be called before psa_crypto_init(). It is + * implementation-defined whether this function may be called + * after psa_crypto_init(). + * + * \note Implementations store metadata about keys including the lifetime + * value, which contains the driver's location indicator. Therefore, + * from one instantiation of the PSA Cryptography + * library to the next one, if there is a key in storage with a certain + * lifetime value, you must always register the same driver (or an + * updated version that communicates with the same secure element) + * with the same location value. + * + * \param location The location value through which this driver will + * be exposed to applications. + * This driver will be used for all keys such that + * `location == #PSA_KEY_LIFETIME_GET_LOCATION( lifetime )`. + * The value #PSA_KEY_LOCATION_LOCAL_STORAGE is reserved + * and may not be used for drivers. Implementations + * may reserve other values. + * \param[in] methods The method table of the driver. This structure must + * remain valid for as long as the cryptography + * module keeps running. It is typically a global + * constant. + * + * \return #PSA_SUCCESS + * The driver was successfully registered. Applications can now + * use \p location to access keys through the methods passed to + * this function. + * \return #PSA_ERROR_BAD_STATE + * This function was called after the initialization of the + * cryptography module, and this implementation does not support + * driver registration at this stage. + * \return #PSA_ERROR_ALREADY_EXISTS + * There is already a registered driver for this value of \p location. + * \return #PSA_ERROR_INVALID_ARGUMENT + * \p location is a reserved value. + * \return #PSA_ERROR_NOT_SUPPORTED + * `methods->hal_version` is not supported by this implementation. + * \return #PSA_ERROR_INSUFFICIENT_MEMORY + * \return #PSA_ERROR_NOT_PERMITTED + * \return #PSA_ERROR_STORAGE_FAILURE + * \return #PSA_ERROR_DATA_CORRUPT + */ +psa_status_t psa_register_se_driver( + psa_key_location_t location, + const psa_drv_se_t *methods); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_SE_DRIVER_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_sizes.h b/lib/mbedtls-2.27.0/include/psa/crypto_sizes.h new file mode 100644 index 0000000..79f9673 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_sizes.h @@ -0,0 +1,1135 @@ +/** + * \file psa/crypto_sizes.h + * + * \brief PSA cryptography module: Mbed TLS buffer size macros + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * This file contains the definitions of macros that are useful to + * compute buffer sizes. The signatures and semantics of these macros + * are standardized, but the definitions are not, because they depend on + * the available algorithms and, in some cases, on permitted tolerances + * on buffer sizes. + * + * In implementations with isolation between the application and the + * cryptography module, implementers should take care to ensure that + * the definitions that are exposed to applications match what the + * module implements. + * + * Macros that compute sizes whose values do not depend on the + * implementation are in crypto.h. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_SIZES_H +#define PSA_CRYPTO_SIZES_H + +/* Include the Mbed TLS configuration file, the way Mbed TLS does it + * in each of its header files. */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8) +#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8) + +#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \ + (((length) + (block_size) - 1) / (block_size) * (block_size)) + +/** 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. + */ +#define PSA_HASH_LENGTH(alg) \ + ( \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD2 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD4 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_MD5 ? 16 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_RIPEMD160 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_1 ? 20 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512 ? 64 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA_512_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_224 ? 28 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_256 ? 32 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_384 ? 48 : \ + PSA_ALG_HMAC_GET_HASH(alg) == PSA_ALG_SHA3_512 ? 64 : \ + 0) + +/** \def PSA_HASH_MAX_SIZE + * + * Maximum size of a hash. + * + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a hash in bytes. + */ +/* Note: for HMAC-SHA-3, the block size is 144 bytes for HMAC-SHA3-226, + * 136 bytes for HMAC-SHA3-256, 104 bytes for SHA3-384, 72 bytes for + * HMAC-SHA3-512. */ +#if defined(MBEDTLS_SHA512_C) +#define PSA_HASH_MAX_SIZE 64 +#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 128 +#else +#define PSA_HASH_MAX_SIZE 32 +#define PSA_HMAC_MAX_HASH_BLOCK_SIZE 64 +#endif + +/** \def PSA_MAC_MAX_SIZE + * + * Maximum size of a MAC. + * + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a MAC in bytes. + */ +/* All non-HMAC MACs have a maximum size that's smaller than the + * minimum possible value of PSA_HASH_MAX_SIZE in this implementation. */ +/* Note that the encoding of truncated MAC algorithms limits this value + * to 64 bytes. + */ +#define PSA_MAC_MAX_SIZE PSA_HASH_MAX_SIZE + +/** The length of a tag for an AEAD algorithm, in bytes. + * + * This macro can be used to allocate a buffer of sufficient size to store the + * tag output from psa_aead_finish(). + * + * See also #PSA_AEAD_TAG_MAX_SIZE. + * + * \param key_type The type of the AEAD key. + * \param key_bits The size of the AEAD key in bits. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The tag length for the specified algorithm and key. + * If the AEAD algorithm does not have an identified + * tag that can be distinguished from the rest of + * the ciphertext, return 0. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ + ((void) (key_bits), 0)) + +/** The maximum tag size for all supported AEAD algorithms, in bytes. + * + * See also #PSA_AEAD_TAG_LENGTH(\p key_type, \p key_bits, \p alg). + */ +#define PSA_AEAD_TAG_MAX_SIZE 16 + +/* The maximum size of an RSA key on this implementation, in bits. + * This is a vendor-specific macro. + * + * Mbed TLS does not set a hard limit on the size of RSA keys: any key + * whose parameters fit in a bignum is accepted. However large keys can + * induce a large memory usage and long computation times. Unlike other + * auxiliary macros in this file and in crypto.h, which reflect how the + * library is configured, this macro defines how the library is + * configured. This implementation refuses to import or generate an + * RSA key whose size is larger than the value defined here. + * + * Note that an implementation may set different size limits for different + * operations, and does not need to accept all key sizes up to the limit. */ +#define PSA_VENDOR_RSA_MAX_KEY_BITS 4096 + +/* The maximum size of an ECC key on this implementation, in bits. + * This is a vendor-specific macro. */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 521 +#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 512 +#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 448 +#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384 +#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 384 +#elif defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256 +#elif defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256 +#elif defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 256 +#elif defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 255 +#elif defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224 +#elif defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 224 +#elif defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192 +#elif defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 192 +#else +#define PSA_VENDOR_ECC_MAX_CURVE_BITS 0 +#endif + +/** This macro returns the maximum supported length of the PSK for the + * TLS-1.2 PSK-to-MS key derivation + * (#PSA_ALG_TLS12_PSK_TO_MS(\c hash_alg)). + * + * The maximum supported length does not depend on the chosen hash algorithm. + * + * Quoting RFC 4279, Sect 5.3: + * TLS implementations supporting these ciphersuites MUST support + * arbitrary PSK identities up to 128 octets in length, and arbitrary + * PSKs up to 64 octets in length. Supporting longer identities and + * keys is RECOMMENDED. + * + * Therefore, no implementation should define a value smaller than 64 + * for #PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE. + */ +#define PSA_TLS12_PSK_TO_MS_PSK_MAX_SIZE 128 + +/** The maximum size of a block cipher. */ +#define PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE 16 + +/** The size of the output of psa_mac_sign_finish(), in bytes. + * + * This is also the MAC size that psa_mac_verify_finish() expects. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type The type of the MAC key. + * \param key_bits The size of the MAC key in bits. + * \param alg A MAC algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_MAC(\p alg) is true). + * + * \return The MAC size for the specified algorithm with + * the specified key parameters. + * \return 0 if the MAC algorithm is not recognized. + * \return Either 0 or the correct size for a MAC algorithm that + * the implementation recognizes, but does not support. + * \return Unspecified if the key parameters are not consistent + * with the algorithm. + */ +#define PSA_MAC_LENGTH(key_type, key_bits, alg) \ + ((alg) & PSA_ALG_MAC_TRUNCATION_MASK ? PSA_MAC_TRUNCATED_LENGTH(alg) : \ + PSA_ALG_IS_HMAC(alg) ? PSA_HASH_LENGTH(PSA_ALG_HMAC_GET_HASH(alg)) : \ + PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + ((void)(key_type), (void)(key_bits), 0)) + +/** The maximum size of the output of psa_aead_encrypt(), in bytes. + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_aead_encrypt() will not fail due to an + * insufficient buffer size. Depending on the algorithm, the actual size of + * the ciphertext may be smaller. + * + * See also #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param plaintext_length Size of the plaintext in bytes. + * + * \return The AEAD ciphertext size for the specified + * algorithm. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, plaintext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + (plaintext_length) + PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ + 0) + +/** A sufficient output buffer size for psa_aead_encrypt(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the ciphertext buffer is at least this large, it is guaranteed + * that psa_aead_encrypt() will not fail due to an insufficient buffer size. + * + * \note This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * See also #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, + * \p plaintext_length). + * + * \param plaintext_length Size of the plaintext in bytes. + * + * \return A sufficient output buffer size for any of the + * supported key types and AEAD algorithms. + * + */ +#define PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(plaintext_length) \ + ((plaintext_length) + PSA_AEAD_TAG_MAX_SIZE) + + +/** The maximum size of the output of psa_aead_decrypt(), in bytes. + * + * If the size of the plaintext buffer is at least this large, it is + * guaranteed that psa_aead_decrypt() will not fail due to an + * insufficient buffer size. Depending on the algorithm, the actual size of + * the plaintext may be smaller. + * + * See also #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param ciphertext_length Size of the plaintext in bytes. + * + * \return The AEAD ciphertext size for the specified + * algorithm. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + (ciphertext_length) > PSA_ALG_AEAD_GET_TAG_LENGTH(alg) ? \ + (ciphertext_length) - PSA_ALG_AEAD_GET_TAG_LENGTH(alg) : \ + 0) + +/** A sufficient output buffer size for psa_aead_decrypt(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the plaintext buffer is at least this large, it is guaranteed + * that psa_aead_decrypt() will not fail due to an insufficient buffer size. + * + * \note This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * See also #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, + * \p ciphertext_length). + * + * \param ciphertext_length Size of the ciphertext in bytes. + * + * \return A sufficient output buffer size for any of the + * supported key types and AEAD algorithms. + * + */ +#define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ + (ciphertext_length) + +/** The default nonce size for an AEAD algorithm, in bytes. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the nonce output from #psa_aead_generate_nonce(). + * + * See also #PSA_AEAD_NONCE_MAX_SIZE. + * + * \note This is not the maximum size of nonce supported as input to + * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), + * just the default size that is generated by #psa_aead_generate_nonce(). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with + * algorithm \p alg. + * + * \param alg An AEAD algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return The default nonce size for the specified key type and algorithm. + * If the key type or AEAD algorithm is not recognized, + * or the parameters are incompatible, return 0. + */ +#define PSA_AEAD_NONCE_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) == 16 ? \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM) ? 13 : \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_GCM) ? 12 : \ + 0 : \ + (key_type) == PSA_KEY_TYPE_CHACHA20 && \ + MBEDTLS_PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305) ? 12 : \ + 0) + +/** The maximum default nonce size among all supported pairs of key types and + * AEAD algorithms, in bytes. + * + * This is equal to or greater than any value that #PSA_AEAD_NONCE_LENGTH() + * may return. + * + * \note This is not the maximum size of nonce supported as input to + * #psa_aead_set_nonce(), #psa_aead_encrypt() or #psa_aead_decrypt(), + * just the largest size that may be generated by + * #psa_aead_generate_nonce(). + */ +#define PSA_AEAD_NONCE_MAX_SIZE 13 + +/** A sufficient output buffer size for psa_aead_update(). + * + * If the size of the output buffer is at least this large, it is + * guaranteed that psa_aead_update() will not fail due to an + * insufficient buffer size. The actual size of the output may be smaller + * in any given call. + * + * See also #PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(\p input_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output buffer size for the specified + * algorithm. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +/* For all the AEAD modes defined in this specification, it is possible + * to emit output without delay. However, hardware may not always be + * capable of this. So for modes based on a block cipher, allow the + * implementation to delay the output until it has a full block. */ +#define PSA_AEAD_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 ? \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), (input_length)) : \ + (input_length) : \ + 0) + +/** A sufficient output buffer size for psa_aead_update(), for any of the + * supported key types and AEAD algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_aead_update() will not fail due to an insufficient buffer size. + * + * See also #PSA_AEAD_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, (input_length))) + +/** A sufficient ciphertext buffer size for psa_aead_finish(). + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_aead_finish() will not fail due to an + * insufficient ciphertext buffer size. The actual size of the output may + * be smaller in any given call. + * + * See also #PSA_AEAD_FINISH_OUTPUT_MAX_SIZE. + * + * \param key_type A symmetric key type that is + compatible with algorithm \p alg. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return A sufficient ciphertext buffer size for the + * specified algorithm. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_FINISH_OUTPUT_SIZE(key_type, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + 0) + +/** A sufficient ciphertext buffer size for psa_aead_finish(), for any of the + * supported key types and AEAD algorithms. + * + * See also #PSA_AEAD_FINISH_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_AEAD_FINISH_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + +/** A sufficient plaintext buffer size for psa_aead_verify(). + * + * If the size of the plaintext buffer is at least this large, it is + * guaranteed that psa_aead_verify() will not fail due to an + * insufficient plaintext buffer size. The actual size of the output may + * be smaller in any given call. + * + * See also #PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE. + * + * \param key_type A symmetric key type that is + * compatible with algorithm \p alg. + * \param alg An AEAD algorithm + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p alg) is true). + * + * \return A sufficient plaintext buffer size for the + * specified algorithm. + * If the key type or AEAD algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_AEAD_VERIFY_OUTPUT_SIZE(key_type, alg) \ + (PSA_AEAD_NONCE_LENGTH(key_type, alg) != 0 && \ + PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + 0) + +/** A sufficient plaintext buffer size for psa_aead_verify(), for any of the + * supported key types and AEAD algorithms. + * + * See also #PSA_AEAD_VERIFY_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_AEAD_VERIFY_OUTPUT_MAX_SIZE (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + +#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \ + (PSA_ALG_IS_RSA_OAEP(alg) ? \ + 2 * PSA_HASH_LENGTH(PSA_ALG_RSA_OAEP_GET_HASH(alg)) + 1 : \ + 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) + +/** Sufficient signature buffer size for psa_sign_hash(). + * + * This macro returns a sufficient buffer size for a signature using a key + * of the specified type and size, with the specified algorithm. + * Note that the actual size of the signature may be smaller + * (some algorithms produce a variable-size signature). + * + * \warning This function may call its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type An asymmetric key type (this may indifferently be a + * key pair type or a public key type). + * \param key_bits The size of the key in bits. + * \param alg The signature algorithm. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_sign_hash() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. + * If the parameters are not valid, the + * return value is unspecified. + */ +#define PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \ + PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \ + ((void)alg, 0)) + +#define PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE \ + PSA_ECDSA_SIGNATURE_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) + +/** \def PSA_SIGNATURE_MAX_SIZE + * + * Maximum size of an asymmetric signature. + * + * This macro expands to a compile-time constant integer. This value + * is the maximum size of a signature in bytes. + */ +#define PSA_SIGNATURE_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) > PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE ? \ + PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ + PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE) + +/** Sufficient output buffer size for psa_asymmetric_encrypt(). + * + * This macro returns a sufficient buffer size for a ciphertext produced using + * a key of the specified type and size, with the specified algorithm. + * Note that the actual size of the ciphertext may be smaller, depending + * on the algorithm. + * + * \warning This function may call its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type An asymmetric key type (this may indifferently be a + * key pair type or a public key type). + * \param key_bits The size of the key in bits. + * \param alg The asymmetric encryption algorithm. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_asymmetric_encrypt() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. + * If the parameters are not valid, the + * return value is unspecified. + */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? \ + ((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \ + 0) + +/** A sufficient output buffer size for psa_asymmetric_encrypt(), for any + * supported asymmetric encryption. + * + * See also #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). + */ +/* This macro assumes that RSA is the only supported asymmetric encryption. */ +#define PSA_ASYMMETRIC_ENCRYPT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) + +/** Sufficient output buffer size for psa_asymmetric_decrypt(). + * + * This macro returns a sufficient buffer size for a plaintext produced using + * a key of the specified type and size, with the specified algorithm. + * Note that the actual size of the plaintext may be smaller, depending + * on the algorithm. + * + * \warning This function may call its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type An asymmetric key type (this may indifferently be a + * key pair type or a public key type). + * \param key_bits The size of the key in bits. + * \param alg The asymmetric encryption algorithm. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_asymmetric_decrypt() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. + * If the parameters are not valid, the + * return value is unspecified. + */ +#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(key_type, key_bits, alg) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? \ + PSA_BITS_TO_BYTES(key_bits) - PSA_RSA_MINIMUM_PADDING_SIZE(alg) : \ + 0) + +/** A sufficient output buffer size for psa_asymmetric_decrypt(), for any + * supported asymmetric decryption. + * + * This macro assumes that RSA is the only supported asymmetric encryption. + * + * See also #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\p key_type, \p key_bits, \p alg). + */ +#define PSA_ASYMMETRIC_DECRYPT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_RSA_MAX_KEY_BITS)) + +/* Maximum size of the ASN.1 encoding of an INTEGER with the specified + * number of bits. + * + * This definition assumes that bits <= 2^19 - 9 so that the length field + * is at most 3 bytes. The length of the encoding is the length of the + * bit string padded to a whole number of bytes plus: + * - 1 type byte; + * - 1 to 3 length bytes; + * - 0 to 1 bytes of leading 0 due to the sign bit. + */ +#define PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(bits) \ + ((bits) / 8 + 5) + +/* Maximum size of the export encoding of an RSA public key. + * Assumes that the public exponent is less than 2^32. + * + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + * + * - 4 bytes of SEQUENCE overhead; + * - n : INTEGER; + * - 7 bytes for the public exponent. + */ +#define PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) \ + (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) + 11) + +/* Maximum size of the export encoding of an RSA key pair. + * Assumes thatthe public exponent is less than 2^32 and that the size + * difference between the two primes is at most 1 bit. + * + * RSAPrivateKey ::= SEQUENCE { + * version Version, -- 0 + * modulus INTEGER, -- N-bit + * publicExponent INTEGER, -- 32-bit + * privateExponent INTEGER, -- N-bit + * prime1 INTEGER, -- N/2-bit + * prime2 INTEGER, -- N/2-bit + * exponent1 INTEGER, -- N/2-bit + * exponent2 INTEGER, -- N/2-bit + * coefficient INTEGER, -- N/2-bit + * } + * + * - 4 bytes of SEQUENCE overhead; + * - 3 bytes of version; + * - 7 half-size INTEGERs plus 2 full-size INTEGERs, + * overapproximated as 9 half-size INTEGERS; + * - 7 bytes for the public exponent. + */ +#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \ + (9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14) + +/* Maximum size of the export encoding of a DSA public key. + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } -- contains DSAPublicKey + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters Dss-Parms } -- SEQUENCE of 3 INTEGERs + * DSAPublicKey ::= INTEGER -- public key, Y + * + * - 3 * 4 bytes of SEQUENCE overhead; + * - 1 + 1 + 7 bytes of algorithm (DSA OID); + * - 4 bytes of BIT STRING overhead; + * - 3 full-size INTEGERs (p, g, y); + * - 1 + 1 + 32 bytes for 1 sub-size INTEGER (q <= 256 bits). + */ +#define PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) \ + (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 59) + +/* Maximum size of the export encoding of a DSA key pair. + * + * DSAPrivateKey ::= SEQUENCE { + * version Version, -- 0 + * prime INTEGER, -- p + * subprime INTEGER, -- q + * generator INTEGER, -- g + * public INTEGER, -- y + * private INTEGER, -- x + * } + * + * - 4 bytes of SEQUENCE overhead; + * - 3 bytes of version; + * - 3 full-size INTEGERs (p, g, y); + * - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits). + */ +#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \ + (PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75) + +/* Maximum size of the export encoding of an ECC public key. + * + * The representation of an ECC public key is: + * - The byte 0x04; + * - `x_P` as a `ceiling(m/8)`-byte string, big-endian; + * - `y_P` as a `ceiling(m/8)`-byte string, big-endian; + * - where m is the bit size associated with the curve. + * + * - 1 byte + 2 * point size. + */ +#define PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) \ + (2 * PSA_BITS_TO_BYTES(key_bits) + 1) + +/* Maximum size of the export encoding of an ECC key pair. + * + * An ECC key pair is represented by the secret value. + */ +#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \ + (PSA_BITS_TO_BYTES(key_bits)) + +/** Sufficient output buffer size for psa_export_key() or + * psa_export_public_key(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * The following code illustrates how to allocate enough memory to export + * a key by querying the key type and size at runtime. + * \code{c} + * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + * psa_status_t status; + * status = psa_get_key_attributes(key, &attributes); + * if (status != PSA_SUCCESS) handle_error(...); + * psa_key_type_t key_type = psa_get_key_type(&attributes); + * size_t key_bits = psa_get_key_bits(&attributes); + * size_t buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits); + * psa_reset_key_attributes(&attributes); + * uint8_t *buffer = malloc(buffer_size); + * if (buffer == NULL) handle_error(...); + * size_t buffer_length; + * status = psa_export_key(key, buffer, buffer_size, &buffer_length); + * if (status != PSA_SUCCESS) handle_error(...); + * \endcode + * + * \param key_type A supported key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_export_key() or psa_export_public_key() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not supported, + * return either a sensible size or 0. + * If the parameters are not valid, the return value is unspecified. + */ +#define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \ + (key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \ + (key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + 0) + +/** Sufficient output buffer size for psa_export_public_key(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * The following code illustrates how to allocate enough memory to export + * a public key by querying the key type and size at runtime. + * \code{c} + * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + * psa_status_t status; + * status = psa_get_key_attributes(key, &attributes); + * if (status != PSA_SUCCESS) handle_error(...); + * psa_key_type_t key_type = psa_get_key_type(&attributes); + * size_t key_bits = psa_get_key_bits(&attributes); + * size_t buffer_size = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits); + * psa_reset_key_attributes(&attributes); + * uint8_t *buffer = malloc(buffer_size); + * if (buffer == NULL) handle_error(...); + * size_t buffer_length; + * status = psa_export_public_key(key, buffer, buffer_size, &buffer_length); + * if (status != PSA_SUCCESS) handle_error(...); + * \endcode + * + * \param key_type A public key or key pair key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_export_public_key() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that is not + * supported, return either a sensible size or 0. + * If the parameters are not valid, + * the return value is unspecified. + * + * If the parameters are valid and supported, + * return the same result as + * #PSA_EXPORT_KEY_OUTPUT_SIZE( + * \p #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\p key_type), + * \p key_bits). + */ +#define PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_RSA(key_type) ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ + 0) + +/** Sufficient buffer size for exporting any asymmetric key pair. + * + * This macro expands to a compile-time constant integer. This value is + * a sufficient buffer size when calling psa_export_key() to export any + * asymmetric key pair, regardless of the exact key type and key size. + * + * See also #PSA_EXPORT_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_EXPORT_KEY_PAIR_MAX_SIZE \ + (PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \ + PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + +/** Sufficient buffer size for exporting any asymmetric public key. + * + * This macro expands to a compile-time constant integer. This value is + * a sufficient buffer size when calling psa_export_key() or + * psa_export_public_key() to export any asymmetric public key, + * regardless of the exact key type and key size. + * + * See also #PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_EXPORT_PUBLIC_KEY_MAX_SIZE \ + (PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) > \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) ? \ + PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_RSA_MAX_KEY_BITS) : \ + PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + +/** Sufficient output buffer size for psa_raw_key_agreement(). + * + * This macro returns a compile-time constant if its arguments are + * compile-time constants. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE. + * + * \param key_type A supported key type. + * \param key_bits The size of the key in bits. + * + * \return If the parameters are valid and supported, return + * a buffer size in bytes that guarantees that + * psa_raw_key_agreement() will not fail with + * #PSA_ERROR_BUFFER_TOO_SMALL. + * If the parameters are a valid combination that + * is not supported, return either a sensible size or 0. + * If the parameters are not valid, + * the return value is unspecified. + */ +/* FFDH is not yet supported in PSA. */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ + (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? \ + PSA_BITS_TO_BYTES(key_bits) : \ + 0) + +/** Maximum size of the output from psa_raw_key_agreement(). + * + * This macro expands to a compile-time constant integer. This value is the + * maximum size of the output any raw key agreement algorithm, in bytes. + * + * See also #PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(\p key_type, \p key_bits). + */ +#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ + (PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)) + +/** The default IV size for a cipher algorithm, in bytes. + * + * The IV that is generated as part of a call to #psa_cipher_encrypt() is always + * the default IV length for the algorithm. + * + * This macro can be used to allocate a buffer of sufficient size to + * store the IV output from #psa_cipher_generate_iv() when using + * a multi-part cipher operation. + * + * See also #PSA_CIPHER_IV_MAX_SIZE. + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with algorithm \p alg. + * + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \return The default IV size for the specified key type and algorithm. + * If the algorithm does not use an IV, return 0. + * If the key type or cipher algorithm is not recognized, + * or the parameters are incompatible, return 0. + */ +#define PSA_CIPHER_IV_LENGTH(key_type, alg) \ + (PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) > 1 && \ + ((alg) == PSA_ALG_CTR || \ + (alg) == PSA_ALG_CFB || \ + (alg) == PSA_ALG_OFB || \ + (alg) == PSA_ALG_XTS || \ + (alg) == PSA_ALG_CBC_NO_PADDING || \ + (alg) == PSA_ALG_CBC_PKCS7) ? PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + (key_type) == PSA_KEY_TYPE_CHACHA20 && \ + (alg) == PSA_ALG_STREAM_CIPHER ? 12 : \ + 0) + +/** The maximum IV size for all supported cipher algorithms, in bytes. + * + * See also #PSA_CIPHER_IV_LENGTH(). + */ +#define PSA_CIPHER_IV_MAX_SIZE 16 + +/** The maximum size of the output of psa_cipher_encrypt(), in bytes. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. + * Depending on the algorithm, the actual size of the output might be smaller. + * + * See also #PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(\p input_length). + * + * \warning This macro may evaluate its arguments multiple times or + * zero times, so you should not pass arguments that contain + * side effects. + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ + (input_length) + 1) + \ + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (input_length) + PSA_CIPHER_IV_LENGTH((key_type), (alg)) : \ + 0)) + +/** A sufficient output buffer size for psa_cipher_encrypt(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_encrypt() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + * + */ +#define PSA_CIPHER_ENCRYPT_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, \ + (input_length) + 1) + \ + PSA_CIPHER_IV_MAX_SIZE) + +/** The maximum size of the output of psa_cipher_decrypt(), in bytes. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. + * Depending on the algorithm, the actual size of the output might be smaller. + * + * See also #PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(\p input_length). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, + * return 0. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) && \ + ((key_type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + (input_length) : \ + 0) + +/** A sufficient output buffer size for psa_cipher_decrypt(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_decrypt() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_DECRYPT_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_DECRYPT_OUTPUT_MAX_SIZE(input_length) \ + (input_length) + +/** A sufficient output buffer size for psa_cipher_update(). + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_update() will not fail due to an insufficient buffer size. + * The actual size of the output might be smaller in any given call. + * + * See also #PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(\p input_length). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \param input_length Size of the input in bytes. + * + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, return 0. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, alg, input_length) \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (((alg) == PSA_ALG_CBC_PKCS7 || \ + (alg) == PSA_ALG_CBC_NO_PADDING || \ + (alg) == PSA_ALG_ECB_NO_PADDING) ? \ + PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type), \ + input_length) : \ + (input_length)) : \ + 0) + +/** A sufficient output buffer size for psa_cipher_update(), for any of the + * supported key types and cipher algorithms. + * + * If the size of the output buffer is at least this large, it is guaranteed + * that psa_cipher_update() will not fail due to an insufficient buffer size. + * + * See also #PSA_CIPHER_UPDATE_OUTPUT_SIZE(\p key_type, \p alg, \p input_length). + * + * \param input_length Size of the input in bytes. + */ +#define PSA_CIPHER_UPDATE_OUTPUT_MAX_SIZE(input_length) \ + (PSA_ROUND_UP_TO_MULTIPLE(PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE, input_length)) + +/** A sufficient ciphertext buffer size for psa_cipher_finish(). + * + * If the size of the ciphertext buffer is at least this large, it is + * guaranteed that psa_cipher_finish() will not fail due to an insufficient + * ciphertext buffer size. The actual size of the output might be smaller in + * any given call. + * + * See also #PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE(). + * + * \param key_type A symmetric key type that is compatible with algorithm + * alg. + * \param alg A cipher algorithm (PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * \return A sufficient output size for the specified key type and + * algorithm. If the key type or cipher algorithm is not + * recognized, or the parameters are incompatible, return 0. + */ +#define PSA_CIPHER_FINISH_OUTPUT_SIZE(key_type, alg) \ + (PSA_ALG_IS_CIPHER(alg) ? \ + (alg == PSA_ALG_CBC_PKCS7 ? \ + PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type) : \ + 0) : \ + 0) + +/** A sufficient ciphertext buffer size for psa_cipher_finish(), for any of the + * supported key types and cipher algorithms. + * + * See also #PSA_CIPHER_FINISH_OUTPUT_SIZE(\p key_type, \p alg). + */ +#define PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE \ + (PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE) + +#endif /* PSA_CRYPTO_SIZES_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_struct.h b/lib/mbedtls-2.27.0/include/psa/crypto_struct.h new file mode 100644 index 0000000..94242f8 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_struct.h @@ -0,0 +1,478 @@ +/** + * \file psa/crypto_struct.h + * + * \brief PSA cryptography module: Mbed TLS structured type implementations + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * This file contains the definitions of some data structures with + * implementation-specific definitions. + * + * In implementations with isolation between the application and the + * cryptography module, it is expected that the front-end and the back-end + * would have different versions of this file. + * + * <h3>Design notes about multipart operation structures</h3> + * + * For multipart operations without driver delegation support, each multipart + * operation structure contains a `psa_algorithm_t alg` field which indicates + * which specific algorithm the structure is for. When the structure is not in + * use, `alg` is 0. Most of the structure consists of a union which is + * discriminated by `alg`. + * + * For multipart operations with driver delegation support, each multipart + * operation structure contains an `unsigned int id` field indicating which + * driver got assigned to do the operation. When the structure is not in use, + * 'id' is 0. The structure contains also a driver context which is the union + * of the contexts of all drivers able to handle the type of multipart + * operation. + * + * Note that when `alg` or `id` is 0, the content of other fields is undefined. + * In particular, it is not guaranteed that a freshly-initialized structure + * is all-zero: we initialize structures to something like `{0, 0}`, which + * is only guaranteed to initializes the first member of the union; + * GCC and Clang initialize the whole structure to 0 (at the time of writing), + * but MSVC and CompCert don't. + * + * In Mbed Crypto, multipart operation structures live independently from + * the key. This allows Mbed Crypto to free the key objects when destroying + * a key slot. If a multipart operation needs to remember the key after + * the setup function returns, the operation structure needs to contain a + * copy of the key. + */ +/* + * Copyright The Mbed TLS Contributors + * 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_STRUCT_H +#define PSA_CRYPTO_STRUCT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Include the Mbed TLS configuration file, the way Mbed TLS does it + * in each of its header files. */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/cmac.h" +#include "mbedtls/gcm.h" + +/* Include the context definition for the compiled-in drivers for the primitive + * algorithms. */ +#include "psa/crypto_driver_contexts_primitives.h" + +struct psa_hash_operation_s +{ + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_driver_wrappers.h. + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. the driver context is not active, in use). */ + unsigned int id; + psa_driver_hash_context_t ctx; +}; + +#define PSA_HASH_OPERATION_INIT {0, {0}} +static inline struct psa_hash_operation_s psa_hash_operation_init( void ) +{ + const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT; + return( v ); +} + +struct psa_cipher_operation_s +{ + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_crypto_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int id; + + unsigned int iv_required : 1; + unsigned int iv_set : 1; + + uint8_t default_iv_length; + + psa_driver_cipher_context_t ctx; +}; + +#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, {0}} +static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) +{ + const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; + return( v ); +} + +/* Include the context definition for the compiled-in drivers for the composite + * algorithms. */ +#include "psa/crypto_driver_contexts_composites.h" + +struct psa_mac_operation_s +{ + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int id; + uint8_t mac_size; + unsigned int is_sign : 1; + psa_driver_mac_context_t ctx; +}; + +#define PSA_MAC_OPERATION_INIT {0, 0, 0, {0}} +static inline struct psa_mac_operation_s psa_mac_operation_init( void ) +{ + const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; + return( v ); +} + +struct psa_aead_operation_s +{ + psa_algorithm_t alg; + unsigned int key_set : 1; + unsigned int iv_set : 1; + uint8_t iv_size; + uint8_t block_size; + union + { + unsigned dummy; /* Enable easier initializing of the union. */ + mbedtls_cipher_context_t cipher; + } ctx; +}; + +#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, {0}} +static inline struct psa_aead_operation_s psa_aead_operation_init( void ) +{ + const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT; + return( v ); +} + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) +typedef struct +{ + uint8_t *info; + size_t info_length; + psa_mac_operation_t hmac; + uint8_t prk[PSA_HASH_MAX_SIZE]; + uint8_t output_block[PSA_HASH_MAX_SIZE]; +#if PSA_HASH_MAX_SIZE > 0xff +#error "PSA_HASH_MAX_SIZE does not fit in uint8_t" +#endif + uint8_t offset_in_block; + uint8_t block_number; + unsigned int state : 2; + unsigned int info_set : 1; +} psa_hkdf_key_derivation_t; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) +typedef enum +{ + PSA_TLS12_PRF_STATE_INIT, /* no input provided */ + PSA_TLS12_PRF_STATE_SEED_SET, /* seed has been set */ + PSA_TLS12_PRF_STATE_KEY_SET, /* key has been set */ + PSA_TLS12_PRF_STATE_LABEL_SET, /* label has been set */ + PSA_TLS12_PRF_STATE_OUTPUT /* output has been started */ +} psa_tls12_prf_key_derivation_state_t; + +typedef struct psa_tls12_prf_key_derivation_s +{ +#if PSA_HASH_MAX_SIZE > 0xff +#error "PSA_HASH_MAX_SIZE does not fit in uint8_t" +#endif + + /* Indicates how many bytes in the current HMAC block have + * not yet been read by the user. */ + uint8_t left_in_block; + + /* The 1-based number of the block. */ + uint8_t block_number; + + psa_tls12_prf_key_derivation_state_t state; + + uint8_t *secret; + size_t secret_length; + uint8_t *seed; + size_t seed_length; + uint8_t *label; + size_t label_length; + + uint8_t Ai[PSA_HASH_MAX_SIZE]; + + /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */ + uint8_t output_block[PSA_HASH_MAX_SIZE]; +} psa_tls12_prf_key_derivation_t; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || + * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ + +struct psa_key_derivation_s +{ + psa_algorithm_t alg; + unsigned int can_output_key : 1; + size_t capacity; + union + { + /* Make the union non-empty even with no supported algorithms. */ + uint8_t dummy; +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) + psa_hkdf_key_derivation_t hkdf; +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) + psa_tls12_prf_key_derivation_t tls12_prf; +#endif + } ctx; +}; + +/* This only zeroes out the first byte in the union, the rest is unspecified. */ +#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, 0, {0}} +static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void ) +{ + const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT; + return( v ); +} + +struct psa_key_policy_s +{ + psa_key_usage_t usage; + psa_algorithm_t alg; + psa_algorithm_t alg2; +}; +typedef struct psa_key_policy_s psa_key_policy_t; + +#define PSA_KEY_POLICY_INIT {0, 0, 0} +static inline struct psa_key_policy_s psa_key_policy_init( void ) +{ + const struct psa_key_policy_s v = PSA_KEY_POLICY_INIT; + return( v ); +} + +/* The type used internally for key sizes. + * Public interfaces use size_t, but internally we use a smaller type. */ +typedef uint16_t psa_key_bits_t; +/* The maximum value of the type used to represent bit-sizes. + * This is used to mark an invalid key size. */ +#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) ) +/* The maximum size of a key in bits. + * Currently defined as the maximum that can be represented, rounded down + * to a whole number of bytes. + * This is an uncast value so that it can be used in preprocessor + * conditionals. */ +#define PSA_MAX_KEY_BITS 0xfff8 + +/** A mask of flags that can be stored in key attributes. + * + * This type is also used internally to store flags in slots. Internal + * flags are defined in library/psa_crypto_core.h. Internal flags may have + * the same value as external flags if they are properly handled during + * key creation and in psa_get_key_attributes. + */ +typedef uint16_t psa_key_attributes_flag_t; + +#define MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER \ + ( (psa_key_attributes_flag_t) 0x0001 ) + +/* A mask of key attribute flags used externally only. + * Only meant for internal checks inside the library. */ +#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \ + MBEDTLS_PSA_KA_FLAG_HAS_SLOT_NUMBER | \ + 0 ) + +/* A mask of key attribute flags used both internally and externally. + * Currently there aren't any. */ +#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \ + 0 ) + +typedef struct +{ + psa_key_type_t type; + psa_key_bits_t bits; + psa_key_lifetime_t lifetime; + mbedtls_svc_key_id_t id; + psa_key_policy_t policy; + psa_key_attributes_flag_t flags; +} psa_core_key_attributes_t; + +#define PSA_CORE_KEY_ATTRIBUTES_INIT {PSA_KEY_TYPE_NONE, 0, PSA_KEY_LIFETIME_VOLATILE, MBEDTLS_SVC_KEY_ID_INIT, PSA_KEY_POLICY_INIT, 0} + +struct psa_key_attributes_s +{ + psa_core_key_attributes_t core; +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) + psa_key_slot_number_t slot_number; +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ + void *domain_parameters; + size_t domain_parameters_size; +}; + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, 0, NULL, 0} +#else +#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0} +#endif + +static inline struct psa_key_attributes_s psa_key_attributes_init( void ) +{ + const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT; + return( v ); +} + +static inline void psa_set_key_id( psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t key ) +{ + psa_key_lifetime_t lifetime = attributes->core.lifetime; + + attributes->core.id = key; + + if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) + { + attributes->core.lifetime = + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_LIFETIME_PERSISTENT, + PSA_KEY_LIFETIME_GET_LOCATION( lifetime ) ); + } +} + +static inline mbedtls_svc_key_id_t psa_get_key_id( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.id ); +} + +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER +static inline void mbedtls_set_key_owner_id( psa_key_attributes_t *attributes, + mbedtls_key_owner_id_t owner ) +{ + attributes->core.id.owner = owner; +} +#endif + +static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, + psa_key_lifetime_t lifetime) +{ + attributes->core.lifetime = lifetime; + if( PSA_KEY_LIFETIME_IS_VOLATILE( lifetime ) ) + { +#ifdef MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + attributes->core.id.key_id = 0; +#else + attributes->core.id = 0; +#endif + } +} + +static inline psa_key_lifetime_t psa_get_key_lifetime( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.lifetime ); +} + +static inline void psa_extend_key_usage_flags( psa_key_usage_t *usage_flags ) +{ + if( *usage_flags & PSA_KEY_USAGE_SIGN_HASH ) + *usage_flags |= PSA_KEY_USAGE_SIGN_MESSAGE; + + if( *usage_flags & PSA_KEY_USAGE_VERIFY_HASH ) + *usage_flags |= PSA_KEY_USAGE_VERIFY_MESSAGE; +} + +static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes, + psa_key_usage_t usage_flags) +{ + psa_extend_key_usage_flags( &usage_flags ); + attributes->core.policy.usage = usage_flags; +} + +static inline psa_key_usage_t psa_get_key_usage_flags( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.policy.usage ); +} + +static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes, + psa_algorithm_t alg) +{ + attributes->core.policy.alg = alg; +} + +static inline psa_algorithm_t psa_get_key_algorithm( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.policy.alg ); +} + +/* This function is declared in crypto_extra.h, which comes after this + * header file, but we need the function here, so repeat the declaration. */ +psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, + psa_key_type_t type, + const uint8_t *data, + size_t data_length); + +static inline void psa_set_key_type(psa_key_attributes_t *attributes, + psa_key_type_t type) +{ + if( attributes->domain_parameters == NULL ) + { + /* Common case: quick path */ + attributes->core.type = type; + } + else + { + /* Call the bigger function to free the old domain paramteres. + * Ignore any errors which may arise due to type requiring + * non-default domain parameters, since this function can't + * report errors. */ + (void) psa_set_key_domain_parameters( attributes, type, NULL, 0 ); + } +} + +static inline psa_key_type_t psa_get_key_type( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.type ); +} + +static inline void psa_set_key_bits(psa_key_attributes_t *attributes, + size_t bits) +{ + if( bits > PSA_MAX_KEY_BITS ) + attributes->core.bits = PSA_KEY_BITS_TOO_LARGE; + else + attributes->core.bits = (psa_key_bits_t) bits; +} + +static inline size_t psa_get_key_bits( + const psa_key_attributes_t *attributes) +{ + return( attributes->core.bits ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* PSA_CRYPTO_STRUCT_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_types.h b/lib/mbedtls-2.27.0/include/psa/crypto_types.h new file mode 100644 index 0000000..386c7d7 --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_types.h @@ -0,0 +1,383 @@ +/** + * \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 The Mbed TLS Contributors + * 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_TYPES_H +#define PSA_CRYPTO_TYPES_H + +#include "crypto_platform.h" + +/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT + * is defined as well to include all PSA code. + */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#define MBEDTLS_PSA_CRYPTO_CLIENT +#endif /* MBEDTLS_PSA_CRYPTO_C */ + +#include <stdint.h> + +/** \defgroup error Error codes + * @{ + */ + +/** + * \brief Function return status. + * + * This is either #PSA_SUCCESS (which is zero), indicating success, + * or a small negative value indicating that an error occurred. Errors are + * encoded as one of the \c PSA_ERROR_xxx values defined here. */ +/* If #PSA_SUCCESS is already defined, it means that #psa_status_t + * is also defined in an external header, so prevent its multiple + * definition. + */ +#ifndef PSA_SUCCESS +typedef int32_t psa_status_t; +#endif + +/**@}*/ + +/** \defgroup crypto_types Key and algorithm types + * @{ + */ + +/** \brief Encoding of a key type. + */ +typedef uint16_t psa_key_type_t; + +/** The type of PSA elliptic curve family identifiers. + * + * The curve identifier is required to create an ECC key using the + * PSA_KEY_TYPE_ECC_KEY_PAIR() or PSA_KEY_TYPE_ECC_PUBLIC_KEY() + * macros. + * + * Values defined by this standard will never be in the range 0x80-0xff. + * Vendors who define additional families must use an encoding in this range. + */ +typedef uint8_t psa_ecc_family_t; + +/** The type of PSA Diffie-Hellman group family identifiers. + * + * The group identifier is required to create an Diffie-Hellman key using the + * PSA_KEY_TYPE_DH_KEY_PAIR() or PSA_KEY_TYPE_DH_PUBLIC_KEY() + * macros. + * + * Values defined by this standard will never be in the range 0x80-0xff. + * Vendors who define additional families must use an encoding in this range. + */ +typedef uint8_t psa_dh_family_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. + * + * The lifetime of a key indicates where it is stored and what system actions + * may create and destroy it. + * + * Lifetime values have the following structure: + * - Bits 0-7 (#PSA_KEY_LIFETIME_GET_PERSISTENCE(\c lifetime)): + * persistence level. This value indicates what device management + * actions can cause it to be destroyed. In particular, it indicates + * whether the key is _volatile_ or _persistent_. + * See ::psa_key_persistence_t for more information. + * - Bits 8-31 (#PSA_KEY_LIFETIME_GET_LOCATION(\c lifetime)): + * location indicator. This value indicates which part of the system + * has access to the key material and can perform operations using the key. + * See ::psa_key_location_t for more information. + * + * Volatile keys are automatically destroyed when the application instance + * terminates or on a power reset of the device. Persistent keys are + * preserved until the application explicitly destroys them or until an + * integration-specific device management event occurs (for example, + * a factory reset). + * + * Persistent keys have a key identifier of type #mbedtls_svc_key_id_t. + * This identifier remains valid throughout the lifetime of the key, + * even if the application instance that created the key terminates. + * The application can call psa_open_key() to open a persistent key that + * it created previously. + * + * The default lifetime of a key is #PSA_KEY_LIFETIME_VOLATILE. The lifetime + * #PSA_KEY_LIFETIME_PERSISTENT is supported if persistent storage is + * available. Other lifetime values may be supported depending on the + * library configuration. + */ +typedef uint32_t psa_key_lifetime_t; + +/** Encoding of key persistence levels. + * + * What distinguishes different persistence levels is what device management + * events may cause keys to be destroyed. _Volatile_ keys are destroyed + * by a power reset. Persistent keys may be destroyed by events such as + * a transfer of ownership or a factory reset. What management events + * actually affect persistent keys at different levels is outside the + * scope of the PSA Cryptography specification. + * + * The PSA Cryptography specification defines the following values of + * persistence levels: + * - \c 0 = #PSA_KEY_PERSISTENCE_VOLATILE: volatile key. + * A volatile key is automatically destroyed by the implementation when + * the application instance terminates. In particular, a volatile key + * is automatically destroyed on a power reset of the device. + * - \c 1 = #PSA_KEY_PERSISTENCE_DEFAULT: + * persistent key with a default lifetime. + * - \c 2-254: currently not supported by Mbed TLS. + * - \c 255 = #PSA_KEY_PERSISTENCE_READ_ONLY: + * read-only or write-once key. + * A key with this persistence level cannot be destroyed. + * Mbed TLS does not currently offer a way to create such keys, but + * integrations of Mbed TLS can use it for built-in keys that the + * application cannot modify (for example, a hardware unique key (HUK)). + * + * \note Key persistence levels are 8-bit values. Key management + * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which + * encode the persistence as the lower 8 bits of a 32-bit value. + */ +typedef uint8_t psa_key_persistence_t; + +/** Encoding of key location indicators. + * + * If an integration of Mbed TLS can make calls to external + * cryptoprocessors such as secure elements, the location of a key + * indicates which secure element performs the operations on the key. + * Depending on the design of the secure element, the key + * material may be stored either in the secure element, or + * in wrapped (encrypted) form alongside the key metadata in the + * primary local storage. + * + * The PSA Cryptography API specification defines the following values of + * location indicators: + * - \c 0: primary local storage. + * This location is always available. + * The primary local storage is typically the same storage area that + * contains the key metadata. + * - \c 1: primary secure element. + * Integrations of Mbed TLS should support this value if there is a secure + * element attached to the operating environment. + * As a guideline, secure elements may provide higher resistance against + * side channel and physical attacks than the primary local storage, but may + * have restrictions on supported key types, sizes, policies and operations + * and may have different performance characteristics. + * - \c 2-0x7fffff: other locations defined by a PSA specification. + * The PSA Cryptography API does not currently assign any meaning to these + * locations, but future versions of that specification or other PSA + * specifications may do so. + * - \c 0x800000-0xffffff: vendor-defined locations. + * No PSA specification will assign a meaning to locations in this range. + * + * \note Key location indicators are 24-bit values. Key management + * interfaces operate on lifetimes (type ::psa_key_lifetime_t) which + * encode the location as the upper 24 bits of a 32-bit value. + */ +typedef uint32_t psa_key_location_t; + +/** Encoding of identifiers of persistent keys. + * + * - Applications may freely choose key identifiers in the range + * #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX. + * - The implementation may define additional key identifiers in the range + * #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX. + * - 0 is reserved as an invalid key identifier. + * - Key identifiers outside these ranges are reserved for future use. + */ +typedef uint32_t psa_key_id_t; + +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) +typedef psa_key_id_t mbedtls_svc_key_id_t; + +#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ +/* Implementation-specific: The Mbed Cryptography library can be built as + * part of a multi-client service that exposes the PSA Cryptograpy API in each + * client and encodes the client identity in the key identifier argument of + * functions such as psa_open_key(). + */ +typedef struct +{ + psa_key_id_t key_id; + mbedtls_key_owner_id_t owner; +} mbedtls_svc_key_id_t; + +#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ + +/**@}*/ + +/** \defgroup policy Key policies + * @{ + */ + +/** \brief Encoding of permitted usage on a key. */ +typedef uint32_t psa_key_usage_t; + +/**@}*/ + +/** \defgroup attributes Key attributes + * @{ + */ + +/** The type of a structure containing key attributes. + * + * This is an opaque structure that can represent the metadata of a key + * object. Metadata that can be stored in attributes includes: + * - The location of the key in storage, indicated by its key identifier + * and its lifetime. + * - The key's policy, comprising usage flags and a specification of + * the permitted algorithm(s). + * - Information about the key itself: the key type and its size. + * - Additional implementation-defined attributes. + * + * The actual key material is not considered an attribute of a key. + * Key attributes do not contain information that is generally considered + * highly confidential. + * + * An attribute structure works like a simple data structure where each function + * `psa_set_key_xxx` sets a field and the corresponding function + * `psa_get_key_xxx` retrieves the value of the corresponding field. + * However, a future version of the library may report values that are + * equivalent to the original one, but have a different encoding. Invalid + * values may be mapped to different, also invalid values. + * + * An attribute structure may contain references to auxiliary resources, + * for example pointers to allocated memory or indirect references to + * pre-calculated values. In order to free such resources, the application + * must call psa_reset_key_attributes(). As an exception, calling + * psa_reset_key_attributes() on an attribute structure is optional if + * the structure has only been modified by the following functions + * since it was initialized or last reset with psa_reset_key_attributes(): + * - psa_set_key_id() + * - psa_set_key_lifetime() + * - psa_set_key_type() + * - psa_set_key_bits() + * - psa_set_key_usage_flags() + * - psa_set_key_algorithm() + * + * Before calling any function on a key attribute structure, the application + * must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_key_attributes_t attributes; + * memset(&attributes, 0, sizeof(attributes)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_key_attributes_t attributes = {0}; + * \endcode + * - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT, + * for example: + * \code + * psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + * \endcode + * - Assign the result of the function psa_key_attributes_init() + * to the structure, for example: + * \code + * psa_key_attributes_t attributes; + * attributes = psa_key_attributes_init(); + * \endcode + * + * A freshly initialized attribute structure contains the following + * values: + * + * - lifetime: #PSA_KEY_LIFETIME_VOLATILE. + * - key identifier: 0 (which is not a valid key identifier). + * - type: \c 0 (meaning that the type is unspecified). + * - key size: \c 0 (meaning that the size is unspecified). + * - usage flags: \c 0 (which allows no usage except exporting a public key). + * - algorithm: \c 0 (which allows no cryptographic usage, but allows + * exporting). + * + * A typical sequence to create a key is as follows: + * -# Create and initialize an attribute structure. + * -# If the key is persistent, call psa_set_key_id(). + * Also call psa_set_key_lifetime() to place the key in a non-default + * location. + * -# Set the key policy with psa_set_key_usage_flags() and + * psa_set_key_algorithm(). + * -# Set the key type with psa_set_key_type(). + * Skip this step if copying an existing key with psa_copy_key(). + * -# When generating a random key with psa_generate_key() or deriving a key + * with psa_key_derivation_output_key(), set the desired key size with + * psa_set_key_bits(). + * -# Call a key creation function: psa_import_key(), psa_generate_key(), + * psa_key_derivation_output_key() or psa_copy_key(). This function reads + * the attribute structure, creates a key with these attributes, and + * outputs a key identifier to the newly created key. + * -# The attribute structure is now no longer necessary. + * You may call psa_reset_key_attributes(), although this is optional + * with the workflow presented here because the attributes currently + * defined in this specification do not require any additional resources + * beyond the structure itself. + * + * A typical sequence to query a key's attributes is as follows: + * -# Call psa_get_key_attributes(). + * -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that + * you are interested in. + * -# Call psa_reset_key_attributes() to free any resources that may be + * used by the attribute structure. + * + * Once a key has been created, it is impossible to change its attributes. + */ +typedef struct psa_key_attributes_s psa_key_attributes_t; + + +#ifndef __DOXYGEN_ONLY__ +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +/* Mbed Crypto defines this type in crypto_types.h because it is also + * visible to applications through an implementation-specific extension. + * For the PSA Cryptography specification, this type is only visible + * via crypto_se_driver.h. */ +typedef uint64_t psa_key_slot_number_t; +#endif /* MBEDTLS_PSA_CRYPTO_SE_C */ +#endif /* !__DOXYGEN_ONLY__ */ + +/**@}*/ + +/** \defgroup derivation Key derivation + * @{ + */ + +/** \brief Encoding of the step of a key derivation. */ +typedef uint16_t psa_key_derivation_step_t; + +/**@}*/ + +#endif /* PSA_CRYPTO_TYPES_H */ diff --git a/lib/mbedtls-2.27.0/include/psa/crypto_values.h b/lib/mbedtls-2.27.0/include/psa/crypto_values.h new file mode 100644 index 0000000..3c82f2a --- /dev/null +++ b/lib/mbedtls-2.27.0/include/psa/crypto_values.h @@ -0,0 +1,2218 @@ +/** + * \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 The Mbed TLS Contributors + * 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_VALUES_H +#define PSA_CRYPTO_VALUES_H + +/** \defgroup error Error codes + * @{ + */ + +/* PSA error codes */ + +/** The action was completed successfully. */ +#define PSA_SUCCESS ((psa_status_t)0) + +/** 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_GENERIC_ERROR ((psa_status_t)-132) + +/** 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)-134) + +/** 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)-133) + +/** 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)-138) + +/** Asking for an item that already exists + * + * Implementations should return this error, when attempting + * to write an item (like a key) that already exists. */ +#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139) + +/** Asking for an item that doesn't exist + * + * Implementations should return this error, if a requested item (like + * a key) does not exist. */ +#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140) + +/** 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 either exists or not, + * but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST + * as applicable. + * + * Implementations shall not return this error code to indicate that a + * key identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * instead. */ +#define PSA_ERROR_BAD_STATE ((psa_status_t)-137) + +/** 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 identifier is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * instead. + */ +#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135) + +/** 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)-141) + +/** 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)-142) + +/** 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 whenever + * 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)-145) + +/** 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_CORRUPTION_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 cannot 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)-146) + +/** 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)-147) + +/** 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_CORRUPTION_DETECTED ((psa_status_t)-151) + +/** 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)-148) + +/** 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)-149) + +/** 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)-150) + +/** Return this error when there's insufficient data when attempting + * to read from a resource. */ +#define PSA_ERROR_INSUFFICIENT_DATA ((psa_status_t)-143) + +/** The key identifier is not valid. See also :ref:\`key-handles\`. + */ +#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)-136) + +/** Stored data has been corrupted. + * + * This error indicates that some persistent storage has suffered corruption. + * It does not indicate the following situations, which have specific error + * codes: + * + * - A corruption of volatile memory - use #PSA_ERROR_CORRUPTION_DETECTED. + * - A communication error between the cryptoprocessor and its external + * storage - use #PSA_ERROR_COMMUNICATION_FAILURE. + * - When the storage is in a valid state but is full - use + * #PSA_ERROR_INSUFFICIENT_STORAGE. + * - When the storage fails for other reasons - use + * #PSA_ERROR_STORAGE_FAILURE. + * - When the stored data is not valid - use #PSA_ERROR_DATA_INVALID. + * + * \note A storage corruption does not indicate that any data that was + * previously read is invalid. However this previously read data might no + * longer be readable from storage. + * + * When a storage failure occurs, it is no longer possible to ensure the + * global integrity of the keystore. + */ +#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152) + +/** Data read from storage is not valid for the implementation. + * + * This error indicates that some data read from storage does not have a valid + * format. It does not indicate the following situations, which have specific + * error codes: + * + * - When the storage or stored data is corrupted - use #PSA_ERROR_DATA_CORRUPT + * - When the storage fails for other reasons - use #PSA_ERROR_STORAGE_FAILURE + * - An invalid argument to the API - use #PSA_ERROR_INVALID_ARGUMENT + * + * This error is typically a result of either storage corruption on a + * cleartext storage backend, or an attempt to read data that was + * written by an incompatible version of the library. + */ +#define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) + +/**@}*/ + +/** \defgroup crypto_types Key and algorithm types + * @{ + */ + +/** An invalid key type value. + * + * Zero is not the encoding of any key type. + */ +#define PSA_KEY_TYPE_NONE ((psa_key_type_t)0x0000) + +/** Vendor-defined key type 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)0x8000) + +#define PSA_KEY_TYPE_CATEGORY_MASK ((psa_key_type_t)0x7000) +#define PSA_KEY_TYPE_CATEGORY_RAW ((psa_key_type_t)0x1000) +#define PSA_KEY_TYPE_CATEGORY_SYMMETRIC ((psa_key_type_t)0x2000) +#define PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY ((psa_key_type_t)0x4000) +#define PSA_KEY_TYPE_CATEGORY_KEY_PAIR ((psa_key_type_t)0x7000) + +#define PSA_KEY_TYPE_CATEGORY_FLAG_PAIR ((psa_key_type_t)0x3000) + +/** Whether a key type is vendor-defined. + * + * See also #PSA_KEY_TYPE_VENDOR_FLAG. + */ +#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_CATEGORY_RAW || \ + ((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC) + +/** Whether a key type is asymmetric: either a key pair or a public key. */ +#define PSA_KEY_TYPE_IS_ASYMMETRIC(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK \ + & ~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_KEY_PAIR(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_KEY_PAIR_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_KEY_PAIR(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)0x1001) + +/** 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_LENGTH(\c alg) where + * \c alg is the HMAC algorithm or the underlying hash algorithm. */ +#define PSA_KEY_TYPE_HMAC ((psa_key_type_t)0x1100) + +/** 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)0x1200) + +/** Key for a 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)0x2400) + +/** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). + * + * The size of the key can be 64 bits (single DES), 128 bits (2-key 3DES) or + * 192 bits (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)0x2301) + +/** Key for a cipher, AEAD or MAC algorithm based on the + * Camellia block cipher. */ +#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x2403) + +/** 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)0x2002) + +/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm. + * + * ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539. + * + * Implementations must support 12-byte nonces, may support 8-byte nonces, + * and should reject other sizes. + */ +#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t)0x2004) + +/** RSA public key. + * + * The size of an RSA key is the bit size of the modulus. + */ +#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x4001) +/** RSA key pair (private and public key). + * + * The size of an RSA key is the bit size of the modulus. + */ +#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x7001) +/** 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_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY) + +#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x4100) +#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x7100) +#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x00ff) +/** Elliptic curve key pair. + * + * The size of an elliptic curve key is the bit size associated with the curve, + * i.e. the bit size of *q* for a curve over a field *F<sub>q</sub>*. + * See the documentation of `PSA_ECC_FAMILY_xxx` curve families for details. + * + * \param curve A value of type ::psa_ecc_family_t that + * identifies the ECC curve to be used. + */ +#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \ + (PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve)) +/** Elliptic curve public key. + * + * The size of an elliptic curve public key is the same as the corresponding + * private key (see #PSA_KEY_TYPE_ECC_KEY_PAIR and the documentation of + * `PSA_ECC_FAMILY_xxx` curve families). + * + * \param curve A value of type ::psa_ecc_family_t that + * identifies the ECC curve to be used. + */ +#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_KEY_PAIR(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_KEY_PAIR(type) \ + (((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \ + PSA_KEY_TYPE_ECC_KEY_PAIR_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_ECC_GET_FAMILY(type) \ + ((psa_ecc_family_t) (PSA_KEY_TYPE_IS_ECC(type) ? \ + ((type) & PSA_KEY_TYPE_ECC_CURVE_MASK) : \ + 0)) + +/** SEC Koblitz curves over prime fields. + * + * This family comprises the following curves: + * secp192k1, secp224k1, secp256k1. + * They are defined in _Standards for Efficient Cryptography_, + * _SEC 2: Recommended Elliptic Curve Domain Parameters_. + * https://www.secg.org/sec2-v2.pdf + */ +#define PSA_ECC_FAMILY_SECP_K1 ((psa_ecc_family_t) 0x17) + +/** SEC random curves over prime fields. + * + * This family comprises the following curves: + * secp192k1, secp224r1, secp256r1, secp384r1, secp521r1. + * They are defined in _Standards for Efficient Cryptography_, + * _SEC 2: Recommended Elliptic Curve Domain Parameters_. + * https://www.secg.org/sec2-v2.pdf + */ +#define PSA_ECC_FAMILY_SECP_R1 ((psa_ecc_family_t) 0x12) +/* SECP160R2 (SEC2 v1, obsolete) */ +#define PSA_ECC_FAMILY_SECP_R2 ((psa_ecc_family_t) 0x1b) + +/** SEC Koblitz curves over binary fields. + * + * This family comprises the following curves: + * sect163k1, sect233k1, sect239k1, sect283k1, sect409k1, sect571k1. + * They are defined in _Standards for Efficient Cryptography_, + * _SEC 2: Recommended Elliptic Curve Domain Parameters_. + * https://www.secg.org/sec2-v2.pdf + */ +#define PSA_ECC_FAMILY_SECT_K1 ((psa_ecc_family_t) 0x27) + +/** SEC random curves over binary fields. + * + * This family comprises the following curves: + * sect163r1, sect233r1, sect283r1, sect409r1, sect571r1. + * They are defined in _Standards for Efficient Cryptography_, + * _SEC 2: Recommended Elliptic Curve Domain Parameters_. + * https://www.secg.org/sec2-v2.pdf + */ +#define PSA_ECC_FAMILY_SECT_R1 ((psa_ecc_family_t) 0x22) + +/** SEC additional random curves over binary fields. + * + * This family comprises the following curve: + * sect163r2. + * It is defined in _Standards for Efficient Cryptography_, + * _SEC 2: Recommended Elliptic Curve Domain Parameters_. + * https://www.secg.org/sec2-v2.pdf + */ +#define PSA_ECC_FAMILY_SECT_R2 ((psa_ecc_family_t) 0x2b) + +/** Brainpool P random curves. + * + * This family comprises the following curves: + * brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1, + * brainpoolP320r1, brainpoolP384r1, brainpoolP512r1. + * It is defined in RFC 5639. + */ +#define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30) + +/** Curve25519 and Curve448. + * + * This family comprises the following Montgomery curves: + * - 255-bit: Bernstein et al., + * _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006. + * The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve. + * - 448-bit: Hamburg, + * _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. + * The algorithm #PSA_ALG_ECDH performs X448 when used with this curve. + */ +#define PSA_ECC_FAMILY_MONTGOMERY ((psa_ecc_family_t) 0x41) + +/** The twisted Edwards curves Ed25519 and Ed448. + * + * These curves are suitable for EdDSA (#PSA_ALG_PURE_EDDSA for both curves, + * #PSA_ALG_ED25519PH for the 255-bit curve, + * #PSA_ALG_ED448PH for the 448-bit curve). + * + * This family comprises the following twisted Edwards curves: + * - 255-bit: Edwards25519, the twisted Edwards curve birationally equivalent + * to Curve25519. + * Bernstein et al., _Twisted Edwards curves_, Africacrypt 2008. + * - 448-bit: Edwards448, the twisted Edwards curve birationally equivalent + * to Curve448. + * Hamburg, _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015. + */ +#define PSA_ECC_FAMILY_TWISTED_EDWARDS ((psa_ecc_family_t) 0x42) + +#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x4200) +#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x7200) +#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x00ff) +/** Diffie-Hellman key pair. + * + * \param group A value of type ::psa_dh_family_t that identifies the + * Diffie-Hellman group to be used. + */ +#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \ + (PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group)) +/** Diffie-Hellman public key. + * + * \param group A value of type ::psa_dh_family_t that identifies the + * Diffie-Hellman group to be used. + */ +#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \ + (PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group)) + +/** Whether a key type is a Diffie-Hellman key (pair or public-only). */ +#define PSA_KEY_TYPE_IS_DH(type) \ + ((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \ + ~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE) +/** Whether a key type is a Diffie-Hellman key pair. */ +#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \ + (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \ + PSA_KEY_TYPE_DH_KEY_PAIR_BASE) +/** Whether a key type is a Diffie-Hellman public key. */ +#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \ + (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \ + PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE) + +/** Extract the group from a Diffie-Hellman key type. */ +#define PSA_KEY_TYPE_DH_GET_FAMILY(type) \ + ((psa_dh_family_t) (PSA_KEY_TYPE_IS_DH(type) ? \ + ((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \ + 0)) + +/** Diffie-Hellman groups defined in RFC 7919 Appendix A. + * + * This family includes groups with the following key sizes (in bits): + * 2048, 3072, 4096, 6144, 8192. A given implementation may support + * all of these sizes or only a subset. + */ +#define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03) + +#define PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) \ + (((type) >> 8) & 7) +/** 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_LENGTH(type) \ + (((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_SYMMETRIC ? \ + 1u << PSA_GET_KEY_TYPE_BLOCK_SIZE_EXPONENT(type) : \ + 0u) + +/** Vendor-defined algorithm flag. + * + * Algorithms defined by this standard will never have the #PSA_ALG_VENDOR_FLAG + * bit set. Vendors who define additional algorithms must use an encoding with + * the #PSA_ALG_VENDOR_FLAG bit set and should respect the bitwise structure + * used by standard encodings whenever practical. + */ +#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)0x02000000) +#define PSA_ALG_CATEGORY_MAC ((psa_algorithm_t)0x03000000) +#define PSA_ALG_CATEGORY_CIPHER ((psa_algorithm_t)0x04000000) +#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x05000000) +#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x06000000) +#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x07000000) +#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x08000000) +#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x09000000) + +/** Whether an algorithm is vendor-defined. + * + * See also #PSA_ALG_VENDOR_FLAG. + */ +#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 an asymmetric signature algorithm, + * also known as public-key signature algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an asymmetric 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 an asymmetric encryption algorithm, + * also known as public-key encryption algorithm. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an asymmetric 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) + +/** 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_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) + +#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff) +/** MD2 */ +#define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001) +/** MD4 */ +#define PSA_ALG_MD4 ((psa_algorithm_t)0x02000002) +/** MD5 */ +#define PSA_ALG_MD5 ((psa_algorithm_t)0x02000003) +/** PSA_ALG_RIPEMD160 */ +#define PSA_ALG_RIPEMD160 ((psa_algorithm_t)0x02000004) +/** SHA1 */ +#define PSA_ALG_SHA_1 ((psa_algorithm_t)0x02000005) +/** SHA2-224 */ +#define PSA_ALG_SHA_224 ((psa_algorithm_t)0x02000008) +/** SHA2-256 */ +#define PSA_ALG_SHA_256 ((psa_algorithm_t)0x02000009) +/** SHA2-384 */ +#define PSA_ALG_SHA_384 ((psa_algorithm_t)0x0200000a) +/** SHA2-512 */ +#define PSA_ALG_SHA_512 ((psa_algorithm_t)0x0200000b) +/** SHA2-512/224 */ +#define PSA_ALG_SHA_512_224 ((psa_algorithm_t)0x0200000c) +/** SHA2-512/256 */ +#define PSA_ALG_SHA_512_256 ((psa_algorithm_t)0x0200000d) +/** SHA3-224 */ +#define PSA_ALG_SHA3_224 ((psa_algorithm_t)0x02000010) +/** SHA3-256 */ +#define PSA_ALG_SHA3_256 ((psa_algorithm_t)0x02000011) +/** SHA3-384 */ +#define PSA_ALG_SHA3_384 ((psa_algorithm_t)0x02000012) +/** SHA3-512 */ +#define PSA_ALG_SHA3_512 ((psa_algorithm_t)0x02000013) +/** The first 512 bits (64 bytes) of the SHAKE256 output. + * + * This is the prehashing for Ed448ph (see #PSA_ALG_ED448PH). For other + * scenarios where a hash function based on SHA3/SHAKE is desired, SHA3-512 + * has the same output size and a (theoretically) higher security strength. + */ +#define PSA_ALG_SHAKE256_512 ((psa_algorithm_t)0x02000015) + +/** In a hash-and-sign algorithm policy, allow any hash algorithm. + * + * This value may be used to form the algorithm usage field of a policy + * for a signature algorithm that is parametrized by a hash. The key + * may then be used to perform operations using the same signature + * algorithm parametrized with any supported hash. + * + * That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros: + * - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS, + * - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA. + * Then you may create and use a key as follows: + * - Set the key usage field using #PSA_ALG_ANY_HASH, for example: + * ``` + * psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); // or VERIFY + * psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH)); + * ``` + * - Import or generate key material. + * - Call psa_sign_hash() or psa_verify_hash(), passing + * an algorithm built from `PSA_xxx_SIGNATURE` and a specific hash. Each + * call to sign or verify a message may use a different hash. + * ``` + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_256), ...); + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA_512), ...); + * psa_sign_hash(key, PSA_xxx_SIGNATURE(PSA_ALG_SHA3_256), ...); + * ``` + * + * This value may not be used to build other algorithms that are + * parametrized over a hash. For any valid use of this macro to build + * an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true. + * + * This value may not be used to build an algorithm specification to + * perform an operation. It is only valid to build policies. + */ +#define PSA_ALG_ANY_HASH ((psa_algorithm_t)0x020000ff) + +#define PSA_ALG_MAC_SUBCATEGORY_MASK ((psa_algorithm_t)0x00c00000) +#define PSA_ALG_HMAC_BASE ((psa_algorithm_t)0x03800000) +/** 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 hash_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)0x003f0000) +#define PSA_MAC_TRUNCATION_OFFSET 16 + +/* In the encoding of a MAC algorithm, the bit corresponding to + * #PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm + * is a wildcard algorithm. A key with such wildcard algorithm as permitted + * algorithm policy can be used with any algorithm corresponding to the + * same base class and having a (potentially truncated) MAC length greater or + * equal than the one encoded in #PSA_ALG_MAC_TRUNCATION_MASK. */ +#define PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000) + +/** Macro to build a truncated MAC algorithm. + * + * A truncated MAC algorithm is identical to the corresponding MAC + * 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 mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_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 mac_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(mac_alg, mac_length) \ + (((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) | \ + ((mac_length) << PSA_MAC_TRUNCATION_OFFSET & PSA_ALG_MAC_TRUNCATION_MASK)) + +/** Macro to build the base MAC algorithm corresponding to a truncated + * MAC algorithm. + * + * \param mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) + * is true). This may be a truncated or untruncated + * MAC algorithm. + * + * \return The corresponding base MAC algorithm. + * \return Unspecified if \p mac_alg is not a supported + * MAC algorithm. + */ +#define PSA_ALG_FULL_LENGTH_MAC(mac_alg) \ + ((mac_alg) & ~(PSA_ALG_MAC_TRUNCATION_MASK | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG)) + +/** Length to which a MAC algorithm is truncated. + * + * \param mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) + * is true). + * + * \return Length of the truncated MAC in bytes. + * \return 0 if \p mac_alg is a non-truncated MAC algorithm. + * \return Unspecified if \p mac_alg is not a supported + * MAC algorithm. + */ +#define PSA_MAC_TRUNCATED_LENGTH(mac_alg) \ + (((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET) + +/** Macro to build a MAC minimum-MAC-length wildcard algorithm. + * + * A minimum-MAC-length MAC wildcard algorithm permits all MAC algorithms + * sharing the same base algorithm, and where the (potentially truncated) MAC + * length of the specific algorithm is equal to or larger then the wildcard + * algorithm's minimum MAC length. + * + * \note When setting the minimum required MAC length to less than the + * smallest MAC length allowed by the base algorithm, this effectively + * becomes an 'any-MAC-length-allowed' policy for that base algorithm. + * + * \param mac_alg A MAC algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_MAC(\p mac_alg) + * is true). + * \param min_mac_length Desired minimum length of the message authentication + * code in bytes. This must be at most the untruncated + * length of the MAC and must be at least 1. + * + * \return The corresponding MAC wildcard algorithm with the + * specified minimum length. + * \return Unspecified if \p mac_alg is not a supported MAC + * algorithm or if \p min_mac_length is less than 1 or + * too large for the specified MAC algorithm. + */ +#define PSA_ALG_AT_LEAST_THIS_LENGTH_MAC(mac_alg, min_mac_length) \ + ( PSA_ALG_TRUNCATED_MAC(mac_alg, min_mac_length) | \ + PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG ) + +#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x03c00000) +/** The CBC-MAC construction over a block cipher + * + * \warning CBC-MAC is insecure in many cases. + * A more secure mode, such as #PSA_ALG_CMAC, is recommended. + */ +#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x03c00100) +/** The CMAC construction over a block cipher */ +#define PSA_ALG_CMAC ((psa_algorithm_t)0x03c00200) + +/** 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 stream cipher mode of a stream cipher algorithm. + * + * The underlying stream cipher is determined by the key type. + * - To use ChaCha20, use a key type of #PSA_KEY_TYPE_CHACHA20. + * - To use ARC4, use a key type of #PSA_KEY_TYPE_ARC4. + */ +#define PSA_ALG_STREAM_CIPHER ((psa_algorithm_t)0x04800100) + +/** 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)0x04c01000) + +/** The CFB stream cipher mode. + * + * The underlying block cipher is determined by the key type. + */ +#define PSA_ALG_CFB ((psa_algorithm_t)0x04c01100) + +/** The OFB stream cipher mode. + * + * The underlying block cipher is determined by the key type. + */ +#define PSA_ALG_OFB ((psa_algorithm_t)0x04c01200) + +/** 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)0x0440ff00) + +/** The Electronic Code Book (ECB) mode of a block cipher, with no padding. + * + * \warning ECB mode does not protect the confidentiality of the encrypted data + * except in extremely narrow circumstances. It is recommended that applications + * only use ECB if they need to construct an operating mode that the + * implementation does not provide. Implementations are encouraged to provide + * the modes that applications need in preference to supporting direct access + * to ECB. + * + * The underlying block cipher is determined by the key type. + * + * This symmetric cipher mode can only be used with messages whose lengths are a + * multiple of the block size of the chosen block cipher. + * + * ECB mode does not accept an initialization vector (IV). When using a + * multi-part cipher operation with this algorithm, psa_cipher_generate_iv() + * and psa_cipher_set_iv() must not be called. + */ +#define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t)0x04404400) + +/** 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)0x04404000) + +/** 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)0x04404100) + +#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000) + +/** Whether the specified algorithm is an AEAD mode on a block cipher. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is an AEAD algorithm which is an AEAD mode 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_AEAD_ON_BLOCK_CIPHER(alg) \ + (((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \ + (PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) + +/** The CCM authenticated encryption algorithm. + * + * The underlying block cipher is determined by the key type. + */ +#define PSA_ALG_CCM ((psa_algorithm_t)0x05500100) + +/** The GCM authenticated encryption algorithm. + * + * The underlying block cipher is determined by the key type. + */ +#define PSA_ALG_GCM ((psa_algorithm_t)0x05500200) + +/** The Chacha20-Poly1305 AEAD algorithm. + * + * The ChaCha20_Poly1305 construction is defined in RFC 7539. + * + * Implementations must support 12-byte nonces, may support 8-byte nonces, + * and should reject other sizes. + * + * Implementations must support 16-byte tags and should reject other sizes. + */ +#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x05100500) + +/* 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)0x003f0000) +#define PSA_AEAD_TAG_LENGTH_OFFSET 16 + +/* In the encoding of an AEAD algorithm, the bit corresponding to + * #PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG encodes the fact that the algorithm + * is a wildcard algorithm. A key with such wildcard algorithm as permitted + * algorithm policy can be used with any algorithm corresponding to the + * same base class and having a tag length greater than or equal to the one + * encoded in #PSA_ALG_AEAD_TAG_LENGTH_MASK. */ +#define PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ((psa_algorithm_t)0x00008000) + +/** Macro to build a shortened AEAD algorithm. + * + * A shortened AEAD algorithm is similar to the corresponding AEAD + * 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 aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_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 aead_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_SHORTENED_TAG(aead_alg, tag_length) \ + (((aead_alg) & ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | \ + PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG)) | \ + ((tag_length) << PSA_AEAD_TAG_LENGTH_OFFSET & \ + PSA_ALG_AEAD_TAG_LENGTH_MASK)) + +/** Retrieve the tag length of a specified AEAD algorithm + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that #PSA_ALG_IS_AEAD(\p aead_alg) + * is true). + * + * \return The tag length specified by the input algorithm. + * \return Unspecified if \p aead_alg is not a supported + * AEAD algorithm. + */ +#define PSA_ALG_AEAD_GET_TAG_LENGTH(aead_alg) \ + (((aead_alg) & PSA_ALG_AEAD_TAG_LENGTH_MASK) >> \ + PSA_AEAD_TAG_LENGTH_OFFSET ) + +/** Calculate the corresponding AEAD algorithm with the default tag length. + * + * \param aead_alg An AEAD algorithm (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_AEAD(\p aead_alg) is true). + * + * \return The corresponding AEAD algorithm with the default + * tag length for that algorithm. + */ +#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG(aead_alg) \ + ( \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CCM) \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_GCM) \ + PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \ + 0) +#define PSA_ALG_AEAD_WITH_DEFAULT_LENGTH_TAG_CASE(aead_alg, ref) \ + PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, 0) == \ + PSA_ALG_AEAD_WITH_SHORTENED_TAG(ref, 0) ? \ + ref : + +/** Macro to build an AEAD minimum-tag-length wildcard algorithm. + * + * A minimum-tag-length AEAD wildcard algorithm permits all AEAD algorithms + * sharing the same base algorithm, and where the tag length of the specific + * algorithm is equal to or larger then the minimum tag length specified by the + * wildcard algorithm. + * + * \note When setting the minimum required tag length to less than the + * smallest tag length allowed by the base algorithm, this effectively + * becomes an 'any-tag-length-allowed' policy for that base algorithm. + * + * \param aead_alg An AEAD algorithm identifier (value of type + * #psa_algorithm_t such that + * #PSA_ALG_IS_AEAD(\p aead_alg) is true). + * \param min_tag_length Desired minimum length of the authentication tag in + * bytes. This must be at least 1 and at most the largest + * allowed tag length of the algorithm. + * + * \return The corresponding AEAD wildcard algorithm with the + * specified minimum length. + * \return Unspecified if \p aead_alg is not a supported + * AEAD algorithm or if \p min_tag_length is less than 1 + * or too large for the specified AEAD algorithm. + */ +#define PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(aead_alg, min_tag_length) \ + ( PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, min_tag_length) | \ + PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG ) + +#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE ((psa_algorithm_t)0x06000200) +/** RSA PKCS#1 v1.5 signature with hashing. + * + * 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). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding RSA PKCS#1 v1.5 signature algorithm. + * \return Unspecified if \p hash_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)0x06000300) +/** 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). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding RSA PSS signature algorithm. + * \return Unspecified if \p hash_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_ECDSA_BASE ((psa_algorithm_t)0x06000600) +/** 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). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding ECDSA signature algorithm. + * \return Unspecified if \p hash_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)0x06000700) +/** 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). + * This includes #PSA_ALG_ANY_HASH + * when specifying the algorithm in a usage policy. + * + * \return The corresponding deterministic ECDSA signature + * algorithm. + * \return Unspecified if \p hash_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_ECDSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00000100) +#define PSA_ALG_IS_ECDSA(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_ECDSA_DETERMINISTIC_FLAG) == \ + PSA_ALG_ECDSA_BASE) +#define PSA_ALG_ECDSA_IS_DETERMINISTIC(alg) \ + (((alg) & PSA_ALG_ECDSA_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)) + +/** Edwards-curve digital signature algorithm without prehashing (PureEdDSA), + * using standard parameters. + * + * Contexts are not supported in the current version of this specification + * because there is no suitable signature interface that can take the + * context as a parameter. A future version of this specification may add + * suitable functions and extend this algorithm to support contexts. + * + * PureEdDSA requires an elliptic curve key on a twisted Edwards curve. + * In this specification, the following curves are supported: + * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 255-bit: Ed25519 as specified + * in RFC 8032. + * The curve is Edwards25519. + * The hash function used internally is SHA-512. + * - #PSA_ECC_FAMILY_TWISTED_EDWARDS, 448-bit: Ed448 as specified + * in RFC 8032. + * The curve is Edwards448. + * The hash function used internally is the first 114 bytes of the + * SHAKE256 output. + * + * This algorithm can be used with psa_sign_message() and + * psa_verify_message(). Since there is no prehashing, it cannot be used + * with psa_sign_hash() or psa_verify_hash(). + * + * The signature format is the concatenation of R and S as defined by + * RFC 8032 §5.1.6 and §5.2.6 (a 64-byte string for Ed25519, a 114-byte + * string for Ed448). + */ +#define PSA_ALG_PURE_EDDSA ((psa_algorithm_t)0x06000800) + +#define PSA_ALG_HASH_EDDSA_BASE ((psa_algorithm_t)0x06000900) +#define PSA_ALG_IS_HASH_EDDSA(alg) \ + (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_HASH_EDDSA_BASE) + +/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), + * using SHA-512 and the Edwards25519 curve. + * + * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. + * + * This algorithm is Ed25519 as specified in RFC 8032. + * The curve is Edwards25519. + * The prehash is SHA-512. + * The hash function used internally is SHA-512. + * + * This is a hash-and-sign algorithm: to calculate a signature, + * you can either: + * - call psa_sign_message() on the message; + * - or calculate the SHA-512 hash of the message + * with psa_hash_compute() + * or with a multi-part hash operation started with psa_hash_setup(), + * using the hash algorithm #PSA_ALG_SHA_512, + * then sign the calculated hash with psa_sign_hash(). + * Verifying a signature is similar, using psa_verify_message() or + * psa_verify_hash() instead of the signature function. + */ +#define PSA_ALG_ED25519PH \ + (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHA_512 & PSA_ALG_HASH_MASK)) + +/** Edwards-curve digital signature algorithm with prehashing (HashEdDSA), + * using SHAKE256 and the Edwards448 curve. + * + * See #PSA_ALG_PURE_EDDSA regarding context support and the signature format. + * + * This algorithm is Ed448 as specified in RFC 8032. + * The curve is Edwards448. + * The prehash is the first 64 bytes of the SHAKE256 output. + * The hash function used internally is the first 114 bytes of the + * SHAKE256 output. + * + * This is a hash-and-sign algorithm: to calculate a signature, + * you can either: + * - call psa_sign_message() on the message; + * - or calculate the first 64 bytes of the SHAKE256 output of the message + * with psa_hash_compute() + * or with a multi-part hash operation started with psa_hash_setup(), + * using the hash algorithm #PSA_ALG_SHAKE256_512, + * then sign the calculated hash with psa_sign_hash(). + * Verifying a signature is similar, using psa_verify_message() or + * psa_verify_hash() instead of the signature function. + */ +#define PSA_ALG_ED448PH \ + (PSA_ALG_HASH_EDDSA_BASE | (PSA_ALG_SHAKE256_512 & PSA_ALG_HASH_MASK)) + +/* Default definition, to be overridden if the library is extended with + * more hash-and-sign algorithms that we want to keep out of this header + * file. */ +#define PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg) 0 + +/** Whether the specified algorithm is a hash-and-sign algorithm. + * + * Hash-and-sign algorithms are asymmetric (public-key) signature algorithms + * structured in two parts: first the calculation of a hash in a way that + * does not depend on the key, then the calculation of a signature from the + * hash value and the key. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a hash-and-sign 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_AND_SIGN(alg) \ + (PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \ + PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_HASH_EDDSA(alg) || \ + PSA_ALG_IS_VENDOR_HASH_AND_SIGN(alg)) + +/** Whether the specified algorithm is a signature algorithm that can be used + * with psa_sign_message() and psa_verify_message(). + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if alg is a signature algorithm that can be used to sign a + * message. 0 if \p alg is a signature algorithm that can only be used + * to sign an already-calculated hash. 0 if \p alg is not a signature + * algorithm. This macro can return either 0 or 1 if \p alg is not a + * supported algorithm identifier. + */ +#define PSA_ALG_IS_SIGN_MESSAGE(alg) \ + (PSA_ALG_IS_HASH_AND_SIGN(alg) || (alg) == PSA_ALG_PURE_EDDSA ) + +/** 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_HASH_AND_SIGN(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)0x07000200) + +#define PSA_ALG_RSA_OAEP_BASE ((psa_algorithm_t)0x07000300) +/** 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 encryption algorithm. + * \return Unspecified if \p hash_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)0x08000100) +/** Macro to build an HKDF algorithm. + * + * For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256. + * + * This key derivation algorithm uses the following inputs: + * - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step. + * It is optional; if omitted, the derivation uses an empty salt. + * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step. + * - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step. + * You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET. + * You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before + * starting to generate output. + * + * \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 hash_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)0x08000200) +/** 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. + * + * This key derivation algorithm uses the following inputs, which must be + * passed in the order given here: + * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed. + * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key. + * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label. + * + * For the application to TLS-1.2 key expansion, the seed is the + * concatenation of ServerHello.Random + ClientHello.Random, + * and 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 hash_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)0x08000300) +/** 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. + * + * This key derivation algorithm uses the following inputs, which must be + * passed in the order given here: + * - #PSA_KEY_DERIVATION_INPUT_SEED is the seed. + * - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key. + * - #PSA_KEY_DERIVATION_INPUT_LABEL is the label. + * + * For the application to TLS-1.2, the seed (which is + * forwarded to the TLS-1.2 PRF) is the concatenation of the + * ClientHello.Random + ServerHello.Random, + * and 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 hash_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)0xfe00ffff) +#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0xffff0000) + +/** Macro to build a combined algorithm that chains a key agreement with + * a key derivation. + * + * \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true). + * \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such + * that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true). + * + * \return The corresponding key agreement and derivation + * algorithm. + * \return Unspecified if \p ka_alg is not a supported + * key agreement algorithm or \p kdf_alg is not a + * supported key derivation algorithm. + */ +#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \ + ((ka_alg) | (kdf_alg)) + +#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_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT) + +/** Whether the specified algorithm is a raw key agreement algorithm. + * + * A raw key agreement algorithm is one that does not specify + * a key derivation function. + * Usually, raw key agreement algorithms are constructed directly with + * a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are + * constructed with #PSA_ALG_KEY_AGREEMENT(). + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \p alg is a raw 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_RAW_KEY_AGREEMENT(alg) \ + (PSA_ALG_IS_KEY_AGREEMENT(alg) && \ + PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION) + +#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \ + ((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg))) + +/** The finite-field Diffie-Hellman (DH) key agreement algorithm. + * + * The shared secret produced by key agreement is + * `g^{ab}` in big-endian format. + * It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p` + * in bits. + */ +#define PSA_ALG_FFDH ((psa_algorithm_t)0x09010000) + +/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm. + * + * This includes the raw finite field Diffie-Hellman algorithm as well as + * finite-field Diffie-Hellman followed by any supporter key derivation + * algorithm. + * + * \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) + +/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm. + * + * The shared secret produced by key agreement 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_FAMILY_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_FAMILY_SECPXXX` and `PSA_ECC_FAMILY_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_FAMILY_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}`. + */ +#define PSA_ALG_ECDH ((psa_algorithm_t)0x09020000) + +/** Whether the specified algorithm is an elliptic curve Diffie-Hellman + * algorithm. + * + * This includes the raw elliptic curve Diffie-Hellman algorithm as well as + * elliptic curve Diffie-Hellman followed by any supporter key derivation + * algorithm. + * + * \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) + +/** Whether the specified algorithm encoding is a wildcard. + * + * Wildcard values may only be used to set the usage algorithm field in + * a policy, not to perform an operation. + * + * \param alg An algorithm identifier (value of type #psa_algorithm_t). + * + * \return 1 if \c alg is a wildcard algorithm encoding. + * \return 0 if \c alg is a non-wildcard algorithm encoding (suitable for + * an operation). + * \return This macro may return either 0 or 1 if \c alg is not a supported + * algorithm identifier. + */ +#define PSA_ALG_IS_WILDCARD(alg) \ + (PSA_ALG_IS_HASH_AND_SIGN(alg) ? \ + PSA_ALG_SIGN_GET_HASH(alg) == PSA_ALG_ANY_HASH : \ + PSA_ALG_IS_MAC(alg) ? \ + (alg & PSA_ALG_MAC_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ + PSA_ALG_IS_AEAD(alg) ? \ + (alg & PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG) != 0 : \ + (alg) == PSA_ALG_ANY_HASH) + +/**@}*/ + +/** \defgroup key_lifetimes Key lifetimes + * @{ + */ + +/** The default lifetime for volatile keys. + * + * A volatile key only exists as long as the identifier to it is not destroyed. + * The key material is guaranteed to be erased on a power reset. + * + * A key with this lifetime is typically stored in the RAM area of the + * PSA Crypto subsystem. However this is an implementation choice. + * If an implementation stores data about the key in a non-volatile memory, + * it must release all the resources associated with the key and erase the + * key material if the calling application terminates. + */ +#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000) + +/** The default lifetime 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 integrations may + * provide their own mechanism (for example to perform a factory reset, + * to prepare for device refurbishment, or to uninstall an application). + * + * This lifetime value is the default storage area for the calling + * application. Integrations of Mbed TLS may support other persistent lifetimes. + * See ::psa_key_lifetime_t for more information. + */ +#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) + +/** The persistence level of volatile keys. + * + * See ::psa_key_persistence_t for more information. + */ +#define PSA_KEY_PERSISTENCE_VOLATILE ((psa_key_persistence_t)0x00) + +/** The default persistence level for persistent keys. + * + * See ::psa_key_persistence_t for more information. + */ +#define PSA_KEY_PERSISTENCE_DEFAULT ((psa_key_persistence_t)0x01) + +/** A persistence level indicating that a key is never destroyed. + * + * See ::psa_key_persistence_t for more information. + */ +#define PSA_KEY_PERSISTENCE_READ_ONLY ((psa_key_persistence_t)0xff) + +#define PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) \ + ((psa_key_persistence_t)((lifetime) & 0x000000ff)) + +#define PSA_KEY_LIFETIME_GET_LOCATION(lifetime) \ + ((psa_key_location_t)((lifetime) >> 8)) + +/** Whether a key lifetime indicates that the key is volatile. + * + * A volatile key is automatically destroyed by the implementation when + * the application instance terminates. In particular, a volatile key + * is automatically destroyed on a power reset of the device. + * + * A key that is not volatile is persistent. Persistent keys are + * preserved until the application explicitly destroys them or until an + * implementation-specific device management event occurs (for example, + * a factory reset). + * + * \param lifetime The lifetime value to query (value of type + * ::psa_key_lifetime_t). + * + * \return \c 1 if the key is volatile, otherwise \c 0. + */ +#define PSA_KEY_LIFETIME_IS_VOLATILE(lifetime) \ + (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ + PSA_KEY_PERSISTENCE_VOLATILE) + +/** Whether a key lifetime indicates that the key is read-only. + * + * Read-only keys cannot be created or destroyed through the PSA Crypto API. + * They must be created through platform-specific means that bypass the API. + * + * Some platforms may offer ways to destroy read-only keys. For example, + * consider a platform with multiple levels of privilege, where a + * low-privilege application can use a key but is not allowed to destroy + * it, and the platform exposes the key to the application with a read-only + * lifetime. High-privilege code can destroy the key even though the + * application sees the key as read-only. + * + * \param lifetime The lifetime value to query (value of type + * ::psa_key_lifetime_t). + * + * \return \c 1 if the key is read-only, otherwise \c 0. + */ +#define PSA_KEY_LIFETIME_IS_READ_ONLY(lifetime) \ + (PSA_KEY_LIFETIME_GET_PERSISTENCE(lifetime) == \ + PSA_KEY_PERSISTENCE_READ_ONLY) + +/** Construct a lifetime from a persistence level and a location. + * + * \param persistence The persistence level + * (value of type ::psa_key_persistence_t). + * \param location The location indicator + * (value of type ::psa_key_location_t). + * + * \return The constructed lifetime value. + */ +#define PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location) \ + ((location) << 8 | (persistence)) + +/** The local storage area for persistent keys. + * + * This storage area is available on all systems that can store persistent + * keys without delegating the storage to a third-party cryptoprocessor. + * + * See ::psa_key_location_t for more information. + */ +#define PSA_KEY_LOCATION_LOCAL_STORAGE ((psa_key_location_t)0x000000) + +#define PSA_KEY_LOCATION_VENDOR_FLAG ((psa_key_location_t)0x800000) + +/** The minimum value for a key identifier chosen by the application. + */ +#define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001) +/** The maximum value for a key identifier chosen by the application. + */ +#define PSA_KEY_ID_USER_MAX ((psa_key_id_t)0x3fffffff) +/** The minimum value for a key identifier chosen by the implementation. + */ +#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t)0x40000000) +/** The maximum value for a key identifier chosen by the implementation. + */ +#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t)0x7fffffff) + + +#if !defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) + +#define MBEDTLS_SVC_KEY_ID_INIT ( (psa_key_id_t)0 ) +#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( id ) +#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( 0 ) + +/** Utility to initialize a key identifier at runtime. + * + * \param unused Unused parameter. + * \param key_id Identifier of the key. + */ +static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( + unsigned int unused, psa_key_id_t key_id ) +{ + (void)unused; + + return( key_id ); +} + +/** Compare two key identifiers. + * + * \param id1 First key identifier. + * \param id2 Second key identifier. + * + * \return Non-zero if the two key identifier are equal, zero otherwise. + */ +static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1, + mbedtls_svc_key_id_t id2 ) +{ + return( id1 == id2 ); +} + +/** Check whether a key identifier is null. + * + * \param key Key identifier. + * + * \return Non-zero if the key identifier is null, zero otherwise. + */ +static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key ) +{ + return( key == 0 ); +} + +#else /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ + +#define MBEDTLS_SVC_KEY_ID_INIT ( (mbedtls_svc_key_id_t){ 0, 0 } ) +#define MBEDTLS_SVC_KEY_ID_GET_KEY_ID( id ) ( ( id ).key_id ) +#define MBEDTLS_SVC_KEY_ID_GET_OWNER_ID( id ) ( ( id ).owner ) + +/** Utility to initialize a key identifier at runtime. + * + * \param owner_id Identifier of the key owner. + * \param key_id Identifier of the key. + */ +static inline mbedtls_svc_key_id_t mbedtls_svc_key_id_make( + mbedtls_key_owner_id_t owner_id, psa_key_id_t key_id ) +{ + return( (mbedtls_svc_key_id_t){ .key_id = key_id, + .owner = owner_id } ); +} + +/** Compare two key identifiers. + * + * \param id1 First key identifier. + * \param id2 Second key identifier. + * + * \return Non-zero if the two key identifier are equal, zero otherwise. + */ +static inline int mbedtls_svc_key_id_equal( mbedtls_svc_key_id_t id1, + mbedtls_svc_key_id_t id2 ) +{ + return( ( id1.key_id == id2.key_id ) && + mbedtls_key_owner_id_equal( id1.owner, id2.owner ) ); +} + +/** Check whether a key identifier is null. + * + * \param key Key identifier. + * + * \return Non-zero if the key identifier is null, zero otherwise. + */ +static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key ) +{ + return( key.key_id == 0 ); +} + +#endif /* !MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */ + +/**@}*/ + +/** \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 copied. + * + * This flag allows the use of psa_copy_key() to make a copy of the key + * with the same policy or a more restrictive policy. + * + * For lifetimes for which the key is located in a secure element which + * enforce the non-exportability of keys, copying a key outside the secure + * element also requires the usage flag #PSA_KEY_USAGE_EXPORT. + * Copying the key inside the secure element is permitted with just + * #PSA_KEY_USAGE_COPY if the secure element supports it. + * For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or + * #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY + * is sufficient to permit the copy. + */ +#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002) + +/** 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 message 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_MESSAGE ((psa_key_usage_t)0x00000400) + +/** Whether the key may be used to verify a message. + * + * This flag allows the key to be used for a MAC verification operation or for + * an asymmetric message signature verification operation, if otherwise + * permitted by the key’s type and policy. + * + * For a key pair, this concerns the public key. + */ +#define PSA_KEY_USAGE_VERIFY_MESSAGE ((psa_key_usage_t)0x00000800) + +/** 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_HASH ((psa_key_usage_t)0x00001000) + +/** 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_HASH ((psa_key_usage_t)0x00002000) + +/** Whether the key may be used to derive other keys. + */ +#define PSA_KEY_USAGE_DERIVE ((psa_key_usage_t)0x00004000) + +/**@}*/ + +/** \defgroup derivation Key derivation + * @{ + */ + +/** A secret input for key derivation. + * + * This should be a key of type #PSA_KEY_TYPE_DERIVE + * (passed to psa_key_derivation_input_key()) + * or the shared secret resulting from a key agreement + * (obtained via psa_key_derivation_key_agreement()). + * + * The secret can also be a direct input (passed to + * key_derivation_input_bytes()). In this case, the derivation operation + * may not be used to derive keys: the operation will only allow + * psa_key_derivation_output_bytes(), not psa_key_derivation_output_key(). + */ +#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101) + +/** A label for key derivation. + * + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t)0x0201) + +/** A salt for key derivation. + * + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202) + +/** An information string for key derivation. + * + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t)0x0203) + +/** A seed for key derivation. + * + * This should be a direct input. + * It can also be a key of type #PSA_KEY_TYPE_RAW_DATA. + */ +#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204) + +/**@}*/ + +/** \defgroup helper_macros Helper macros + * @{ + */ + +/* Helper macros */ + +/** Check if two AEAD algorithm identifiers refer to the same AEAD algorithm + * regardless of the tag length they encode. + * + * \param aead_alg_1 An AEAD algorithm identifier. + * \param aead_alg_2 An AEAD algorithm identifier. + * + * \return 1 if both identifiers refer to the same AEAD algorithm, + * 0 otherwise. + * Unspecified if neither \p aead_alg_1 nor \p aead_alg_2 are + * a supported AEAD algorithm. + */ +#define MBEDTLS_PSA_ALG_AEAD_EQUAL(aead_alg_1, aead_alg_2) \ + (!(((aead_alg_1) ^ (aead_alg_2)) & \ + ~(PSA_ALG_AEAD_TAG_LENGTH_MASK | PSA_ALG_AEAD_AT_LEAST_THIS_LENGTH_FLAG))) + +/**@}*/ + +#endif /* PSA_CRYPTO_VALUES_H */ |