Merge remote-tracking branch 'psa/pr/230' into feature-psa
Implement a key handle mechanism
This commit is contained in:
commit
1a76f3971c
25 changed files with 2203 additions and 1189 deletions
|
@ -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,
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
/* PSA requires several types which C99 provides in stdint.h. */
|
||||
#include <stdint.h>
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 */
|
||||
|
|
99
library/psa_crypto_core.h
Normal file
99
library/psa_crypto_core.h
Normal file
|
@ -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 */
|
287
library/psa_crypto_slot_management.c
Normal file
287
library/psa_crypto_slot_management.c
Normal file
|
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#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 */
|
58
library/psa_crypto_slot_management.h
Normal file
58
library/psa_crypto_slot_management.h
Normal file
|
@ -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 */
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
84
tests/suites/test_suite_psa_crypto_slot_management.data
Normal file
84
tests/suites/test_suite_psa_crypto_slot_management.data
Normal file
|
@ -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
|
398
tests/suites/test_suite_psa_crypto_slot_management.function
Normal file
398
tests/suites/test_suite_psa_crypto_slot_management.function
Normal file
|
@ -0,0 +1,398 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include <stdint.h>
|
||||
|
||||
#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 */
|
||||
|
|
@ -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 );
|
||||
|
|
|
@ -231,7 +231,9 @@
|
|||
<ClInclude Include="..\..\include\psa\crypto_platform.h" />
|
||||
<ClInclude Include="..\..\include\psa\crypto_sizes.h" />
|
||||
<ClInclude Include="..\..\include\psa\crypto_struct.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_core.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_invasive.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_slot_management.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_storage.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_storage_backend.h" />
|
||||
</ItemGroup>
|
||||
|
@ -291,6 +293,7 @@
|
|||
<ClCompile Include="..\..\library\platform_util.c" />
|
||||
<ClCompile Include="..\..\library\poly1305.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_slot_management.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_storage.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_storage_file.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_storage_its.c" />
|
||||
|
|
Loading…
Reference in a new issue