diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 1ca64922e..c58d22ae4 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -36,19 +36,15 @@ * @{ */ -/** \brief Key slot number. +/** \brief Key handle. * - * This type represents key slots. It must be an unsigned integral + * This type represents open handles to keys. It must be an unsigned integral * type. The choice of type is implementation-dependent. - * 0 is not a valid key slot number. The meaning of other values is - * implementation dependent. * - * At any given point in time, each key slot either contains a - * cryptographic object, or is empty. Key slots are persistent: - * once set, the cryptographic object remains in the key slot until - * explicitly destroyed. + * 0 is not a valid key handle. How other handle values are assigned is + * implementation-dependent. */ -typedef _unsigned_integral_type_ psa_key_slot_t; +typedef _unsigned_integral_type_ psa_key_handle_t; /**@}*/ #endif /* __DOXYGEN_ONLY__ */ @@ -133,17 +129,17 @@ typedef int32_t psa_status_t; /** A slot is occupied, but must be empty to carry out the * requested action. * - * If the slot number is invalid (i.e. the requested action could - * not be performed even after erasing the slot's content), - * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */ + * If a handle is invalid, it does not designate an occupied slot. + * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. + */ #define PSA_ERROR_OCCUPIED_SLOT ((psa_status_t)5) /** A slot is empty, but must be occupied to carry out the * requested action. * - * If the slot number is invalid (i.e. the requested action could - * not be performed even after creating appropriate content in the slot), - * implementations shall return #PSA_ERROR_INVALID_ARGUMENT instead. */ + * If a handle is invalid, it does not designate an empty slot. + * The error for an invalid handle is #PSA_ERROR_INVALID_HANDLE. + */ #define PSA_ERROR_EMPTY_SLOT ((psa_status_t)6) /** The requested action cannot be performed in the current state. @@ -166,7 +162,12 @@ typedef int32_t psa_status_t; * Implementations shall not return this error code to indicate * that a key slot is occupied when it needs to be free or vice versa, * but shall return #PSA_ERROR_OCCUPIED_SLOT or #PSA_ERROR_EMPTY_SLOT - * as applicable. */ + * as applicable. + * + * Implementation shall not return this error code to indicate that a + * key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE + * instead. + */ #define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)8) /** There is not enough runtime memory. @@ -314,6 +315,10 @@ typedef int32_t psa_status_t; * generator will always return this error. */ #define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)18) +/** The key handle is not valid. + */ +#define PSA_ERROR_INVALID_HANDLE ((psa_status_t)19) + /** * \brief Library initialization. * @@ -1401,6 +1406,181 @@ typedef uint32_t psa_algorithm_t; * @{ */ +/** Encoding of key lifetimes. + */ +typedef uint32_t psa_key_lifetime_t; + +/** Encoding of identifiers of persistent keys. + */ +typedef uint32_t psa_key_id_t; + +/** A volatile key only exists as long as the handle to it is not closed. + * The key material is guaranteed to be erased on a power reset. + */ +#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000) + +/** The default storage area for persistent keys. + * + * A persistent key remains in storage until it is explicitly destroyed or + * until the corresponding storage area is wiped. This specification does + * not define any mechanism to wipe a storage area, but implementations may + * provide their own mechanism (for example to perform a factory reset, + * to prepare for device refurbishment, or to uninstall an application). + * + * This lifetime value is the default storage area for the calling + * application. Implementations may offer other storage areas designated + * by other lifetime values as implementation-specific extensions. + */ +#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) + +/** \brief Retrieve the lifetime of an open key. + * + * \param handle Handle to query. + * \param[out] lifetime On success, the lifetime value. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_TAMPERING_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_get_key_lifetime(psa_key_handle_t handle, + psa_key_lifetime_t *lifetime); + + +/** Allocate a key slot for a transient key, i.e. a key which is only stored + * in volatile memory. + * + * The allocated key slot and its handle remain valid until the + * application calls psa_close_key() or psa_destroy_key() or until the + * application terminates. + * + * This function takes a key type and maximum size as arguments so that + * the implementation can reserve a corresponding amount of memory. + * Implementations are not required to enforce this limit: if the application + * later tries to create a larger key or a key of a different type, it + * is implementation-defined whether this may succeed. + * + * \param type The type of key that the slot will contain. + * \param max_bits The maximum key size that the slot will contain. + * \param[out] handle On success, a handle to a volatile key slot. + * + * \retval #PSA_SUCCESS + * Success. The application can now use the value of `*handle` + * to access the newly allocated key slot. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * There was not enough memory, or the maximum number of key slots + * has been reached. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * This implementation does not support this key type. + */ + +psa_status_t psa_allocate_key(psa_key_type_t type, + size_t max_bits, + psa_key_handle_t *handle); + +/** Open a handle to an existing persistent key. + * + * Open a handle to a key which was previously created with psa_create_key(). + * + * \param lifetime The lifetime of the key. This designates a storage + * area where the key material is stored. This must not + * be #PSA_KEY_LIFETIME_VOLATILE. + * \param id The persistent identifier of the key. + * \param[out] handle On success, a handle to a key slot which contains + * the data and metadata loaded from the specified + * persistent location. + * + * \retval #PSA_SUCCESS + * Success. The application can now use the value of `*handle` + * to access the newly allocated key slot. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_EMPTY_SLOT + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p lifetime is invalid, for example #PSA_KEY_LIFETIME_VOLATILE. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p id is invalid for the specified lifetime. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p lifetime is not supported. + * \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. + */ +psa_status_t psa_open_key(psa_key_lifetime_t lifetime, + psa_key_id_t id, + psa_key_handle_t *handle); + +/** Create a new persistent key slot. + * + * Create a new persistent key slot and return a handle to it. The handle + * remains valid until the application calls psa_close_key() or terminates. + * The application can open the key again with psa_open_key() until it + * removes the key by calling psa_destroy_key(). + * + * \param lifetime The lifetime of the key. This designates a storage + * area where the key material is stored. This must not + * be #PSA_KEY_LIFETIME_VOLATILE. + * \param id The persistent identifier of the key. + * \param type The type of key that the slot will contain. + * \param max_bits The maximum key size that the slot will contain. + * \param[out] handle On success, a handle to the newly created key slot. + * When key material is later created in this key slot, + * it will be saved to the specified persistent location. + * + * \retval #PSA_SUCCESS + * Success. The application can now use the value of `*handle` + * to access the newly allocated key slot. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_OCCUPIED_SLOT + * There is already a key with the identifier \p id in the storage + * area designated by \p lifetime. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p lifetime is invalid, for example #PSA_KEY_LIFETIME_VOLATILE. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p id is invalid for the specified lifetime. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p lifetime is not supported. + * \retval #PSA_ERROR_NOT_PERMITTED + * \p lifetime is valid, but the application does not have the + * permission to create a key there. + */ +psa_status_t psa_create_key(psa_key_lifetime_t lifetime, + psa_key_id_t id, + psa_key_type_t type, + size_t max_bits, + psa_key_handle_t *handle); + +/** Close a key handle. + * + * If the handle designates a volatile key, destroy the key material and + * free all associated resources, just like psa_destroy_key(). + * + * If the handle designates a persistent key, free all resources associated + * with the key in volatile memory. The key slot in persistent storage is + * not affected and can be opened again later with psa_open_key(). + * + * \param handle The key handle to close. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + */ +psa_status_t psa_close_key(psa_key_handle_t handle); + +/**@}*/ + +/** \defgroup import_export Key import and export + * @{ + */ + /** * \brief Import a key in binary format. * @@ -1416,9 +1596,12 @@ typedef uint32_t psa_algorithm_t; * minimize the risk that an invalid input is accidentally interpreted * according to a different format. * - * \param key 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 handle Handle to the slot where the key will be stored. + * This must be a valid slot for a key of the chosen + * type: it must have been obtained by calling + * psa_allocate_key() or psa_create_key() with the + * correct \p type and with a maximum size that is + * compatible with \p data. * \param type Key type (a \c PSA_KEY_TYPE_XXX value). On a successful * import, the key slot will contain a key of this type. * \param[in] data Buffer containing the key data. The content of this @@ -1430,6 +1613,9 @@ typedef uint32_t psa_algorithm_t; * * \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_INVALID_HANDLE * \retval #PSA_ERROR_NOT_SUPPORTED * The key type or key size is not supported, either by the * implementation in general or in this particular slot. @@ -1449,31 +1635,30 @@ typedef uint32_t psa_algorithm_t; * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_import_key(psa_key_slot_t key, +psa_status_t psa_import_key(psa_key_handle_t handle, psa_key_type_t type, const uint8_t *data, size_t data_length); /** - * \brief Destroy a key and restore the slot to its default state. + * \brief Destroy a key. * * This function destroys the content of the key slot from both volatile * memory and, if applicable, non-volatile storage. Implementations shall * make a best effort to ensure that any previous content of the slot is * unrecoverable. * - * This function also erases any metadata such as policies. It returns the - * specified slot to its default state. + * This function also erases any metadata such as policies and frees all + * resources associated with the key. * - * \param key The key slot to erase. + * \param handle Handle to the key slot to erase. * * \retval #PSA_SUCCESS * The slot's content, if any, has been erased. * \retval #PSA_ERROR_NOT_PERMITTED * The slot holds content and cannot be erased because it is * read-only, either due to a policy or due to physical restrictions. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The specified slot number does not designate a valid slot. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_COMMUNICATION_FAILURE * There was an failure in communication with the cryptoprocessor. * The key material may still be present in the cryptoprocessor. @@ -1491,13 +1676,12 @@ psa_status_t psa_import_key(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_destroy_key(psa_key_slot_t key); +psa_status_t psa_destroy_key(psa_key_handle_t handle); /** * \brief Get basic metadata about a key. * - * \param key Slot whose content is queried. This must - * be an occupied key slot. + * \param handle Handle to the key slot to query. * \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX value). * This may be a null pointer, in which case the key type * is not written. @@ -1506,7 +1690,9 @@ psa_status_t psa_destroy_key(psa_key_slot_t key); * is not written. * * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT + * The handle is to a key slot which does not contain key material yet. * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED @@ -1515,7 +1701,7 @@ psa_status_t psa_destroy_key(psa_key_slot_t key); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_get_key_information(psa_key_slot_t key, +psa_status_t psa_get_key_information(psa_key_handle_t handle, psa_key_type_t *type, size_t *bits); @@ -1581,14 +1767,14 @@ psa_status_t psa_get_key_information(psa_key_slot_t key, * - 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(). * - * \param key Slot whose content is to be exported. This must - * be an occupied key slot. + * \param handle Handle to 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_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_NOT_SUPPORTED @@ -1606,7 +1792,7 @@ psa_status_t psa_get_key_information(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_export_key(psa_key_slot_t key, +psa_status_t psa_export_key(psa_key_handle_t handle, uint8_t *data, size_t data_size, size_t *data_length); @@ -1683,14 +1869,14 @@ psa_status_t psa_export_key(psa_key_slot_t key, * namedCurve OBJECT IDENTIFIER } * ``` * - * \param key Slot whose content is to be exported. This must - * be an occupied key slot. + * \param handle Handle to 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_EMPTY_SLOT * \retval #PSA_ERROR_INVALID_ARGUMENT * The key is neither a public key nor a key pair. @@ -1709,7 +1895,7 @@ psa_status_t psa_export_key(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_export_public_key(psa_key_slot_t key, +psa_status_t psa_export_public_key(psa_key_handle_t handle, uint8_t *data, size_t data_size, size_t *data_length); @@ -1835,10 +2021,15 @@ psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy); * Implementations may set restrictions on supported key policies * depending on the key type and the key slot. * - * \param key The key slot whose policy is to be changed. + * \param handle Handle to the key whose policy is to be changed. * \param[in] policy The policy object to query. * * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, it is implementation-defined whether + * the policy has been saved to persistent storage. Implementations + * may defer saving the policy until the key material is created. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_OCCUPIED_SLOT * \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -1850,15 +2041,16 @@ psa_algorithm_t psa_key_policy_get_algorithm(const psa_key_policy_t *policy); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_set_key_policy(psa_key_slot_t key, +psa_status_t psa_set_key_policy(psa_key_handle_t handle, const psa_key_policy_t *policy); /** \brief Get the usage policy for a key slot. * - * \param key The key slot whose policy is being queried. + * \param handle Handle to the key slot whose policy is being queried. * \param[out] policy On success, the key's policy. * * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_COMMUNICATION_FAILURE * \retval #PSA_ERROR_HARDWARE_FAILURE * \retval #PSA_ERROR_TAMPERING_DETECTED @@ -1867,99 +2059,11 @@ psa_status_t psa_set_key_policy(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_get_key_policy(psa_key_slot_t key, +psa_status_t psa_get_key_policy(psa_key_handle_t handle, psa_key_policy_t *policy); /**@}*/ -/** \defgroup persistence Key lifetime - * @{ - */ - -/** Encoding of key lifetimes. - */ -typedef uint32_t psa_key_lifetime_t; - -/** A volatile key slot retains its content as long as the application is - * running. It is guaranteed to be erased on a power reset. - */ -#define PSA_KEY_LIFETIME_VOLATILE ((psa_key_lifetime_t)0x00000000) - -/** A persistent key slot retains its content as long as it is not explicitly - * destroyed. - */ -#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) - -/** A write-once key slot may not be modified once a key has been set. - * It will retain its content as long as the device remains operational. - */ -#define PSA_KEY_LIFETIME_WRITE_ONCE ((psa_key_lifetime_t)0x7fffffff) - -/** \brief Retrieve the lifetime of a key slot. - * - * The assignment of lifetimes to slots is implementation-dependent. - * - * \param key Slot to query. - * \param[out] lifetime On success, the lifetime value. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key slot is invalid. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_TAMPERING_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_get_key_lifetime(psa_key_slot_t key, - psa_key_lifetime_t *lifetime); - -/** \brief Change the lifetime of a key slot. - * - * Whether the lifetime of a key slot can be changed at all, and if so - * whether the lifetime of an occupied key slot can be changed, is - * implementation-dependent. - * - * When creating a persistent key, you must call this function before creating - * the key material with psa_import_key(), psa_generate_key() or - * psa_generator_import_key(). To open an existing persistent key, you must - * call this function with the correct lifetime value before using the slot - * for a cryptographic operation. Once a slot's lifetime has been set, - * the lifetime remains associated with the slot until a subsequent call to - * psa_set_key_lifetime(), until the key is wiped with psa_destroy_key or - * until the application terminates (or disconnects from the cryptography - * service, if the implementation offers such a possibility). - * - * \param key Slot whose lifetime is to be changed. - * \param lifetime The lifetime value to set for the given key slot. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key slot is invalid, - * or the lifetime value is invalid. - * \retval #PSA_ERROR_NOT_SUPPORTED - * The implementation does not support the specified lifetime value, - * at least for the specified key slot. - * \retval #PSA_ERROR_OCCUPIED_SLOT - * The slot contains a key, and the implementation does not support - * changing the lifetime of an occupied slot. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_TAMPERING_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_set_key_lifetime(psa_key_slot_t key, - psa_key_lifetime_t lifetime); - -/**@}*/ - /** \defgroup hash Message digests * @{ */ @@ -2212,12 +2316,13 @@ typedef struct psa_mac_operation_s psa_mac_operation_t; * - A call to psa_mac_sign_finish() or psa_mac_abort(). * * \param[out] operation The operation object to use. - * \param key Slot containing the key to use for the operation. + * \param handle Handle to the key to use for the operation. * \param alg The MAC algorithm to compute (\c PSA_ALG_XXX value * such that #PSA_ALG_IS_MAC(alg) is true). * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -2234,7 +2339,7 @@ typedef struct psa_mac_operation_s psa_mac_operation_t; * results in this error code. */ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg); /** Start a multipart MAC verification operation. @@ -2264,12 +2369,13 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * - A call to psa_mac_verify_finish() or psa_mac_abort(). * * \param[out] operation The operation object to use. - * \param key Slot containing the key to use for the operation. + * \param handle Handle to the key to use for the operation. * \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_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -2286,7 +2392,7 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * results in this error code. */ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg); /** Add a message fragment to a multipart MAC operation. @@ -2463,13 +2569,14 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t; * - A call to psa_cipher_finish() or psa_cipher_abort(). * * \param[out] operation The operation object to use. - * \param key Slot containing the key to use for the operation. + * \param handle Handle to the key to use for the operation. * \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_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -2486,7 +2593,7 @@ typedef struct psa_cipher_operation_s psa_cipher_operation_t; * results in this error code. */ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg); /** Set the key for a multipart symmetric decryption operation. @@ -2516,13 +2623,14 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * - A call to psa_cipher_finish() or psa_cipher_abort(). * * \param[out] operation The operation object to use. - * \param key Slot containing the key to use for the operation. + * \param handle Handle to the key to use for the operation. * \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_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -2539,7 +2647,7 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * results in this error code. */ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg); /** Generate an IV for a symmetric encryption operation. @@ -2742,7 +2850,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); /** Process an authenticated encryption operation. * - * \param key Slot containing the key to use. + * \param handle Handle to the key to use for the operation. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2770,6 +2878,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -2785,7 +2894,7 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_aead_encrypt(psa_key_slot_t key, +psa_status_t psa_aead_encrypt(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -2799,7 +2908,7 @@ psa_status_t psa_aead_encrypt(psa_key_slot_t key, /** Process an authenticated decryption operation. * - * \param key Slot containing the key to use. + * \param handle Handle to the key to use for the operation. * \param alg The AEAD algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_AEAD(\p alg) is true). @@ -2825,6 +2934,7 @@ psa_status_t psa_aead_encrypt(psa_key_slot_t key, * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT * \retval #PSA_ERROR_INVALID_SIGNATURE * The ciphertext is not authentic. @@ -2842,7 +2952,7 @@ psa_status_t psa_aead_encrypt(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_aead_decrypt(psa_key_slot_t key, +psa_status_t psa_aead_decrypt(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -2880,7 +2990,8 @@ psa_status_t psa_aead_decrypt(psa_key_slot_t key, * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * - * \param key Key slot containing an asymmetric key pair. + * \param handle Handle to the key to use for the operation. + * It must be an asymmetric key pair. * \param alg A signature algorithm that is compatible with * the type of \p key. * \param[in] hash The hash or message to sign. @@ -2909,7 +3020,7 @@ psa_status_t psa_aead_decrypt(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_sign(psa_key_slot_t key, +psa_status_t psa_asymmetric_sign(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -2926,8 +3037,8 @@ psa_status_t psa_asymmetric_sign(psa_key_slot_t key, * parameter to this function. You can use #PSA_ALG_SIGN_GET_HASH(\p alg) * to determine the hash algorithm to use. * - * \param key Key slot containing a public key or an - * asymmetric key pair. + * \param handle Handle to the key to use for the operation. + * It must be a public key or an asymmetric key pair. * \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 @@ -2952,7 +3063,7 @@ psa_status_t psa_asymmetric_sign(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_verify(psa_key_slot_t key, +psa_status_t psa_asymmetric_verify(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -2967,8 +3078,9 @@ psa_status_t psa_asymmetric_verify(psa_key_slot_t key, /** * \brief Encrypt a short message with a public key. * - * \param key Key slot containing a public key or an - * asymmetric key pair. + * \param handle Handle to the key to use for the operation. + * It must be a public key or an asymmetric + * key pair. * \param alg An asymmetric encryption algorithm that is * compatible with the type of \p key. * \param[in] input The message to encrypt. @@ -3010,7 +3122,7 @@ psa_status_t psa_asymmetric_verify(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key, +psa_status_t psa_asymmetric_encrypt(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3023,7 +3135,8 @@ psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key, /** * \brief Decrypt a short message with a private key. * - * \param key Key slot containing an asymmetric key pair. + * \param handle Handle to the key to use for the operation. + * It must be an asymmetric key pair. * \param alg An asymmetric encryption algorithm that is * compatible with the type of \p key. * \param[in] input The message to decrypt. @@ -3066,7 +3179,7 @@ psa_status_t psa_asymmetric_encrypt(psa_key_slot_t key, * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_asymmetric_decrypt(psa_key_slot_t key, +psa_status_t psa_asymmetric_decrypt(psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -3137,9 +3250,9 @@ static psa_crypto_generator_t psa_crypto_generator_init(void); * \param[in] generator The generator to query. * \param[out] capacity On success, the capacity of the generator. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_BAD_STATE - * \retval PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE */ psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator, size_t *capacity); @@ -3155,19 +3268,19 @@ psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator, * written. * \param output_length Number of bytes to output. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_INSUFFICIENT_CAPACITY + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_CAPACITY * There were fewer than \p output_length bytes * in the generator. Note that in this case, no * output is written to the output buffer. * The generator'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 - * \retval PSA_ERROR_INSUFFICIENT_MEMORY - * \retval PSA_ERROR_COMMUNICATION_FAILURE - * \retval PSA_ERROR_HARDWARE_FAILURE - * \retval PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_TAMPERING_DETECTED */ psa_status_t psa_generator_read(psa_crypto_generator_t *generator, uint8_t *output, @@ -3185,42 +3298,47 @@ psa_status_t psa_generator_read(psa_crypto_generator_t *generator, * if the implementation provides an isolation boundary then * the key material is not exposed outside the isolation boundary. * - * \param key 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 handle Handle to the slot where the key will be stored. + * This must be a valid slot for a key of the chosen + * type: it must have been obtained by calling + * psa_allocate_key() or psa_create_key() with the + * correct \p type and with a maximum size that is + * compatible with \p bits. + * It must not contain any key material yet. * \param type Key type (a \c PSA_KEY_TYPE_XXX value). * This must be a symmetric key type. * \param bits Key size in bits. * \param[in,out] generator The generator object to read from. * - * \retval PSA_SUCCESS + * \retval #PSA_SUCCESS * Success. - * \retval PSA_ERROR_INSUFFICIENT_CAPACITY + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_INSUFFICIENT_CAPACITY * There were fewer than \p output_length bytes * in the generator. Note that in this case, no * output is written to the output buffer. * The generator'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 + * \retval #PSA_ERROR_NOT_SUPPORTED * The key type or key size is not supported, either by the * implementation in general or in this particular slot. - * \retval PSA_ERROR_BAD_STATE - * \retval PSA_ERROR_INVALID_ARGUMENT - * The key slot is invalid. - * \retval PSA_ERROR_OCCUPIED_SLOT + * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_OCCUPIED_SLOT * There is already a key in the specified slot. - * \retval PSA_ERROR_INSUFFICIENT_MEMORY - * \retval PSA_ERROR_INSUFFICIENT_STORAGE - * \retval PSA_ERROR_COMMUNICATION_FAILURE - * \retval PSA_ERROR_HARDWARE_FAILURE - * \retval PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_TAMPERING_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_generator_import_key(psa_key_slot_t key, +psa_status_t psa_generator_import_key(psa_key_handle_t handle, psa_key_type_t type, size_t bits, psa_crypto_generator_t *generator); @@ -3241,11 +3359,11 @@ psa_status_t psa_generator_import_key(psa_key_slot_t key, * * \param[in,out] generator The generator to abort. * - * \retval PSA_SUCCESS - * \retval PSA_ERROR_BAD_STATE - * \retval PSA_ERROR_COMMUNICATION_FAILURE - * \retval PSA_ERROR_HARDWARE_FAILURE - * \retval PSA_ERROR_TAMPERING_DETECTED + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE + * \retval #PSA_ERROR_HARDWARE_FAILURE + * \retval #PSA_ERROR_TAMPERING_DETECTED */ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); @@ -3280,7 +3398,7 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); * a logical zero (`{0}`), * \c PSA_CRYPTO_GENERATOR_INIT or * psa_crypto_generator_init(). - * \param key Slot containing the secret key to use. + * \param handle Handle to the secret key. * \param alg The key derivation algorithm to compute * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). @@ -3293,6 +3411,7 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -3310,7 +3429,7 @@ psa_status_t psa_generator_abort(psa_crypto_generator_t *generator); * results in this error code. */ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *salt, size_t salt_length, @@ -3333,7 +3452,7 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, * a logical zero (`{0}`), * \c PSA_CRYPTO_GENERATOR_INIT or * psa_crypto_generator_init(). - * \param private_key Slot containing the private key to use. + * \param private_key Handle to the private key to use. * \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 @@ -3346,6 +3465,7 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, * * \retval #PSA_SUCCESS * Success. + * \retval #PSA_ERROR_INVALID_HANDLE * \retval #PSA_ERROR_EMPTY_SLOT * \retval #PSA_ERROR_NOT_PERMITTED * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -3360,7 +3480,7 @@ psa_status_t psa_key_derivation(psa_crypto_generator_t *generator, * \retval #PSA_ERROR_TAMPERING_DETECTED */ psa_status_t psa_key_agreement(psa_crypto_generator_t *generator, - psa_key_slot_t private_key, + psa_key_handle_t private_key, const uint8_t *peer_key, size_t peer_key_length, psa_algorithm_t alg); @@ -3409,9 +3529,13 @@ typedef struct { /** * \brief Generate a key or key pair. * - * \param key 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 handle Handle to the slot where the key will be stored. + * This must be a valid slot for a key of the chosen + * type: it must have been obtained by calling + * psa_allocate_key() or psa_create_key() with the + * correct \p type and with a maximum size that is + * compatible with \p bits. + * It must not contain any key material yet. * \param type Key type (a \c PSA_KEY_TYPE_XXX value). * \param bits Key size in bits. * \param[in] extra Extra parameters for key generation. The @@ -3440,6 +3564,12 @@ typedef struct { * \c NULL then \p extra_size must be zero. * * \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_INVALID_HANDLE + * \retval #PSA_ERROR_OCCUPIED_SLOT + * There is already a key in the specified slot. * \retval #PSA_ERROR_NOT_SUPPORTED * \retval #PSA_ERROR_INVALID_ARGUMENT * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -3452,7 +3582,7 @@ typedef struct { * It is implementation-dependent whether a failure to initialize * results in this error code. */ -psa_status_t psa_generate_key(psa_key_slot_t key, +psa_status_t psa_generate_key(psa_key_handle_t handle, psa_key_type_t type, size_t bits, const void *extra, diff --git a/include/psa/crypto_platform.h b/include/psa/crypto_platform.h index 9af320d1e..50ca546fb 100644 --- a/include/psa/crypto_platform.h +++ b/include/psa/crypto_platform.h @@ -46,7 +46,7 @@ /* PSA requires several types which C99 provides in stdint.h. */ #include -/* Integral type representing a key slot number. */ -typedef uint16_t psa_key_slot_t; +/* Integral type representing a key handle. */ +typedef uint16_t psa_key_handle_t; #endif /* PSA_CRYPTO_PLATFORM_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c8070bb27..3a3f61bcf 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -54,6 +54,7 @@ set(src_crypto platform_util.c poly1305.c psa_crypto.c + psa_crypto_slot_management.c psa_crypto_storage.c psa_crypto_storage_file.c psa_crypto_storage_its.c diff --git a/library/Makefile b/library/Makefile index 95faaaef3..1822a24af 100644 --- a/library/Makefile +++ b/library/Makefile @@ -83,6 +83,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ pkcs5.o pkparse.o pkwrite.o \ platform.o platform_util.o poly1305.o \ psa_crypto.o \ + psa_crypto_slot_management.o \ psa_crypto_storage.o \ psa_crypto_storage_file.o \ psa_crypto_storage_its.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 8e70c4160..0a47fae44 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -43,7 +43,9 @@ #include "psa/crypto.h" +#include "psa_crypto_core.h" #include "psa_crypto_invasive.h" +#include "psa_crypto_slot_management.h" /* Include internal declarations that are useful for implementing persistently * stored keys. */ #include "psa_crypto_storage.h" @@ -80,6 +82,7 @@ #include "mbedtls/md_internal.h" #include "mbedtls/pk.h" #include "mbedtls/pk_internal.h" +#include "mbedtls/platform_util.h" #include "mbedtls/ripemd160.h" #include "mbedtls/rsa.h" #include "mbedtls/sha1.h" @@ -93,12 +96,6 @@ #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) -/* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) -{ - volatile unsigned char *p = v; while( n-- ) *p++ = 0; -} - /* constant-time buffer comparison */ static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n ) { @@ -117,31 +114,6 @@ static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n ) /* Global data, support functions and library management */ /****************************************************************/ -/* Number of key slots (plus one because 0 is not used). - * The value is a compile-time constant for now, for simplicity. */ -#define PSA_KEY_SLOT_COUNT 32 - -typedef struct -{ - psa_key_type_t type; - psa_key_policy_t policy; - psa_key_lifetime_t lifetime; - union - { - struct raw_data - { - uint8_t *data; - size_t bytes; - } raw; -#if defined(MBEDTLS_RSA_C) - mbedtls_rsa_context *rsa; -#endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_ECP_C) - mbedtls_ecp_keypair *ecp; -#endif /* MBEDTLS_ECP_C */ - } data; -} key_slot_t; - static int key_type_is_raw_bytes( psa_key_type_t type ) { return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) ); @@ -158,10 +130,8 @@ typedef struct void (* entropy_free )( mbedtls_entropy_context *ctx ); mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; - key_slot_t key_slots[PSA_KEY_SLOT_COUNT]; unsigned initialized : 1; unsigned rng_state : 2; - unsigned key_slots_initialized : 1; } psa_global_data_t; static psa_global_data_t global_data; @@ -638,9 +608,12 @@ exit: } #endif /* defined(MBEDTLS_ECP_C) */ -static psa_status_t psa_import_key_into_slot( key_slot_t *slot, - const uint8_t *data, - size_t data_length ) +/** Import key data into a slot. `slot->type` must have been set + * previously. This function assumes that the slot does not contain + * any key material yet. On failure, the slot content is unchanged. */ +psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, + const uint8_t *data, + size_t data_length ) { psa_status_t status = PSA_SUCCESS; @@ -719,71 +692,17 @@ static psa_status_t psa_import_key_into_slot( key_slot_t *slot, return( PSA_SUCCESS ); } -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t key, - key_slot_t *p_slot ) -{ - psa_status_t status = PSA_SUCCESS; - uint8_t *key_data = NULL; - size_t key_data_length = 0; - - status = psa_load_persistent_key( key, &( p_slot )->type, - &( p_slot )->policy, &key_data, - &key_data_length ); - if( status != PSA_SUCCESS ) - goto exit; - status = psa_import_key_into_slot( p_slot, - key_data, key_data_length ); -exit: - psa_free_persistent_key_data( key_data, key_data_length ); - return( status ); -} -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - -/* Retrieve a key slot, occupied or not. */ -static psa_status_t psa_get_key_slot( psa_key_slot_t key, - key_slot_t **p_slot ) -{ - GUARD_MODULE_INITIALIZED; - - /* 0 is not a valid slot number under any circumstance. This - * implementation provides slots number 1 to N where N is the - * number of available slots. */ - if( key == 0 || key > ARRAY_LENGTH( global_data.key_slots ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - *p_slot = &global_data.key_slots[key - 1]; - -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( ( *p_slot )->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) - { - /* There are two circumstances this can occur: the key material has - * not yet been created, or the key exists in storage but has not yet - * been loaded into memory. */ - if( ( *p_slot )->type == PSA_KEY_TYPE_NONE ) - { - psa_status_t status = PSA_SUCCESS; - status = psa_load_persistent_key_into_slot( key, *p_slot ); - if( status != PSA_ERROR_EMPTY_SLOT ) - return( status ); - } - } -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - - return( PSA_SUCCESS ); -} - /* Retrieve an empty key slot (slot with no key data, but possibly * with some metadata such as a policy). */ -static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key, - key_slot_t **p_slot ) +static psa_status_t psa_get_empty_key_slot( psa_key_handle_t handle, + psa_key_slot_t **p_slot ) { psa_status_t status; - key_slot_t *slot = NULL; + psa_key_slot_t *slot = NULL; *p_slot = NULL; - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -797,17 +716,17 @@ static psa_status_t psa_get_empty_key_slot( psa_key_slot_t key, /** Retrieve a slot which must contain a key. The key must have allow all the * usage flags set in \p usage. If \p alg is nonzero, the key must allow * operations with this algorithm. */ -static psa_status_t psa_get_key_from_slot( psa_key_slot_t key, - key_slot_t **p_slot, +static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle, + psa_key_slot_t **p_slot, psa_key_usage_t usage, psa_algorithm_t alg ) { psa_status_t status; - key_slot_t *slot = NULL; + psa_key_slot_t *slot = NULL; *p_slot = NULL; - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); if( slot->type == PSA_KEY_TYPE_NONE ) @@ -828,7 +747,8 @@ static psa_status_t psa_get_key_from_slot( psa_key_slot_t key, return( PSA_SUCCESS ); } -static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot ) +/** Wipe key data from a slot. Preserve metadata such as the policy. */ +static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) { if( slot->type == PSA_KEY_TYPE_NONE ) { @@ -864,15 +784,27 @@ static psa_status_t psa_remove_key_data_from_memory( key_slot_t *slot ) return( PSA_SUCCESS ); } -psa_status_t psa_import_key( psa_key_slot_t key, +/** Completely wipe a slot in memory, including its policy. + * Persistent storage is not affected. */ +psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ) +{ + psa_status_t status = psa_remove_key_data_from_memory( slot ); + /* At this point, key material and other type-specific content has + * been wiped. Clear remaining metadata. We can call memset and not + * zeroize because the metadata is not particularly sensitive. */ + memset( slot, 0, sizeof( *slot ) ); + return( status ); +} + +psa_status_t psa_import_key( psa_key_handle_t handle, psa_key_type_t type, const uint8_t *data, size_t data_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; - status = psa_get_empty_key_slot( key, &slot ); + status = psa_get_empty_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -889,7 +821,8 @@ psa_status_t psa_import_key( psa_key_slot_t key, if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { /* Store in file location */ - status = psa_save_persistent_key( key, slot->type, &slot->policy, data, + status = psa_save_persistent_key( slot->persistent_storage_id, + slot->type, &slot->policy, data, data_length ); if( status != PSA_SUCCESS ) { @@ -902,31 +835,30 @@ psa_status_t psa_import_key( psa_key_slot_t key, return( status ); } -psa_status_t psa_destroy_key( psa_key_slot_t key ) +psa_status_t psa_destroy_key( psa_key_handle_t handle ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status = PSA_SUCCESS; psa_status_t storage_status = PSA_SUCCESS; - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { - storage_status = psa_destroy_persistent_key( key ); + storage_status = + psa_destroy_persistent_key( slot->persistent_storage_id ); } #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - status = psa_remove_key_data_from_memory( slot ); - /* Zeroize the slot to wipe metadata such as policies. */ - mbedtls_zeroize( slot, sizeof( *slot ) ); + status = psa_wipe_key_slot( slot ); if( status != PSA_SUCCESS ) return( status ); return( storage_status ); } /* Return the size of the key in the given slot, in bits. */ -static size_t psa_get_key_bits( const key_slot_t *slot ) +static size_t psa_get_key_bits( const psa_key_slot_t *slot ) { if( key_type_is_raw_bytes( slot->type ) ) return( slot->data.raw.bytes * 8 ); @@ -942,18 +874,18 @@ static size_t psa_get_key_bits( const key_slot_t *slot ) return( 0 ); } -psa_status_t psa_get_key_information( psa_key_slot_t key, +psa_status_t psa_get_key_information( psa_key_handle_t handle, psa_key_type_t *type, size_t *bits ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( type != NULL ) *type = 0; if( bits != NULL ) *bits = 0; - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -966,7 +898,7 @@ psa_status_t psa_get_key_information( psa_key_slot_t key, return( PSA_SUCCESS ); } -static psa_status_t psa_internal_export_key( key_slot_t *slot, +static psa_status_t psa_internal_export_key( psa_key_slot_t *slot, uint8_t *data, size_t data_size, size_t *data_length, @@ -1074,12 +1006,12 @@ static psa_status_t psa_internal_export_key( key_slot_t *slot, } } -psa_status_t psa_export_key( psa_key_slot_t key, +psa_status_t psa_export_key( psa_key_handle_t handle, uint8_t *data, size_t data_size, size_t *data_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; /* Set the key to empty now, so that even when there are errors, we always @@ -1091,19 +1023,19 @@ psa_status_t psa_export_key( psa_key_slot_t key, /* Export requires the EXPORT flag. There is an exception for public keys, * which don't require any flag, but psa_get_key_from_slot takes * care of this. */ - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_EXPORT, 0 ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_EXPORT, 0 ); if( status != PSA_SUCCESS ) return( status ); return( psa_internal_export_key( slot, data, data_size, data_length, 0 ) ); } -psa_status_t psa_export_public_key( psa_key_slot_t key, +psa_status_t psa_export_public_key( psa_key_handle_t handle, uint8_t *data, size_t data_size, size_t *data_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; /* Set the key to empty now, so that even when there are errors, we always @@ -1113,7 +1045,7 @@ psa_status_t psa_export_public_key( psa_key_slot_t key, *data_length = 0; /* Exporting a public key doesn't require a usage flag. */ - status = psa_get_key_from_slot( key, &slot, 0, 0 ); + status = psa_get_key_from_slot( handle, &slot, 0, 0 ); if( status != PSA_SUCCESS ) return( status ); return( psa_internal_export_key( slot, data, data_size, @@ -1121,8 +1053,7 @@ psa_status_t psa_export_public_key( psa_key_slot_t key, } #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t key, - key_slot_t *slot, +static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t *slot, size_t bits ) { psa_status_t status; @@ -1140,14 +1071,15 @@ static psa_status_t psa_save_generated_persistent_key( psa_key_slot_t key, goto exit; } /* Store in file location */ - status = psa_save_persistent_key( key, slot->type, &slot->policy, + status = psa_save_persistent_key( slot->persistent_storage_id, + slot->type, &slot->policy, data, key_length ); if( status != PSA_SUCCESS ) { slot->type = PSA_KEY_TYPE_NONE; } exit: - mbedtls_zeroize( data, key_length ); + mbedtls_platform_zeroize( data, key_length ); mbedtls_free( data ); return( status ); } @@ -1654,7 +1586,7 @@ static psa_status_t psa_mac_init( psa_mac_operation_t *operation, #if defined(MBEDTLS_MD_C) static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) { - mbedtls_zeroize( hmac->opad, sizeof( hmac->opad ) ); + mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); return( psa_hash_abort( &hmac->hash_ctx ) ); } @@ -1716,7 +1648,7 @@ bad_state: #if defined(MBEDTLS_CMAC_C) static int psa_cmac_setup( psa_mac_operation_t *operation, size_t key_bits, - key_slot_t *slot, + psa_key_slot_t *slot, const mbedtls_cipher_info_t *cipher_info ) { int ret; @@ -1798,19 +1730,19 @@ static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, status = psa_hash_update( &hmac->hash_ctx, ipad, block_size ); cleanup: - mbedtls_zeroize( ipad, key_length ); + mbedtls_platform_zeroize( ipad, key_length ); return( status ); } #endif /* MBEDTLS_MD_C */ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg, int is_sign ) { psa_status_t status; - key_slot_t *slot; + psa_key_slot_t *slot; size_t key_bits; psa_key_usage_t usage = is_sign ? PSA_KEY_USAGE_SIGN : PSA_KEY_USAGE_VERIFY; @@ -1823,7 +1755,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, if( is_sign ) operation->is_sign = 1; - status = psa_get_key_from_slot( key, &slot, usage, alg ); + status = psa_get_key_from_slot( handle, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; key_bits = psa_get_key_bits( slot ); @@ -1916,17 +1848,17 @@ exit: } psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg ) { - return( psa_mac_setup( operation, key, alg, 1 ) ); + return( psa_mac_setup( operation, handle, alg, 1 ) ); } psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg ) { - return( psa_mac_setup( operation, key, alg, 0 ) ); + return( psa_mac_setup( operation, handle, alg, 0 ) ); } psa_status_t psa_mac_update( psa_mac_operation_t *operation, @@ -2004,7 +1936,7 @@ static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, memcpy( mac, tmp, mac_size ); exit: - mbedtls_zeroize( tmp, hash_size ); + mbedtls_platform_zeroize( tmp, hash_size ); return( status ); } #endif /* MBEDTLS_MD_C */ @@ -2028,7 +1960,7 @@ static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation, int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp ); if( ret == 0 ) memcpy( mac, tmp, operation->mac_size ); - mbedtls_zeroize( tmp, sizeof( tmp ) ); + mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); return( mbedtls_to_psa_error( ret ) ); } else @@ -2116,7 +2048,7 @@ cleanup: else psa_mac_abort( operation ); - mbedtls_zeroize( actual_mac, sizeof( actual_mac ) ); + mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); return( status ); } @@ -2383,7 +2315,7 @@ cleanup: } #endif /* MBEDTLS_ECDSA_C */ -psa_status_t psa_asymmetric_sign( psa_key_slot_t key, +psa_status_t psa_asymmetric_sign( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -2391,12 +2323,12 @@ psa_status_t psa_asymmetric_sign( psa_key_slot_t key, size_t signature_size, size_t *signature_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; *signature_length = signature_size; - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN, alg ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_SIGN, alg ); if( status != PSA_SUCCESS ) goto exit; if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) @@ -2459,17 +2391,17 @@ exit: return( status ); } -psa_status_t psa_asymmetric_verify( psa_key_slot_t key, +psa_status_t psa_asymmetric_verify( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_VERIFY, alg ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_VERIFY, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -2515,7 +2447,7 @@ static void psa_rsa_oaep_set_padding_mode( psa_algorithm_t alg, } #endif /* defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) */ -psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key, +psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -2525,7 +2457,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key, size_t output_size, size_t *output_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; (void) input; @@ -2539,7 +2471,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) || @@ -2595,7 +2527,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key, } } -psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key, +psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *input, size_t input_length, @@ -2605,7 +2537,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key, size_t output_size, size_t *output_length ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; (void) input; @@ -2619,7 +2551,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! PSA_KEY_TYPE_IS_KEYPAIR( slot->type ) ) @@ -2705,13 +2637,13 @@ static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation, } static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg, mbedtls_operation_t cipher_operation ) { int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; psa_status_t status; - key_slot_t *slot; + psa_key_slot_t *slot; size_t key_bits; const mbedtls_cipher_info_t *cipher_info = NULL; psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ? @@ -2722,7 +2654,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - status = psa_get_key_from_slot( key, &slot, usage, alg); + status = psa_get_key_from_slot( handle, &slot, usage, alg); if( status != PSA_SUCCESS ) return( status ); key_bits = psa_get_key_bits( slot ); @@ -2797,17 +2729,17 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, } psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg ) { - return( psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT ) ); + return( psa_cipher_setup( operation, handle, alg, MBEDTLS_ENCRYPT ) ); } psa_status_t psa_cipher_decrypt_setup( psa_cipher_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg ) { - return( psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT ) ); + return( psa_cipher_setup( operation, handle, alg, MBEDTLS_DECRYPT ) ); } psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation, @@ -2957,7 +2889,7 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, goto error; } - mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); + mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); status = psa_cipher_abort( operation ); return( status ); @@ -2966,7 +2898,7 @@ error: *output_length = 0; - mbedtls_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); + mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); (void) psa_cipher_abort( operation ); return( status ); @@ -3030,16 +2962,16 @@ psa_algorithm_t psa_key_policy_get_algorithm( const psa_key_policy_t *policy ) } #endif /* !defined(MBEDTLS_PSA_CRYPTO_SPM) */ -psa_status_t psa_set_key_policy( psa_key_slot_t key, +psa_status_t psa_set_key_policy( psa_key_handle_t handle, const psa_key_policy_t *policy ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( policy == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_empty_key_slot( key, &slot ); + status = psa_get_empty_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -3056,16 +2988,16 @@ psa_status_t psa_set_key_policy( psa_key_slot_t key, return( PSA_SUCCESS ); } -psa_status_t psa_get_key_policy( psa_key_slot_t key, +psa_status_t psa_get_key_policy( psa_key_handle_t handle, psa_key_policy_t *policy ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( policy == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -3080,13 +3012,13 @@ psa_status_t psa_get_key_policy( psa_key_slot_t key, /* Key Lifetime */ /****************************************************************/ -psa_status_t psa_get_key_lifetime( psa_key_slot_t key, +psa_status_t psa_get_key_lifetime( psa_key_handle_t handle, psa_key_lifetime_t *lifetime ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; - status = psa_get_key_slot( key, &slot ); + status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -3095,34 +3027,6 @@ psa_status_t psa_get_key_lifetime( psa_key_slot_t key, return( PSA_SUCCESS ); } -psa_status_t psa_set_key_lifetime( psa_key_slot_t key, - psa_key_lifetime_t lifetime ) -{ - key_slot_t *slot; - psa_status_t status; - - if( lifetime != PSA_KEY_LIFETIME_VOLATILE && - lifetime != PSA_KEY_LIFETIME_PERSISTENT && - lifetime != PSA_KEY_LIFETIME_WRITE_ONCE ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - status = psa_get_empty_key_slot( key, &slot ); - if( status != PSA_SUCCESS ) - return( status ); - - if( lifetime == PSA_KEY_LIFETIME_WRITE_ONCE ) - return( PSA_ERROR_NOT_SUPPORTED ); - -#if !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( lifetime == PSA_KEY_LIFETIME_PERSISTENT ) - return( PSA_ERROR_NOT_SUPPORTED ); -#endif - - slot->lifetime = lifetime; - - return( PSA_SUCCESS ); -} - /****************************************************************/ @@ -3131,7 +3035,7 @@ psa_status_t psa_set_key_lifetime( psa_key_slot_t key, typedef struct { - key_slot_t *slot; + psa_key_slot_t *slot; const mbedtls_cipher_info_t *cipher_info; union { @@ -3165,7 +3069,7 @@ static void psa_aead_abort( aead_operation_t *operation ) } static psa_status_t psa_aead_setup( aead_operation_t *operation, - psa_key_slot_t key, + psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -3173,7 +3077,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, size_t key_bits; mbedtls_cipher_id_t cipher_id; - status = psa_get_key_from_slot( key, &operation->slot, usage, alg ); + status = psa_get_key_from_slot( handle, &operation->slot, usage, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3238,7 +3142,7 @@ cleanup: return( status ); } -psa_status_t psa_aead_encrypt( psa_key_slot_t key, +psa_status_t psa_aead_encrypt( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -3256,7 +3160,7 @@ psa_status_t psa_aead_encrypt( psa_key_slot_t key, *ciphertext_length = 0; - status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3332,7 +3236,7 @@ static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length, return( PSA_SUCCESS ); } -psa_status_t psa_aead_decrypt( psa_key_slot_t key, +psa_status_t psa_aead_decrypt( psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, @@ -3350,7 +3254,7 @@ psa_status_t psa_aead_decrypt( psa_key_slot_t key, *plaintext_length = 0; - status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_aead_setup( &operation, handle, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3428,7 +3332,7 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator ) { if( generator->ctx.buffer.data != NULL ) { - mbedtls_zeroize( generator->ctx.buffer.data, + mbedtls_platform_zeroize( generator->ctx.buffer.data, generator->ctx.buffer.size ); mbedtls_free( generator->ctx.buffer.data ); } @@ -3446,14 +3350,14 @@ psa_status_t psa_generator_abort( psa_crypto_generator_t *generator ) { if( generator->ctx.tls12_prf.key != NULL ) { - mbedtls_zeroize( generator->ctx.tls12_prf.key, + mbedtls_platform_zeroize( generator->ctx.tls12_prf.key, generator->ctx.tls12_prf.key_len ); mbedtls_free( generator->ctx.tls12_prf.key ); } if( generator->ctx.tls12_prf.Ai_with_seed != NULL ) { - mbedtls_zeroize( generator->ctx.tls12_prf.Ai_with_seed, + mbedtls_platform_zeroize( generator->ctx.tls12_prf.Ai_with_seed, generator->ctx.tls12_prf.Ai_with_seed_len ); mbedtls_free( generator->ctx.tls12_prf.Ai_with_seed ); } @@ -3779,7 +3683,7 @@ static void psa_des_set_key_parity( uint8_t *data, size_t data_size ) } #endif /* MBEDTLS_DES_C */ -psa_status_t psa_generator_import_key( psa_key_slot_t key, +psa_status_t psa_generator_import_key( psa_key_handle_t handle, psa_key_type_t type, size_t bits, psa_crypto_generator_t *generator ) @@ -3803,7 +3707,7 @@ psa_status_t psa_generator_import_key( psa_key_slot_t key, if( type == PSA_KEY_TYPE_DES ) psa_des_set_key_parity( data, bytes ); #endif /* MBEDTLS_DES_C */ - status = psa_import_key( key, type, data, bytes ); + status = psa_import_key( handle, type, data, bytes ); exit: mbedtls_free( data ); @@ -3955,7 +3859,7 @@ static psa_status_t psa_generator_tls12_psk_to_ms_setup( salt, salt_length, label, label_length ); - mbedtls_zeroize( pms, sizeof( pms ) ); + mbedtls_platform_zeroize( pms, sizeof( pms ) ); return( status ); } #endif /* MBEDTLS_MD_C */ @@ -4060,7 +3964,7 @@ static psa_status_t psa_key_derivation_internal( } psa_status_t psa_key_derivation( psa_crypto_generator_t *generator, - psa_key_slot_t key, + psa_key_handle_t handle, psa_algorithm_t alg, const uint8_t *salt, size_t salt_length, @@ -4068,7 +3972,7 @@ psa_status_t psa_key_derivation( psa_crypto_generator_t *generator, size_t label_length, size_t capacity ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( generator->alg != 0 ) @@ -4080,7 +3984,7 @@ psa_status_t psa_key_derivation( psa_crypto_generator_t *generator, if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_DERIVE, alg ); + status = psa_get_key_from_slot( handle, &slot, PSA_KEY_USAGE_DERIVE, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -4165,7 +4069,7 @@ exit: * to potentially free embedded data structures and wipe confidential data. */ static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generator, - key_slot_t *private_key, + psa_key_slot_t *private_key, const uint8_t *peer_key, size_t peer_key_length, psa_algorithm_t alg ) @@ -4206,17 +4110,17 @@ static psa_status_t psa_key_agreement_internal( psa_crypto_generator_t *generato NULL, 0, NULL, 0, PSA_GENERATOR_UNBRIDLED_CAPACITY ); exit: - mbedtls_zeroize( shared_secret, shared_secret_length ); + mbedtls_platform_zeroize( shared_secret, shared_secret_length ); return( status ); } psa_status_t psa_key_agreement( psa_crypto_generator_t *generator, - psa_key_slot_t private_key, + psa_key_handle_t private_key, const uint8_t *peer_key, size_t peer_key_length, psa_algorithm_t alg ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -4316,19 +4220,19 @@ psa_status_t mbedtls_psa_inject_entropy( const unsigned char *seed, } #endif -psa_status_t psa_generate_key( psa_key_slot_t key, +psa_status_t psa_generate_key( psa_key_handle_t handle, psa_key_type_t type, size_t bits, const void *extra, size_t extra_size ) { - key_slot_t *slot; + psa_key_slot_t *slot; psa_status_t status; if( extra == NULL && extra_size != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_empty_key_slot( key, &slot ); + status = psa_get_empty_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -4437,7 +4341,7 @@ psa_status_t psa_generate_key( psa_key_slot_t key, #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { - return( psa_save_generated_persistent_key( key, slot, bits ) ); + return( psa_save_generated_persistent_key( slot, bits ) ); } #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ @@ -4462,21 +4366,7 @@ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( void mbedtls_psa_crypto_free( void ) { - psa_key_slot_t key; - key_slot_t *slot; - psa_status_t status; - if( global_data.key_slots_initialized ) - { - for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) - { - status = psa_get_key_slot( key, &slot ); - if( status != PSA_SUCCESS ) - continue; - psa_remove_key_data_from_memory( slot ); - /* Zeroize the slot to wipe metadata such as policies. */ - mbedtls_zeroize( slot, sizeof( *slot ) ); - } - } + psa_wipe_all_key_slots( ); if( global_data.rng_state != RNG_NOT_INITIALIZED ) { mbedtls_ctr_drbg_free( &global_data.ctr_drbg ); @@ -4485,12 +4375,12 @@ void mbedtls_psa_crypto_free( void ) /* Wipe all remaining data, including configuration. * In particular, this sets all state indicator to the value * indicating "uninitialized". */ - mbedtls_zeroize( &global_data, sizeof( global_data ) ); + mbedtls_platform_zeroize( &global_data, sizeof( global_data ) ); } psa_status_t psa_crypto_init( void ) { - int ret; + psa_status_t status; const unsigned char drbg_seed[] = "PSA"; /* Double initialization is explicitly allowed. */ @@ -4508,26 +4398,26 @@ psa_status_t psa_crypto_init( void ) global_data.entropy_init( &global_data.entropy ); mbedtls_ctr_drbg_init( &global_data.ctr_drbg ); global_data.rng_state = RNG_INITIALIZED; - ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg, - mbedtls_entropy_func, - &global_data.entropy, - drbg_seed, sizeof( drbg_seed ) - 1 ); - if( ret != 0 ) + status = mbedtls_to_psa_error( + mbedtls_ctr_drbg_seed( &global_data.ctr_drbg, + mbedtls_entropy_func, + &global_data.entropy, + drbg_seed, sizeof( drbg_seed ) - 1 ) ); + if( status != PSA_SUCCESS ) goto exit; global_data.rng_state = RNG_SEEDED; - /* Initialize the key slots. Zero-initialization has made all key - * slots empty, so there is nothing to do. In a future version we will - * load data from storage. */ - global_data.key_slots_initialized = 1; + status = psa_initialize_key_slots( ); + if( status != PSA_SUCCESS ) + goto exit; /* All done. */ global_data.initialized = 1; exit: - if( ret != 0 ) + if( status != PSA_SUCCESS ) mbedtls_psa_crypto_free( ); - return( mbedtls_to_psa_error( ret ) ); + return( status ); } #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h new file mode 100644 index 000000000..c28968197 --- /dev/null +++ b/library/psa_crypto_core.h @@ -0,0 +1,99 @@ +/* + * PSA crypto core internal interfaces + */ +/* Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef PSA_CRYPTO_CORE_H +#define PSA_CRYPTO_CORE_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "psa/crypto.h" + +#include "mbedtls/ecp.h" +#include "mbedtls/rsa.h" + +/** The data structure representing a key slot, containing key material + * and metadata for one key. + */ +typedef struct +{ + psa_key_type_t type; + psa_key_policy_t policy; + psa_key_lifetime_t lifetime; + psa_key_id_t persistent_storage_id; + unsigned allocated : 1; + union + { + struct raw_data + { + uint8_t *data; + size_t bytes; + } raw; +#if defined(MBEDTLS_RSA_C) + mbedtls_rsa_context *rsa; +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECP_C) + mbedtls_ecp_keypair *ecp; +#endif /* MBEDTLS_ECP_C */ + } data; +} psa_key_slot_t; + +/** Completely wipe a slot in memory, including its policy. + * + * Persistent storage is not affected. + * + * \param[in,out] slot The key slot to wipe. + * + * \retval PSA_SUCCESS + * Success. This includes the case of a key slot that was + * already fully wiped. + * \retval PSA_ERROR_TAMPERING_DETECTED + */ +psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ); + +/** Import key data into a slot. + * + * `slot->type` must have been set previously. + * This function assumes that the slot does not contain any key material yet. + * On failure, the slot content is unchanged. + * + * Persistent storage is not affected. + * + * \param[in,out] slot The key slot to import data into. + * Its `type` field must have previously been set to + * the desired key type. + * It must not contain any key material yet. + * \param[in] data Buffer containing the key material to parse and import. + * \param data_length Size of \p data in bytes. + * + * \retval PSA_SUCCESS + * \retval PSA_ERROR_INVALID_ARGUMENT + * \retval PSA_ERROR_NOT_SUPPORTED + * \retval PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, + const uint8_t *data, + size_t data_length ); + +#endif /* PSA_CRYPTO_CORE_H */ diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c new file mode 100644 index 000000000..0b4399f5e --- /dev/null +++ b/library/psa_crypto_slot_management.c @@ -0,0 +1,287 @@ +/* + * PSA crypto layer on top of Mbed TLS crypto + */ +/* Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#include "psa/crypto.h" + +#include "psa_crypto_core.h" +#include "psa_crypto_slot_management.h" +#include "psa_crypto_storage.h" + +#include +#include +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) + +typedef struct +{ + psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT]; + unsigned key_slots_initialized : 1; +} psa_global_data_t; + +static psa_global_data_t global_data; + +/* Access a key slot at the given handle. The handle of a key slot is + * the index of the slot in the global slot array, plus one so that handles + * start at 1 and not 0. */ +psa_status_t psa_get_key_slot( psa_key_handle_t handle, + psa_key_slot_t **p_slot ) +{ + psa_key_slot_t *slot = NULL; + + if( ! global_data.key_slots_initialized ) + return( PSA_ERROR_BAD_STATE ); + + /* 0 is not a valid handle under any circumstance. This + * implementation provides slots number 1 to N where N is the + * number of available slots. */ + if( handle == 0 || handle > ARRAY_LENGTH( global_data.key_slots ) ) + return( PSA_ERROR_INVALID_HANDLE ); + slot = &global_data.key_slots[handle - 1]; + + /* If the slot hasn't been allocated, the handle is invalid. */ + if( ! slot->allocated ) + return( PSA_ERROR_INVALID_HANDLE ); + + *p_slot = slot; + return( PSA_SUCCESS ); +} + +psa_status_t psa_initialize_key_slots( void ) +{ + /* Nothing to do: program startup and psa_wipe_all_key_slots() both + * guarantee that the key slots are initialized to all-zero, which + * means that all the key slots are in a valid, empty state. */ + global_data.key_slots_initialized = 1; + return( PSA_SUCCESS ); +} + +void psa_wipe_all_key_slots( void ) +{ + psa_key_handle_t key; + for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) + { + psa_key_slot_t *slot = &global_data.key_slots[key - 1]; + (void) psa_wipe_key_slot( slot ); + } + global_data.key_slots_initialized = 0; +} + +/** Find a free key slot and mark it as in use. + * + * \param[out] handle On success, a slot number that is not in use. This + * value can be used as a handle to the slot. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +static psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle ) +{ + for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) + { + psa_key_slot_t *slot = &global_data.key_slots[*handle - 1]; + if( ! slot->allocated ) + { + slot->allocated = 1; + return( PSA_SUCCESS ); + } + } + return( PSA_ERROR_INSUFFICIENT_MEMORY ); +} + +/** Wipe a key slot and mark it as available. + * + * This does not affect persistent storage. + * + * \param handle The handle to the key slot to release. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_TAMPERING_DETECTED + */ +static psa_status_t psa_internal_release_key_slot( psa_key_handle_t handle ) +{ + psa_key_slot_t *slot; + psa_status_t status; + + status = psa_get_key_slot( handle, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + return( psa_wipe_key_slot( slot ) ); +} + +psa_status_t psa_allocate_key( psa_key_type_t type, + size_t max_bits, + psa_key_handle_t *handle ) +{ + /* This implementation doesn't reserve memory for the keys. */ + (void) type; + (void) max_bits; + *handle = 0; + return( psa_internal_allocate_key_slot( handle ) ); +} + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) +static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot ) +{ + psa_status_t status = PSA_SUCCESS; + uint8_t *key_data = NULL; + size_t key_data_length = 0; + + status = psa_load_persistent_key( p_slot->persistent_storage_id, + &( p_slot )->type, + &( p_slot )->policy, &key_data, + &key_data_length ); + if( status != PSA_SUCCESS ) + goto exit; + status = psa_import_key_into_slot( p_slot, + key_data, key_data_length ); +exit: + psa_free_persistent_key_data( key_data, key_data_length ); + return( status ); +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ + +/** Declare a slot as persistent and load it from storage. + * + * This function may only be called immediately after a successful call + * to psa_internal_allocate_key_slot(). + * + * \param handle A handle to a key slot freshly allocated with + * psa_internal_allocate_key_slot(). + * + * \retval #PSA_SUCCESS + * The slot content was loaded successfully. + * \retval #PSA_ERROR_EMPTY_SLOT + * There is no content for this slot in persistent storage. + * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \p id is not acceptable. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_STORAGE_FAILURE + */ +static psa_status_t psa_internal_make_key_persistent( psa_key_handle_t handle, + psa_key_id_t id ) +{ +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + psa_key_slot_t *slot; + psa_status_t status; + + /* Reject id=0 because by general library conventions, 0 is an invalid + * value wherever possible. */ + if( id == 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + /* Reject high values because the file names are reserved for the + * library's internal use. */ + if( id >= PSA_MAX_PERSISTENT_KEY_IDENTIFIER ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + status = psa_get_key_slot( handle, &slot ); + if( status != PSA_SUCCESS ) + return( status ); + + slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT; + slot->persistent_storage_id = id; + status = psa_load_persistent_key_into_slot( slot ); + + return( status ); + +#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ + (void) handle; + (void) id; + return( PSA_ERROR_NOT_SUPPORTED ); +#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */ +} + +static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime, + psa_key_id_t id, + psa_key_handle_t *handle, + psa_status_t wanted_load_status ) +{ + psa_status_t status; + + *handle = 0; + + if( lifetime != PSA_KEY_LIFETIME_PERSISTENT ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + status = psa_internal_allocate_key_slot( handle ); + if( status != PSA_SUCCESS ) + return( status ); + + status = psa_internal_make_key_persistent( *handle, id ); + if( status != wanted_load_status ) + { + psa_internal_release_key_slot( *handle ); + *handle = 0; + } + return( status ); +} + +psa_status_t psa_open_key( psa_key_lifetime_t lifetime, + psa_key_id_t id, + psa_key_handle_t *handle ) +{ + return( persistent_key_setup( lifetime, id, handle, PSA_SUCCESS ) ); +} + +psa_status_t psa_create_key( psa_key_lifetime_t lifetime, + psa_key_id_t id, + psa_key_type_t type, + size_t max_bits, + psa_key_handle_t *handle ) +{ + psa_status_t status; + + /* This implementation doesn't reserve memory for the keys. */ + (void) type; + (void) max_bits; + + status = persistent_key_setup( lifetime, id, handle, + PSA_ERROR_EMPTY_SLOT ); + switch( status ) + { + case PSA_SUCCESS: return( PSA_ERROR_OCCUPIED_SLOT ); + case PSA_ERROR_EMPTY_SLOT: return( PSA_SUCCESS ); + default: return( status ); + } +} + +psa_status_t psa_close_key( psa_key_handle_t handle ) +{ + return( psa_internal_release_key_slot( handle ) ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h new file mode 100644 index 000000000..6746bad91 --- /dev/null +++ b/library/psa_crypto_slot_management.h @@ -0,0 +1,58 @@ +/* + * PSA crypto layer on top of Mbed TLS crypto + */ +/* Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H +#define PSA_CRYPTO_SLOT_MANAGEMENT_H + +/* Number of key slots (plus one because 0 is not used). + * The value is a compile-time constant for now, for simplicity. */ +#define PSA_KEY_SLOT_COUNT 32 + +/** Access a key slot at the given handle. + * + * \param handle Key handle to query. + * \param[out] p_slot On success, `*p_slot` contains a pointer to the + * key slot in memory designated by \p handle. + * + * \retval PSA_SUCCESS + * Success: \p handle is a handle to `*p_slot`. Note that `*p_slot` + * may be empty or occupied. + * \retval PSA_ERROR_INVALID_HANDLE + * \p handle is out of range or is not in use. + * \retval PSA_ERROR_BAD_STATE + * The library has not been initialized. + */ +psa_status_t psa_get_key_slot( psa_key_handle_t handle, + psa_key_slot_t **p_slot ); + +/** Initialize the key slot structures. + * + * \retval PSA_SUCCESS + * Currently this function always succeeds. + */ +psa_status_t psa_initialize_key_slots( void ); + +/** Delete all data from key slots in memory. + * + * This does not affect persistent storage. */ +void psa_wipe_all_key_slots( void ); + +#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */ diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c index 0a5805b62..687269b07 100644 --- a/library/psa_crypto_storage.c +++ b/library/psa_crypto_storage.c @@ -147,7 +147,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, return( PSA_SUCCESS ); } -psa_status_t psa_save_persistent_key( const psa_key_slot_t key, +psa_status_t psa_save_persistent_key( const psa_key_id_t key, const psa_key_type_t type, const psa_key_policy_t *policy, const uint8_t *data, @@ -185,7 +185,7 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length ) mbedtls_free( key_data ); } -psa_status_t psa_load_persistent_key( psa_key_slot_t key, +psa_status_t psa_load_persistent_key( psa_key_id_t key, psa_key_type_t *type, psa_key_policy_t *policy, uint8_t **data, diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index 167b0db05..85881c164 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -44,6 +44,23 @@ extern "C" { * inadvertently store an obscene amount of data) */ #define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 ) +/** The maximum permitted persistent slot number. + * + * In Mbed Crypto 0.1.0b: + * - Using the file backend, all key ids are ok except 0. + * - Using the ITS backend, all key ids are ok except 0xFFFFFF52 + * (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the + * device's random seed (if this feature is enabled). + * - Only key ids from 1 to #PSA_KEY_SLOT_COUNT are actually used. + * + * Since we need to preserve the random seed, avoid using that key slot. + * Reserve a whole range of key slots just in case something else comes up. + * + * This limitation will probably become moot when we implement client + * separation for key storage. + */ +#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xffff0000 + /** * \brief Format key data and metadata and save to a location for given key * slot. @@ -56,20 +73,20 @@ extern "C" { * already occupied non-persistent key, as well as validating the key data. * * - * \param key Slot number of the key to be stored. This must be a - * valid slot for a key of the chosen type. This should be - * an occupied key slot with an unoccupied corresponding - * storage location. + * \param key Persistent identifier of the key to be stored. This + * should be an unoccupied storage location. * \param type Key type (a \c PSA_KEY_TYPE_XXX value). * \param[in] policy The key policy to save. * \param[in] data Buffer containing the key data. * \param data_length The number of bytes that make up the key data. * * \retval PSA_SUCCESS + * \retval PSA_ERROR_INSUFFICIENT_MEMORY * \retval PSA_ERROR_INSUFFICIENT_STORAGE * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_OCCUPIED_SLOT */ -psa_status_t psa_save_persistent_key( const psa_key_slot_t key, +psa_status_t psa_save_persistent_key( const psa_key_id_t key, const psa_key_type_t type, const psa_key_policy_t *policy, const uint8_t *data, @@ -87,10 +104,8 @@ psa_status_t psa_save_persistent_key( const psa_key_slot_t key, * this function to zeroize and free this buffer, regardless of whether this * function succeeds or fails. * - * \param key Slot number whose content is to be loaded. This - * must be an unoccupied key slot with an occupied - * corresponding storage location. The key slot - * lifetime must be set to persistent. + * \param key Persistent identifier of the key to be loaded. This + * should be an occupied storage location. * \param[out] type On success, the key type (a \c PSA_KEY_TYPE_XXX * value). * \param[out] policy On success, the key's policy. @@ -100,8 +115,9 @@ psa_status_t psa_save_persistent_key( const psa_key_slot_t key, * \retval PSA_SUCCESS * \retval PSA_ERROR_INSUFFICIENT_MEMORY * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_EMPTY_SLOT */ -psa_status_t psa_load_persistent_key( psa_key_slot_t key, +psa_status_t psa_load_persistent_key( psa_key_id_t key, psa_key_type_t *type, psa_key_policy_t *policy, uint8_t **data, @@ -110,16 +126,18 @@ psa_status_t psa_load_persistent_key( psa_key_slot_t key, /** * \brief Remove persistent data for the given key slot number. * - * \param key Slot number whose content is to be removed + * \param key Persistent identifier of the key to remove * from persistent storage. * * \retval PSA_SUCCESS + * The key was successfully removed, + * or the key did not exist. * \retval PSA_ERROR_STORAGE_FAILURE */ -psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key ); +psa_status_t psa_destroy_persistent_key( const psa_key_id_t key ); /** - * \brief Zeroizes and frees the given buffer. + * \brief Free the temporary buffer allocated by psa_load_persistent_key(). * * This function must be called at some point after psa_load_persistent_key() * to zeroize and free the memory allocated to the buffer in that function. diff --git a/library/psa_crypto_storage_backend.h b/library/psa_crypto_storage_backend.h index 3ca9a1d74..47896b872 100644 --- a/library/psa_crypto_storage_backend.h +++ b/library/psa_crypto_storage_backend.h @@ -47,15 +47,16 @@ extern "C" { * This function reads data from a storage backend and returns the data in a * buffer. * - * \param key Slot number whose content is to be loaded. This must - * be a key slot whose lifetime is set to persistent. - * \param[out] data Buffer where the data is to be written. - * \param data_size Size of the \c data buffer in bytes. + * \param key Persistent identifier of the key to be loaded. This + * should be an occupied storage location. + * \param[out] data Buffer where the data is to be written. + * \param data_size Size of the \c data buffer in bytes. * * \retval PSA_SUCCESS * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_EMPTY_SLOT */ -psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, +psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data, size_t data_size ); /** @@ -63,7 +64,8 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, * * This function stores the given data buffer to a persistent storage. * - * \param key Slot number whose content is to be stored. + * \param key Persistent identifier of the key to be stored. This + * should be an unoccupied storage location. * \param[in] data Buffer containing the data to be stored. * \param data_length The number of bytes * that make up the data. @@ -71,8 +73,9 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, * \retval PSA_SUCCESS * \retval PSA_ERROR_INSUFFICIENT_STORAGE * \retval PSA_ERROR_STORAGE_FAILURE + * \retval PSA_ERROR_OCCUPIED_SLOT */ -psa_status_t psa_crypto_storage_store( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_store( const psa_key_id_t key, const uint8_t *data, size_t data_length ); @@ -82,26 +85,26 @@ psa_status_t psa_crypto_storage_store( const psa_key_slot_t key, * This function checks if any key data or metadata exists for the key slot in * the persistent storage. * - * \param key Slot number whose content is to be checked. + * \param key Persistent identifier to check. * * \retval 0 * No persistent data present for slot number * \retval 1 * Persistent data present for slot number */ -int psa_is_key_present_in_storage( const psa_key_slot_t key ); +int psa_is_key_present_in_storage( const psa_key_id_t key ); /** * \brief Get data length for given key slot number. * - * \param key Slot number whose stored data length is to be obtained. - * \param[out] data_length The number of bytes - * that make up the data. + * \param key Persistent identifier whose stored data length + * is to be obtained. + * \param[out] data_length The number of bytes that make up the data. * * \retval PSA_SUCCESS * \retval PSA_ERROR_STORAGE_FAILURE */ -psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key, size_t *data_length ); diff --git a/library/psa_crypto_storage_file.c b/library/psa_crypto_storage_file.c index 03c711af3..87420be98 100644 --- a/library/psa_crypto_storage_file.c +++ b/library/psa_crypto_storage_file.c @@ -48,15 +48,16 @@ enum { MAX_LOCATION_LEN = sizeof(CRYPTO_STORAGE_FILE_LOCATION) + 40 }; -static void key_slot_to_location( const psa_key_slot_t key, - char *location, - size_t location_size ) +static void key_id_to_location( const psa_key_id_t key, + char *location, + size_t location_size ) { mbedtls_snprintf( location, location_size, - CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%d", key ); + CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_%lu", + (unsigned long) key ); } -psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, +psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data, size_t data_size ) { psa_status_t status = PSA_SUCCESS; @@ -64,7 +65,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, size_t num_read; char slot_location[MAX_LOCATION_LEN]; - key_slot_to_location( key, slot_location, MAX_LOCATION_LEN ); + key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); file = fopen( slot_location, "rb" ); if( file == NULL ) { @@ -81,12 +82,12 @@ exit: return( status ); } -int psa_is_key_present_in_storage( const psa_key_slot_t key ) +int psa_is_key_present_in_storage( const psa_key_id_t key ) { char slot_location[MAX_LOCATION_LEN]; FILE *file; - key_slot_to_location( key, slot_location, MAX_LOCATION_LEN ); + key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); file = fopen( slot_location, "r" ); if( file == NULL ) @@ -99,7 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_slot_t key ) return( 1 ); } -psa_status_t psa_crypto_storage_store( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_store( const psa_key_id_t key, const uint8_t *data, size_t data_length ) { @@ -114,7 +115,7 @@ psa_status_t psa_crypto_storage_store( const psa_key_slot_t key, * affect actual keys. */ const char *temp_location = CRYPTO_STORAGE_FILE_LOCATION "psa_key_slot_0"; - key_slot_to_location( key, slot_location, MAX_LOCATION_LEN ); + key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); if( psa_is_key_present_in_storage( key ) == 1 ) return( PSA_ERROR_OCCUPIED_SLOT ); @@ -154,12 +155,12 @@ exit: return( status ); } -psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key ) +psa_status_t psa_destroy_persistent_key( const psa_key_id_t key ) { FILE *file; char slot_location[MAX_LOCATION_LEN]; - key_slot_to_location( key, slot_location, MAX_LOCATION_LEN ); + key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); /* Only try remove the file if it exists */ file = fopen( slot_location, "rb" ); @@ -173,7 +174,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key ) return( PSA_SUCCESS ); } -psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key, size_t *data_length ) { psa_status_t status = PSA_SUCCESS; @@ -181,7 +182,7 @@ psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key, long file_size; char slot_location[MAX_LOCATION_LEN]; - key_slot_to_location( key, slot_location, MAX_LOCATION_LEN ); + key_id_to_location( key, slot_location, MAX_LOCATION_LEN ); file = fopen( slot_location, "rb" ); if( file == NULL ) diff --git a/library/psa_crypto_storage_its.c b/library/psa_crypto_storage_its.c index 35caa39ad..d53467a1a 100644 --- a/library/psa_crypto_storage_its.c +++ b/library/psa_crypto_storage_its.c @@ -68,12 +68,12 @@ static psa_status_t its_to_psa_error( psa_its_status_t ret ) } } -static uint32_t psa_its_identifier_of_slot( psa_key_slot_t key ) +static uint32_t psa_its_identifier_of_slot( psa_key_id_t key ) { return( key ); } -psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, +psa_status_t psa_crypto_storage_load( const psa_key_id_t key, uint8_t *data, size_t data_size ) { psa_its_status_t ret; @@ -92,7 +92,7 @@ psa_status_t psa_crypto_storage_load( const psa_key_slot_t key, uint8_t *data, return( status ); } -int psa_is_key_present_in_storage( const psa_key_slot_t key ) +int psa_is_key_present_in_storage( const psa_key_id_t key ) { psa_its_status_t ret; uint32_t data_identifier = psa_its_identifier_of_slot( key ); @@ -105,7 +105,7 @@ int psa_is_key_present_in_storage( const psa_key_slot_t key ) return( 1 ); } -psa_status_t psa_crypto_storage_store( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_store( const psa_key_id_t key, const uint8_t *data, size_t data_length ) { @@ -143,7 +143,7 @@ exit: return( status ); } -psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key ) +psa_status_t psa_destroy_persistent_key( const psa_key_id_t key ) { psa_its_status_t ret; uint32_t data_identifier = psa_its_identifier_of_slot( key ); @@ -163,7 +163,7 @@ psa_status_t psa_destroy_persistent_key( const psa_key_slot_t key ) return( PSA_SUCCESS ); } -psa_status_t psa_crypto_storage_get_data_length( const psa_key_slot_t key, +psa_status_t psa_crypto_storage_get_data_length( const psa_key_id_t key, size_t *data_length ) { psa_its_status_t ret; diff --git a/programs/psa/crypto_examples.c b/programs/psa/crypto_examples.c index 72c41fa79..53b6b2ae7 100644 --- a/programs/psa/crypto_examples.c +++ b/programs/psa/crypto_examples.c @@ -44,10 +44,7 @@ int main( void ) } #else -/* Use key slot 1 for our cipher key. Key slot 0 is reserved as unused. */ -static const psa_key_slot_t key_slot_cipher = 1; - -static psa_status_t set_key_policy( psa_key_slot_t key_slot, +static psa_status_t set_key_policy( psa_key_handle_t key_handle, psa_key_usage_t key_usage, psa_algorithm_t alg ) { @@ -56,7 +53,7 @@ static psa_status_t set_key_policy( psa_key_slot_t key_slot, psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, key_usage, alg ); - status = psa_set_key_policy( key_slot, &policy ); + status = psa_set_key_policy( key_handle, &policy ); ASSERT_STATUS( status, PSA_SUCCESS ); exit: return( status ); @@ -98,7 +95,7 @@ exit: return( status ); } -static psa_status_t cipher_encrypt( psa_key_slot_t key_slot, +static psa_status_t cipher_encrypt( psa_key_handle_t key_handle, psa_algorithm_t alg, uint8_t * iv, size_t iv_size, @@ -114,7 +111,7 @@ static psa_status_t cipher_encrypt( psa_key_slot_t key_slot, size_t iv_len = 0; memset( &operation, 0, sizeof( operation ) ); - status = psa_cipher_encrypt_setup( &operation, key_slot, alg ); + status = psa_cipher_encrypt_setup( &operation, key_handle, alg ); ASSERT_STATUS( status, PSA_SUCCESS ); status = psa_cipher_generate_iv( &operation, iv, iv_size, &iv_len ); @@ -129,7 +126,7 @@ exit: return( status ); } -static psa_status_t cipher_decrypt( psa_key_slot_t key_slot, +static psa_status_t cipher_decrypt( psa_key_handle_t key_handle, psa_algorithm_t alg, const uint8_t * iv, size_t iv_size, @@ -144,7 +141,7 @@ static psa_status_t cipher_decrypt( psa_key_slot_t key_slot, psa_cipher_operation_t operation; memset( &operation, 0, sizeof( operation ) ); - status = psa_cipher_decrypt_setup( &operation, key_slot, alg ); + status = psa_cipher_decrypt_setup( &operation, key_handle, alg ); ASSERT_STATUS( status, PSA_SUCCESS ); status = psa_cipher_set_iv( &operation, iv, iv_size ); @@ -170,6 +167,7 @@ cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void ) const psa_algorithm_t alg = PSA_ALG_CBC_NO_PADDING; psa_status_t status; + psa_key_handle_t key_handle = 0; size_t output_len = 0; uint8_t iv[block_size]; uint8_t input[block_size]; @@ -179,21 +177,24 @@ cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void ) status = psa_generate_random( input, sizeof( input ) ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = set_key_policy( key_slot_cipher, + status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = set_key_policy( key_handle, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits, NULL, 0 ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ), input, sizeof( input ), part_size, encrypt, sizeof( encrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ), encrypt, output_len, part_size, decrypt, sizeof( decrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); @@ -202,7 +203,7 @@ cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void ) ASSERT_STATUS( status, PSA_SUCCESS ); exit: - psa_destroy_key( key_slot_cipher ); + psa_destroy_key( key_handle ); return( status ); } @@ -218,6 +219,7 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void ) const psa_algorithm_t alg = PSA_ALG_CBC_PKCS7; psa_status_t status; + psa_key_handle_t key_handle = 0; size_t output_len = 0; uint8_t iv[block_size], input[input_size], encrypt[input_size + block_size], decrypt[input_size + block_size]; @@ -225,21 +227,24 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void ) status = psa_generate_random( input, sizeof( input ) ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = set_key_policy( key_slot_cipher, + status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle ); + ASSERT_STATUS( status, PSA_SUCCESS ); + + status = set_key_policy( key_handle, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits, NULL, 0 ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ), input, sizeof( input ), part_size, encrypt, sizeof( encrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ), encrypt, output_len, part_size, decrypt, sizeof( decrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); @@ -248,7 +253,7 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_cbc_pkcs7_multi( void ) ASSERT_STATUS( status, PSA_SUCCESS ); exit: - psa_destroy_key( key_slot_cipher ); + psa_destroy_key( key_handle ); return( status ); } @@ -263,6 +268,7 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void ) const psa_algorithm_t alg = PSA_ALG_CTR; psa_status_t status; + psa_key_handle_t key_handle = 0; size_t output_len = 0; uint8_t iv[block_size], input[input_size], encrypt[input_size], decrypt[input_size]; @@ -270,21 +276,23 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void ) status = psa_generate_random( input, sizeof( input ) ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = set_key_policy( key_slot_cipher, + status = psa_allocate_key( PSA_KEY_TYPE_AES, key_bits, &key_handle ); + ASSERT_STATUS( status, PSA_SUCCESS ); + status = set_key_policy( key_handle, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = psa_generate_key( key_slot_cipher, PSA_KEY_TYPE_AES, key_bits, + status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits, NULL, 0 ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_encrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ), input, sizeof( input ), part_size, encrypt, sizeof( encrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); - status = cipher_decrypt( key_slot_cipher, alg, iv, sizeof( iv ), + status = cipher_decrypt( key_handle, alg, iv, sizeof( iv ), encrypt, output_len, part_size, decrypt, sizeof( decrypt ), &output_len ); ASSERT_STATUS( status, PSA_SUCCESS ); @@ -293,7 +301,7 @@ static psa_status_t cipher_example_encrypt_decrypt_aes_ctr_multi( void ) ASSERT_STATUS( status, PSA_SUCCESS ); exit: - psa_destroy_key( key_slot_cipher ); + psa_destroy_key( key_handle ); return( status ); } diff --git a/programs/psa/key_ladder_demo.c b/programs/psa/key_ladder_demo.c index 2c75ca462..470b1fce4 100644 --- a/programs/psa/key_ladder_demo.c +++ b/programs/psa/key_ladder_demo.c @@ -167,15 +167,6 @@ typedef struct uint8_t iv[WRAPPING_IV_SIZE]; } wrapped_data_header_t; -/* This program uses three key slots: one for the master key, one to - * derive intermediate keys, and one for the wrapping key. We use a - * single slot for all the intermediate keys because they are only - * needed successively, so each time we derive an intermediate key, - * we destroy the previous one. */ -static const psa_key_slot_t master_key_slot = 1; -static const psa_key_slot_t derived_key_slot = 2; -static const psa_key_slot_t wrapping_key_slot = 3; - /* The modes that this program can operate in (see usage). */ enum program_mode { @@ -187,7 +178,7 @@ enum program_mode /* Save a key to a file. In the real world, you may want to export a derived * key sometimes, to share it with another party. */ -static psa_status_t save_key( psa_key_slot_t key_slot, +static psa_status_t save_key( psa_key_handle_t key_handle, const char *output_file_name ) { psa_status_t status = PSA_SUCCESS; @@ -195,7 +186,7 @@ static psa_status_t save_key( psa_key_slot_t key_slot, size_t key_size; FILE *key_file = NULL; - PSA_CHECK( psa_export_key( key_slot, + PSA_CHECK( psa_export_key( key_handle, key_data, sizeof( key_data ), &key_size ) ); SYS_CHECK( ( key_file = fopen( output_file_name, "wb" ) ) != NULL ); @@ -217,22 +208,27 @@ exit: static psa_status_t generate( const char *key_file_name ) { psa_status_t status = PSA_SUCCESS; + psa_key_handle_t key_handle = 0; psa_key_policy_t policy; + PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ), + &key_handle ) ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT, KDF_ALG ); - PSA_CHECK( psa_set_key_policy( master_key_slot, &policy ) ); + PSA_CHECK( psa_set_key_policy( key_handle, &policy ) ); - PSA_CHECK( psa_generate_key( master_key_slot, + PSA_CHECK( psa_generate_key( key_handle, PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ), NULL, 0 ) ); - PSA_CHECK( save_key( master_key_slot, key_file_name ) ); + PSA_CHECK( save_key( key_handle, key_file_name ) ); exit: + (void) psa_destroy_key( key_handle ); return( status ); } @@ -241,10 +237,10 @@ exit: * In the real world, this master key would be stored in an internal memory * and the storage would be managed by the keystore capability of the PSA * crypto library. */ -static psa_status_t import_key_from_file( psa_key_slot_t key_slot, - psa_key_usage_t usage, +static psa_status_t import_key_from_file( psa_key_usage_t usage, psa_algorithm_t alg, - const char *key_file_name ) + const char *key_file_name, + psa_key_handle_t *master_key_handle ) { psa_status_t status = PSA_SUCCESS; psa_key_policy_t policy; @@ -253,6 +249,8 @@ static psa_status_t import_key_from_file( psa_key_slot_t key_slot, FILE *key_file = NULL; unsigned char extra_byte; + *master_key_handle = 0; + SYS_CHECK( ( key_file = fopen( key_file_name, "rb" ) ) != NULL ); SYS_CHECK( ( key_size = fread( key_data, 1, sizeof( key_data ), key_file ) ) != 0 ); @@ -266,30 +264,41 @@ static psa_status_t import_key_from_file( psa_key_slot_t key_slot, SYS_CHECK( fclose( key_file ) == 0 ); key_file = NULL; + PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( key_size ), + master_key_handle ) ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); - PSA_CHECK( psa_set_key_policy( key_slot, &policy ) ); - PSA_CHECK( psa_import_key( key_slot, + PSA_CHECK( psa_set_key_policy( *master_key_handle, &policy ) ); + PSA_CHECK( psa_import_key( *master_key_handle, PSA_KEY_TYPE_DERIVE, key_data, key_size ) ); exit: if( key_file != NULL ) fclose( key_file ); mbedtls_platform_zeroize( key_data, sizeof( key_data ) ); + if( status != PSA_SUCCESS ) + { + /* If psa_allocate_key hasn't been called yet or has failed, + * *master_key_handle is 0. psa_destroy_key(0) is guaranteed to do + * nothing and return PSA_ERROR_INVALID_HANDLE. */ + (void) psa_destroy_key( *master_key_handle ); + *master_key_handle = 0; + } return( status ); } /* Derive the intermediate keys, using the list of labels provided on - * the command line. */ + * the command line. On input, *key_handle is a handle to the master key. + * This function closes the master key. On successful output, *key_handle + * is a handle to the final derived key. */ static psa_status_t derive_key_ladder( const char *ladder[], - size_t ladder_depth ) + size_t ladder_depth, + psa_key_handle_t *key_handle ) { psa_status_t status = PSA_SUCCESS; psa_key_policy_t policy; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; - /* We'll derive the first intermediate key from the master key, then - * each subsequent intemediate key from the previous intemediate key. */ - psa_key_slot_t parent_key_slot = master_key_slot; size_t i; psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, @@ -303,63 +312,81 @@ static psa_status_t derive_key_ladder( const char *ladder[], * the current intermediate key (if i>0). */ PSA_CHECK( psa_key_derivation( &generator, - parent_key_slot, + *key_handle, KDF_ALG, DERIVE_KEY_SALT, DERIVE_KEY_SALT_LENGTH, (uint8_t*) ladder[i], strlen( ladder[i] ), KEY_SIZE_BYTES ) ); /* When the parent key is not the master key, destroy it, * since it is no longer needed. */ - if( i != 0 ) - PSA_CHECK( psa_destroy_key( derived_key_slot ) ); - PSA_CHECK( psa_set_key_policy( derived_key_slot, &policy ) ); + PSA_CHECK( psa_close_key( *key_handle ) ); + *key_handle = 0; + PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ), + key_handle ) ); + PSA_CHECK( psa_set_key_policy( *key_handle, &policy ) ); /* Use the generator obtained from the parent key to create * the next intermediate key. */ PSA_CHECK( psa_generator_import_key( - derived_key_slot, + *key_handle, PSA_KEY_TYPE_DERIVE, PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ), &generator ) ); PSA_CHECK( psa_generator_abort( &generator ) ); - parent_key_slot = derived_key_slot; } exit: psa_generator_abort( &generator ); + if( status != PSA_SUCCESS ) + { + psa_close_key( *key_handle ); + *key_handle = 0; + } return( status ); } /* Derive a wrapping key from the last intermediate key. */ -static psa_status_t derive_wrapping_key( psa_key_usage_t usage ) +static psa_status_t derive_wrapping_key( psa_key_usage_t usage, + psa_key_handle_t derived_key_handle, + psa_key_handle_t *wrapping_key_handle ) { psa_status_t status = PSA_SUCCESS; psa_key_policy_t policy; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; + *wrapping_key_handle = 0; + PSA_CHECK( psa_allocate_key( PSA_KEY_TYPE_AES, WRAPPING_KEY_BITS, + wrapping_key_handle ) ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, WRAPPING_ALG ); - PSA_CHECK( psa_set_key_policy( wrapping_key_slot, &policy ) ); + PSA_CHECK( psa_set_key_policy( *wrapping_key_handle, &policy ) ); PSA_CHECK( psa_key_derivation( &generator, - derived_key_slot, + derived_key_handle, KDF_ALG, WRAPPING_KEY_SALT, WRAPPING_KEY_SALT_LENGTH, NULL, 0, PSA_BITS_TO_BYTES( WRAPPING_KEY_BITS ) ) ); PSA_CHECK( psa_generator_import_key( - wrapping_key_slot, + *wrapping_key_handle, PSA_KEY_TYPE_AES, WRAPPING_KEY_BITS, &generator ) ); exit: psa_generator_abort( &generator ); + if( status != PSA_SUCCESS ) + { + psa_close_key( *wrapping_key_handle ); + *wrapping_key_handle = 0; + } return( status ); } static psa_status_t wrap_data( const char *input_file_name, - const char *output_file_name ) + const char *output_file_name, + psa_key_handle_t wrapping_key_handle ) { psa_status_t status; FILE *input_file = NULL; @@ -407,7 +434,7 @@ static psa_status_t wrap_data( const char *input_file_name, /* Wrap the data. */ PSA_CHECK( psa_generate_random( header.iv, WRAPPING_IV_SIZE ) ); - PSA_CHECK( psa_aead_encrypt( wrapping_key_slot, WRAPPING_ALG, + PSA_CHECK( psa_aead_encrypt( wrapping_key_handle, WRAPPING_ALG, header.iv, WRAPPING_IV_SIZE, (uint8_t *) &header, sizeof( header ), buffer, input_size, @@ -435,7 +462,8 @@ exit: } static psa_status_t unwrap_data( const char *input_file_name, - const char *output_file_name ) + const char *output_file_name, + psa_key_handle_t wrapping_key_handle ) { psa_status_t status; FILE *input_file = NULL; @@ -487,7 +515,7 @@ static psa_status_t unwrap_data( const char *input_file_name, input_file = NULL; /* Unwrap the data. */ - PSA_CHECK( psa_aead_decrypt( wrapping_key_slot, WRAPPING_ALG, + PSA_CHECK( psa_aead_decrypt( wrapping_key_handle, WRAPPING_ALG, header.iv, WRAPPING_IV_SIZE, (uint8_t *) &header, sizeof( header ), buffer, ciphertext_size, @@ -525,6 +553,8 @@ static psa_status_t run( enum program_mode mode, const char *output_file_name ) { psa_status_t status = PSA_SUCCESS; + psa_key_handle_t derivation_key_handle = 0; + psa_key_handle_t wrapping_key_handle = 0; /* Initialize the PSA crypto library. */ PSA_CHECK( psa_crypto_init( ) ); @@ -534,26 +564,33 @@ static psa_status_t run( enum program_mode mode, return( generate( key_file_name ) ); /* Read the master key. */ - PSA_CHECK( import_key_from_file( master_key_slot, - PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT, + PSA_CHECK( import_key_from_file( PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT, KDF_ALG, - key_file_name ) ); + key_file_name, + &derivation_key_handle ) ); /* Calculate the derived key for this session. */ - PSA_CHECK( derive_key_ladder( ladder, ladder_depth ) ); + PSA_CHECK( derive_key_ladder( ladder, ladder_depth, + &derivation_key_handle ) ); switch( mode ) { case MODE_SAVE: - PSA_CHECK( save_key( derived_key_slot, output_file_name ) ); + PSA_CHECK( save_key( derivation_key_handle, output_file_name ) ); break; case MODE_UNWRAP: - PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_DECRYPT ) ); - PSA_CHECK( unwrap_data( input_file_name, output_file_name ) ); + PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_DECRYPT, + derivation_key_handle, + &wrapping_key_handle ) ); + PSA_CHECK( unwrap_data( input_file_name, output_file_name, + wrapping_key_handle ) ); break; case MODE_WRAP: - PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_ENCRYPT ) ); - PSA_CHECK( wrap_data( input_file_name, output_file_name ) ); + PSA_CHECK( derive_wrapping_key( PSA_KEY_USAGE_ENCRYPT, + derivation_key_handle, + &wrapping_key_handle ) ); + PSA_CHECK( wrap_data( input_file_name, output_file_name, + wrapping_key_handle ) ); break; default: /* Unreachable but some compilers don't realize it. */ @@ -561,6 +598,11 @@ static psa_status_t run( enum program_mode mode, } exit: + /* Close any remaining key. Deinitializing the crypto library would do + * this anyway, but explicitly closing handles makes the code easier + * to reuse. */ + (void) psa_close_key( derivation_key_handle ); + (void) psa_close_key( wrapping_key_handle ); /* Deinitialize the PSA crypto library. */ mbedtls_psa_crypto_free( ); return( status ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 56ce9338a..21cdfaba2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -116,6 +116,7 @@ add_test_suite(psa_crypto_hash) add_test_suite(psa_crypto_init) add_test_suite(psa_crypto_metadata) add_test_suite(psa_crypto_persistent_key) +add_test_suite(psa_crypto_slot_management) add_test_suite(psa_crypto_storage_file) add_test_suite(shax) add_test_suite(ssl) diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index f416b3035..cbe3fa0d4 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -95,7 +95,7 @@ typedef struct data_tag * You must set \p pointer to \c NULL before calling this macro and * put `mbedtls_free( pointer )` in the test's cleanup code. * - * If \p size is zero, the resulting \p pointer will be \c NULL. + * If \p length is zero, the resulting \p pointer will be \c NULL. * This is usually what we want in tests since API functions are * supposed to accept null pointers when a buffer size is zero. * @@ -105,20 +105,21 @@ typedef struct data_tag * \param pointer An lvalue where the address of the allocated buffer * will be stored. * This expression may be evaluated multiple times. - * \param size Buffer size to allocate in bytes. + * \param length Number of elements to allocate. * This expression may be evaluated multiple times. * */ -#define ASSERT_ALLOC( pointer, size ) \ - do \ - { \ - TEST_ASSERT( ( pointer ) == NULL ); \ - if( ( size ) != 0 ) \ - { \ - ( pointer ) = mbedtls_calloc( 1, ( size ) ); \ - TEST_ASSERT( ( pointer ) != NULL ); \ - } \ - } \ +#define ASSERT_ALLOC( pointer, length ) \ + do \ + { \ + TEST_ASSERT( ( pointer ) == NULL ); \ + if( ( length ) != 0 ) \ + { \ + ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \ + ( length ) ); \ + TEST_ASSERT( ( pointer ) != NULL ); \ + } \ + } \ while( 0 ) /** Compare two buffers and fail the test case if they differ. diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 91739f55e..848e8edfd 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1,9 +1,6 @@ PSA compile-time sanity checks static_checks: -PSA fill 250 slots -fill_slots:250 - PSA import/export raw: 0 bytes import_export:"":PSA_KEY_TYPE_RAW_DATA:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_SUCCESS:1 @@ -32,14 +29,14 @@ PSA import to non empty key slot depends_on:MBEDTLS_AES_C import_key_nonempty_slot -PSA export empty key slot -export_invalid_slot:1:PSA_ERROR_EMPTY_SLOT +PSA export invalid handle (0) +export_invalid_handle:0:PSA_ERROR_INVALID_HANDLE -PSA export out of range key slot - lower bound -export_invalid_slot:0:PSA_ERROR_INVALID_ARGUMENT +PSA export invalid handle (smallest plausible handle) +export_invalid_handle:1:PSA_ERROR_INVALID_HANDLE -PSA export out of range key slot - upper bound -export_invalid_slot:(psa_key_slot_t)(-1):PSA_ERROR_INVALID_ARGUMENT +PSA export invalid handle (largest plausible handle) +export_invalid_handle:-1:PSA_ERROR_INVALID_HANDLE PSA export a slot where there was some activity but no key material creation export_with_no_key_activity @@ -320,6 +317,10 @@ PSA import EC keypair: valid key but RSA depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):PSA_ERROR_INVALID_ARGUMENT +PSA import failure preserves policy +depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 +import_twice:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_USAGE_VERIFY:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"":PSA_ERROR_INVALID_ARGUMENT:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30819f300d06092a864886f70d010101050003818d0030818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_SUCCESS + PSA import RSA key pair: maximum size exceeded depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C import_rsa_made_up:PSA_VENDOR_RSA_MAX_KEY_BITS+8:1:PSA_ERROR_NOT_SUPPORTED @@ -467,18 +468,6 @@ PSA key policy: agreement, wrong algorithm depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C agreement_key_policy:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH(PSA_ALG_SELECT_RAW):PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_FFDH(PSA_ALG_SELECT_RAW) -PSA key lifetime: set and get volatile -key_lifetime:PSA_KEY_LIFETIME_VOLATILE - -PSA key lifetime set: invalid key slot -key_lifetime_set_fail:0:PSA_KEY_LIFETIME_VOLATILE:PSA_ERROR_INVALID_ARGUMENT - -PSA key lifetime set: cannot change write_once lifetime -key_lifetime_set_fail:1:PSA_KEY_LIFETIME_WRITE_ONCE:PSA_ERROR_NOT_SUPPORTED - -PSA key lifetime set: invalid key lifetime value -key_lifetime_set_fail:1:PSA_KEY_LIFETIME_PERSISTENT+1:PSA_ERROR_INVALID_ARGUMENT - PSA hash setup: good, SHA-1 depends_on:MBEDTLS_SHA1_C hash_setup:PSA_ALG_SHA_1:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 2fa060b25..c40ac5f7d 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -130,7 +130,7 @@ static int construct_fake_rsa_key( unsigned char *buffer, return( len ); } -static int exercise_mac_key( psa_key_slot_t key, +static int exercise_mac_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -142,7 +142,7 @@ static int exercise_mac_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_SIGN ) { TEST_ASSERT( psa_mac_sign_setup( &operation, - key, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_sign_finish( &operation, @@ -157,7 +157,7 @@ static int exercise_mac_key( psa_key_slot_t key, PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE ); TEST_ASSERT( psa_mac_verify_setup( &operation, - key, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_update( &operation, input, sizeof( input ) ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_verify_finish( &operation, @@ -172,7 +172,7 @@ exit: return( 0 ); } -static int exercise_cipher_key( psa_key_slot_t key, +static int exercise_cipher_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -188,7 +188,7 @@ static int exercise_cipher_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_ENCRYPT ) { TEST_ASSERT( psa_cipher_encrypt_setup( &operation, - key, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_generate_iv( &operation, iv, sizeof( iv ), &iv_length ) == PSA_SUCCESS ); @@ -210,11 +210,11 @@ static int exercise_cipher_key( psa_key_slot_t key, if( ! ( usage & PSA_KEY_USAGE_ENCRYPT ) ) { size_t bits; - TEST_ASSERT( psa_get_key_information( key, &type, &bits ) ); + TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) ); iv_length = PSA_BLOCK_CIPHER_BLOCK_SIZE( type ); } TEST_ASSERT( psa_cipher_decrypt_setup( &operation, - key, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_set_iv( &operation, iv, iv_length ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_update( &operation, @@ -243,7 +243,7 @@ exit: return( 0 ); } -static int exercise_aead_key( psa_key_slot_t key, +static int exercise_aead_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -256,7 +256,7 @@ static int exercise_aead_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_ENCRYPT ) { - TEST_ASSERT( psa_aead_encrypt( key, alg, + TEST_ASSERT( psa_aead_encrypt( handle, alg, nonce, nonce_length, NULL, 0, plaintext, sizeof( plaintext ), @@ -270,7 +270,7 @@ static int exercise_aead_key( psa_key_slot_t key, ( usage & PSA_KEY_USAGE_ENCRYPT ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE ); - TEST_ASSERT( psa_aead_decrypt( key, alg, + TEST_ASSERT( psa_aead_decrypt( handle, alg, nonce, nonce_length, NULL, 0, ciphertext, ciphertext_length, @@ -284,7 +284,7 @@ exit: return( 0 ); } -static int exercise_signature_key( psa_key_slot_t key, +static int exercise_signature_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -301,7 +301,7 @@ static int exercise_signature_key( psa_key_slot_t key, psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg ); if( hash_alg != 0 ) payload_length = PSA_HASH_SIZE( hash_alg ); - TEST_ASSERT( psa_asymmetric_sign( key, alg, + TEST_ASSERT( psa_asymmetric_sign( handle, alg, payload, payload_length, signature, sizeof( signature ), &signature_length ) == PSA_SUCCESS ); @@ -313,7 +313,7 @@ static int exercise_signature_key( psa_key_slot_t key, ( usage & PSA_KEY_USAGE_SIGN ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE ); - TEST_ASSERT( psa_asymmetric_verify( key, alg, + TEST_ASSERT( psa_asymmetric_verify( handle, alg, payload, payload_length, signature, signature_length ) == verify_status ); @@ -325,7 +325,7 @@ exit: return( 0 ); } -static int exercise_asymmetric_encryption_key( psa_key_slot_t key, +static int exercise_asymmetric_encryption_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -337,7 +337,7 @@ static int exercise_asymmetric_encryption_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_ENCRYPT ) { TEST_ASSERT( - psa_asymmetric_encrypt( key, alg, + psa_asymmetric_encrypt( handle, alg, plaintext, plaintext_length, NULL, 0, ciphertext, sizeof( ciphertext ), @@ -347,7 +347,7 @@ static int exercise_asymmetric_encryption_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_DECRYPT ) { psa_status_t status = - psa_asymmetric_decrypt( key, alg, + psa_asymmetric_decrypt( handle, alg, ciphertext, ciphertext_length, NULL, 0, plaintext, sizeof( plaintext ), @@ -364,7 +364,7 @@ exit: return( 0 ); } -static int exercise_key_derivation_key( psa_key_slot_t key, +static int exercise_key_derivation_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -378,7 +378,7 @@ static int exercise_key_derivation_key( psa_key_slot_t key, if( usage & PSA_KEY_USAGE_DERIVE ) { TEST_ASSERT( psa_key_derivation( &generator, - key, alg, + handle, alg, label, label_length, seed, seed_length, sizeof( output ) ) == PSA_SUCCESS ); @@ -397,7 +397,7 @@ exit: /* We need two keys to exercise key agreement. Exercise the * private key against its own public key. */ static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator, - psa_key_type_t key_slot, + psa_key_handle_t handle, psa_algorithm_t alg ) { psa_key_type_t private_key_type; @@ -410,18 +410,18 @@ static psa_status_t key_agreement_with_self( psa_crypto_generator_t *generator, * good enough: callers will report it as a failed test anyway. */ psa_status_t status = PSA_ERROR_UNKNOWN_ERROR; - TEST_ASSERT( psa_get_key_information( key_slot, + TEST_ASSERT( psa_get_key_information( handle, &private_key_type, &key_bits ) == PSA_SUCCESS ); public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( private_key_type ); public_key_length = PSA_KEY_EXPORT_MAX_SIZE( public_key_type, key_bits ); ASSERT_ALLOC( public_key, public_key_length ); TEST_ASSERT( public_key != NULL ); - TEST_ASSERT( psa_export_public_key( key_slot, + TEST_ASSERT( psa_export_public_key( handle, public_key, public_key_length, &public_key_length ) == PSA_SUCCESS ); - status = psa_key_agreement( generator, key_slot, + status = psa_key_agreement( generator, handle, public_key, public_key_length, alg ); exit: @@ -429,7 +429,7 @@ exit: return( status ); } -static int exercise_key_agreement_key( psa_key_slot_t key, +static int exercise_key_agreement_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -441,7 +441,7 @@ static int exercise_key_agreement_key( psa_key_slot_t key, { /* We need two keys to exercise key agreement. Exercise the * private key against its own public key. */ - TEST_ASSERT( key_agreement_with_self( &generator, key, alg ) == + TEST_ASSERT( key_agreement_with_self( &generator, handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_generator_read( &generator, output, @@ -713,7 +713,7 @@ exit: return( 0 ); } -static int exercise_export_key( psa_key_slot_t slot, +static int exercise_export_key( psa_key_handle_t handle, psa_key_usage_t usage ) { psa_key_type_t type; @@ -723,12 +723,12 @@ static int exercise_export_key( psa_key_slot_t slot, size_t exported_length = 0; int ok = 0; - TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) == PSA_SUCCESS ); if( ( usage & PSA_KEY_USAGE_EXPORT ) == 0 && ! PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) { - TEST_ASSERT( psa_export_key( slot, NULL, 0, &exported_length ) == + TEST_ASSERT( psa_export_key( handle, NULL, 0, &exported_length ) == PSA_ERROR_NOT_PERMITTED ); return( 1 ); } @@ -736,7 +736,7 @@ static int exercise_export_key( psa_key_slot_t slot, exported_size = PSA_KEY_EXPORT_MAX_SIZE( type, bits ); ASSERT_ALLOC( exported, exported_size ); - TEST_ASSERT( psa_export_key( slot, + TEST_ASSERT( psa_export_key( handle, exported, exported_size, &exported_length ) == PSA_SUCCESS ); ok = exported_key_sanity_check( type, bits, exported, exported_length ); @@ -746,7 +746,7 @@ exit: return( ok ); } -static int exercise_export_public_key( psa_key_slot_t slot ) +static int exercise_export_public_key( psa_key_handle_t handle ) { psa_key_type_t type; psa_key_type_t public_type; @@ -756,10 +756,10 @@ static int exercise_export_public_key( psa_key_slot_t slot ) size_t exported_length = 0; int ok = 0; - TEST_ASSERT( psa_get_key_information( slot, &type, &bits ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_information( handle, &type, &bits ) == PSA_SUCCESS ); if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( type ) ) { - TEST_ASSERT( psa_export_public_key( slot, + TEST_ASSERT( psa_export_public_key( handle, NULL, 0, &exported_length ) == PSA_ERROR_INVALID_ARGUMENT ); return( 1 ); @@ -769,7 +769,7 @@ static int exercise_export_public_key( psa_key_slot_t slot ) exported_size = PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ); ASSERT_ALLOC( exported, exported_size ); - TEST_ASSERT( psa_export_public_key( slot, + TEST_ASSERT( psa_export_public_key( handle, exported, exported_size, &exported_length ) == PSA_SUCCESS ); ok = exported_key_sanity_check( public_type, bits, @@ -780,7 +780,7 @@ exit: return( ok ); } -static int exercise_key( psa_key_slot_t slot, +static int exercise_key( psa_key_handle_t handle, psa_key_usage_t usage, psa_algorithm_t alg ) { @@ -788,19 +788,19 @@ static int exercise_key( psa_key_slot_t slot, if( alg == 0 ) ok = 1; /* If no algorihm, do nothing (used for raw data "keys"). */ else if( PSA_ALG_IS_MAC( alg ) ) - ok = exercise_mac_key( slot, usage, alg ); + ok = exercise_mac_key( handle, usage, alg ); else if( PSA_ALG_IS_CIPHER( alg ) ) - ok = exercise_cipher_key( slot, usage, alg ); + ok = exercise_cipher_key( handle, usage, alg ); else if( PSA_ALG_IS_AEAD( alg ) ) - ok = exercise_aead_key( slot, usage, alg ); + ok = exercise_aead_key( handle, usage, alg ); else if( PSA_ALG_IS_SIGN( alg ) ) - ok = exercise_signature_key( slot, usage, alg ); + ok = exercise_signature_key( handle, usage, alg ); else if( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) ) - ok = exercise_asymmetric_encryption_key( slot, usage, alg ); + ok = exercise_asymmetric_encryption_key( handle, usage, alg ); else if( PSA_ALG_IS_KEY_DERIVATION( alg ) ) - ok = exercise_key_derivation_key( slot, usage, alg ); + ok = exercise_key_derivation_key( handle, usage, alg ); else if( PSA_ALG_IS_KEY_AGREEMENT( alg ) ) - ok = exercise_key_agreement_key( slot, usage, alg ); + ok = exercise_key_agreement_key( handle, usage, alg ); else { char message[40]; @@ -811,8 +811,8 @@ static int exercise_key( psa_key_slot_t slot, ok = 0; } - ok = ok && exercise_export_key( slot, usage ); - ok = ok && exercise_export_public_key( slot ); + ok = ok && exercise_export_key( handle, usage ); + ok = ok && exercise_export_public_key( handle ); return( ok ); } @@ -845,6 +845,13 @@ static psa_key_usage_t usage_to_exercise( psa_key_type_t type, } +/* An overapproximation of the amount of storage needed for a key of the + * given type and with the given content. The API doesn't make it easy + * to find a good value for the size. The current implementation doesn't + * care about the value anyway. */ +#define KEY_BITS_FROM_DATA( type, data ) \ + ( data )->len + typedef enum { IMPORT_KEY = 0, GENERATE_KEY = 1, @@ -871,66 +878,10 @@ void static_checks( ) } /* END_CASE */ -/* BEGIN_CASE */ -void fill_slots( int max_arg ) -{ - /* Fill all the slots until we run out of memory or out of slots, - * or until some limit specified in the test data for the sake of - * implementations with an essentially unlimited number of slots. - * This test assumes that available slots are numbered from 1. */ - - psa_key_slot_t slot; - psa_key_slot_t max = 0; - psa_key_policy_t policy; - uint8_t exported[sizeof( max )]; - size_t exported_size; - psa_status_t status; - - TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); - - psa_key_policy_init( &policy ); - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 ); - - for( max = 1; max <= (size_t) max_arg; max++ ) - { - status = psa_set_key_policy( max, &policy ); - /* Stop filling slots if we run out of memory or out of - * available slots. */ - TEST_ASSERT( status == PSA_SUCCESS || - status == PSA_ERROR_INSUFFICIENT_MEMORY || - status == PSA_ERROR_INVALID_ARGUMENT ); - if( status != PSA_SUCCESS ) - break; - status = psa_import_key( max, PSA_KEY_TYPE_RAW_DATA, - (uint8_t*) &max, sizeof( max ) ); - /* Since psa_set_key_policy succeeded, we know that the slot - * number is valid. But we may legitimately run out of memory. */ - TEST_ASSERT( status == PSA_SUCCESS || - status == PSA_ERROR_INSUFFICIENT_MEMORY ); - if( status != PSA_SUCCESS ) - break; - } - /* `max` is now the first slot number that wasn't filled. */ - max -= 1; - - for( slot = 1; slot <= max; slot++ ) - { - TEST_ASSERT( psa_export_key( slot, - exported, sizeof( exported ), - &exported_size ) == PSA_SUCCESS ); - ASSERT_COMPARE( &slot, sizeof( slot ), exported, exported_size ); - } - -exit: - /* Do not destroy the keys. mbedtls_psa_crypto_free() should do it. */ - mbedtls_psa_crypto_free( ); -} -/* END_CASE */ - /* BEGIN_CASE */ void import( data_t *data, int type, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_status_t expected_status = expected_status_arg; psa_status_t status; @@ -938,10 +889,55 @@ void import( data_t *data, int type, int expected_status_arg ) TEST_ASSERT( PSA_CRYPTO_TEST_SIZE_T_RANGE( data->len ) ); TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); - status = psa_import_key( slot, type, data->x, data->len ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); + status = psa_import_key( handle, type, data->x, data->len ); TEST_ASSERT( status == expected_status ); if( status == PSA_SUCCESS ) - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void import_twice( int alg_arg, int usage_arg, + int type1_arg, data_t *data1, + int expected_import1_status_arg, + int type2_arg, data_t *data2, + int expected_import2_status_arg ) +{ + psa_key_handle_t handle = 0; + psa_algorithm_t alg = alg_arg; + psa_key_usage_t usage = usage_arg; + psa_key_type_t type1 = type1_arg; + psa_status_t expected_import1_status = expected_import1_status_arg; + psa_key_type_t type2 = type2_arg; + psa_status_t expected_import2_status = expected_import2_status_arg; + psa_key_policy_t policy; + psa_status_t status; + + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_allocate_key( type1, + MAX( KEY_BITS_FROM_DATA( type1, data1 ), + KEY_BITS_FROM_DATA( type2, data2 ) ), + &handle ) == PSA_SUCCESS ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, usage, alg ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); + + status = psa_import_key( handle, type1, data1->x, data1->len ); + TEST_ASSERT( status == expected_import1_status ); + status = psa_import_key( handle, type2, data2->x, data2->len ); + TEST_ASSERT( status == expected_import2_status ); + + if( expected_import1_status == PSA_SUCCESS || + expected_import2_status == PSA_SUCCESS ) + { + TEST_ASSERT( exercise_key( handle, usage, alg ) ); + } exit: mbedtls_psa_crypto_free( ); @@ -951,7 +947,7 @@ exit: /* BEGIN_CASE */ void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; size_t bits = bits_arg; psa_status_t expected_status = expected_status_arg; psa_status_t status; @@ -972,10 +968,11 @@ void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg ) length = ret; /* Try importing the key */ - status = psa_import_key( slot, type, p, length ); + TEST_ASSERT( psa_allocate_key( type, bits, &handle ) == PSA_SUCCESS ); + status = psa_import_key( handle, type, p, length ); TEST_ASSERT( status == expected_status ); if( status == PSA_SUCCESS ) - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); exit: mbedtls_free( buffer ); @@ -993,8 +990,7 @@ void import_export( data_t *data, int expected_export_status_arg, int canonical_input ) { - int slot = 1; - int slot2 = slot + 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_export_status = expected_export_status_arg; @@ -1016,23 +1012,28 @@ void import_export( data_t *data, ASSERT_ALLOC( reexported, export_size ); TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, expected_bits, &handle ) == + PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage_arg, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); + + TEST_ASSERT( psa_get_key_information( + handle, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == PSA_SUCCESS ); /* Test the key information */ - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, &got_type, &got_bits ) == PSA_SUCCESS ); TEST_ASSERT( got_type == type ); TEST_ASSERT( got_bits == (size_t) expected_bits ); /* Export the key */ - status = psa_export_key( slot, + status = psa_export_key( handle, exported, export_size, &exported_length ); TEST_ASSERT( status == expected_export_status ); @@ -1051,32 +1052,36 @@ void import_export( data_t *data, goto destroy; } - if( ! exercise_export_key( slot, usage_arg ) ) + if( ! exercise_export_key( handle, usage_arg ) ) goto exit; if( canonical_input ) ASSERT_COMPARE( data->x, data->len, exported, exported_length ); else { - TEST_ASSERT( psa_set_key_policy( slot2, &policy ) == PSA_SUCCESS ); + psa_key_handle_t handle2; + TEST_ASSERT( psa_allocate_key( type, expected_bits, &handle2 ) == + PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle2, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot2, type, + TEST_ASSERT( psa_import_key( handle2, type, exported, exported_length ) == PSA_SUCCESS ); - TEST_ASSERT( psa_export_key( slot2, + TEST_ASSERT( psa_export_key( handle2, reexported, export_size, &reexported_length ) == PSA_SUCCESS ); ASSERT_COMPARE( exported, exported_length, reexported, reexported_length ); + TEST_ASSERT( psa_close_key( handle2 ) == PSA_SUCCESS ); } TEST_ASSERT( exported_length <= PSA_KEY_EXPORT_MAX_SIZE( type, got_bits ) ); destroy: /* Destroy the key */ - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + handle, NULL, NULL ) == PSA_ERROR_INVALID_HANDLE ); exit: mbedtls_free( exported ); @@ -1088,18 +1093,21 @@ exit: /* BEGIN_CASE */ void import_key_nonempty_slot( ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = PSA_KEY_TYPE_RAW_DATA; psa_status_t status; const uint8_t data[] = { 0x1, 0x2, 0x3, 0x4, 0x5 }; TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, PSA_BYTES_TO_BITS( sizeof( data ) ), + &handle ) == PSA_SUCCESS ); + /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data, sizeof( data ) ) == PSA_SUCCESS ); /* Import the key again */ - status = psa_import_key( slot, type, data, sizeof( data ) ); + status = psa_import_key( handle, type, data, sizeof( data ) ); TEST_ASSERT( status == PSA_ERROR_OCCUPIED_SLOT ); exit: @@ -1108,7 +1116,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void export_invalid_slot( int slot, int expected_export_status_arg ) +void export_invalid_handle( int handle, int expected_export_status_arg ) { psa_status_t status; unsigned char *exported = NULL; @@ -1119,7 +1127,7 @@ void export_invalid_slot( int slot, int expected_export_status_arg ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); /* Export the key */ - status = psa_export_key( slot, + status = psa_export_key( (psa_key_handle_t) handle, exported, export_size, &exported_length ); TEST_ASSERT( status == expected_export_status ); @@ -1132,7 +1140,7 @@ exit: /* BEGIN_CASE */ void export_with_no_key_activity( ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_algorithm_t alg = PSA_ALG_CTR; psa_status_t status; psa_key_policy_t policy; @@ -1142,12 +1150,14 @@ void export_with_no_key_activity( ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0, + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); /* Export the key */ - status = psa_export_key( slot, + status = psa_export_key( handle, exported, export_size, &exported_length ); TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT ); @@ -1160,7 +1170,7 @@ exit: /* BEGIN_CASE */ void cipher_with_no_key_activity( ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_status_t status; psa_key_policy_t policy; psa_cipher_operation_t operation; @@ -1168,11 +1178,13 @@ void cipher_with_no_key_activity( ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 0, + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, exercise_alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - status = psa_cipher_encrypt_setup( &operation, slot, exercise_alg ); + status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg ); TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT ); exit: @@ -1185,7 +1197,7 @@ exit: void export_after_import_failure( data_t *data, int type_arg, int expected_import_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_status_t status; unsigned char *exported = NULL; @@ -1195,13 +1207,16 @@ void export_after_import_failure( data_t *data, int type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); + /* Import the key - expect failure */ - status = psa_import_key( slot, type, + status = psa_import_key( handle, type, data->x, data->len ); TEST_ASSERT( status == expected_import_status ); /* Export the key */ - status = psa_export_key( slot, + status = psa_export_key( handle, exported, export_size, &exported_length ); TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT ); @@ -1215,7 +1230,7 @@ exit: void cipher_after_import_failure( data_t *data, int type_arg, int expected_import_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_cipher_operation_t operation; psa_key_type_t type = type_arg; psa_status_t status; @@ -1224,12 +1239,15 @@ void cipher_after_import_failure( data_t *data, int type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); + /* Import the key - expect failure */ - status = psa_import_key( slot, type, + status = psa_import_key( handle, type, data->x, data->len ); TEST_ASSERT( status == expected_import_status ); - status = psa_cipher_encrypt_setup( &operation, slot, exercise_alg ); + status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg ); TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT ); exit: @@ -1241,7 +1259,7 @@ exit: /* BEGIN_CASE */ void export_after_destroy_key( data_t *data, int type_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_status_t status; psa_key_policy_t policy; @@ -1252,26 +1270,28 @@ void export_after_destroy_key( data_t *data, int type_arg ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); export_size = (ptrdiff_t) data->len; ASSERT_ALLOC( exported, export_size ); /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_export_key( slot, exported, export_size, + TEST_ASSERT( psa_export_key( handle, exported, export_size, &exported_length ) == PSA_SUCCESS ); /* Destroy the key */ - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); /* Export the key */ - status = psa_export_key( slot, exported, export_size, + status = psa_export_key( handle, exported, export_size, &exported_length ); - TEST_ASSERT( status == PSA_ERROR_EMPTY_SLOT ); + TEST_ASSERT( status == PSA_ERROR_INVALID_HANDLE ); exit: mbedtls_free( exported ); @@ -1287,7 +1307,7 @@ void import_export_public_key( data_t *data, int expected_export_status_arg, data_t *expected_public_key ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_export_status = expected_export_status_arg; @@ -1299,17 +1319,19 @@ void import_export_public_key( data_t *data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == PSA_SUCCESS ); /* Export the public key */ ASSERT_ALLOC( exported, export_size ); - status = psa_export_public_key( slot, + status = psa_export_public_key( handle, exported, export_size, &exported_length ); TEST_ASSERT( status == expected_export_status ); @@ -1317,7 +1339,7 @@ void import_export_public_key( data_t *data, { psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type ); size_t bits; - TEST_ASSERT( psa_get_key_information( slot, NULL, &bits ) == + TEST_ASSERT( psa_get_key_information( handle, NULL, &bits ) == PSA_SUCCESS ); TEST_ASSERT( expected_public_key->len <= PSA_KEY_EXPORT_MAX_SIZE( public_type, bits ) ); @@ -1327,7 +1349,7 @@ void import_export_public_key( data_t *data, exit: mbedtls_free( exported ); - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1338,7 +1360,7 @@ void import_and_exercise_key( data_t *data, int bits_arg, int alg_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; size_t bits = bits_arg; psa_algorithm_t alg = alg_arg; @@ -1350,27 +1372,29 @@ void import_and_exercise_key( data_t *data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, KEY_BITS_FROM_DATA( type, data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); /* Import the key */ - status = psa_import_key( slot, type, data->x, data->len ); + status = psa_import_key( handle, type, data->x, data->len ); TEST_ASSERT( status == PSA_SUCCESS ); /* Test the key information */ - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, &got_type, &got_bits ) == PSA_SUCCESS ); TEST_ASSERT( got_type == type ); TEST_ASSERT( got_bits == bits ); /* Do something with the key according to its type and permitted usage. */ - if( ! exercise_key( slot, usage, alg ) ) + if( ! exercise_key( handle, usage, alg ) ) goto exit; exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1378,7 +1402,7 @@ exit: /* BEGIN_CASE */ void key_policy( int usage_arg, int alg_arg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_algorithm_t alg = alg_arg; psa_key_usage_t usage = usage_arg; psa_key_type_t key_type = PSA_KEY_TYPE_AES; @@ -1390,25 +1414,26 @@ void key_policy( int usage_arg, int alg_arg ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( sizeof( key ) ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy_set ); psa_key_policy_init( &policy_get ); - psa_key_policy_set_usage( &policy_set, usage, alg ); TEST_ASSERT( psa_key_policy_get_usage( &policy_set ) == usage ); TEST_ASSERT( psa_key_policy_get_algorithm( &policy_set ) == alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy_set ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy_set ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key, sizeof( key ) ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_policy( key_slot, &policy_get ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_policy( handle, &policy_get ) == PSA_SUCCESS ); TEST_ASSERT( policy_get.usage == policy_set.usage ); TEST_ASSERT( policy_get.alg == policy_set.alg ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1420,7 +1445,7 @@ void mac_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_mac_operation_t operation; psa_status_t status; @@ -1428,14 +1453,17 @@ void mac_key_policy( int policy_usage, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = psa_mac_sign_setup( &operation, key_slot, exercise_alg ); + status = psa_mac_sign_setup( &operation, handle, exercise_alg ); if( policy_alg == exercise_alg && ( policy_usage & PSA_KEY_USAGE_SIGN ) != 0 ) TEST_ASSERT( status == PSA_SUCCESS ); @@ -1444,7 +1472,7 @@ void mac_key_policy( int policy_usage, psa_mac_abort( &operation ); memset( mac, 0, sizeof( mac ) ); - status = psa_mac_verify_setup( &operation, key_slot, exercise_alg ); + status = psa_mac_verify_setup( &operation, handle, exercise_alg ); if( policy_alg == exercise_alg && ( policy_usage & PSA_KEY_USAGE_VERIFY ) != 0 ) TEST_ASSERT( status == PSA_SUCCESS ); @@ -1453,7 +1481,7 @@ void mac_key_policy( int policy_usage, exit: psa_mac_abort( &operation ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1465,21 +1493,24 @@ void cipher_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_cipher_operation_t operation; psa_status_t status; TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = psa_cipher_encrypt_setup( &operation, key_slot, exercise_alg ); + status = psa_cipher_encrypt_setup( &operation, handle, exercise_alg ); if( policy_alg == exercise_alg && ( policy_usage & PSA_KEY_USAGE_ENCRYPT ) != 0 ) TEST_ASSERT( status == PSA_SUCCESS ); @@ -1487,7 +1518,7 @@ void cipher_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); psa_cipher_abort( &operation ); - status = psa_cipher_decrypt_setup( &operation, key_slot, exercise_alg ); + status = psa_cipher_decrypt_setup( &operation, handle, exercise_alg ); if( policy_alg == exercise_alg && ( policy_usage & PSA_KEY_USAGE_DECRYPT ) != 0 ) TEST_ASSERT( status == PSA_SUCCESS ); @@ -1496,7 +1527,7 @@ void cipher_key_policy( int policy_usage, exit: psa_cipher_abort( &operation ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1510,7 +1541,7 @@ void aead_key_policy( int policy_usage, int tag_length_arg, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_status_t status; unsigned char nonce[16] = {0}; @@ -1524,14 +1555,17 @@ void aead_key_policy( int policy_usage, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = psa_aead_encrypt( key_slot, exercise_alg, + status = psa_aead_encrypt( handle, exercise_alg, nonce, nonce_length, NULL, 0, NULL, 0, @@ -1544,7 +1578,7 @@ void aead_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); memset( tag, 0, sizeof( tag ) ); - status = psa_aead_decrypt( key_slot, exercise_alg, + status = psa_aead_decrypt( handle, exercise_alg, nonce, nonce_length, NULL, 0, tag, tag_length, @@ -1557,7 +1591,7 @@ void aead_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1569,7 +1603,7 @@ void asymmetric_encryption_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_status_t status; size_t key_bits; @@ -1579,21 +1613,24 @@ void asymmetric_encryption_key_policy( int policy_usage, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_information( key_slot, + TEST_ASSERT( psa_get_key_information( handle, NULL, &key_bits ) == PSA_SUCCESS ); buffer_length = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, exercise_alg ); ASSERT_ALLOC( buffer, buffer_length ); - status = psa_asymmetric_encrypt( key_slot, exercise_alg, + status = psa_asymmetric_encrypt( handle, exercise_alg, NULL, 0, NULL, 0, buffer, buffer_length, @@ -1606,7 +1643,7 @@ void asymmetric_encryption_key_policy( int policy_usage, if( buffer_length != 0 ) memset( buffer, 0, buffer_length ); - status = psa_asymmetric_decrypt( key_slot, exercise_alg, + status = psa_asymmetric_decrypt( handle, exercise_alg, buffer, buffer_length, NULL, 0, buffer, buffer_length, @@ -1618,7 +1655,7 @@ void asymmetric_encryption_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); mbedtls_free( buffer ); } @@ -1631,7 +1668,7 @@ void asymmetric_signature_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_status_t status; unsigned char payload[16] = {1}; @@ -1641,14 +1678,17 @@ void asymmetric_signature_key_policy( int policy_usage, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = psa_asymmetric_sign( key_slot, exercise_alg, + status = psa_asymmetric_sign( handle, exercise_alg, payload, payload_length, signature, sizeof( signature ), &signature_length ); @@ -1659,7 +1699,7 @@ void asymmetric_signature_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); memset( signature, 0, sizeof( signature ) ); - status = psa_asymmetric_verify( key_slot, exercise_alg, + status = psa_asymmetric_verify( handle, exercise_alg, payload, payload_length, signature, sizeof( signature ) ); if( policy_alg == exercise_alg && @@ -1669,7 +1709,7 @@ void asymmetric_signature_key_policy( int policy_usage, TEST_ASSERT( status == PSA_ERROR_NOT_PERMITTED ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1681,21 +1721,24 @@ void derive_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; psa_status_t status; TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = psa_key_derivation( &generator, key_slot, + status = psa_key_derivation( &generator, handle, exercise_alg, NULL, 0, NULL, 0, @@ -1708,7 +1751,7 @@ void derive_key_policy( int policy_usage, exit: psa_generator_abort( &generator ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1720,7 +1763,7 @@ void agreement_key_policy( int policy_usage, data_t *key_data, int exercise_alg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_policy_t policy; psa_key_type_t key_type = key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -1728,14 +1771,17 @@ void agreement_key_policy( int policy_usage, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, policy_usage, policy_alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - status = key_agreement_with_self( &generator, key_slot, exercise_alg ); + status = key_agreement_with_self( &generator, handle, exercise_alg ); if( policy_alg == exercise_alg && ( policy_usage & PSA_KEY_USAGE_DERIVE ) != 0 ) @@ -1745,62 +1791,7 @@ void agreement_key_policy( int policy_usage, exit: psa_generator_abort( &generator ); - psa_destroy_key( key_slot ); - mbedtls_psa_crypto_free( ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void key_lifetime( int lifetime_arg ) -{ - int key_slot = 1; - psa_key_type_t key_type = PSA_KEY_TYPE_RAW_DATA; - unsigned char key[32] = {0}; - psa_key_lifetime_t lifetime_set = lifetime_arg; - psa_key_lifetime_t lifetime_get; - - memset( key, 0x2a, sizeof( key ) ); - - TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_set_key_lifetime( key_slot, - lifetime_set ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_import_key( key_slot, key_type, - key, sizeof( key ) ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_get_key_lifetime( key_slot, - &lifetime_get ) == PSA_SUCCESS ); - - TEST_ASSERT( lifetime_get == lifetime_set ); - -exit: - psa_destroy_key( key_slot ); - mbedtls_psa_crypto_free( ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void key_lifetime_set_fail( int key_slot_arg, - int lifetime_arg, - int expected_status_arg ) -{ - psa_key_slot_t key_slot = key_slot_arg; - psa_key_lifetime_t lifetime_set = lifetime_arg; - psa_status_t actual_status; - psa_status_t expected_status = expected_status_arg; - - TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); - - actual_status = psa_set_key_lifetime( key_slot, lifetime_set ); - - if( actual_status == PSA_SUCCESS ) - actual_status = psa_set_key_lifetime( key_slot, lifetime_set ); - - TEST_ASSERT( expected_status == actual_status ); - -exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1928,7 +1919,7 @@ void mac_setup( int key_type_arg, int alg_arg, int expected_status_arg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; @@ -1938,21 +1929,23 @@ void mac_setup( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); - status = psa_mac_sign_setup( &operation, key_slot, alg ); + status = psa_mac_sign_setup( &operation, handle, alg ); psa_mac_abort( &operation ); TEST_ASSERT( status == expected_status ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -1964,7 +1957,7 @@ void mac_sign( int key_type_arg, data_t *input, data_t *expected_mac ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_mac_operation_t operation; @@ -1983,16 +1976,18 @@ void mac_sign( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); /* Calculate the MAC. */ TEST_ASSERT( psa_mac_sign_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_update( &operation, input->x, input->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_sign_finish( &operation, @@ -2008,7 +2003,7 @@ void mac_sign( int key_type_arg, sizeof( actual_mac ) - mac_length ) ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2020,7 +2015,7 @@ void mac_verify( int key_type_arg, data_t *input, data_t *expected_mac ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_mac_operation_t operation; @@ -2037,16 +2032,18 @@ void mac_verify( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_verify_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); - TEST_ASSERT( psa_destroy_key( key_slot ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_update( &operation, input->x, input->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_mac_verify_finish( &operation, @@ -2054,7 +2051,7 @@ void mac_verify( int key_type_arg, expected_mac->len ) == PSA_SUCCESS ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2065,7 +2062,7 @@ void cipher_setup( int key_type_arg, int alg_arg, int expected_status_arg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; @@ -2075,19 +2072,21 @@ void cipher_setup( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); - status = psa_cipher_encrypt_setup( &operation, key_slot, alg ); + status = psa_cipher_encrypt_setup( &operation, handle, alg ); psa_cipher_abort( &operation ); TEST_ASSERT( status == expected_status ); exit: - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2098,7 +2097,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, data_t *input, data_t *expected_output, int expected_status_arg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_status_t status; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; @@ -2124,15 +2123,17 @@ void cipher_encrypt( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_encrypt_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_set_iv( &operation, iv, iv_size ) == PSA_SUCCESS ); @@ -2161,7 +2162,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, exit: mbedtls_free( output ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2173,7 +2174,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, int first_part_size, data_t *expected_output ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char iv[16] = {0}; @@ -2197,15 +2198,17 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_encrypt_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_set_iv( &operation, iv, sizeof( iv ) ) == PSA_SUCCESS ); @@ -2236,7 +2239,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, exit: mbedtls_free( output ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2248,7 +2251,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, int first_part_size, data_t *expected_output ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; @@ -2273,15 +2276,17 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_decrypt_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_set_iv( &operation, iv, sizeof( iv ) ) == PSA_SUCCESS ); @@ -2314,7 +2319,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, exit: mbedtls_free( output ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2325,7 +2330,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, data_t *input, data_t *expected_output, int expected_status_arg ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_status_t status; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; @@ -2351,15 +2356,17 @@ void cipher_decrypt( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_decrypt_setup( &operation, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_set_iv( &operation, iv, iv_size ) == PSA_SUCCESS ); @@ -2389,7 +2396,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, exit: mbedtls_free( output ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2399,7 +2406,7 @@ void cipher_verify_output( int alg_arg, int key_type_arg, data_t *key, data_t *input ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char iv[16] = {0}; @@ -2423,17 +2430,19 @@ void cipher_verify_output( int alg_arg, int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_encrypt_setup( &operation1, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_decrypt_setup( &operation2, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_generate_iv( &operation1, iv, iv_size, @@ -2476,7 +2485,7 @@ void cipher_verify_output( int alg_arg, int key_type_arg, exit: mbedtls_free( output1 ); mbedtls_free( output2 ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2488,7 +2497,7 @@ void cipher_verify_output_multipart( int alg_arg, data_t *input, int first_part_size ) { - int key_slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char iv[16] = {0}; @@ -2512,17 +2521,19 @@ void cipher_verify_output_multipart( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( key_slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( key_slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key->x, key->len ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_encrypt_setup( &operation1, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_decrypt_setup( &operation2, - key_slot, alg ) == PSA_SUCCESS ); + handle, alg ) == PSA_SUCCESS ); TEST_ASSERT( psa_cipher_generate_iv( &operation1, iv, iv_size, @@ -2584,7 +2595,7 @@ void cipher_verify_output_multipart( int alg_arg, exit: mbedtls_free( output1 ); mbedtls_free( output2 ); - psa_destroy_key( key_slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -2597,7 +2608,7 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, data_t *input_data, int expected_result_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char *output_data = NULL; @@ -2623,16 +2634,18 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_aead_encrypt( slot, alg, + TEST_ASSERT( psa_aead_encrypt( handle, alg, nonce->x, nonce->len, additional_data->x, additional_data->len, @@ -2644,7 +2657,7 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, { ASSERT_ALLOC( output_data2, output_length ); - TEST_ASSERT( psa_aead_decrypt( slot, alg, + TEST_ASSERT( psa_aead_decrypt( handle, alg, nonce->x, nonce->len, additional_data->x, additional_data->len, @@ -2657,7 +2670,7 @@ void aead_encrypt_decrypt( int key_type_arg, data_t *key_data, } exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output_data ); mbedtls_free( output_data2 ); mbedtls_psa_crypto_free( ); @@ -2672,7 +2685,7 @@ void aead_encrypt( int key_type_arg, data_t *key_data, data_t *input_data, data_t *expected_result ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char *output_data = NULL; @@ -2697,15 +2710,17 @@ void aead_encrypt( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT , alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_aead_encrypt( slot, alg, + TEST_ASSERT( psa_aead_encrypt( handle, alg, nonce->x, nonce->len, additional_data->x, additional_data->len, input_data->x, input_data->len, @@ -2716,7 +2731,7 @@ void aead_encrypt( int key_type_arg, data_t *key_data, output_data, output_length ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output_data ); mbedtls_psa_crypto_free( ); } @@ -2731,7 +2746,7 @@ void aead_decrypt( int key_type_arg, data_t *key_data, data_t *expected_data, int expected_result_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char *output_data = NULL; @@ -2757,15 +2772,17 @@ void aead_decrypt( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT , alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_aead_decrypt( slot, alg, + TEST_ASSERT( psa_aead_decrypt( handle, alg, nonce->x, nonce->len, additional_data->x, additional_data->len, @@ -2778,7 +2795,7 @@ void aead_decrypt( int key_type_arg, data_t *key_data, output_data, output_length ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output_data ); mbedtls_psa_crypto_free( ); } @@ -2804,7 +2821,7 @@ void sign_deterministic( int key_type_arg, data_t *key_data, int alg_arg, data_t *input_data, data_t *output_data ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t key_bits; @@ -2822,14 +2839,17 @@ void sign_deterministic( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, NULL, &key_bits ) == PSA_SUCCESS ); @@ -2842,7 +2862,7 @@ void sign_deterministic( int key_type_arg, data_t *key_data, ASSERT_ALLOC( signature, signature_size ); /* Perform the signature. */ - TEST_ASSERT( psa_asymmetric_sign( slot, alg, + TEST_ASSERT( psa_asymmetric_sign( handle, alg, input_data->x, input_data->len, signature, signature_size, &signature_length ) == PSA_SUCCESS ); @@ -2851,7 +2871,7 @@ void sign_deterministic( int key_type_arg, data_t *key_data, signature, signature_length ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( signature ); mbedtls_psa_crypto_free( ); } @@ -2862,7 +2882,7 @@ void sign_fail( int key_type_arg, data_t *key_data, int alg_arg, data_t *input_data, int signature_size_arg, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t signature_size = signature_size_arg; @@ -2881,15 +2901,18 @@ void sign_fail( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - actual_status = psa_asymmetric_sign( slot, alg, + actual_status = psa_asymmetric_sign( handle, alg, input_data->x, input_data->len, signature, signature_size, &signature_length ); @@ -2901,7 +2924,7 @@ void sign_fail( int key_type_arg, data_t *key_data, TEST_ASSERT( signature_length <= signature_size ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( signature ); mbedtls_psa_crypto_free( ); } @@ -2911,7 +2934,7 @@ exit: void sign_verify( int key_type_arg, data_t *key_data, int alg_arg, data_t *input_data ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t key_bits; @@ -2922,16 +2945,19 @@ void sign_verify( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, NULL, &key_bits ) == PSA_SUCCESS ); @@ -2944,7 +2970,7 @@ void sign_verify( int key_type_arg, data_t *key_data, ASSERT_ALLOC( signature, signature_size ); /* Perform the signature. */ - TEST_ASSERT( psa_asymmetric_sign( slot, alg, + TEST_ASSERT( psa_asymmetric_sign( handle, alg, input_data->x, input_data->len, signature, signature_size, &signature_length ) == PSA_SUCCESS ); @@ -2954,7 +2980,7 @@ void sign_verify( int key_type_arg, data_t *key_data, /* Use the library to verify that the signature is correct. */ TEST_ASSERT( psa_asymmetric_verify( - slot, alg, + handle, alg, input_data->x, input_data->len, signature, signature_length ) == PSA_SUCCESS ); @@ -2965,14 +2991,14 @@ void sign_verify( int key_type_arg, data_t *key_data, * because ECDSA may ignore the last few bits of the input. */ input_data->x[0] ^= 1; TEST_ASSERT( psa_asymmetric_verify( - slot, alg, + handle, alg, input_data->x, input_data->len, signature, signature_length ) == PSA_ERROR_INVALID_SIGNATURE ); } exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( signature ); mbedtls_psa_crypto_free( ); } @@ -2983,7 +3009,7 @@ void asymmetric_verify( int key_type_arg, data_t *key_data, int alg_arg, data_t *hash_data, data_t *signature_data ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_key_policy_t policy; @@ -2999,20 +3025,23 @@ void asymmetric_verify( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_asymmetric_verify( slot, alg, + TEST_ASSERT( psa_asymmetric_verify( handle, alg, hash_data->x, hash_data->len, signature_data->x, signature_data->len ) == PSA_SUCCESS ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3023,7 +3052,7 @@ void asymmetric_verify_fail( int key_type_arg, data_t *key_data, data_t *signature_data, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; psa_status_t actual_status; @@ -3039,15 +3068,18 @@ void asymmetric_verify_fail( int key_type_arg, data_t *key_data, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - actual_status = psa_asymmetric_verify( slot, alg, + actual_status = psa_asymmetric_verify( handle, alg, hash_data->x, hash_data->len, signature_data->x, signature_data->len ); @@ -3055,7 +3087,7 @@ void asymmetric_verify_fail( int key_type_arg, data_t *key_data, TEST_ASSERT( actual_status == expected_status ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3069,7 +3101,7 @@ void asymmetric_encrypt( int key_type_arg, int expected_output_length_arg, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t expected_output_length = expected_output_length_arg; @@ -3083,23 +3115,27 @@ void asymmetric_encrypt( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + /* Import the key */ + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Determine the maximum output length */ - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, NULL, &key_bits ) == PSA_SUCCESS ); output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg ); ASSERT_ALLOC( output, output_size ); /* Encrypt the input */ - actual_status = psa_asymmetric_encrypt( slot, alg, + actual_status = psa_asymmetric_encrypt( handle, alg, input_data->x, input_data->len, label->x, label->len, output, output_size, @@ -3114,7 +3150,7 @@ void asymmetric_encrypt( int key_type_arg, output_length = ~0; if( output_size != 0 ) memset( output, 0, output_size ); - actual_status = psa_asymmetric_encrypt( slot, alg, + actual_status = psa_asymmetric_encrypt( handle, alg, input_data->x, input_data->len, NULL, label->len, output, output_size, @@ -3124,7 +3160,7 @@ void asymmetric_encrypt( int key_type_arg, } exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output ); mbedtls_psa_crypto_free( ); } @@ -3137,7 +3173,7 @@ void asymmetric_encrypt_decrypt( int key_type_arg, data_t *input_data, data_t *label ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t key_bits; @@ -3156,19 +3192,22 @@ void asymmetric_encrypt_decrypt( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Determine the maximum ciphertext length */ - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, NULL, &key_bits ) == PSA_SUCCESS ); output_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( key_type, key_bits, alg ); @@ -3179,7 +3218,7 @@ void asymmetric_encrypt_decrypt( int key_type_arg, /* We test encryption by checking that encrypt-then-decrypt gives back * the original plaintext because of the non-optional random * part of encryption process which prevents using fixed vectors. */ - TEST_ASSERT( psa_asymmetric_encrypt( slot, alg, + TEST_ASSERT( psa_asymmetric_encrypt( handle, alg, input_data->x, input_data->len, label->x, label->len, output, output_size, @@ -3188,7 +3227,7 @@ void asymmetric_encrypt_decrypt( int key_type_arg, * it looks sensible. */ TEST_ASSERT( output_length <= output_size ); - TEST_ASSERT( psa_asymmetric_decrypt( slot, alg, + TEST_ASSERT( psa_asymmetric_decrypt( handle, alg, output, output_length, label->x, label->len, output2, output2_size, @@ -3197,7 +3236,7 @@ void asymmetric_encrypt_decrypt( int key_type_arg, output2, output2_length ); exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output ); mbedtls_free( output2 ); mbedtls_psa_crypto_free( ); @@ -3212,7 +3251,7 @@ void asymmetric_decrypt( int key_type_arg, data_t *label, data_t *expected_data ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char *output = NULL; @@ -3232,15 +3271,18 @@ void asymmetric_decrypt( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_asymmetric_decrypt( slot, alg, + TEST_ASSERT( psa_asymmetric_decrypt( handle, alg, input_data->x, input_data->len, label->x, label->len, output, @@ -3256,7 +3298,7 @@ void asymmetric_decrypt( int key_type_arg, output_length = ~0; if( output_size != 0 ) memset( output, 0, output_size ); - TEST_ASSERT( psa_asymmetric_decrypt( slot, alg, + TEST_ASSERT( psa_asymmetric_decrypt( handle, alg, input_data->x, input_data->len, NULL, label->len, output, @@ -3267,7 +3309,7 @@ void asymmetric_decrypt( int key_type_arg, } exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output ); mbedtls_psa_crypto_free( ); } @@ -3281,7 +3323,7 @@ void asymmetric_decrypt_fail( int key_type_arg, data_t *label, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; unsigned char *output = NULL; @@ -3301,15 +3343,18 @@ void asymmetric_decrypt_fail( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + KEY_BITS_FROM_DATA( key_type, key_data ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DECRYPT, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - actual_status = psa_asymmetric_decrypt( slot, alg, + actual_status = psa_asymmetric_decrypt( handle, alg, input_data->x, input_data->len, label->x, label->len, output, output_size, @@ -3324,7 +3369,7 @@ void asymmetric_decrypt_fail( int key_type_arg, output_length = ~0; if( output_size != 0 ) memset( output, 0, output_size ); - actual_status = psa_asymmetric_decrypt( slot, alg, + actual_status = psa_asymmetric_decrypt( handle, alg, input_data->x, input_data->len, NULL, label->len, output, output_size, @@ -3334,7 +3379,7 @@ void asymmetric_decrypt_fail( int key_type_arg, } exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_free( output ); mbedtls_psa_crypto_free( ); } @@ -3349,7 +3394,7 @@ void derive_setup( int key_type_arg, int requested_capacity_arg, int expected_status_arg ) { - psa_key_slot_t slot = 1; + psa_key_handle_t handle = 0; size_t key_type = key_type_arg; psa_algorithm_t alg = alg_arg; size_t requested_capacity = requested_capacity_arg; @@ -3359,22 +3404,24 @@ void derive_setup( int key_type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data->x, key_data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_key_derivation( &generator, slot, alg, + TEST_ASSERT( psa_key_derivation( &generator, handle, alg, salt->x, salt->len, label->x, label->len, requested_capacity ) == expected_status ); exit: psa_generator_abort( &generator ); - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3382,7 +3429,7 @@ exit: /* BEGIN_CASE */ void test_derive_invalid_generator_state( ) { - psa_key_slot_t base_key = 1; + psa_key_handle_t handle = 0; size_t key_type = PSA_KEY_TYPE_DERIVE; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; psa_algorithm_t alg = PSA_ALG_HKDF( PSA_ALG_SHA_256 ); @@ -3395,22 +3442,25 @@ void test_derive_invalid_generator_state( ) TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( key_type, + PSA_BYTES_TO_BITS( sizeof( key_data ) ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( base_key, key_type, + TEST_ASSERT( psa_import_key( handle, key_type, key_data, sizeof( key_data ) ) == PSA_SUCCESS ); /* valid key derivation */ - TEST_ASSERT( psa_key_derivation( &generator, base_key, alg, + TEST_ASSERT( psa_key_derivation( &generator, handle, alg, NULL, 0, NULL, 0, capacity ) == PSA_SUCCESS ); /* state of generator shouldn't allow additional generation */ - TEST_ASSERT( psa_key_derivation( &generator, base_key, alg, + TEST_ASSERT( psa_key_derivation( &generator, handle, alg, NULL, 0, NULL, 0, capacity ) == PSA_ERROR_BAD_STATE ); @@ -3424,7 +3474,7 @@ void test_derive_invalid_generator_state( ) exit: psa_generator_abort( &generator ); - psa_destroy_key( base_key ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3466,7 +3516,7 @@ void derive_output( int alg_arg, data_t *expected_output1, data_t *expected_output2 ) { - psa_key_slot_t slot = 1; + psa_key_handle_t handle = 0; psa_algorithm_t alg = alg_arg; size_t requested_capacity = requested_capacity_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3492,16 +3542,19 @@ void derive_output( int alg_arg, ASSERT_ALLOC( output_buffer, output_buffer_size ); TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE, + TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Extraction phase. */ - TEST_ASSERT( psa_key_derivation( &generator, slot, alg, + TEST_ASSERT( psa_key_derivation( &generator, handle, alg, salt->x, salt->len, label->x, label->len, requested_capacity ) == PSA_SUCCESS ); @@ -3549,7 +3602,7 @@ void derive_output( int alg_arg, exit: mbedtls_free( output_buffer ); psa_generator_abort( &generator ); - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3561,7 +3614,7 @@ void derive_full( int alg_arg, data_t *label, int requested_capacity_arg ) { - psa_key_slot_t slot = 1; + psa_key_handle_t handle = 0; psa_algorithm_t alg = alg_arg; size_t requested_capacity = requested_capacity_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3572,16 +3625,19 @@ void derive_full( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( key_data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_DERIVE, + TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_DERIVE, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Extraction phase. */ - TEST_ASSERT( psa_key_derivation( &generator, slot, alg, + TEST_ASSERT( psa_key_derivation( &generator, handle, alg, salt->x, salt->len, label->x, label->len, requested_capacity ) == PSA_SUCCESS ); @@ -3615,7 +3671,7 @@ void derive_full( int alg_arg, exit: psa_generator_abort( &generator ); - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3630,8 +3686,8 @@ void derive_key_exercise( int alg_arg, int derived_usage_arg, int derived_alg_arg ) { - psa_key_slot_t base_key = 1; - psa_key_slot_t derived_key = 2; + psa_key_handle_t base_handle = 0; + psa_key_handle_t derived_handle = 0; psa_algorithm_t alg = alg_arg; psa_key_type_t derived_type = derived_type_arg; size_t derived_bits = derived_bits_arg; @@ -3645,40 +3701,45 @@ void derive_key_exercise( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( key_data->len ), + &base_handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE, + TEST_ASSERT( psa_set_key_policy( base_handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Derive a key. */ - TEST_ASSERT( psa_key_derivation( &generator, base_key, alg, + TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg, salt->x, salt->len, label->x, label->len, capacity ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( derived_type, derived_bits, + &derived_handle ) == PSA_SUCCESS ); psa_key_policy_set_usage( &policy, derived_usage, derived_alg ); - TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_generator_import_key( derived_key, + TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_generator_import_key( derived_handle, derived_type, derived_bits, &generator ) == PSA_SUCCESS ); /* Test the key information */ - TEST_ASSERT( psa_get_key_information( derived_key, + TEST_ASSERT( psa_get_key_information( derived_handle, &got_type, &got_bits ) == PSA_SUCCESS ); TEST_ASSERT( got_type == derived_type ); TEST_ASSERT( got_bits == derived_bits ); /* Exercise the derived key. */ - if( ! exercise_key( derived_key, derived_usage, derived_alg ) ) + if( ! exercise_key( derived_handle, derived_usage, derived_alg ) ) goto exit; exit: psa_generator_abort( &generator ); - psa_destroy_key( base_key ); - psa_destroy_key( derived_key ); + psa_destroy_key( base_handle ); + psa_destroy_key( derived_handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3691,10 +3752,11 @@ void derive_key_export( int alg_arg, int bytes1_arg, int bytes2_arg ) { - psa_key_slot_t base_key = 1; - psa_key_slot_t derived_key = 2; + psa_key_handle_t base_handle = 0; + psa_key_handle_t derived_handle = 0; psa_algorithm_t alg = alg_arg; size_t bytes1 = bytes1_arg; + size_t derived_bits = PSA_BYTES_TO_BITS( bytes1 ); size_t bytes2 = bytes2_arg; size_t capacity = bytes1 + bytes2; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3707,15 +3769,18 @@ void derive_key_export( int alg_arg, ASSERT_ALLOC( export_buffer, capacity ); TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( key_data->len ), + &base_handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); - TEST_ASSERT( psa_set_key_policy( base_key, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( base_key, PSA_KEY_TYPE_DERIVE, + TEST_ASSERT( psa_set_key_policy( base_handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_import_key( base_handle, PSA_KEY_TYPE_DERIVE, key_data->x, key_data->len ) == PSA_SUCCESS ); /* Derive some material and output it. */ - TEST_ASSERT( psa_key_derivation( &generator, base_key, alg, + TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg, salt->x, salt->len, label->x, label->len, capacity ) == PSA_SUCCESS ); @@ -3725,27 +3790,32 @@ void derive_key_export( int alg_arg, TEST_ASSERT( psa_generator_abort( &generator ) == PSA_SUCCESS ); /* Derive the same output again, but this time store it in key objects. */ - TEST_ASSERT( psa_key_derivation( &generator, base_key, alg, + TEST_ASSERT( psa_key_derivation( &generator, base_handle, alg, salt->x, salt->len, label->x, label->len, capacity ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, derived_bits, + &derived_handle ) == PSA_SUCCESS ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 ); - TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_generator_import_key( derived_key, + TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_generator_import_key( derived_handle, PSA_KEY_TYPE_RAW_DATA, - PSA_BYTES_TO_BITS( bytes1 ), + derived_bits, &generator ) == PSA_SUCCESS ); - TEST_ASSERT( psa_export_key( derived_key, + TEST_ASSERT( psa_export_key( derived_handle, export_buffer, bytes1, &length ) == PSA_SUCCESS ); TEST_ASSERT( length == bytes1 ); - TEST_ASSERT( psa_destroy_key( derived_key ) == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_policy( derived_key, &policy ) == PSA_SUCCESS ); - TEST_ASSERT( psa_generator_import_key( derived_key, + TEST_ASSERT( psa_destroy_key( derived_handle ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, + PSA_BYTES_TO_BITS( bytes2 ), + &derived_handle ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( derived_handle, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_generator_import_key( derived_handle, PSA_KEY_TYPE_RAW_DATA, PSA_BYTES_TO_BITS( bytes2 ), &generator ) == PSA_SUCCESS ); - TEST_ASSERT( psa_export_key( derived_key, + TEST_ASSERT( psa_export_key( derived_handle, export_buffer + bytes1, bytes2, &length ) == PSA_SUCCESS ); TEST_ASSERT( length == bytes2 ); @@ -3757,8 +3827,8 @@ exit: mbedtls_free( output_buffer ); mbedtls_free( export_buffer ); psa_generator_abort( &generator ); - psa_destroy_key( base_key ); - psa_destroy_key( derived_key ); + psa_destroy_key( base_handle ); + psa_destroy_key( derived_handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -3769,7 +3839,7 @@ void key_agreement_setup( int alg_arg, data_t *peer_key_data, int expected_status_arg ) { - psa_key_slot_t our_key = 1; + psa_key_handle_t our_key = 0; psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3777,6 +3847,10 @@ void key_agreement_setup( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( our_key_type, + KEY_BITS_FROM_DATA( our_key_type, + our_key_data ), + &our_key ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS ); @@ -3802,7 +3876,7 @@ void key_agreement_capacity( int alg_arg, data_t *peer_key_data, int expected_capacity_arg ) { - psa_key_slot_t our_key = 1; + psa_key_handle_t our_key = 0; psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3812,6 +3886,10 @@ void key_agreement_capacity( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( our_key_type, + KEY_BITS_FROM_DATA( our_key_type, + our_key_data ), + &our_key ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS ); @@ -3856,7 +3934,7 @@ void key_agreement_output( int alg_arg, data_t *peer_key_data, data_t *expected_output1, data_t *expected_output2 ) { - psa_key_slot_t our_key = 1; + psa_key_handle_t our_key = 0; psa_algorithm_t alg = alg_arg; psa_key_type_t our_key_type = our_key_type_arg; psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT; @@ -3868,6 +3946,10 @@ void key_agreement_output( int alg_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( our_key_type, + KEY_BITS_FROM_DATA( our_key_type, + our_key_data ), + &our_key ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_DERIVE, alg ); TEST_ASSERT( psa_set_key_policy( our_key, &policy ) == PSA_SUCCESS ); @@ -3961,7 +4043,7 @@ void generate_key( int type_arg, int alg_arg, int expected_status_arg ) { - int slot = 1; + psa_key_handle_t handle = 0; psa_key_type_t type = type_arg; psa_key_usage_t usage = usage_arg; size_t bits = bits_arg; @@ -3975,16 +4057,17 @@ void generate_key( int type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + TEST_ASSERT( psa_allocate_key( type, bits, &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); psa_key_policy_set_usage( &policy, usage, alg ); - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); /* Generate a key */ - TEST_ASSERT( psa_generate_key( slot, type, bits, + TEST_ASSERT( psa_generate_key( handle, type, bits, NULL, 0 ) == expected_status ); /* Test the key information */ - TEST_ASSERT( psa_get_key_information( slot, + TEST_ASSERT( psa_get_key_information( handle, &got_type, &got_bits ) == expected_info_status ); if( expected_info_status != PSA_SUCCESS ) @@ -3993,11 +4076,11 @@ void generate_key( int type_arg, TEST_ASSERT( got_bits == bits ); /* Do something with the key according to its type and permitted usage. */ - if( ! exercise_key( slot, usage, alg ) ) + if( ! exercise_key( handle, usage, alg ) ) goto exit; exit: - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free( ); } /* END_CASE */ @@ -4008,8 +4091,8 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, int alg_arg, int generation_method, int export_status ) { - psa_key_slot_t slot = 1; - psa_key_slot_t base_key = 2; + psa_key_handle_t handle = 0; + psa_key_handle_t base_key; psa_key_type_t type = (psa_key_type_t) type_arg; psa_key_type_t type_get; size_t bits_get; @@ -4031,33 +4114,34 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, 1, + type, bits, + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy_set ); - psa_key_policy_set_usage( &policy_set, policy_usage, policy_alg ); + TEST_ASSERT( psa_set_key_policy( handle, &policy_set ) == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_policy( slot, &policy_set ) == PSA_SUCCESS ); switch( generation_method ) { case IMPORT_KEY: /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == PSA_SUCCESS ); break; case GENERATE_KEY: /* Generate a key */ - TEST_ASSERT( psa_generate_key( slot, type, bits, + TEST_ASSERT( psa_generate_key( handle, type, bits, NULL, 0 ) == PSA_SUCCESS ); break; case DERIVE_KEY: /* Create base key */ + TEST_ASSERT( psa_allocate_key( PSA_KEY_TYPE_DERIVE, + PSA_BYTES_TO_BITS( data->len ), + &base_key ) == PSA_SUCCESS ); psa_key_policy_init( &base_policy_set ); - psa_key_policy_set_usage( &base_policy_set, PSA_KEY_USAGE_DERIVE, base_policy_alg ); TEST_ASSERT( psa_set_key_policy( @@ -4070,38 +4154,35 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, NULL, 0, NULL, 0, export_size ) == PSA_SUCCESS ); TEST_ASSERT( psa_generator_import_key( - slot, PSA_KEY_TYPE_RAW_DATA, + handle, PSA_KEY_TYPE_RAW_DATA, bits, &generator ) == PSA_SUCCESS ); break; } /* Export the key */ - TEST_ASSERT( psa_export_key( slot, first_export, export_size, + TEST_ASSERT( psa_export_key( handle, first_export, export_size, &first_exported_length ) == export_status ); /* Shutdown and restart */ mbedtls_psa_crypto_free(); - TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - /* Mark slot as persistent again */ - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - /* Check key slot still contains key data */ + TEST_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, 1, + &handle ) == PSA_SUCCESS ); TEST_ASSERT( psa_get_key_information( - slot, &type_get, &bits_get ) == PSA_SUCCESS ); + handle, &type_get, &bits_get ) == PSA_SUCCESS ); TEST_ASSERT( type_get == type ); TEST_ASSERT( bits_get == (size_t) bits ); - TEST_ASSERT( psa_get_key_policy( slot, &policy_get ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_policy( handle, &policy_get ) == PSA_SUCCESS ); TEST_ASSERT( psa_key_policy_get_usage( &policy_get ) == policy_usage ); TEST_ASSERT( psa_key_policy_get_algorithm( &policy_get ) == policy_alg ); /* Export the key again */ - TEST_ASSERT( psa_export_key( slot, second_export, export_size, + TEST_ASSERT( psa_export_key( handle, second_export, export_size, &second_exported_length ) == export_status ); if( export_status == PSA_SUCCESS ) @@ -4121,13 +4202,13 @@ void persistent_key_load_key_from_storage( data_t *data, int type_arg, } /* Do something with the key according to its type and permitted usage. */ - if( ! exercise_key( slot, policy_usage, policy_alg ) ) + if( ! exercise_key( handle, policy_usage, policy_alg ) ) goto exit; exit: mbedtls_free( first_export ); mbedtls_free( second_export ); - psa_destroy_key( slot ); + psa_destroy_key( handle ); mbedtls_psa_crypto_free(); } /* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index 46e547c93..c9eb8e103 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -24,10 +24,6 @@ save_large_persistent_key:0:PSA_SUCCESS Save larger than maximum size persistent raw key, should fail save_large_persistent_key:1:PSA_ERROR_INSUFFICIENT_STORAGE -Persistent key is configurable -depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -persistent_key_is_configurable:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" - Persistent key destroy depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C persistent_key_destroy:1:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RAW_DATA:"deadbeef" @@ -36,10 +32,6 @@ Persistent key destroy missing key depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C persistent_key_destroy:1:0:PSA_KEY_TYPE_RSA_KEYPAIR:"":PSA_KEY_TYPE_RAW_DATA:"deadbeef" -Key lifetime defaults to volatile -depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -default_volatile_lifetime:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24" - Persistent key import depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C persistent_key_import:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index 0ede6e6c8..08c7ca017 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -85,7 +85,8 @@ exit: /* BEGIN_CASE */ void save_large_persistent_key( int data_too_large, int expected_status ) { - psa_key_slot_t slot = 1; + psa_key_id_t key_id = 42; + psa_key_handle_t handle = 0; uint8_t *data = NULL; size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE; @@ -96,180 +97,107 @@ void save_large_persistent_key( int data_too_large, int expected_status ) TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + PSA_KEY_TYPE_RAW_DATA, + PSA_BYTES_TO_BITS( data_length ), + &handle ) == PSA_SUCCESS ); - TEST_ASSERT( psa_import_key( slot, PSA_KEY_TYPE_RAW_DATA, + TEST_ASSERT( psa_import_key( handle, PSA_KEY_TYPE_RAW_DATA, data, data_length ) == expected_status ); exit: mbedtls_free( data ); - psa_destroy_persistent_key( slot ); - mbedtls_psa_crypto_free(); -} -/* END_CASE */ - - -/* BEGIN_CASE */ -void persistent_key_is_configurable( int slot_arg, int type_arg, - data_t *data ) -{ - psa_key_policy_t policy; - psa_key_lifetime_t lifetime; - psa_key_slot_t slot = (psa_key_slot_t) slot_arg; - psa_key_type_t type = (psa_key_type_t) type_arg; - - TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - - psa_key_policy_init( &policy ); - - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_import_key( slot, type, - data->x, data->len ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); - - TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); - -exit: - psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); + psa_destroy_persistent_key( key_id ); } /* END_CASE */ /* BEGIN_CASE */ -void persistent_key_destroy( int slot_arg, int should_store, +void persistent_key_destroy( int key_id_arg, int should_store, int first_type_arg, data_t *first_data, int second_type_arg, data_t *second_data ) { psa_key_policy_t policy; - psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_id_t key_id = key_id_arg; + psa_key_handle_t handle = 0; psa_key_type_t first_type = (psa_key_type_t) first_type_arg; psa_key_type_t second_type = (psa_key_type_t) second_type_arg; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - psa_key_policy_init( &policy ); + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + first_type, + PSA_BYTES_TO_BITS( first_data->len ), + &handle ) == PSA_SUCCESS ); + if( should_store == 1 ) { TEST_ASSERT( psa_import_key( - slot, first_type, + handle, first_type, first_data->x, first_data->len ) == PSA_SUCCESS ); } /* Destroy the key */ - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); - - TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); /* Check key slot storage is removed */ - TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); - - /* Check destroying the key again doesn't report failure */ - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); + TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 ); + TEST_ASSERT( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + &handle ) == PSA_ERROR_EMPTY_SLOT ); + TEST_ASSERT( handle == 0 ); /* Shutdown and restart */ mbedtls_psa_crypto_free(); - TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - /* Mark slot as persistent again */ - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - - /* Check key slot is empty */ - TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); - - /* Import different key data to ensure slot really was empty */ - psa_key_policy_init( &policy ); - - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, - PSA_ALG_VENDOR_FLAG ); - - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); - + /* Create another key in the same slot */ + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + second_type, + PSA_BYTES_TO_BITS( second_data->len ), + &handle ) == PSA_SUCCESS ); TEST_ASSERT( psa_import_key( - slot, second_type, + handle, second_type, second_data->x, second_data->len ) == PSA_SUCCESS ); exit: - psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free(); + psa_destroy_persistent_key( key_id ); } /* END_CASE */ /* BEGIN_CASE */ -void default_volatile_lifetime( int slot_arg, int type_arg, data_t *data ) -{ - psa_key_policy_t policy; - psa_key_slot_t slot = (psa_key_slot_t) slot_arg; - psa_key_type_t type = (psa_key_type_t) type_arg; - - TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - - psa_key_policy_init( &policy ); - - TEST_ASSERT( psa_import_key( slot, type, - data->x, data->len ) == PSA_SUCCESS ); - - /* Shutdown and restart */ - mbedtls_psa_crypto_free(); - - TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - - /* Check key slot is empty */ - TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); - -exit: - psa_destroy_persistent_key( slot ); - mbedtls_psa_crypto_free(); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void persistent_key_import( int slot_arg, int type_arg, data_t *data, +void persistent_key_import( int key_id_arg, int type_arg, data_t *data, int expected_status ) { psa_key_policy_t policy; psa_key_lifetime_t lifetime; - psa_key_slot_t slot = (psa_key_slot_t) slot_arg; + psa_key_id_t key_id = (psa_key_id_t) key_id_arg; psa_key_type_t type = (psa_key_type_t) type_arg; + psa_key_handle_t handle = 0; TEST_ASSERT( psa_crypto_init() == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); - + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + type, + PSA_BYTES_TO_BITS( data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); - - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == expected_status ); if( expected_status != PSA_SUCCESS ) { - TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); + TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 ); goto exit; } - TEST_ASSERT( psa_get_key_lifetime( slot, &lifetime ) == PSA_SUCCESS ); - + TEST_ASSERT( psa_get_key_lifetime( handle, &lifetime ) == PSA_SUCCESS ); TEST_ASSERT( lifetime == PSA_KEY_LIFETIME_PERSISTENT ); exit: - psa_destroy_persistent_key( slot ); + psa_destroy_persistent_key( key_id ); mbedtls_psa_crypto_free(); } /* END_CASE */ @@ -278,8 +206,9 @@ exit: void import_export_persistent_key( data_t *data, int type_arg, int expected_bits, int key_not_exist ) { - psa_key_slot_t slot = 1; + psa_key_id_t key_id = 42; psa_key_type_t type = (psa_key_type_t) type_arg; + psa_key_handle_t handle = 0; unsigned char *exported = NULL; size_t export_size = data->len; size_t exported_length; @@ -292,51 +221,48 @@ void import_export_persistent_key( data_t *data, int type_arg, TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); - TEST_ASSERT( psa_set_key_lifetime( - slot, PSA_KEY_LIFETIME_PERSISTENT ) == PSA_SUCCESS ); + TEST_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, + type, + PSA_BYTES_TO_BITS( data->len ), + &handle ) == PSA_SUCCESS ); psa_key_policy_init( &policy ); - psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, PSA_ALG_VENDOR_FLAG ); - - TEST_ASSERT( psa_set_key_policy( slot, &policy ) == PSA_SUCCESS ); + TEST_ASSERT( psa_set_key_policy( handle, &policy ) == PSA_SUCCESS ); /* Import the key */ - TEST_ASSERT( psa_import_key( slot, type, + TEST_ASSERT( psa_import_key( handle, type, data->x, data->len ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_lifetime( - slot, &lifetime_get ) == PSA_SUCCESS ); + TEST_ASSERT( psa_get_key_lifetime( handle, &lifetime_get ) == PSA_SUCCESS ); TEST_ASSERT( lifetime_get == PSA_KEY_LIFETIME_PERSISTENT ); /* Test the key information */ TEST_ASSERT( psa_get_key_information( - slot, &got_type, &got_bits ) == PSA_SUCCESS ); + handle, &got_type, &got_bits ) == PSA_SUCCESS ); TEST_ASSERT( got_type == type ); TEST_ASSERT( got_bits == (size_t) expected_bits ); - TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 1 ); + TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 1 ); if( key_not_exist ) { - psa_destroy_persistent_key( slot ); + psa_destroy_persistent_key( key_id ); } /* Export the key */ - TEST_ASSERT( psa_export_key( slot, exported, export_size, + TEST_ASSERT( psa_export_key( handle, exported, export_size, &exported_length ) == PSA_SUCCESS ); ASSERT_COMPARE( data->x, data->len, exported, exported_length ); /* Destroy the key */ - TEST_ASSERT( psa_destroy_key( slot ) == PSA_SUCCESS ); - TEST_ASSERT( psa_get_key_information( - slot, NULL, NULL ) == PSA_ERROR_EMPTY_SLOT ); - TEST_ASSERT( psa_is_key_present_in_storage( slot ) == 0 ); + TEST_ASSERT( psa_destroy_key( handle ) == PSA_SUCCESS ); + TEST_ASSERT( psa_is_key_present_in_storage( key_id ) == 0 ); exit: mbedtls_free( exported ); - psa_destroy_persistent_key( slot ); mbedtls_psa_crypto_free( ); + psa_destroy_persistent_key( key_id ); } /* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_slot_management.data b/tests/suites/test_suite_psa_crypto_slot_management.data new file mode 100644 index 000000000..39661b9ed --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_slot_management.data @@ -0,0 +1,84 @@ +Transient slot, check after closing +transient_slot_lifecycle:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE + +Transient slot, check after destroying +transient_slot_lifecycle:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY + +Transient slot, check after restart +transient_slot_lifecycle:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN + +Persistent slot, check after closing +persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE + +Persistent slot, check after destroying +persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY + +Persistent slot, check after restart +persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:128:0:0:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN + +Attempt to overwrite: close before, same type +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:CLOSE_BEFORE + +Attempt to overwrite: close before, different type +depends_on:MBEDTLS_AES_C +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_AES:CLOSE_BEFORE + +Attempt to overwrite: close after, same type +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:CLOSE_AFTER + +Attempt to overwrite: close after, different type +depends_on:MBEDTLS_AES_C +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_AES:CLOSE_AFTER + +Attempt to overwrite: keep open, same type +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:KEEP_OPEN + +Attempt to overwrite: keep open, different type +depends_on:MBEDTLS_AES_C +create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_AES:KEEP_OPEN + +Open failure: invalid identifier (0) +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +open_fail:PSA_KEY_LIFETIME_PERSISTENT:0:PSA_ERROR_INVALID_ARGUMENT + +Open failure: invalid identifier (random seed UID) +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +open_fail:PSA_KEY_LIFETIME_PERSISTENT:PSA_CRYPTO_ITS_RANDOM_SEED_UID:PSA_ERROR_INVALID_ARGUMENT + +Open failure: non-existent identifier +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +open_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_EMPTY_SLOT + +Open failure: volatile lifetime +open_fail:PSA_KEY_LIFETIME_VOLATILE:1:PSA_ERROR_INVALID_ARGUMENT + +Open failure: invalid lifetime +open_fail:0x7fffffff:0:PSA_ERROR_INVALID_ARGUMENT + +Create failure: volatile lifetime +create_fail:PSA_KEY_LIFETIME_VOLATILE:1:PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT + +Create failure: invalid lifetime +create_fail:0x7fffffff:0:PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT + +Create failure: invalid key id (0) +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +create_fail:PSA_KEY_LIFETIME_PERSISTENT:0:PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT + +Create failure: invalid key id (random seed UID) +depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C +create_fail:PSA_KEY_LIFETIME_PERSISTENT:PSA_CRYPTO_ITS_RANDOM_SEED_UID:PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_INVALID_ARGUMENT + +Open not supported +depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C +open_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_NOT_SUPPORTED + +Create not supported +depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C +create_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_TYPE_RAW_DATA:8:PSA_ERROR_NOT_SUPPORTED + +Close/destroy invalid handle +invalid_handle: + +Open many transient handles +many_transient_handles:42 diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function new file mode 100644 index 000000000..fdcb5a949 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_slot_management.function @@ -0,0 +1,398 @@ +/* BEGIN_HEADER */ +#include + +#if defined(MBEDTLS_PSA_CRYPTO_SPM) +#include "spm/psa_defs.h" +#endif +#include "psa/crypto.h" + +#include "psa_crypto_storage.h" + +#define PSA_ASSERT( expr ) TEST_ASSERT( ( expr ) == PSA_SUCCESS ) + +typedef enum +{ + CLOSE_BY_CLOSE, + CLOSE_BY_DESTROY, + CLOSE_BY_SHUTDOWN, +} close_method_t; + +typedef enum +{ + KEEP_OPEN, + CLOSE_BEFORE, + CLOSE_AFTER, +} reopen_policy_t; + +/* All test functions that create persistent keys must call + * `TEST_MAX_KEY_ID( key_id )` before creating a persistent key with this + * identifier, and must call psa_purge_key_storage() in their cleanup + * code. */ + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) +/* There is no API to purge all keys. For this test suite, require that + * all key IDs be less than a certain maximum, or a well-known value + * which corresponds to a file that does not contain a key. */ +#define MAX_KEY_ID_FOR_TEST 32 +#define KEY_ID_IS_WELL_KNOWN( key_id ) \ + ( ( key_id ) == PSA_CRYPTO_ITS_RANDOM_SEED_UID ) +#define TEST_MAX_KEY_ID( key_id ) \ + TEST_ASSERT( ( key_id ) <= MAX_KEY_ID_FOR_TEST || \ + KEY_ID_IS_WELL_KNOWN( key_id ) ) +void psa_purge_key_storage( void ) +{ + psa_key_id_t i; + /* The tests may have potentially created key ids from 1 to + * MAX_KEY_ID_FOR_TEST. In addition, run the destroy function on key id + * 0, which file-based storage uses as a temporary file. */ + for( i = 0; i <= MAX_KEY_ID_FOR_TEST; i++ ) + psa_destroy_persistent_key( i ); +} +#else +#define TEST_MAX_KEY_ID( key_id ) ( (void) ( key_id ) ) +#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ + +static int psa_key_policy_equal( psa_key_policy_t *p1, + psa_key_policy_t *p2 ) +{ + return( psa_key_policy_get_usage( p1 ) == psa_key_policy_get_usage( p2 ) && + psa_key_policy_get_algorithm( p1 ) == psa_key_policy_get_algorithm( p2 ) ); +} + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void transient_slot_lifecycle( int type_arg, int max_bits_arg, + int alg_arg, int usage_arg, + data_t *key_data, + int close_method_arg ) +{ + psa_key_type_t type = type_arg; + size_t max_bits = max_bits_arg; + psa_algorithm_t alg = alg_arg; + psa_key_usage_t usage_flags = usage_arg; + close_method_t close_method = close_method_arg; + psa_key_type_t read_type; + psa_key_handle_t handle = 0; + psa_key_policy_t policy; + + PSA_ASSERT( psa_crypto_init( ) ); + + /* Get a handle and import a key. */ + PSA_ASSERT( psa_allocate_key( type, max_bits, &handle ) ); + TEST_ASSERT( handle != 0 ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, usage_flags, alg ); + PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); + PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) ); + PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ); + TEST_ASSERT( read_type == type ); + + /* Do something that invalidates the handle. */ + switch( close_method ) + { + case CLOSE_BY_CLOSE: + PSA_ASSERT( psa_close_key( handle ) ); + break; + case CLOSE_BY_DESTROY: + PSA_ASSERT( psa_destroy_key( handle ) ); + break; + case CLOSE_BY_SHUTDOWN: + mbedtls_psa_crypto_free( ); + PSA_ASSERT( psa_crypto_init( ) ); + break; + } + /* Test that the handle is now invalid. */ + TEST_ASSERT( psa_get_key_information( handle, &read_type, NULL ) == + PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_close_key( handle ) == PSA_ERROR_INVALID_HANDLE ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +void persistent_slot_lifecycle( int lifetime_arg, int id_arg, + int type_arg, int max_bits_arg, + int alg_arg, int usage_arg, + data_t *key_data, + int close_method_arg ) +{ + psa_key_lifetime_t lifetime = lifetime_arg; + psa_key_id_t id = id_arg; + psa_key_type_t type = type_arg; + size_t max_bits = max_bits_arg; + psa_algorithm_t alg = alg_arg; + psa_key_usage_t usage_flags = usage_arg; + close_method_t close_method = close_method_arg; + psa_key_type_t read_type; + psa_key_handle_t handle = 0; + psa_key_policy_t policy; + + TEST_MAX_KEY_ID( id ); + + PSA_ASSERT( psa_crypto_init( ) ); + + /* Get a handle and import a key. */ + PSA_ASSERT( psa_create_key( lifetime, id, type, max_bits, &handle ) ); + TEST_ASSERT( handle != 0 ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, usage_flags, alg ); + PSA_ASSERT( psa_set_key_policy( handle, &policy ) ); + PSA_ASSERT( psa_import_key( handle, type, key_data->x, key_data->len ) ); + PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ); + TEST_ASSERT( read_type == type ); + + /* Close the key and reopen it. */ + PSA_ASSERT( psa_close_key( handle ) ); + PSA_ASSERT( psa_open_key( lifetime, id, &handle ) ); + PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ); + TEST_ASSERT( read_type == type ); + + /* Do something that invalidates the handle. */ + switch( close_method ) + { + case CLOSE_BY_CLOSE: + PSA_ASSERT( psa_close_key( handle ) ); + break; + case CLOSE_BY_DESTROY: + PSA_ASSERT( psa_destroy_key( handle ) ); + break; + case CLOSE_BY_SHUTDOWN: + mbedtls_psa_crypto_free( ); + PSA_ASSERT( psa_crypto_init( ) ); + break; + } + /* Test that the handle is now invalid. */ + TEST_ASSERT( psa_get_key_information( handle, &read_type, NULL ) == + PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_close_key( handle ) == PSA_ERROR_INVALID_HANDLE ); + + /* Try to reopen the key. If we destroyed it, check that it doesn't + * exist, otherwise check that it still exists. */ + switch( close_method ) + { + case CLOSE_BY_CLOSE: + case CLOSE_BY_SHUTDOWN: + PSA_ASSERT( psa_open_key( lifetime, id, &handle ) ); + PSA_ASSERT( psa_get_key_information( handle, &read_type, NULL ) ); + TEST_ASSERT( read_type == type ); + break; + case CLOSE_BY_DESTROY: + TEST_ASSERT( psa_open_key( lifetime, id, &handle ) == + PSA_ERROR_EMPTY_SLOT ); + break; + } + +exit: + mbedtls_psa_crypto_free( ); + psa_purge_key_storage( ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ +void create_existent( int lifetime_arg, int id_arg, + int new_type_arg, + int reopen_policy_arg ) +{ + psa_key_lifetime_t lifetime = lifetime_arg; + psa_key_id_t id = id_arg; + psa_key_handle_t handle1 = 0, handle2 = 0; + psa_key_policy_t policy1, read_policy; + psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA; + psa_key_type_t type2 = new_type_arg; + psa_key_type_t read_type; + const uint8_t material1[16] = "test material #1"; + size_t bits1 = PSA_BYTES_TO_BITS( sizeof( material1 ) ); + size_t read_bits; + uint8_t reexported[sizeof( material1 )]; + size_t reexported_length; + reopen_policy_t reopen_policy = reopen_policy_arg; + + TEST_MAX_KEY_ID( id ); + + PSA_ASSERT( psa_crypto_init( ) ); + + /* Create a key. */ + PSA_ASSERT( psa_create_key( lifetime, id, type1, bits1, &handle1 ) ); + TEST_ASSERT( handle1 != 0 ); + psa_key_policy_init( &policy1 ); + psa_key_policy_set_usage( &policy1, PSA_KEY_USAGE_EXPORT, 0 ); + PSA_ASSERT( psa_set_key_policy( handle1, &policy1 ) ); + PSA_ASSERT( psa_import_key( handle1, type1, + material1, sizeof( material1 ) ) ); + + if( reopen_policy == CLOSE_BEFORE ) + PSA_ASSERT( psa_close_key( handle1 ) ); + + /* Attempt to create a new key in the same slot. */ + TEST_ASSERT( psa_create_key( lifetime, id, type2, bits1, &handle2 ) == + PSA_ERROR_OCCUPIED_SLOT ); + TEST_ASSERT( handle2 == 0 ); + + if( reopen_policy == CLOSE_AFTER ) + PSA_ASSERT( psa_close_key( handle1 ) ); + if( reopen_policy == CLOSE_BEFORE || reopen_policy == CLOSE_AFTER ) + PSA_ASSERT( psa_open_key( lifetime, id, &handle1 ) ); + + /* Check that the original key hasn't changed. */ + PSA_ASSERT( psa_get_key_policy( handle1, &read_policy ) ); + TEST_ASSERT( psa_key_policy_equal( &read_policy, &policy1 ) ); + PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) ); + TEST_ASSERT( read_type == type1 ); + TEST_ASSERT( read_bits == bits1 ); + PSA_ASSERT( psa_export_key( handle1, + reexported, sizeof( reexported ), + &reexported_length ) ); + ASSERT_COMPARE( material1, sizeof( material1 ), + reexported, reexported_length ); + +exit: + mbedtls_psa_crypto_free( ); + psa_purge_key_storage( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void open_fail( int lifetime_arg, int id_arg, + int expected_status_arg ) +{ + psa_key_lifetime_t lifetime = lifetime_arg; + psa_key_id_t id = id_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_handle_t handle = 0xdead; + + PSA_ASSERT( psa_crypto_init( ) ); + + TEST_ASSERT( psa_open_key( lifetime, id, &handle ) == expected_status ); + TEST_ASSERT( handle == 0 ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void create_fail( int lifetime_arg, int id_arg, + int type_arg, int max_bits_arg, + int expected_status_arg ) +{ + psa_key_lifetime_t lifetime = lifetime_arg; + psa_key_id_t id = id_arg; + psa_key_type_t type = type_arg; + size_t max_bits = max_bits_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_handle_t handle = 0xdead; + + TEST_MAX_KEY_ID( id ); + + PSA_ASSERT( psa_crypto_init( ) ); + + TEST_ASSERT( psa_create_key( lifetime, id, + type, max_bits, + &handle ) == expected_status ); + TEST_ASSERT( handle == 0 ); + +exit: + mbedtls_psa_crypto_free( ); +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + psa_purge_key_storage( ); +#endif +} +/* END_CASE */ + +/* BEGIN_CASE */ +void invalid_handle( ) +{ + psa_key_handle_t handle1 = 0; + psa_key_policy_t policy; + psa_key_type_t read_type; + size_t read_bits; + uint8_t material[1] = "a"; + + PSA_ASSERT( psa_crypto_init( ) ); + + /* Allocate a handle and store a key in it. */ + PSA_ASSERT( psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, 1, &handle1 ) ); + TEST_ASSERT( handle1 != 0 ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, 0, 0 ); + PSA_ASSERT( psa_set_key_policy( handle1, &policy ) ); + PSA_ASSERT( psa_import_key( handle1, PSA_KEY_TYPE_RAW_DATA, + material, sizeof( material ) ) ); + + /* Attempt to close and destroy some invalid handles. */ + TEST_ASSERT( psa_close_key( 0 ) == PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_close_key( handle1 - 1 ) == PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_close_key( handle1 + 1 ) == PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_destroy_key( 0 ) == PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_destroy_key( handle1 - 1 ) == PSA_ERROR_INVALID_HANDLE ); + TEST_ASSERT( psa_destroy_key( handle1 + 1 ) == PSA_ERROR_INVALID_HANDLE ); + + /* After all this, check that the original handle is intact. */ + PSA_ASSERT( psa_get_key_information( handle1, &read_type, &read_bits ) ); + TEST_ASSERT( read_type == PSA_KEY_TYPE_RAW_DATA ); + TEST_ASSERT( read_bits == PSA_BYTES_TO_BITS( sizeof( material ) ) ); + PSA_ASSERT( psa_close_key( handle1 ) ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void many_transient_handles( int max_handles_arg ) +{ + psa_key_handle_t *handles = NULL; + size_t max_handles = max_handles_arg; + size_t i, j; + psa_status_t status; + psa_key_policy_t policy; + uint8_t exported[sizeof( size_t )]; + size_t exported_length; + size_t max_bits = PSA_BITS_TO_BYTES( sizeof( exported ) ); + + ASSERT_ALLOC( handles, max_handles ); + PSA_ASSERT( psa_crypto_init( ) ); + psa_key_policy_init( &policy ); + psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 ); + + for( i = 0; i < max_handles; i++ ) + { + status = psa_allocate_key( PSA_KEY_TYPE_RAW_DATA, max_bits, + &handles[i] ); + if( status == PSA_ERROR_INSUFFICIENT_MEMORY ) + break; + TEST_ASSERT( status == PSA_SUCCESS ); + TEST_ASSERT( handles[i] != 0 ); + for( j = 0; j < i; j++ ) + TEST_ASSERT( handles[i] != handles[j] ); + PSA_ASSERT( psa_set_key_policy( handles[i], &policy ) ); + PSA_ASSERT( psa_import_key( handles[i], PSA_KEY_TYPE_RAW_DATA, + (uint8_t *) &i, sizeof( i ) ) ); + } + max_handles = i; + + for( i = 1; i < max_handles; i++ ) + { + PSA_ASSERT( psa_close_key( handles[i - 1] ) ); + PSA_ASSERT( psa_export_key( handles[i], + exported, sizeof( exported ), + &exported_length ) ); + ASSERT_COMPARE( exported, exported_length, + (uint8_t *) &i, sizeof( i ) ); + } + PSA_ASSERT( psa_close_key( handles[i - 1] ) ); + +exit: + mbedtls_psa_crypto_free( ); + mbedtls_free( handles ); +} +/* END_CASE */ + diff --git a/tests/suites/test_suite_psa_crypto_storage_file.function b/tests/suites/test_suite_psa_crypto_storage_file.function index b6dcad777..e753d7862 100644 --- a/tests/suites/test_suite_psa_crypto_storage_file.function +++ b/tests/suites/test_suite_psa_crypto_storage_file.function @@ -11,9 +11,11 @@ */ /* BEGIN_CASE */ -void load_data_from_file( int slot_to_load, data_t *data, int should_make_file, +void load_data_from_file( int id_to_load_arg, + data_t *data, int should_make_file, int capacity_arg, int expected_status ) { + psa_key_id_t id_to_load = id_to_load_arg; char slot_location[] = "psa_key_slot_1"; psa_status_t status; int ret; @@ -36,8 +38,7 @@ void load_data_from_file( int slot_to_load, data_t *data, int should_make_file, /* Read from the file with psa_crypto_storage_load. */ loaded_data = mbedtls_calloc( 1, capacity ); TEST_ASSERT( loaded_data != NULL ); - status = psa_crypto_storage_load( (psa_key_slot_t) slot_to_load, loaded_data, - file_size ); + status = psa_crypto_storage_load( id_to_load, loaded_data, file_size ); /* Check we get the expected status. */ TEST_ASSERT( status == expected_status ); diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index d305c4515..366b97e55 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -231,7 +231,9 @@ + + @@ -291,6 +293,7 @@ +