Merge branch 'psa-api-1.0-beta' into merge-psa-api-branch-into-development
This commit is contained in:
commit
8aa7e9bc56
60 changed files with 10579 additions and 4410 deletions
|
@ -193,3 +193,92 @@ The layout of a key file is:
|
|||
* key material length (4 bytes)
|
||||
* key material: output of `psa_export_key`
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
Mbed Crypto TBD
|
||||
---------------
|
||||
|
||||
Tags: TBD
|
||||
|
||||
Released in TBD 2019. <br>
|
||||
Integrated in Mbed OS TBD.
|
||||
|
||||
### Changes introduced in TBD
|
||||
|
||||
* The layout of a key file now has a lifetime field before the type field.
|
||||
* Key files can store references to keys in a secure element. In such key files, the key material contains the slot number.
|
||||
|
||||
### File namespace on a PSA platform on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The Crypto service can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
Assumption: the owner identifier is a nonzero value of type `int32_t`.
|
||||
|
||||
* Files 0 through 0xfffeffff: unused.
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0). The upper 32 bits determine the owner.
|
||||
|
||||
### File namespace on ITS as a library on TBD
|
||||
|
||||
Assumption: ITS provides a 64-bit file identifier namespace. The entity using the crypto library can use arbitrary file identifiers and no other part of the system accesses the same file identifier namespace.
|
||||
|
||||
This is a library integration, so there is no owner. The key file identifier is identical to the key identifier.
|
||||
|
||||
* File 0: unused.
|
||||
* Files 1 through 0xfffeffff: [content](#key-file-format-for-1.0.0) of the [key whose identifier is the file identifier](#key-names-for-1.0.0).
|
||||
* Files 0xffff0000 through 0xffffffff: reserved for internal use of the crypto library or crypto service. See [non-key files](#non-key-files-on-tbd).
|
||||
* Files 0x100000000 through 0xffffffffffffffff: unused.
|
||||
|
||||
### Non-key files on TBD
|
||||
|
||||
File identifiers in the range 0xffff0000 through 0xffffffff are reserved for internal use in Mbed Crypto.
|
||||
|
||||
* Files 0xfffffe02 through 0xfffffeff (`PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime`): secure element driver storage. The content of the file is the secure element driver's persistent data.
|
||||
* File 0xffffff52 (`PSA_CRYPTO_ITS_RANDOM_SEED_UID`): [nonvolatile random seed](#nonvolatile-random-seed-file-format-for-1.0.0).
|
||||
* File 0xffffff54 (`PSA_CRYPTO_ITS_TRANSACTION_UID`): [transaction file](#transaction-file-format-for-tbd).
|
||||
* Other files are unused and reserved for future use.
|
||||
|
||||
### Key file format for TBD
|
||||
|
||||
All integers are encoded in little-endian order in 8-bit bytes except where otherwise indicated.
|
||||
|
||||
The layout of a key file is:
|
||||
|
||||
* magic (8 bytes): `"PSA\0KEY\0"`.
|
||||
* version (4 bytes): 0.
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value.
|
||||
* type (4 bytes): `psa_key_type_t` value.
|
||||
* policy usage flags (4 bytes): `psa_key_usage_t` value.
|
||||
* policy usage algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* policy enrollment algorithm (4 bytes): `psa_algorithm_t` value.
|
||||
* key material length (4 bytes).
|
||||
* key material:
|
||||
* For a transparent key: output of `psa_export_key`.
|
||||
* For an opaque key (key in a secure element): slot number (8 bytes), in platform endianness.
|
||||
* Any trailing data is rejected on load.
|
||||
|
||||
### Transaction file format for TBD
|
||||
|
||||
The transaction file contains data about an ongoing action that cannot be completed atomically. It exists only if there is an ongoing transaction.
|
||||
|
||||
All integers are encoded in platform endianness.
|
||||
|
||||
All currently existing transactions concern a key in a secure element.
|
||||
|
||||
The layout of a transaction file is:
|
||||
|
||||
* type (2 bytes): the [transaction type](#transaction-types-on-tbd).
|
||||
* unused (2 bytes)
|
||||
* lifetime (4 bytes): `psa_key_lifetime_t` value that corresponds to a key in a secure element.
|
||||
* slot number (8 bytes): `psa_key_slot_number_t` value. This is the unique designation of the key for the secure element driver.
|
||||
* key identifier (4 bytes in a library integration, 8 bytes on a PSA platform): the internal representation of the key identifier. On a PSA platform, this encodes the key owner in the same way as [in file identifiers for key files](#file-namespace-on-a-psa-platform-on-tbd)).
|
||||
|
||||
#### Transaction types on TBD
|
||||
|
||||
* 0x0001: key creation. The following locations may or may not contain data about the key that is being created:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
* 0x0002: key destruction. The following locations may or may not still contain data about the key that is being destroyed:
|
||||
* The slot in the secure element designated by the slot number.
|
||||
* The file containing the key metadata designated by the key identifier.
|
||||
* The driver persistent data.
|
||||
|
|
|
@ -73,7 +73,7 @@ Importing a key and checking key information:
|
|||
1. Test the information stored in this slot:
|
||||
```C
|
||||
int key_slot = 1;
|
||||
uint8_t *data = "KEYPAIR_KEY_DATA";
|
||||
uint8_t *data = "KEY_PAIR_KEY_DATA";
|
||||
size_t data_size;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_RSA_PUBLIC_KEY;
|
||||
size_t got_bits;
|
||||
|
@ -127,7 +127,7 @@ This allows the key in the key slot to be used for RSA signing.
|
|||
PSA_ALG_RSA_PKCS1V15_SIGN_RAW);
|
||||
status = psa_set_key_policy(key_slot, &policy);
|
||||
|
||||
status = psa_import_key(key_slot, PSA_KEY_TYPE_RSA_KEYPAIR,
|
||||
status = psa_import_key(key_slot, PSA_KEY_TYPE_RSA_KEY_PAIR,
|
||||
key, sizeof(key));
|
||||
|
||||
/* Sing message using the key */
|
||||
|
@ -335,7 +335,7 @@ Deriving a new AES-CTR 128-bit encryption key into a given key slot using HKDF w
|
|||
1. Set up the generator using the `psa_key_derivation` function providing a key slot containing a key that can be used for key derivation and a salt and label (Note: salt and label are optional).
|
||||
1. Initiate a key policy to for the derived key by calling `psa_key_policy_set_usage()` with `PSA_KEY_USAGE_ENCRYPT` parameter and the algorithm `PSA_ALG_CTR`.
|
||||
1. Set the key policy to the derived key slot.
|
||||
1. Import a key from generator into the desired key slot using (`psa_generator_import_key`).
|
||||
1. Import a key from generator into the desired key slot using (`psa_key_derivation_output_key`).
|
||||
1. Clean up generator.
|
||||
|
||||
At this point the derived key slot holds a new 128-bit AES-CTR encryption key derived from the key, salt and label provided:
|
||||
|
@ -358,7 +358,7 @@ At this point the derived key slot holds a new 128-bit AES-CTR encryption key de
|
|||
|
||||
psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_key_derivation_operation_t generator = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
size_t derived_bits = 128;
|
||||
size_t capacity = PSA_BITS_TO_BYTES(derived_bits);
|
||||
|
||||
|
@ -378,10 +378,10 @@ At this point the derived key slot holds a new 128-bit AES-CTR encryption key de
|
|||
|
||||
psa_set_key_policy(derived_key, &policy);
|
||||
|
||||
psa_generator_import_key(derived_key, PSA_KEY_TYPE_AES, derived_bits, &generator);
|
||||
psa_key_derivation_output_key(derived_key, PSA_KEY_TYPE_AES, derived_bits, &generator);
|
||||
|
||||
/* Clean up generator and key */
|
||||
psa_generator_abort(&generator);
|
||||
psa_key_derivation_abort(&generator);
|
||||
/* as part of clean up you may want to clean up the keys used by calling:
|
||||
* psa_destroy_key( base_key ); or psa_destroy_key( derived_key ); */
|
||||
mbedtls_psa_crypto_free();
|
||||
|
@ -510,7 +510,7 @@ Generate a piece of random 128-bit AES data:
|
|||
psa_set_key_policy(slot, &policy);
|
||||
|
||||
/* Generate a key */
|
||||
psa_generate_key(slot, PSA_KEY_TYPE_AES, bits, NULL, 0);
|
||||
psa_generate_key(slot, PSA_KEY_TYPE_AES, bits);
|
||||
|
||||
psa_export_key(slot, exported, exported_size, &exported_length)
|
||||
|
||||
|
|
|
@ -458,6 +458,12 @@
|
|||
#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \
|
||||
! ( defined(MBEDTLS_PSA_CRYPTO_C) && \
|
||||
defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) )
|
||||
#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
|
||||
! defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
|
||||
|
|
|
@ -124,14 +124,13 @@ typedef enum
|
|||
MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
|
||||
MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
|
||||
/* use raw key material internally imported */
|
||||
/* into a allocated key slot, and which */
|
||||
/* hence need to destroy that key slot */
|
||||
/* when they are no longer needed. */
|
||||
/* as a volatile key, and which hence need */
|
||||
/* to destroy that key when the context is */
|
||||
/* freed. */
|
||||
MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
|
||||
/* which use a key from a key slot */
|
||||
/* provided by the user, and which */
|
||||
/* hence should not be destroyed when */
|
||||
/* the context is no longer needed. */
|
||||
/* which use a key provided by the */
|
||||
/* user, and which hence will not be */
|
||||
/* destroyed when the context is freed. */
|
||||
} mbedtls_cipher_psa_key_ownership;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -1746,6 +1746,22 @@
|
|||
*/
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_SE_C
|
||||
*
|
||||
* Enable secure element support in the Platform Security Architecture
|
||||
* cryptography API.
|
||||
*
|
||||
* \warning This feature is not yet suitable for production. It is provided
|
||||
* for API evaluation and testing purposes only.
|
||||
*
|
||||
* Module: library/psa_crypto_se.c
|
||||
*
|
||||
* Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
*
|
||||
*/
|
||||
//#define MBEDTLS_PSA_CRYPTO_SE_C
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
*
|
||||
|
|
|
@ -217,7 +217,7 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx );
|
|||
*
|
||||
* \note For contexts that have been set up with
|
||||
* mbedtls_pk_setup_opaque(), this does not free the underlying
|
||||
* key slot and you still need to call psa_destroy_key()
|
||||
* PSA key and you still need to call psa_destroy_key()
|
||||
* independently if you want to destroy that key.
|
||||
*/
|
||||
void mbedtls_pk_free( mbedtls_pk_context *ctx );
|
||||
|
@ -259,21 +259,21 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
|
|||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/**
|
||||
* \brief Initialize a PK context to wrap a PSA key slot.
|
||||
* \brief Initialize a PK context to wrap a PSA key.
|
||||
*
|
||||
* \note This function replaces mbedtls_pk_setup() for contexts
|
||||
* that wrap a (possibly opaque) PSA key slot instead of
|
||||
* that wrap a (possibly opaque) PSA key instead of
|
||||
* storing and manipulating the key material directly.
|
||||
*
|
||||
* \param ctx The context to initialize. It must be empty (type NONE).
|
||||
* \param key The PSA key slot to wrap, which must hold an ECC key pair
|
||||
* \param key The PSA key to wrap, which must hold an ECC key pair
|
||||
* (see notes below).
|
||||
*
|
||||
* \note The wrapped key slot must remain valid as long as the
|
||||
* \note The wrapped key must remain valid as long as the
|
||||
* wrapping PK context is in use, that is at least between
|
||||
* the point this function is called and the point
|
||||
* mbedtls_pk_free() is called on this context. The wrapped
|
||||
* key slot might then be independently used or destroyed.
|
||||
* key might then be independently used or destroyed.
|
||||
*
|
||||
* \note This function is currently only available for ECC key
|
||||
* pairs (that is, ECC keys containing private key material).
|
||||
|
@ -281,7 +281,7 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
|
|||
*
|
||||
* \return \c 0 on success.
|
||||
* \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
|
||||
* (context already used, invalid key slot).
|
||||
* (context already used, invalid key handle).
|
||||
* \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
|
||||
* ECC key pair.
|
||||
* \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
|
||||
|
@ -788,7 +788,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
|
|||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
/**
|
||||
* \brief Turn an EC key into an Opaque one
|
||||
* \brief Turn an EC key into an opaque one.
|
||||
*
|
||||
* \warning This is a temporary utility function for tests. It might
|
||||
* change or be removed at any time without notice.
|
||||
|
@ -796,18 +796,19 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
|
|||
* \note Only ECDSA keys are supported so far. Signing with the
|
||||
* specified hash is the only allowed use of that key.
|
||||
*
|
||||
* \param pk Input: the EC key to transfer to a PSA key slot.
|
||||
* Output: a PK context wrapping that PSA key slot.
|
||||
* \param slot Output: the chosen slot for storing the key.
|
||||
* It's the caller's responsibility to destroy that slot
|
||||
* after calling mbedtls_pk_free() on the PK context.
|
||||
* \param pk Input: the EC key to import to a PSA key.
|
||||
* Output: a PK context wrapping that PSA key.
|
||||
* \param handle Output: a PSA key handle.
|
||||
* It's the caller's responsibility to call
|
||||
* psa_destroy_key() on that handle after calling
|
||||
* mbedtls_pk_free() on the PK context.
|
||||
* \param hash_alg The hash algorithm to allow for use with that key.
|
||||
*
|
||||
* \return \c 0 if successful.
|
||||
* \return An Mbed TLS error code otherwise.
|
||||
*/
|
||||
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||
psa_key_handle_t *slot,
|
||||
psa_key_handle_t *handle,
|
||||
psa_algorithm_t hash_alg );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
|
|
|
@ -413,7 +413,7 @@ static inline int mbedtls_psa_err_translate_pk( psa_status_t status )
|
|||
/* All other failures */
|
||||
case PSA_ERROR_COMMUNICATION_FAILURE:
|
||||
case PSA_ERROR_HARDWARE_FAILURE:
|
||||
case PSA_ERROR_TAMPERING_DETECTED:
|
||||
case PSA_ERROR_CORRUPTION_DETECTED:
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
default: /* We return the same as for the 'other failures',
|
||||
* but list them separately nonetheless to indicate
|
||||
|
|
2253
include/psa/crypto.h
2253
include/psa/crypto.h
File diff suppressed because it is too large
Load diff
|
@ -62,21 +62,19 @@ extern "C" {
|
|||
MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( PSA_ERROR_INSUFFICIENT_DATA )
|
||||
#endif
|
||||
|
||||
/** \addtogroup policy
|
||||
/** \addtogroup attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Set the enrollment algorithm in a key policy.
|
||||
/** \brief Declare the enrollment algorithm for a key.
|
||||
*
|
||||
* An operation on a key may indifferently use the algorithm set with
|
||||
* psa_key_policy_set_usage() or with this function.
|
||||
* psa_set_key_algorithm() or with this function.
|
||||
*
|
||||
* \param[in,out] policy The key policy to modify. It must have been
|
||||
* initialized as per the documentation for
|
||||
* #psa_key_policy_t.
|
||||
* \param alg2 A second algorithm that the key may be used for,
|
||||
* in addition to the algorithm set with
|
||||
* psa_key_policy_set_usage().
|
||||
* \param[out] attributes The attribute structure to write to.
|
||||
* \param alg2 A second algorithm that the key may be used
|
||||
* for, in addition to the algorithm set with
|
||||
* psa_set_key_algorithm().
|
||||
*
|
||||
* \warning Setting an enrollment algorithm is not recommended, because
|
||||
* using the same key with different algorithms can allow some
|
||||
|
@ -87,17 +85,24 @@ extern "C" {
|
|||
* verified that the usage of the key with multiple algorithms
|
||||
* is safe.
|
||||
*/
|
||||
void psa_key_policy_set_enrollment_algorithm(psa_key_policy_t *policy,
|
||||
psa_algorithm_t alg2);
|
||||
static inline void psa_set_key_enrollment_algorithm(
|
||||
psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg2)
|
||||
{
|
||||
attributes->core.policy.alg2 = alg2;
|
||||
}
|
||||
|
||||
/** \brief Retrieve the enrollment algorithm field of a policy structure.
|
||||
/** Retrieve the enrollment algorithm policy from key attributes.
|
||||
*
|
||||
* \param[in] policy The policy object to query.
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
*
|
||||
* \return The enrollment algorithm for a key with this policy.
|
||||
* \return The enrollment algorithm stored in the attribute structure.
|
||||
*/
|
||||
psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
|
||||
const psa_key_policy_t *policy);
|
||||
static inline psa_algorithm_t psa_get_key_enrollment_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.alg2 );
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
@ -111,6 +116,43 @@ psa_algorithm_t psa_key_policy_get_enrollment_algorithm(
|
|||
*/
|
||||
void mbedtls_psa_crypto_free( void );
|
||||
|
||||
/** \brief Statistics about
|
||||
* resource consumption related to the PSA keystore.
|
||||
*
|
||||
* \note The content of this structure is not part of the stable API and ABI
|
||||
* of Mbed Crypto and may change arbitrarily from version to version.
|
||||
*/
|
||||
typedef struct mbedtls_psa_stats_s
|
||||
{
|
||||
/** Number of slots containing key material for a volatile key. */
|
||||
size_t volatile_slots;
|
||||
/** Number of slots containing key material for a key which is in
|
||||
* internal persistent storage. */
|
||||
size_t persistent_slots;
|
||||
/** Number of slots containing a reference to a key in a
|
||||
* secure element. */
|
||||
size_t external_slots;
|
||||
/** Number of slots which are occupied, but do not contain
|
||||
* key material yet. */
|
||||
size_t half_filled_slots;
|
||||
/** Number of slots that contain cache data. */
|
||||
size_t cache_slots;
|
||||
/** Number of slots that are not used for anything. */
|
||||
size_t empty_slots;
|
||||
/** Largest key id value among open keys in internal persistent storage. */
|
||||
psa_key_id_t max_open_internal_key_id;
|
||||
/** Largest key id value among open keys in secure elements. */
|
||||
psa_key_id_t max_open_external_key_id;
|
||||
} mbedtls_psa_stats_t;
|
||||
|
||||
/** \brief Get statistics about
|
||||
* resource consumption related to the PSA keystore.
|
||||
*
|
||||
* \note When Mbed Crypto is built as part of a service, with isolation
|
||||
* between the application and the keystore, the service may or
|
||||
* may not expose this function.
|
||||
*/
|
||||
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats );
|
||||
|
||||
/**
|
||||
* \brief Inject an initial entropy seed for the random generator into
|
||||
|
@ -179,9 +221,308 @@ void mbedtls_psa_crypto_free( void );
|
|||
* The library has already been initialized. It is no longer
|
||||
* possible to call this function.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_inject_entropy(const unsigned char *seed,
|
||||
psa_status_t mbedtls_psa_inject_entropy(uint8_t *seed,
|
||||
size_t seed_size);
|
||||
|
||||
#if defined(PSA_PRE_1_0_KEY_DERIVATION)
|
||||
/** Set up a key derivation operation.
|
||||
*
|
||||
* FIMXE This function is no longer part of the official API. Its prototype
|
||||
* is only kept around for the sake of tests that haven't been updated yet.
|
||||
*
|
||||
* A key derivation algorithm takes three inputs: a secret input \p handle and
|
||||
* two non-secret inputs \p label and p salt.
|
||||
* The result of this function is a byte generator which can
|
||||
* be used to produce keys and other cryptographic material.
|
||||
*
|
||||
* The role of \p label and \p salt is as follows:
|
||||
* - For HKDF (#PSA_ALG_HKDF), \p salt is the salt used in the "extract" step
|
||||
* and \p label is the info string used in the "expand" step.
|
||||
*
|
||||
* \param[in,out] operation The key derivation object to set up. It must
|
||||
* have been initialized as per the documentation
|
||||
* for #psa_key_derivation_operation_t and not
|
||||
* yet be in 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).
|
||||
* \param[in] salt Salt to use.
|
||||
* \param salt_length Size of the \p salt buffer in bytes.
|
||||
* \param[in] label Label to use.
|
||||
* \param label_length Size of the \p label buffer in bytes.
|
||||
* \param capacity The maximum number of bytes that the
|
||||
* operation will be able to provide.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \retval #PSA_ERROR_INVALID_HANDLE
|
||||
* \retval #PSA_ERROR_EMPTY_SLOT
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \c key is not compatible with \c alg,
|
||||
* or \p capacity is too large for the specified algorithm and key.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \c alg is not supported or is not a key derivation algorithm.
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
* The library has not been previously initialized by psa_crypto_init().
|
||||
* It is implementation-dependent whether a failure to initialize
|
||||
* results in this error code.
|
||||
*/
|
||||
psa_status_t psa_key_derivation(psa_key_derivation_operation_t *operation,
|
||||
psa_key_handle_t handle,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *salt,
|
||||
size_t salt_length,
|
||||
const uint8_t *label,
|
||||
size_t label_length,
|
||||
size_t capacity);
|
||||
#endif /* PSA_PRE_1_0_KEY_DERIVATION */
|
||||
|
||||
/** \addtogroup crypto_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** DSA public key.
|
||||
*
|
||||
* The import and export format is the
|
||||
* representation of the public key `y = g^x mod p` as a big-endian byte
|
||||
* string. The length of the byte string is the length of the base prime `p`
|
||||
* in bytes.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
|
||||
|
||||
/** DSA key pair (private and public key).
|
||||
*
|
||||
* The import and export format is the
|
||||
* representation of the private key `x` as a big-endian byte string. The
|
||||
* length of the byte string is the private key size in bytes (leading zeroes
|
||||
* are not stripped).
|
||||
*
|
||||
* Determinstic DSA key derivation with psa_generate_derived_key follows
|
||||
* FIPS 186-4 §B.1.2: interpret the byte string as integer
|
||||
* in big-endian order. Discard it if it is not in the range
|
||||
* [0, *N* - 2] where *N* is the boundary of the private key domain
|
||||
* (the prime *p* for Diffie-Hellman, the subprime *q* for DSA,
|
||||
* or the order of the curve's base point for ECC).
|
||||
* Add 1 to the resulting integer and use this as the private key *x*.
|
||||
*
|
||||
*/
|
||||
#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t)0x70020000)
|
||||
|
||||
/** Whether a key type is an DSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
|
||||
|
||||
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
|
||||
/** DSA signature with hashing.
|
||||
*
|
||||
* This is the signature scheme defined by FIPS 186-4,
|
||||
* with a random per-message secret number (*k*).
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DSA(hash_alg) \
|
||||
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
|
||||
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
|
||||
/** Deterministic DSA signature with hashing.
|
||||
*
|
||||
* This is the deterministic variant defined by RFC 6979 of
|
||||
* the signature scheme defined by FIPS 186-4.
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
|
||||
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_IS_DSA(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
|
||||
PSA_ALG_DSA_BASE)
|
||||
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
|
||||
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
|
||||
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
|
||||
|
||||
/* We need to expand the sample definition of this macro from
|
||||
* the API definition. */
|
||||
#undef PSA_ALG_IS_HASH_AND_SIGN
|
||||
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
|
||||
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
|
||||
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \addtogroup attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Custom Diffie-Hellman group.
|
||||
*
|
||||
* For keys of type #PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM), the group data comes
|
||||
* from domain parameters set by psa_set_key_domain_parameters().
|
||||
*/
|
||||
/* This value is reserved for private use in the TLS named group registry. */
|
||||
#define PSA_DH_GROUP_CUSTOM ((psa_dh_group_t) 0x01fc)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set domain parameters for a key.
|
||||
*
|
||||
* Some key types require additional domain parameters in addition to
|
||||
* the key type identifier and the key size. Use this function instead
|
||||
* of psa_set_key_type() when you need to specify domain parameters.
|
||||
*
|
||||
* The format for the required domain parameters varies based on the key type.
|
||||
*
|
||||
* - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEY_PAIR),
|
||||
* the domain parameter data consists of the public exponent,
|
||||
* represented as a big-endian integer with no leading zeros.
|
||||
* This information is used when generating an RSA key pair.
|
||||
* When importing a key, the public exponent is read from the imported
|
||||
* key data and the exponent recorded in the attribute structure is ignored.
|
||||
* As an exception, the public exponent 65537 is represented by an empty
|
||||
* byte string.
|
||||
* - For DSA keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY or #PSA_KEY_TYPE_DSA_KEY_PAIR),
|
||||
* the `Dss-Parms` format as defined by RFC 3279 §2.3.2.
|
||||
* ```
|
||||
* Dss-Parms ::= SEQUENCE {
|
||||
* p INTEGER,
|
||||
* q INTEGER,
|
||||
* g INTEGER
|
||||
* }
|
||||
* ```
|
||||
* - For Diffie-Hellman key exchange keys
|
||||
* (#PSA_KEY_TYPE_DH_PUBLIC_KEY(#PSA_DH_GROUP_CUSTOM) or
|
||||
* #PSA_KEY_TYPE_DH_KEY_PAIR(#PSA_DH_GROUP_CUSTOM)), the
|
||||
* `DomainParameters` format as defined by RFC 3279 §2.3.3.
|
||||
* ```
|
||||
* DomainParameters ::= SEQUENCE {
|
||||
* p INTEGER, -- odd prime, p=jq +1
|
||||
* g INTEGER, -- generator, g
|
||||
* q INTEGER, -- factor of p-1
|
||||
* j INTEGER OPTIONAL, -- subgroup factor
|
||||
* validationParms ValidationParms OPTIONAL
|
||||
* }
|
||||
* ValidationParms ::= SEQUENCE {
|
||||
* seed BIT STRING,
|
||||
* pgenCounter INTEGER
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* \note This function may allocate memory or other resources.
|
||||
* Once you have called this function on an attribute structure,
|
||||
* you must call psa_reset_key_attributes() to free these resources.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param[in,out] attributes Attribute structure where the specified domain
|
||||
* parameters will be stored.
|
||||
* If this function fails, the content of
|
||||
* \p attributes is not modified.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[in] data Buffer containing the key domain parameters.
|
||||
* The content of this buffer is interpreted
|
||||
* according to \p type as described above.
|
||||
* \param data_length Size of the \p data buffer in bytes.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
*/
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
/**
|
||||
* \brief Get domain parameters for a key.
|
||||
*
|
||||
* Get the domain parameters for a key with this function, if any. The format
|
||||
* of the domain parameters written to \p data is specified in the
|
||||
* documentation for psa_set_key_domain_parameters().
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param[in] attributes The key attribute structure to query.
|
||||
* \param[out] data On success, the key domain parameters.
|
||||
* \param data_size Size of the \p data buffer in bytes.
|
||||
* The buffer is guaranteed to be large
|
||||
* enough if its size in bytes is at least
|
||||
* the value given by
|
||||
* PSA_KEY_DOMAIN_PARAMETERS_SIZE().
|
||||
* \param[out] data_length On success, the number of bytes
|
||||
* that make up the key domain parameters data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||
*/
|
||||
psa_status_t psa_get_key_domain_parameters(
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/** Safe output buffer size for psa_get_key_domain_parameters().
|
||||
*
|
||||
* This macro returns a compile-time constant if its arguments are
|
||||
* compile-time constants.
|
||||
*
|
||||
* \warning This function may call its arguments multiple times or
|
||||
* zero times, so you should not pass arguments that contain
|
||||
* side effects.
|
||||
*
|
||||
* \note This is an experimental extension to the interface. It may change
|
||||
* in future versions of the library.
|
||||
*
|
||||
* \param key_type A supported key type.
|
||||
* \param key_bits The size of the key in bits.
|
||||
*
|
||||
* \return If the parameters are valid and supported, return
|
||||
* a buffer size in bytes that guarantees that
|
||||
* psa_get_key_domain_parameters() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
*/
|
||||
#define PSA_KEY_DOMAIN_PARAMETERS_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_RSA(key_type) ? sizeof(int) : \
|
||||
PSA_KEY_TYPE_IS_DH(key_type) ? PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_DSA(key_type) ? PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) : \
|
||||
0)
|
||||
#define PSA_DH_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 3 /*without optional parts*/)
|
||||
#define PSA_DSA_KEY_DOMAIN_PARAMETERS_SIZE(key_bits) \
|
||||
(4 + (PSA_BITS_TO_BYTES(key_bits) + 5) * 2 /*p, g*/ + 34 /*q*/)
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
* space in which the PSA Crypto implementation runs, typically secure
|
||||
* elements (SEs).
|
||||
*
|
||||
* This file is part of the PSA Crypto Driver Model, containing functions for
|
||||
* driver developers to implement to enable hardware to be called in a
|
||||
* standardized way by a PSA Cryptographic API implementation. The functions
|
||||
* comprising the driver model, which driver authors implement, are not
|
||||
* intended to be called by application developers.
|
||||
* This file is part of the PSA Crypto Driver HAL (hardware abstraction layer),
|
||||
* containing functions for driver developers to implement to enable hardware
|
||||
* to be called in a standardized way by a PSA Cryptography API
|
||||
* implementation. The functions comprising the driver HAL, which driver
|
||||
* authors implement, are not intended to be called by application developers.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -40,10 +40,106 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup se_init Secure element driver initialization
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/** \brief Driver context structure
|
||||
*
|
||||
* Driver functions receive a pointer to this structure.
|
||||
* Each registered driver has one instance of this structure.
|
||||
*
|
||||
* Implementations must include the fields specified here and
|
||||
* may include other fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/** A read-only pointer to the driver's persistent data.
|
||||
*
|
||||
* Drivers typically use this persistent data to keep track of
|
||||
* which slot numbers are available. This is only a guideline:
|
||||
* drivers may use the persistent data for any purpose, keeping
|
||||
* in mind the restrictions on when the persistent data is saved
|
||||
* to storage: the persistent data is only saved after calling
|
||||
* certain functions that receive a writable pointer to the
|
||||
* persistent data.
|
||||
*
|
||||
* The core allocates a memory buffer for the persistent data.
|
||||
* The pointer is guaranteed to be suitably aligned for any data type,
|
||||
* like a pointer returned by `malloc` (but the core can use any
|
||||
* method to allocate the buffer, not necessarily `malloc`).
|
||||
*
|
||||
* The size of this buffer is in the \c persistent_data_size field of
|
||||
* this structure.
|
||||
*
|
||||
* Before the driver is initialized for the first time, the content of
|
||||
* the persistent data is all-bits-zero. After a driver upgrade, if the
|
||||
* size of the persistent data has increased, the original data is padded
|
||||
* on the right with zeros; if the size has decreased, the original data
|
||||
* is truncated to the new size.
|
||||
*
|
||||
* This pointer is to read-only data. Only a few driver functions are
|
||||
* allowed to modify the persistent data. These functions receive a
|
||||
* writable pointer. These functions are:
|
||||
* - psa_drv_se_t::p_init
|
||||
* - psa_drv_se_key_management_t::p_allocate
|
||||
* - psa_drv_se_key_management_t::p_destroy
|
||||
*
|
||||
* The PSA Cryptography core saves the persistent data from one
|
||||
* session to the next. It does this before returning from API functions
|
||||
* that call a driver method that is allowed to modify the persistent
|
||||
* data, specifically:
|
||||
* - psa_crypto_init() causes a call to psa_drv_se_t::p_init, and may call
|
||||
* psa_drv_se_key_management_t::p_destroy to complete an action
|
||||
* that was interrupted by a power failure.
|
||||
* - Key creation functions cause a call to
|
||||
* psa_drv_se_key_management_t::p_allocate, and may cause a call to
|
||||
* psa_drv_se_key_management_t::p_destroy in case an error occurs.
|
||||
* - psa_destroy_key() causes a call to
|
||||
* psa_drv_se_key_management_t::p_destroy.
|
||||
*/
|
||||
const void *const persistent_data;
|
||||
|
||||
/** The size of \c persistent_data in bytes.
|
||||
*
|
||||
* This is always equal to the value of the `persistent_data_size` field
|
||||
* of the ::psa_drv_se_t structure when the driver is registered.
|
||||
*/
|
||||
const size_t persistent_data_size;
|
||||
|
||||
/** Driver transient data.
|
||||
*
|
||||
* The core initializes this value to 0 and does not read or modify it
|
||||
* afterwards. The driver may store whatever it wants in this field.
|
||||
*/
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_context_t;
|
||||
|
||||
/** \brief A driver initialization function.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param lifetime The lifetime value for which this driver
|
||||
* is registered.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The driver is operational.
|
||||
* The core will update the persistent data in storage.
|
||||
* \return
|
||||
* Any other return value prevents the driver from being used in
|
||||
* this session.
|
||||
* The core will NOT update the persistent data in storage.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_init_t)(psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
psa_key_lifetime_t lifetime);
|
||||
|
||||
/** An internal designation of a key slot between the core part of the
|
||||
* PSA Crypto implementation and the driver. The meaning of this value
|
||||
* is driver-dependent. */
|
||||
typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after psa_key_slot_t is removed from Mbed crypto
|
||||
typedef uint64_t psa_key_slot_number_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup se_mac Secure Element Message Authentication Codes
|
||||
* Generation and authentication of Message Authentication Codes (MACs) using
|
||||
|
@ -65,7 +161,8 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
|
|||
/** \brief A function that starts a secure element MAC operation for a PSA
|
||||
* Crypto Driver implementation
|
||||
*
|
||||
* \param[in,out] p_context A structure that will contain the
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A structure that will contain the
|
||||
* hardware-specific MAC context
|
||||
* \param[in] key_slot The slot of the key to be used for the
|
||||
* operation
|
||||
|
@ -75,28 +172,29 @@ typedef uint32_t psa_key_slot_number_t; // Change this to psa_key_slot_t after p
|
|||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm);
|
||||
|
||||
/** \brief A function that continues a previously started secure element MAC
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously-established MAC operation to be
|
||||
* updated
|
||||
* \param[in] p_input A buffer containing the message to be appended
|
||||
* to the MAC operation
|
||||
* \param[in] input_length The size in bytes of the input message buffer
|
||||
* \param[in] input_length The size in bytes of the input message buffer
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_update_t)(void *op_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length);
|
||||
|
||||
/** \brief a function that completes a previously started secure element MAC
|
||||
* operation by returning the resulting MAC.
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started MAC operation to be
|
||||
* finished
|
||||
* \param[out] p_mac A buffer where the generated MAC will be
|
||||
|
@ -109,7 +207,7 @@ typedef psa_status_t (*psa_drv_se_mac_update_t)(void *p_context,
|
|||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *op_context,
|
||||
uint8_t *p_mac,
|
||||
size_t mac_size,
|
||||
size_t *p_mac_length);
|
||||
|
@ -117,11 +215,11 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
|||
/** \brief A function that completes a previously started secure element MAC
|
||||
* operation by comparing the resulting MAC against a provided value
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be fiinished
|
||||
* \param[in] p_mac The MAC value against which the resulting MAC will
|
||||
* be compared against
|
||||
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
|
||||
* \param[in,out] op_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be fiinished
|
||||
* \param[in] p_mac The MAC value against which the resulting MAC
|
||||
* will be compared against
|
||||
* \param[in] mac_length The size in bytes of the value stored in `p_mac`
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* The operation completed successfully and the MACs matched each
|
||||
|
@ -130,21 +228,22 @@ typedef psa_status_t (*psa_drv_se_mac_finish_t)(void *p_context,
|
|||
* The operation completed successfully, but the calculated MAC did
|
||||
* not match the provided MAC
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_mac_finish_verify_t)(void *op_context,
|
||||
const uint8_t *p_mac,
|
||||
size_t mac_length);
|
||||
|
||||
/** \brief A function that aborts a previous started secure element MAC
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be aborted
|
||||
* \param[in,out] op_context A hardware-specific structure for the previously
|
||||
* started MAC operation to be aborted
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
|
||||
typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *op_context);
|
||||
|
||||
/** \brief A function that performs a secure element MAC operation in one
|
||||
* command and returns the calculated MAC
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] p_input A buffer containing the message to be MACed
|
||||
* \param[in] input_length The size in bytes of `p_input`
|
||||
* \param[in] key_slot The slot of the key to be used
|
||||
|
@ -159,7 +258,8 @@ typedef psa_status_t (*psa_drv_se_mac_abort_t)(void *p_context);
|
|||
* \retval PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
||||
typedef psa_status_t (*psa_drv_se_mac_generate_t)(psa_drv_se_context_t *drv_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
|
@ -170,6 +270,7 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
|||
/** \brief A function that performs a secure element MAC operation in one
|
||||
* command and compares the resulting MAC against a provided value
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] p_input A buffer containing the message to be MACed
|
||||
* \param[in] input_length The size in bytes of `input`
|
||||
* \param[in] key_slot The slot of the key to be used
|
||||
|
@ -186,7 +287,8 @@ typedef psa_status_t (*psa_drv_se_mac_generate_t)(const uint8_t *p_input,
|
|||
* The operation completed successfully, but the calculated MAC did
|
||||
* not match the provided MAC
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_mac_verify_t)(const uint8_t *p_input,
|
||||
typedef psa_status_t (*psa_drv_se_mac_verify_t)(psa_drv_se_context_t *drv_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
|
@ -263,7 +365,8 @@ typedef struct {
|
|||
/** \brief A function that provides the cipher setup function for a
|
||||
* secure element driver
|
||||
*
|
||||
* \param[in,out] p_context A structure that will contain the
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A structure that will contain the
|
||||
* hardware-specific cipher context.
|
||||
* \param[in] key_slot The slot of the key to be used for the
|
||||
* operation
|
||||
|
@ -275,7 +378,8 @@ typedef struct {
|
|||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction);
|
||||
|
@ -288,21 +392,21 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(void *p_context,
|
|||
* generate function is not necessary for the drivers to implement as the PSA
|
||||
* Crypto implementation can do the generation using its RNG features.
|
||||
*
|
||||
* \param[in,out] p_context A structure that contains the previously set up
|
||||
* \param[in,out] op_context A structure that contains the previously set up
|
||||
* hardware-specific cipher context
|
||||
* \param[in] p_iv A buffer containing the initialization vector
|
||||
* \param[in] iv_length The size (in bytes) of the `p_iv` buffer
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context,
|
||||
const uint8_t *p_iv,
|
||||
size_t iv_length);
|
||||
|
||||
/** \brief A function that continues a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
|
@ -317,7 +421,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *p_context,
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_size,
|
||||
uint8_t *p_output,
|
||||
|
@ -327,7 +431,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
|||
/** \brief A function that completes a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
* \param[out] p_output The caller-allocated buffer where the output
|
||||
* will be placed
|
||||
|
@ -338,7 +442,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *p_context,
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length);
|
||||
|
@ -346,10 +450,10 @@ typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *p_context,
|
|||
/** \brief A function that aborts a previously started secure element cipher
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure for the
|
||||
* \param[in,out] op_context A hardware-specific structure for the
|
||||
* previously started cipher operation
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
|
||||
typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context);
|
||||
|
||||
/** \brief A function that performs the ECB block mode for secure element
|
||||
* cipher operations
|
||||
|
@ -357,23 +461,25 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *p_context);
|
|||
* Note: this function should only be used with implementations that do not
|
||||
* provide a needed higher-level operation.
|
||||
*
|
||||
* \param[in] key_slot The slot of the key to be used for the operation
|
||||
* \param[in] algorithm The algorithm to be used in the cipher operation
|
||||
* \param[in] direction Indicates whether the operation is an encrypt or
|
||||
* decrypt
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
* \param[in] input_size The size in bytes of the buffer pointed to by
|
||||
* `p_input`
|
||||
* \param[out] p_output The caller-allocated buffer where the output will
|
||||
* be placed
|
||||
* \param[in] output_size The allocated size in bytes of the `p_output`
|
||||
* buffer
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot The slot of the key to be used for the operation
|
||||
* \param[in] algorithm The algorithm to be used in the cipher operation
|
||||
* \param[in] direction Indicates whether the operation is an encrypt or
|
||||
* decrypt
|
||||
* \param[in] p_input A buffer containing the data to be
|
||||
* encrypted/decrypted
|
||||
* \param[in] input_size The size in bytes of the buffer pointed to by
|
||||
* `p_input`
|
||||
* \param[out] p_output The caller-allocated buffer where the output
|
||||
* will be placed
|
||||
* \param[in] output_size The allocated size in bytes of the `p_output`
|
||||
* buffer
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction,
|
||||
const uint8_t *p_input,
|
||||
|
@ -427,6 +533,7 @@ typedef struct {
|
|||
* \brief A function that signs a hash or short message with a private key in
|
||||
* a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of an asymmetric key pair
|
||||
* \param[in] alg A signature algorithm that is compatible
|
||||
* with the type of `key`
|
||||
|
@ -439,7 +546,8 @@ typedef struct {
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
|
@ -451,6 +559,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
|
|||
* \brief A function that verifies the signature a hash or short message using
|
||||
* an asymmetric public key in a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of a public key or an asymmetric key
|
||||
* pair
|
||||
* \param[in] alg A signature algorithm that is compatible with
|
||||
|
@ -463,7 +572,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_key_slot_number_t key_s
|
|||
* \retval PSA_SUCCESS
|
||||
* The signature is valid.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
|
@ -474,6 +584,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
|
|||
* \brief A function that encrypts a short message with an asymmetric public
|
||||
* key in a secure element
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of a public key or an asymmetric key
|
||||
* pair
|
||||
* \param[in] alg An asymmetric encryption algorithm that is
|
||||
|
@ -499,7 +610,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_key_slot_number_t key
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
|
@ -513,6 +625,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
|
|||
* \brief A function that decrypts a short message with an asymmetric private
|
||||
* key in a secure element.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Key slot of an asymmetric key pair
|
||||
* \param[in] alg An asymmetric encryption algorithm that is
|
||||
* compatible with the type of `key`
|
||||
|
@ -537,7 +650,8 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_key_slot_number_t ke
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
|
@ -581,6 +695,7 @@ typedef struct {
|
|||
/** \brief A function that performs a secure element authenticated encryption
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot containing the key to use.
|
||||
* \param[in] algorithm The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
|
@ -608,7 +723,8 @@ typedef struct {
|
|||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
const uint8_t *p_nonce,
|
||||
size_t nonce_length,
|
||||
|
@ -622,6 +738,7 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
|
|||
|
||||
/** A function that peforms a secure element authenticated decryption operation
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot containing the key to use
|
||||
* \param[in] algorithm The AEAD algorithm to compute
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
|
@ -648,7 +765,8 @@ typedef psa_status_t (*psa_drv_se_aead_encrypt_t)(psa_key_slot_number_t key_slot
|
|||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_aead_decrypt_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
const uint8_t *p_nonce,
|
||||
size_t nonce_length,
|
||||
|
@ -685,31 +803,61 @@ typedef struct {
|
|||
*/
|
||||
/**@{*/
|
||||
|
||||
/** \brief A function that allocates a slot for a key.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param[in] attributes Attributes of the key.
|
||||
* \param[out] key_slot Slot where the key will be stored.
|
||||
* This must be a valid slot for a key of the
|
||||
* chosen type. It must be unoccupied.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* The core will record \c *key_slot as the key slot where the key
|
||||
* is stored and will update the persistent data in storage.
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_allocate_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t *key_slot);
|
||||
|
||||
/** \brief A function that imports a key into a secure element in binary format
|
||||
*
|
||||
* This function can support any output from psa_export_key(). Refer to the
|
||||
* documentation of psa_export_key() for the format for each key type.
|
||||
*
|
||||
* \param[in] key_slot Slot where the key will be stored
|
||||
* This must be a valid slot for a key of the chosen
|
||||
* type. It must be unoccupied.
|
||||
* \param[in] lifetime The required lifetime of the key storage
|
||||
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
|
||||
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
|
||||
* \param[in] usage The allowed uses of the key
|
||||
* \param[in] p_data Buffer containing the key data
|
||||
* \param[in] data_length Size of the `data` buffer in bytes
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot where the key will be stored
|
||||
* This must be a valid slot for a key of the
|
||||
* chosen type. It must be unoccupied.
|
||||
* \param[in] lifetime The required lifetime of the key storage
|
||||
* \param[in] type Key type (a \c PSA_KEY_TYPE_XXX value)
|
||||
* \param[in] algorithm Key algorithm (a \c PSA_ALG_XXX value)
|
||||
* \param[in] usage The allowed uses of the key
|
||||
* \param[in] p_data Buffer containing the key data
|
||||
* \param[in] data_length Size of the `data` buffer in bytes
|
||||
* \param[out] bits On success, the key size in bits. The driver
|
||||
* must determine this value after parsing the
|
||||
* key according to the key type.
|
||||
* This value is not used if the function fails.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_import_key_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_type_t type,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_usage_t usage,
|
||||
const uint8_t *p_data,
|
||||
size_t data_length);
|
||||
size_t data_length,
|
||||
size_t *bits);
|
||||
|
||||
/**
|
||||
* \brief A function that destroys a secure element key and restore the slot to
|
||||
|
@ -721,12 +869,18 @@ typedef psa_status_t (*psa_drv_se_import_key_t)(psa_key_slot_number_t key_slot,
|
|||
*
|
||||
* This function returns the specified slot to its default state.
|
||||
*
|
||||
* \param[in] key_slot The key slot to erase.
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] persistent_data A pointer to the persistent data
|
||||
* that allows writing.
|
||||
* \param key_slot The key slot to erase.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The slot's content, if any, has been erased.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
||||
typedef psa_status_t (*psa_drv_se_destroy_key_t)(
|
||||
psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
psa_key_slot_number_t key_slot);
|
||||
|
||||
/**
|
||||
* \brief A function that exports a secure element key in binary format
|
||||
|
@ -743,6 +897,7 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
|||
* `psa_export_key()` does. Refer to the
|
||||
* documentation of `psa_export_key()` for the format for each key type.
|
||||
*
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key Slot whose content is to be exported. This must
|
||||
* be an occupied key slot.
|
||||
* \param[out] p_data Buffer where the key data is to be written.
|
||||
|
@ -756,9 +911,10 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)(psa_key_slot_number_t key);
|
|||
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE
|
||||
* \retval #PSA_ERROR_HARDWARE_FAILURE
|
||||
* \retval #PSA_ERROR_TAMPERING_DETECTED
|
||||
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
|
||||
typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key,
|
||||
uint8_t *p_data,
|
||||
size_t data_size,
|
||||
size_t *p_data_length);
|
||||
|
@ -767,31 +923,34 @@ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_key_slot_number_t key,
|
|||
* \brief A function that generates a symmetric or asymmetric key on a secure
|
||||
* element
|
||||
*
|
||||
* If \p type is asymmetric (`#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) == 1`),
|
||||
* If \p type is asymmetric (#PSA_KEY_TYPE_IS_ASYMMETRIC(\p type) = 1),
|
||||
* the public component of the generated key will be placed in `p_pubkey_out`.
|
||||
* The format of the public key information will match the format specified for
|
||||
* the psa_export_key() function for the key type.
|
||||
*
|
||||
* \param[in] key_slot Slot where the generated key will be placed
|
||||
* \param[in] type The type of the key to be generated
|
||||
* \param[in] usage The prescribed usage of the generated key
|
||||
* Note: Not all Secure Elements support the same
|
||||
* restrictions that PSA Crypto does (and vice versa).
|
||||
* Driver developers should endeavor to match the
|
||||
* usages as close as possible.
|
||||
* \param[in] bits The size in bits of the key to be generated.
|
||||
* \param[in] extra Extra parameters for key generation. The
|
||||
* interpretation of this parameter should match the
|
||||
* interpretation in the `extra` parameter is the
|
||||
* `psa_generate_key` function
|
||||
* \param[in] extra_size The size in bytes of the \p extra buffer
|
||||
* \param[out] p_pubkey_out The buffer where the public key information will
|
||||
* be placed
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in] key_slot Slot where the generated key will be placed
|
||||
* \param[in] type The type of the key to be generated
|
||||
* \param[in] usage The prescribed usage of the generated key
|
||||
* Note: Not all Secure Elements support the same
|
||||
* restrictions that PSA Crypto does (and vice
|
||||
* versa).
|
||||
* Driver developers should endeavor to match the
|
||||
* usages as close as possible.
|
||||
* \param[in] bits The size in bits of the key to be generated.
|
||||
* \param[in] extra Extra parameters for key generation. The
|
||||
* interpretation of this parameter should match
|
||||
* the interpretation in the `extra` parameter is
|
||||
* the `psa_generate_key` function
|
||||
* \param[in] extra_size The size in bytes of the \p extra buffer
|
||||
* \param[out] p_pubkey_out The buffer where the public key information will
|
||||
* be placed
|
||||
* \param[in] pubkey_out_size The size in bytes of the `p_pubkey_out` buffer
|
||||
* \param[out] p_pubkey_length Upon successful completion, will contain the
|
||||
* size of the data placed in `p_pubkey_out`.
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot,
|
||||
typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_key_type_t type,
|
||||
psa_key_usage_t usage,
|
||||
size_t bits,
|
||||
|
@ -811,6 +970,8 @@ typedef psa_status_t (*psa_drv_se_generate_key_t)(psa_key_slot_number_t key_slot
|
|||
* If one of the functions is not implemented, it should be set to NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Function that allocates a slot. */
|
||||
psa_drv_se_allocate_key_t p_allocate;
|
||||
/** Function that performs a key import operation */
|
||||
psa_drv_se_import_key_t p_import;
|
||||
/** Function that performs a generation */
|
||||
|
@ -819,6 +980,8 @@ typedef struct {
|
|||
psa_drv_se_destroy_key_t p_destroy;
|
||||
/** Function that performs a key export operation */
|
||||
psa_drv_se_export_key_t p_export;
|
||||
/** Function that performs a public key export operation */
|
||||
psa_drv_se_export_key_t p_export_public;
|
||||
} psa_drv_se_key_management_t;
|
||||
|
||||
/**@}*/
|
||||
|
@ -875,15 +1038,17 @@ typedef struct {
|
|||
/** \brief A function that Sets up a secure element key derivation operation by
|
||||
* specifying the algorithm and the source key sot
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] kdf_alg The algorithm to be used for the key derivation
|
||||
* \param[in] souce_key The key to be used as the source material for the
|
||||
* key derivation
|
||||
* \param[in,out] drv_context The driver context structure.
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] kdf_alg The algorithm to be used for the key derivation
|
||||
* \param[in] source_key The key to be used as the source material for
|
||||
* the key derivation
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_algorithm_t kdf_alg,
|
||||
psa_key_slot_number_t source_key);
|
||||
|
||||
|
@ -894,7 +1059,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
|||
* expeced that this function may be called multiple times for the same
|
||||
* operation, each with a different algorithm-specific `collateral_id`
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] collateral_id An ID for the collateral being provided
|
||||
* \param[in] p_collateral A buffer containing the collateral data
|
||||
|
@ -902,7 +1067,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(void *p_context,
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context,
|
||||
uint32_t collateral_id,
|
||||
const uint8_t *p_collateral,
|
||||
size_t collateral_size);
|
||||
|
@ -910,14 +1075,14 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *p_context,
|
|||
/** \brief A function that performs the final secure element key derivation
|
||||
* step and place the generated key material in a slot
|
||||
*
|
||||
* \param[in,out] p_context A hardware-specific structure containing any
|
||||
* \param[in,out] op_context A hardware-specific structure containing any
|
||||
* context information for the implementation
|
||||
* \param[in] dest_key The slot where the generated key material
|
||||
* should be placed
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context,
|
||||
psa_key_slot_number_t dest_key);
|
||||
|
||||
/** \brief A function that performs the final step of a secure element key
|
||||
|
@ -931,7 +1096,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *p_context,
|
|||
*
|
||||
* \retval PSA_SUCCESS
|
||||
*/
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *p_context,
|
||||
typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length);
|
||||
|
@ -961,6 +1126,113 @@ typedef struct {
|
|||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup se_registration Secure element driver registration
|
||||
*/
|
||||
/**@{*/
|
||||
|
||||
/** A structure containing pointers to all the entry points of a
|
||||
* secure element driver.
|
||||
*
|
||||
* Future versions of this specification may add extra substructures at
|
||||
* the end of this structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/** The version of the driver HAL that this driver implements.
|
||||
* This is a protection against loading driver binaries built against
|
||||
* a different version of this specification.
|
||||
* Use #PSA_DRV_SE_HAL_VERSION.
|
||||
*/
|
||||
uint32_t hal_version;
|
||||
|
||||
/** The size of the driver's persistent data in bytes.
|
||||
*
|
||||
* This can be 0 if the driver does not need persistent data.
|
||||
*
|
||||
* See the documentation of psa_drv_se_context_t::persistent_data
|
||||
* for more information about why and how a driver can use
|
||||
* persistent data.
|
||||
*/
|
||||
size_t persistent_data_size;
|
||||
|
||||
/** The driver initialization function.
|
||||
*
|
||||
* This function is called once during the initialization of the
|
||||
* PSA Cryptography subsystem, before any other function of the
|
||||
* driver is called. If this function returns a failure status,
|
||||
* the driver will be unusable, at least until the next system reset.
|
||||
*
|
||||
* If this field is \c NULL, it is equivalent to a function that does
|
||||
* nothing and returns #PSA_SUCCESS.
|
||||
*/
|
||||
psa_drv_se_init_t p_init;
|
||||
|
||||
const psa_drv_se_key_management_t *key_management;
|
||||
const psa_drv_se_mac_t *mac;
|
||||
const psa_drv_se_cipher_t *cipher;
|
||||
const psa_drv_se_aead_t *aead;
|
||||
const psa_drv_se_asymmetric_t *asymmetric;
|
||||
const psa_drv_se_key_derivation_t *derivation;
|
||||
} psa_drv_se_t;
|
||||
|
||||
/** The current version of the secure element driver HAL.
|
||||
*/
|
||||
/* 0.0.0 patchlevel 5 */
|
||||
#define PSA_DRV_SE_HAL_VERSION 0x00000005
|
||||
|
||||
/** Register an external cryptoprocessor (secure element) driver.
|
||||
*
|
||||
* This function is only intended to be used by driver code, not by
|
||||
* application code. In implementations with separation between the
|
||||
* PSA cryptography module and applications, this function should
|
||||
* only be available to callers that run in the same memory space as
|
||||
* the cryptography module, and should not be exposed to applications
|
||||
* running in a different memory space.
|
||||
*
|
||||
* This function may be called before psa_crypto_init(). It is
|
||||
* implementation-defined whether this function may be called
|
||||
* after psa_crypto_init().
|
||||
*
|
||||
* \note Implementations store metadata about keys including the lifetime
|
||||
* value. Therefore, from one instantiation of the PSA Cryptography
|
||||
* library to the next one, if there is a key in storage with a certain
|
||||
* lifetime value, you must always register the same driver (or an
|
||||
* updated version that communicates with the same secure element)
|
||||
* with the same lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value through which this driver will
|
||||
* be exposed to applications.
|
||||
* The values #PSA_KEY_LIFETIME_VOLATILE and
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT are reserved and
|
||||
* may not be used for drivers. Implementations
|
||||
* may reserve other values.
|
||||
* \param[in] methods The method table of the driver. This structure must
|
||||
* remain valid for as long as the cryptography
|
||||
* module keeps running. It is typically a global
|
||||
* constant.
|
||||
*
|
||||
* \return PSA_SUCCESS
|
||||
* The driver was successfully registered. Applications can now
|
||||
* use \p lifetime to access keys through the methods passed to
|
||||
* this function.
|
||||
* \return PSA_ERROR_BAD_STATE
|
||||
* This function was called after the initialization of the
|
||||
* cryptography module, and this implementation does not support
|
||||
* driver registration at this stage.
|
||||
* \return PSA_ERROR_ALREADY_EXISTS
|
||||
* There is already a registered driver for this value of \p lifetime.
|
||||
* \return PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p lifetime is a reserved value.
|
||||
* \return PSA_ERROR_NOT_SUPPORTED
|
||||
* `methods->hal_version` is not supported by this implementation.
|
||||
* \return PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \return PSA_ERROR_NOT_PERMITTED
|
||||
*/
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t *methods);
|
||||
|
||||
/**@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
#define PSA_BITS_TO_BYTES(bits) (((bits) + 7) / 8)
|
||||
#define PSA_BYTES_TO_BITS(bytes) ((bytes) * 8)
|
||||
|
||||
#define PSA_ROUND_UP_TO_MULTIPLE(block_size, length) \
|
||||
(((length) + (block_size) - 1) / (block_size) * (block_size))
|
||||
|
||||
/** The size of the output of psa_hash_finish(), in bytes.
|
||||
*
|
||||
* This is also the hash size that psa_hash_verify() expects.
|
||||
|
@ -269,7 +272,7 @@
|
|||
* \param key_type The type of the MAC key.
|
||||
* \param key_bits The size of the MAC key in bits.
|
||||
* \param alg A MAC algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_MAC(alg) is true).
|
||||
* #PSA_ALG_IS_MAC(\p alg) is true).
|
||||
*
|
||||
* \return The MAC size for the specified algorithm with
|
||||
* the specified key parameters.
|
||||
|
@ -294,7 +297,7 @@
|
|||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(alg) is true).
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param plaintext_length Size of the plaintext in bytes.
|
||||
*
|
||||
* \return The AEAD ciphertext size for the specified
|
||||
|
@ -318,7 +321,7 @@
|
|||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(alg) is true).
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param ciphertext_length Size of the plaintext in bytes.
|
||||
*
|
||||
* \return The AEAD ciphertext size for the specified
|
||||
|
@ -330,7 +333,81 @@
|
|||
*/
|
||||
#define PSA_AEAD_DECRYPT_OUTPUT_SIZE(alg, ciphertext_length) \
|
||||
(PSA_AEAD_TAG_LENGTH(alg) != 0 ? \
|
||||
(plaintext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
(ciphertext_length) - PSA_AEAD_TAG_LENGTH(alg) : \
|
||||
0)
|
||||
|
||||
/** A sufficient output buffer size for psa_aead_update().
|
||||
*
|
||||
* If the size of the output buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_update() will not fail due to an
|
||||
* insufficient buffer size. The actual size of the output may be smaller
|
||||
* in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
* \param input_length Size of the input in bytes.
|
||||
*
|
||||
* \return A sufficient output buffer size for the specified
|
||||
* algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
/* For all the AEAD modes defined in this specification, it is possible
|
||||
* to emit output without delay. However, hardware may not always be
|
||||
* capable of this. So for modes based on a block cipher, allow the
|
||||
* implementation to delay the output until it has a full block. */
|
||||
#define PSA_AEAD_UPDATE_OUTPUT_SIZE(alg, input_length) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_ROUND_UP_TO_MULTIPLE(PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE, (input_length)) : \
|
||||
(input_length))
|
||||
|
||||
/** A sufficient ciphertext buffer size for psa_aead_finish().
|
||||
*
|
||||
* If the size of the ciphertext buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_finish() will not fail due to an
|
||||
* insufficient ciphertext buffer size. The actual size of the output may
|
||||
* be smaller in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \return A sufficient ciphertext buffer size for the
|
||||
* specified algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_FINISH_OUTPUT_SIZE(alg) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
|
||||
0)
|
||||
|
||||
/** A sufficient plaintext buffer size for psa_aead_verify().
|
||||
*
|
||||
* If the size of the plaintext buffer is at least this large, it is
|
||||
* guaranteed that psa_aead_verify() will not fail due to an
|
||||
* insufficient plaintext buffer size. The actual size of the output may
|
||||
* be smaller in any given call.
|
||||
*
|
||||
* \param alg An AEAD algorithm
|
||||
* (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_AEAD(\p alg) is true).
|
||||
*
|
||||
* \return A sufficient plaintext buffer size for the
|
||||
* specified algorithm.
|
||||
* If the AEAD algorithm is not recognized, return 0.
|
||||
* An implementation may return either 0 or a
|
||||
* correct size for an AEAD algorithm that it
|
||||
* recognizes, but does not support.
|
||||
*/
|
||||
#define PSA_AEAD_VERIFY_OUTPUT_SIZE(alg) \
|
||||
(PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) ? \
|
||||
PSA_MAX_BLOCK_CIPHER_BLOCK_SIZE : \
|
||||
0)
|
||||
|
||||
#define PSA_RSA_MINIMUM_PADDING_SIZE(alg) \
|
||||
|
@ -349,9 +426,9 @@
|
|||
#define PSA_ECDSA_SIGNATURE_SIZE(curve_bits) \
|
||||
(PSA_BITS_TO_BYTES(curve_bits) * 2)
|
||||
|
||||
/** Safe signature buffer size for psa_asymmetric_sign().
|
||||
/** Sufficient signature buffer size for psa_asymmetric_sign().
|
||||
*
|
||||
* This macro returns a safe buffer size for a signature using a key
|
||||
* This macro returns a sufficient buffer size for a signature using a key
|
||||
* of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the signature may be smaller
|
||||
* (some algorithms produce a variable-size signature).
|
||||
|
@ -370,7 +447,7 @@
|
|||
* psa_asymmetric_sign() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
|
@ -380,9 +457,9 @@
|
|||
PSA_KEY_TYPE_IS_ECC(key_type) ? PSA_ECDSA_SIGNATURE_SIZE(key_bits) : \
|
||||
((void)alg, 0))
|
||||
|
||||
/** Safe output buffer size for psa_asymmetric_encrypt().
|
||||
/** Sufficient output buffer size for psa_asymmetric_encrypt().
|
||||
*
|
||||
* This macro returns a safe buffer size for a ciphertext produced using
|
||||
* This macro returns a sufficient buffer size for a ciphertext produced using
|
||||
* a key of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the ciphertext may be smaller, depending
|
||||
* on the algorithm.
|
||||
|
@ -401,7 +478,7 @@
|
|||
* psa_asymmetric_encrypt() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
|
@ -411,9 +488,9 @@
|
|||
((void)alg, PSA_BITS_TO_BYTES(key_bits)) : \
|
||||
0)
|
||||
|
||||
/** Safe output buffer size for psa_asymmetric_decrypt().
|
||||
/** Sufficient output buffer size for psa_asymmetric_decrypt().
|
||||
*
|
||||
* This macro returns a safe buffer size for a ciphertext produced using
|
||||
* This macro returns a sufficient buffer size for a ciphertext produced using
|
||||
* a key of the specified type and size, with the specified algorithm.
|
||||
* Note that the actual size of the ciphertext may be smaller, depending
|
||||
* on the algorithm.
|
||||
|
@ -432,7 +509,7 @@
|
|||
* psa_asymmetric_decrypt() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
|
@ -491,7 +568,7 @@
|
|||
* overapproximated as 9 half-size INTEGERS;
|
||||
* - 7 bytes for the public exponent.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(9 * PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE((key_bits) / 2 + 1) + 14)
|
||||
|
||||
/* Maximum size of the export encoding of a DSA public key.
|
||||
|
@ -529,7 +606,7 @@
|
|||
* - 3 full-size INTEGERs (p, g, y);
|
||||
* - 2 * (1 + 1 + 32) bytes for 2 sub-size INTEGERs (q, x <= 256 bits).
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_KEY_EXPORT_ASN1_INTEGER_MAX_SIZE(key_bits) * 3 + 75)
|
||||
|
||||
/* Maximum size of the export encoding of an ECC public key.
|
||||
|
@ -549,10 +626,10 @@
|
|||
*
|
||||
* An ECC key pair is represented by the secret value.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) \
|
||||
#define PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) \
|
||||
(PSA_BITS_TO_BYTES(key_bits))
|
||||
|
||||
/** Safe output buffer size for psa_export_key() or psa_export_public_key().
|
||||
/** Sufficient output buffer size for psa_export_key() or psa_export_public_key().
|
||||
*
|
||||
* This macro returns a compile-time constant if its arguments are
|
||||
* compile-time constants.
|
||||
|
@ -564,32 +641,36 @@
|
|||
* The following code illustrates how to allocate enough memory to export
|
||||
* a key by querying the key type and size at runtime.
|
||||
* \code{c}
|
||||
* psa_key_type_t key_type;
|
||||
* size_t key_bits;
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* psa_status_t status;
|
||||
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||
* status = psa_get_key_attributes(key, &attributes);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* psa_key_type_t key_type = psa_get_key_type(&attributes);
|
||||
* size_t key_bits = psa_get_key_bits(&attributes);
|
||||
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits);
|
||||
* unsigned char *buffer = malloc(buffer_size);
|
||||
* if (buffer != NULL) handle_error(...);
|
||||
* psa_reset_key_attributes(&attributes);
|
||||
* uint8_t *buffer = malloc(buffer_size);
|
||||
* if (buffer == NULL) handle_error(...);
|
||||
* size_t buffer_length;
|
||||
* status = psa_export_key(key, buffer, buffer_size, &buffer_length);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* \endcode
|
||||
*
|
||||
* For psa_export_public_key(), calculate the buffer size from the
|
||||
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR
|
||||
* public key type. You can use the macro #PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR
|
||||
* to convert a key pair type to the corresponding public key type.
|
||||
* \code{c}
|
||||
* psa_key_type_t key_type;
|
||||
* size_t key_bits;
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* psa_status_t status;
|
||||
* status = psa_get_key_information(key, &key_type, &key_bits);
|
||||
* status = psa_get_key_attributes(key, &attributes);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(key_type);
|
||||
* psa_key_type_t key_type = psa_get_key_type(&attributes);
|
||||
* psa_key_type_t public_key_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type);
|
||||
* size_t key_bits = psa_get_key_bits(&attributes);
|
||||
* size_t buffer_size = PSA_KEY_EXPORT_MAX_SIZE(public_key_type, key_bits);
|
||||
* unsigned char *buffer = malloc(buffer_size);
|
||||
* if (buffer != NULL) handle_error(...);
|
||||
* psa_reset_key_attributes(&attributes);
|
||||
* uint8_t *buffer = malloc(buffer_size);
|
||||
* if (buffer == NULL) handle_error(...);
|
||||
* size_t buffer_length;
|
||||
* status = psa_export_public_key(key, buffer, buffer_size, &buffer_length);
|
||||
* if (status != PSA_SUCCESS) handle_error(...);
|
||||
|
@ -603,18 +684,18 @@
|
|||
* psa_asymmetric_sign() will not fail with
|
||||
* #PSA_ERROR_BUFFER_TOO_SMALL.
|
||||
* If the parameters are a valid combination that is not supported
|
||||
* by the implementation, this macro either shall return either a
|
||||
* by the implementation, this macro shall return either a
|
||||
* sensible size or 0.
|
||||
* If the parameters are not valid, the
|
||||
* return value is unspecified.
|
||||
*/
|
||||
#define PSA_KEY_EXPORT_MAX_SIZE(key_type, key_bits) \
|
||||
(PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type) ? PSA_BITS_TO_BYTES(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_KEYPAIR ? PSA_KEY_EXPORT_RSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_KEY_PAIR ? PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY ? PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_KEYPAIR ? PSA_KEY_EXPORT_DSA_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_KEY_PAIR ? PSA_KEY_EXPORT_DSA_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
(key_type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY ? PSA_KEY_EXPORT_DSA_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_KEYPAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEYPAIR_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_KEY_PAIR(key_type) ? PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(key_bits) : \
|
||||
PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \
|
||||
0)
|
||||
|
||||
|
|
|
@ -152,6 +152,27 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
|
|||
return( v );
|
||||
}
|
||||
|
||||
struct psa_aead_operation_s
|
||||
{
|
||||
psa_algorithm_t alg;
|
||||
unsigned int key_set : 1;
|
||||
unsigned int iv_set : 1;
|
||||
uint8_t iv_size;
|
||||
uint8_t block_size;
|
||||
union
|
||||
{
|
||||
unsigned dummy; /* Enable easier initializing of the union. */
|
||||
mbedtls_cipher_context_t cipher;
|
||||
} ctx;
|
||||
};
|
||||
|
||||
#define PSA_AEAD_OPERATION_INIT {0, 0, 0, 0, 0, {0}}
|
||||
static inline struct psa_aead_operation_s psa_aead_operation_init( void )
|
||||
{
|
||||
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
typedef struct
|
||||
{
|
||||
|
@ -165,17 +186,31 @@ typedef struct
|
|||
#endif
|
||||
uint8_t offset_in_block;
|
||||
uint8_t block_number;
|
||||
} psa_hkdf_generator_t;
|
||||
unsigned int state : 2;
|
||||
unsigned int info_set : 1;
|
||||
} psa_hkdf_key_derivation_t;
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
|
||||
/*
|
||||
* If this option is not turned on, then the function `psa_key_derivation()`
|
||||
* is removed. And the new psa_tls12_prf_key_derivation_t context is used along
|
||||
* with the corresponding new API.
|
||||
*
|
||||
* The sole purpose of this option is to make the transition to the new API
|
||||
* smoother. Once the transition is complete it can and should be removed
|
||||
* along with the old API and its implementation.
|
||||
*/
|
||||
#define PSA_PRE_1_0_KEY_DERIVATION
|
||||
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
typedef struct psa_tls12_prf_generator_s
|
||||
#if defined(PSA_PRE_1_0_KEY_DERIVATION)
|
||||
typedef struct psa_tls12_prf_key_derivation_s
|
||||
{
|
||||
/* The TLS 1.2 PRF uses the key for each HMAC iteration,
|
||||
* hence we must store it for the lifetime of the generator.
|
||||
* hence we must store it for the lifetime of the operation.
|
||||
* This is different from HKDF, where the key is only used
|
||||
* in the extraction phase, but not during expansion. */
|
||||
unsigned char *key;
|
||||
uint8_t *key;
|
||||
size_t key_len;
|
||||
|
||||
/* `A(i) + seed` in the notation of RFC 5246, Sect. 5 */
|
||||
|
@ -196,31 +231,66 @@ typedef struct psa_tls12_prf_generator_s
|
|||
/* The 1-based number of the block. */
|
||||
uint8_t block_number;
|
||||
|
||||
} psa_tls12_prf_generator_t;
|
||||
} psa_tls12_prf_key_derivation_t;
|
||||
#else
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TLS12_PRF_STATE_INIT, /* no input provided */
|
||||
TLS12_PRF_STATE_SEED_SET, /* seed has been set */
|
||||
TLS12_PRF_STATE_KEY_SET, /* key has been set */
|
||||
TLS12_PRF_STATE_LABEL_SET, /* label has been set */
|
||||
TLS12_PRF_STATE_OUTPUT /* output has been started */
|
||||
} psa_tls12_prf_key_derivation_state_t;
|
||||
|
||||
typedef struct psa_tls12_prf_key_derivation_s
|
||||
{
|
||||
#if PSA_HASH_MAX_SIZE > 0xff
|
||||
#error "PSA_HASH_MAX_SIZE does not fit in uint8_t"
|
||||
#endif
|
||||
|
||||
/* Indicates how many bytes in the current HMAC block have
|
||||
* not yet been read by the user. */
|
||||
uint8_t left_in_block;
|
||||
|
||||
/* The 1-based number of the block. */
|
||||
uint8_t block_number;
|
||||
|
||||
psa_tls12_prf_key_derivation_state_t state;
|
||||
|
||||
uint8_t *seed;
|
||||
size_t seed_length;
|
||||
uint8_t *label;
|
||||
size_t label_length;
|
||||
psa_hmac_internal_data hmac;
|
||||
uint8_t Ai[PSA_HASH_MAX_SIZE];
|
||||
|
||||
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
|
||||
uint8_t output_block[PSA_HASH_MAX_SIZE];
|
||||
} psa_tls12_prf_key_derivation_t;
|
||||
#endif /* PSA_PRE_1_0_KEY_DERIVATION */
|
||||
#endif /* MBEDTLS_MD_C */
|
||||
|
||||
struct psa_crypto_generator_s
|
||||
struct psa_key_derivation_s
|
||||
{
|
||||
psa_algorithm_t alg;
|
||||
size_t capacity;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t size;
|
||||
} buffer;
|
||||
/* Make the union non-empty even with no supported algorithms. */
|
||||
uint8_t dummy;
|
||||
#if defined(MBEDTLS_MD_C)
|
||||
psa_hkdf_generator_t hkdf;
|
||||
psa_tls12_prf_generator_t tls12_prf;
|
||||
psa_hkdf_key_derivation_t hkdf;
|
||||
psa_tls12_prf_key_derivation_t tls12_prf;
|
||||
#endif
|
||||
} ctx;
|
||||
};
|
||||
|
||||
#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
|
||||
static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
|
||||
/* This only zeroes out the first byte in the union, the rest is unspecified. */
|
||||
#define PSA_KEY_DERIVATION_OPERATION_INIT {0, 0, {0}}
|
||||
static inline struct psa_key_derivation_s psa_key_derivation_operation_init( void )
|
||||
{
|
||||
const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
|
||||
const struct psa_key_derivation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
|
@ -230,6 +300,7 @@ struct psa_key_policy_s
|
|||
psa_algorithm_t alg;
|
||||
psa_algorithm_t alg2;
|
||||
};
|
||||
typedef struct psa_key_policy_s psa_key_policy_t;
|
||||
|
||||
#define PSA_KEY_POLICY_INIT {0, 0, 0}
|
||||
static inline struct psa_key_policy_s psa_key_policy_init( void )
|
||||
|
@ -238,4 +309,141 @@ static inline struct psa_key_policy_s psa_key_policy_init( void )
|
|||
return( v );
|
||||
}
|
||||
|
||||
/* The type used internally for key sizes.
|
||||
* Public interfaces use size_t, but internally we use a smaller type. */
|
||||
typedef uint16_t psa_key_bits_t;
|
||||
/* The maximum value of the type used to represent bit-sizes.
|
||||
* This is used to mark an invalid key size. */
|
||||
#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) )
|
||||
/* The maximum size of a key in bits.
|
||||
* Currently defined as the maximum that can be represented, rounded down
|
||||
* to a whole number of bytes.
|
||||
* This is an uncast value so that it can be used in preprocessor
|
||||
* conditionals. */
|
||||
#define PSA_MAX_KEY_BITS 0xfff8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
psa_key_type_t type;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_id_t id;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_bits_t bits;
|
||||
uint16_t flags;
|
||||
} psa_core_key_attributes_t;
|
||||
|
||||
#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, 0, {0, 0, 0}, 0, 0}
|
||||
|
||||
struct psa_key_attributes_s
|
||||
{
|
||||
psa_core_key_attributes_t core;
|
||||
void *domain_parameters;
|
||||
size_t domain_parameters_size;
|
||||
};
|
||||
|
||||
#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0}
|
||||
static inline struct psa_key_attributes_s psa_key_attributes_init( void )
|
||||
{
|
||||
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
|
||||
return( v );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_id(psa_key_attributes_t *attributes,
|
||||
psa_key_id_t id)
|
||||
{
|
||||
attributes->core.id = id;
|
||||
if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
|
||||
}
|
||||
|
||||
static inline psa_key_id_t psa_get_key_id(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.id );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes,
|
||||
psa_key_lifetime_t lifetime)
|
||||
{
|
||||
attributes->core.lifetime = lifetime;
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
attributes->core.id = 0;
|
||||
}
|
||||
|
||||
static inline psa_key_lifetime_t psa_get_key_lifetime(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.lifetime );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
|
||||
psa_key_usage_t usage_flags)
|
||||
{
|
||||
attributes->core.policy.usage = usage_flags;
|
||||
}
|
||||
|
||||
static inline psa_key_usage_t psa_get_key_usage_flags(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.usage );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
attributes->core.policy.alg = alg;
|
||||
}
|
||||
|
||||
static inline psa_algorithm_t psa_get_key_algorithm(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.policy.alg );
|
||||
}
|
||||
|
||||
/* This function is declared in crypto_extra.h, which comes after this
|
||||
* header file, but we need the function here, so repeat the declaration. */
|
||||
psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type,
|
||||
const uint8_t *data,
|
||||
size_t data_length);
|
||||
|
||||
static inline void psa_set_key_type(psa_key_attributes_t *attributes,
|
||||
psa_key_type_t type)
|
||||
{
|
||||
if( attributes->domain_parameters == NULL )
|
||||
{
|
||||
/* Common case: quick path */
|
||||
attributes->core.type = type;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the bigger function to free the old domain paramteres.
|
||||
* Ignore any errors which may arise due to type requiring
|
||||
* non-default domain parameters, since this function can't
|
||||
* report errors. */
|
||||
(void) psa_set_key_domain_parameters( attributes, type, NULL, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
static inline psa_key_type_t psa_get_key_type(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.type );
|
||||
}
|
||||
|
||||
static inline void psa_set_key_bits(psa_key_attributes_t *attributes,
|
||||
size_t bits)
|
||||
{
|
||||
if( bits > PSA_MAX_KEY_BITS )
|
||||
attributes->core.bits = PSA_KEY_BITS_TOO_LARGE;
|
||||
else
|
||||
attributes->core.bits = (psa_key_bits_t) bits;
|
||||
}
|
||||
|
||||
static inline size_t psa_get_key_bits(
|
||||
const psa_key_attributes_t *attributes)
|
||||
{
|
||||
return( attributes->core.bits );
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_STRUCT_H */
|
||||
|
|
|
@ -45,9 +45,9 @@
|
|||
* \brief Function return status.
|
||||
*
|
||||
* This is either #PSA_SUCCESS (which is zero), indicating success,
|
||||
* or a nonzero value indicating that an error occurred. Errors are
|
||||
* encoded as one of the \c PSA_ERROR_xxx values defined here.
|
||||
* If #PSA_SUCCESS is already defined, it means that #psa_status_t
|
||||
* or a small negative value indicating that an error occurred. Errors are
|
||||
* encoded as one of the \c PSA_ERROR_xxx values defined here. */
|
||||
/* If #PSA_SUCCESS is already defined, it means that #psa_status_t
|
||||
* is also defined in an external header, so prevent its multiple
|
||||
* definition.
|
||||
*/
|
||||
|
@ -68,6 +68,9 @@ typedef uint32_t psa_key_type_t;
|
|||
/** The type of PSA elliptic curve identifiers. */
|
||||
typedef uint16_t psa_ecc_curve_t;
|
||||
|
||||
/** The type of PSA Diffie-Hellman group identifiers. */
|
||||
typedef uint16_t psa_dh_group_t;
|
||||
|
||||
/** \brief Encoding of a cryptographic algorithm.
|
||||
*
|
||||
* For algorithms that can be applied to multiple key types, this type
|
||||
|
@ -85,10 +88,30 @@ typedef uint32_t psa_algorithm_t;
|
|||
*/
|
||||
|
||||
/** Encoding of key lifetimes.
|
||||
*
|
||||
* The lifetime of a key indicates where it is stored and what system actions
|
||||
* may create and destroy it.
|
||||
*
|
||||
* Keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE are automatically
|
||||
* destroyed when the application terminates or on a power reset.
|
||||
*
|
||||
* Keys with a lifetime other than #PSA_KEY_LIFETIME_VOLATILE are said
|
||||
* to be _persistent_.
|
||||
* Persistent keys are preserved if the application or the system restarts.
|
||||
* Persistent keys have a key identifier of type #psa_key_id_t.
|
||||
* The application can call psa_open_key() to open a persistent key that
|
||||
* it created previously.
|
||||
*/
|
||||
typedef uint32_t psa_key_lifetime_t;
|
||||
|
||||
/** Encoding of identifiers of persistent keys.
|
||||
*
|
||||
* - Applications may freely choose key identifiers in the range
|
||||
* #PSA_KEY_ID_USER_MIN to #PSA_KEY_ID_USER_MAX.
|
||||
* - Implementations may define additional key identifiers in the range
|
||||
* #PSA_KEY_ID_VENDOR_MIN to #PSA_KEY_ID_VENDOR_MAX.
|
||||
* - 0 is reserved as an invalid key identifier.
|
||||
* - Key identifiers outside these ranges are reserved for future use.
|
||||
*/
|
||||
/* Implementation-specific quirk: The Mbed Crypto library can be built as
|
||||
* part of a multi-client service that exposes the PSA Crypto API in each
|
||||
|
@ -110,4 +133,126 @@ typedef uint32_t psa_key_usage_t;
|
|||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup attributes Key attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** The type of a structure containing key attributes.
|
||||
*
|
||||
* This is an opaque structure that can represent the metadata of a key
|
||||
* object. Metadata that can be stored in attributes includes:
|
||||
* - The location of the key in storage, indicated by its key identifier
|
||||
* and its lifetime.
|
||||
* - The key's policy, comprising usage flags and a specification of
|
||||
* the permitted algorithm(s).
|
||||
* - Information about the key itself: the key type and its size.
|
||||
* - Implementations may define additional attributes.
|
||||
*
|
||||
* The actual key material is not considered an attribute of a key.
|
||||
* Key attributes do not contain information that is generally considered
|
||||
* highly confidential.
|
||||
*
|
||||
* An attribute structure can be a simple data structure where each function
|
||||
* `psa_set_key_xxx` sets a field and the corresponding function
|
||||
* `psa_get_key_xxx` retrieves the value of the corresponding field.
|
||||
* However, implementations may report values that are equivalent to the
|
||||
* original one, but have a different encoding. For example, an
|
||||
* implementation may use a more compact representation for types where
|
||||
* many bit-patterns are invalid or not supported, and store all values
|
||||
* that it does not support as a special marker value. In such an
|
||||
* implementation, after setting an invalid value, the corresponding
|
||||
* get function returns an invalid value which may not be the one that
|
||||
* was originally stored.
|
||||
*
|
||||
* An attribute structure may contain references to auxiliary resources,
|
||||
* for example pointers to allocated memory or indirect references to
|
||||
* pre-calculated values. In order to free such resources, the application
|
||||
* must call psa_reset_key_attributes(). As an exception, calling
|
||||
* psa_reset_key_attributes() on an attribute structure is optional if
|
||||
* the structure has only been modified by the following functions
|
||||
* since it was initialized or last reset with psa_reset_key_attributes():
|
||||
* - psa_set_key_id()
|
||||
* - psa_set_key_lifetime()
|
||||
* - psa_set_key_type()
|
||||
* - psa_set_key_bits()
|
||||
* - psa_set_key_usage_flags()
|
||||
* - psa_set_key_algorithm()
|
||||
*
|
||||
* Before calling any function on a key attribute structure, the application
|
||||
* must initialize it by any of the following means:
|
||||
* - Set the structure to all-bits-zero, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes;
|
||||
* memset(&attributes, 0, sizeof(attributes));
|
||||
* \endcode
|
||||
* - Initialize the structure to logical zero values, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes = {0};
|
||||
* \endcode
|
||||
* - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
|
||||
* for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
* \endcode
|
||||
* - Assign the result of the function psa_key_attributes_init()
|
||||
* to the structure, for example:
|
||||
* \code
|
||||
* psa_key_attributes_t attributes;
|
||||
* attributes = psa_key_attributes_init();
|
||||
* \endcode
|
||||
*
|
||||
* A freshly initialized attribute structure contains the following
|
||||
* values:
|
||||
*
|
||||
* - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
|
||||
* - key identifier: unspecified.
|
||||
* - type: \c 0.
|
||||
* - key size: \c 0.
|
||||
* - usage flags: \c 0.
|
||||
* - algorithm: \c 0.
|
||||
*
|
||||
* A typical sequence to create a key is as follows:
|
||||
* -# Create and initialize an attribute structure.
|
||||
* -# If the key is persistent, call psa_set_key_id().
|
||||
* Also call psa_set_key_lifetime() to place the key in a non-default
|
||||
* location.
|
||||
* -# Set the key policy with psa_set_key_usage_flags() and
|
||||
* psa_set_key_algorithm().
|
||||
* -# Set the key type with psa_set_key_type().
|
||||
* Skip this step if copying an existing key with psa_copy_key().
|
||||
* -# When generating a random key with psa_generate_key() or deriving a key
|
||||
* with psa_key_derivation_output_key(), set the desired key size with
|
||||
* psa_set_key_bits().
|
||||
* -# Call a key creation function: psa_import_key(), psa_generate_key(),
|
||||
* psa_key_derivation_output_key() or psa_copy_key(). This function reads
|
||||
* the attribute structure, creates a key with these attributes, and
|
||||
* outputs a handle to the newly created key.
|
||||
* -# The attribute structure is now no longer necessary.
|
||||
* You may call psa_reset_key_attributes(), although this is optional
|
||||
* with the workflow presented here because the attributes currently
|
||||
* defined in this specification do not require any additional resources
|
||||
* beyond the structure itself.
|
||||
*
|
||||
* A typical sequence to query a key's attributes is as follows:
|
||||
* -# Call psa_get_key_attributes().
|
||||
* -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
|
||||
* you are interested in.
|
||||
* -# Call psa_reset_key_attributes() to free any resources that may be
|
||||
* used by the attribute structure.
|
||||
*
|
||||
* Once a key has been created, it is impossible to change its attributes.
|
||||
*/
|
||||
typedef struct psa_key_attributes_s psa_key_attributes_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup derivation Key derivation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \brief Encoding of the step of a key derivation. */
|
||||
typedef uint16_t psa_key_derivation_step_t;
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* PSA_CRYPTO_TYPES_H */
|
||||
|
|
|
@ -105,9 +105,13 @@
|
|||
* descriptions for permitted sequencing of functions.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate
|
||||
* that a key slot is occupied when it needs to be free or vice versa,
|
||||
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable. */
|
||||
* that a key either exists or not,
|
||||
* but shall instead return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate that a
|
||||
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
|
||||
* instead. */
|
||||
#define PSA_ERROR_BAD_STATE ((psa_status_t)-137)
|
||||
|
||||
/** The parameters passed to the function are invalid.
|
||||
|
@ -115,12 +119,7 @@
|
|||
* Implementations may return this error any time a parameter or
|
||||
* combination of parameters are recognized as invalid.
|
||||
*
|
||||
* Implementations shall not return this error code to indicate
|
||||
* that a key slot is occupied when it needs to be free or vice versa,
|
||||
* but shall return #PSA_ERROR_ALREADY_EXISTS or #PSA_ERROR_DOES_NOT_EXIST
|
||||
* as applicable.
|
||||
*
|
||||
* Implementation shall not return this error code to indicate that a
|
||||
* Implementations shall not return this error code to indicate that a
|
||||
* key handle is invalid, but shall return #PSA_ERROR_INVALID_HANDLE
|
||||
* instead.
|
||||
*/
|
||||
|
@ -162,7 +161,7 @@
|
|||
*
|
||||
* This error indicates that some persistent storage is corrupted.
|
||||
* It should not be used for a corruption of volatile memory
|
||||
* (use #PSA_ERROR_TAMPERING_DETECTED), for a communication error
|
||||
* (use #PSA_ERROR_CORRUPTION_DETECTED), for a communication error
|
||||
* between the cryptoprocessor and its external storage (use
|
||||
* #PSA_ERROR_COMMUNICATION_FAILURE), or when the storage is
|
||||
* in a valid state but is full (use #PSA_ERROR_INSUFFICIENT_STORAGE).
|
||||
|
@ -175,7 +174,7 @@
|
|||
* the global integrity of the keystore. Depending on the global
|
||||
* integrity guarantees offered by the implementation, access to other
|
||||
* data may or may not fail even if the data is still readable but
|
||||
* its integrity canont be guaranteed.
|
||||
* its integrity cannot be guaranteed.
|
||||
*
|
||||
* Implementations should only use this error code to report a
|
||||
* permanent storage corruption. However application writers should
|
||||
|
@ -218,7 +217,7 @@
|
|||
* This error indicates an attack against the application. Implementations
|
||||
* shall not return this error code as a consequence of the behavior of
|
||||
* the application itself. */
|
||||
#define PSA_ERROR_TAMPERING_DETECTED ((psa_status_t)-151)
|
||||
#define PSA_ERROR_CORRUPTION_DETECTED ((psa_status_t)-151)
|
||||
|
||||
/** There is not enough entropy to generate random data needed
|
||||
* for the requested action.
|
||||
|
@ -324,7 +323,7 @@
|
|||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_PUBLIC_KEY)
|
||||
/** Whether a key type is a key pair containing a private part and a public
|
||||
* part. */
|
||||
#define PSA_KEY_TYPE_IS_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_IS_KEY_PAIR(type) \
|
||||
(((type) & PSA_KEY_TYPE_CATEGORY_MASK) == PSA_KEY_TYPE_CATEGORY_KEY_PAIR)
|
||||
/** The key pair type corresponding to a public key type.
|
||||
*
|
||||
|
@ -336,7 +335,7 @@
|
|||
* If \p type is not a public key or a key pair,
|
||||
* the return value is undefined.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY(type) \
|
||||
#define PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY(type) \
|
||||
((type) | PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||
/** The public key type corresponding to a key pair type.
|
||||
*
|
||||
|
@ -348,7 +347,7 @@
|
|||
* If \p type is not a public key or a key pair,
|
||||
* the return value is undefined.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) \
|
||||
((type) & ~PSA_KEY_TYPE_CATEGORY_FLAG_PAIR)
|
||||
|
||||
/** Raw data.
|
||||
|
@ -374,7 +373,7 @@
|
|||
*/
|
||||
#define PSA_KEY_TYPE_DERIVE ((psa_key_type_t)0x52000000)
|
||||
|
||||
/** Key for an cipher, AEAD or MAC algorithm based on the AES block cipher.
|
||||
/** Key for a cipher, AEAD or MAC algorithm based on the AES block cipher.
|
||||
*
|
||||
* The size of the key can be 16 bytes (AES-128), 24 bytes (AES-192) or
|
||||
* 32 bytes (AES-256).
|
||||
|
@ -392,7 +391,7 @@
|
|||
*/
|
||||
#define PSA_KEY_TYPE_DES ((psa_key_type_t)0x40000002)
|
||||
|
||||
/** Key for an cipher, AEAD or MAC algorithm based on the
|
||||
/** Key for a cipher, AEAD or MAC algorithm based on the
|
||||
* Camellia block cipher. */
|
||||
#define PSA_KEY_TYPE_CAMELLIA ((psa_key_type_t)0x40000003)
|
||||
|
||||
|
@ -402,40 +401,41 @@
|
|||
* legacy protocols. */
|
||||
#define PSA_KEY_TYPE_ARC4 ((psa_key_type_t)0x40000004)
|
||||
|
||||
/** Key for the ChaCha20 stream cipher or the Chacha20-Poly1305 AEAD algorithm.
|
||||
*
|
||||
* ChaCha20 and the ChaCha20_Poly1305 construction are defined in RFC 7539.
|
||||
*
|
||||
* Implementations must support 12-byte nonces, may support 8-byte nonces,
|
||||
* and should reject other sizes.
|
||||
*/
|
||||
#define PSA_KEY_TYPE_CHACHA20 ((psa_key_type_t)0x40000005)
|
||||
|
||||
/** RSA public key. */
|
||||
#define PSA_KEY_TYPE_RSA_PUBLIC_KEY ((psa_key_type_t)0x60010000)
|
||||
/** RSA key pair (private and public key). */
|
||||
#define PSA_KEY_TYPE_RSA_KEYPAIR ((psa_key_type_t)0x70010000)
|
||||
#define PSA_KEY_TYPE_RSA_KEY_PAIR ((psa_key_type_t)0x70010000)
|
||||
/** Whether a key type is an RSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_RSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
/** DSA public key. */
|
||||
#define PSA_KEY_TYPE_DSA_PUBLIC_KEY ((psa_key_type_t)0x60020000)
|
||||
/** DSA key pair (private and public key). */
|
||||
#define PSA_KEY_TYPE_DSA_KEYPAIR ((psa_key_type_t)0x70020000)
|
||||
/** Whether a key type is an DSA key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DSA(type) \
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)
|
||||
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_RSA_PUBLIC_KEY)
|
||||
|
||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE ((psa_key_type_t)0x60030000)
|
||||
#define PSA_KEY_TYPE_ECC_KEYPAIR_BASE ((psa_key_type_t)0x70030000)
|
||||
#define PSA_KEY_TYPE_ECC_KEY_PAIR_BASE ((psa_key_type_t)0x70030000)
|
||||
#define PSA_KEY_TYPE_ECC_CURVE_MASK ((psa_key_type_t)0x0000ffff)
|
||||
/** Elliptic curve key pair. */
|
||||
#define PSA_KEY_TYPE_ECC_KEYPAIR(curve) \
|
||||
(PSA_KEY_TYPE_ECC_KEYPAIR_BASE | (curve))
|
||||
#define PSA_KEY_TYPE_ECC_KEY_PAIR(curve) \
|
||||
(PSA_KEY_TYPE_ECC_KEY_PAIR_BASE | (curve))
|
||||
/** Elliptic curve public key. */
|
||||
#define PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve) \
|
||||
(PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE | (curve))
|
||||
|
||||
/** Whether a key type is an elliptic curve key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_ECC(type) \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) & \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
|
||||
~PSA_KEY_TYPE_ECC_CURVE_MASK) == PSA_KEY_TYPE_ECC_PUBLIC_KEY_BASE)
|
||||
/** Whether a key type is an elliptic curve key pair. */
|
||||
#define PSA_KEY_TYPE_IS_ECC_KEYPAIR(type) \
|
||||
#define PSA_KEY_TYPE_IS_ECC_KEY_PAIR(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
|
||||
PSA_KEY_TYPE_ECC_KEYPAIR_BASE)
|
||||
PSA_KEY_TYPE_ECC_KEY_PAIR_BASE)
|
||||
/** Whether a key type is an elliptic curve public key. */
|
||||
#define PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_ECC_CURVE_MASK) == \
|
||||
|
@ -480,9 +480,61 @@
|
|||
#define PSA_ECC_CURVE_BRAINPOOL_P256R1 ((psa_ecc_curve_t) 0x001a)
|
||||
#define PSA_ECC_CURVE_BRAINPOOL_P384R1 ((psa_ecc_curve_t) 0x001b)
|
||||
#define PSA_ECC_CURVE_BRAINPOOL_P512R1 ((psa_ecc_curve_t) 0x001c)
|
||||
/** Curve25519.
|
||||
*
|
||||
* This is the curve defined in Bernstein et al.,
|
||||
* _Curve25519: new Diffie-Hellman speed records_, LNCS 3958, 2006.
|
||||
* The algorithm #PSA_ALG_ECDH performs X25519 when used with this curve.
|
||||
*/
|
||||
#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
|
||||
/** Curve448
|
||||
*
|
||||
* This is the curve defined in Hamburg,
|
||||
* _Ed448-Goldilocks, a new elliptic curve_, NIST ECC Workshop, 2015.
|
||||
* The algorithm #PSA_ALG_ECDH performs X448 when used with this curve.
|
||||
*/
|
||||
#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
|
||||
|
||||
#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000)
|
||||
#define PSA_KEY_TYPE_DH_KEY_PAIR_BASE ((psa_key_type_t)0x70040000)
|
||||
#define PSA_KEY_TYPE_DH_GROUP_MASK ((psa_key_type_t)0x0000ffff)
|
||||
/** Diffie-Hellman key pair. */
|
||||
#define PSA_KEY_TYPE_DH_KEY_PAIR(group) \
|
||||
(PSA_KEY_TYPE_DH_KEY_PAIR_BASE | (group))
|
||||
/** Diffie-Hellman public key. */
|
||||
#define PSA_KEY_TYPE_DH_PUBLIC_KEY(group) \
|
||||
(PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE | (group))
|
||||
|
||||
/** Whether a key type is a Diffie-Hellman key (pair or public-only). */
|
||||
#define PSA_KEY_TYPE_IS_DH(type) \
|
||||
((PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) & \
|
||||
~PSA_KEY_TYPE_DH_GROUP_MASK) == PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
|
||||
/** Whether a key type is a Diffie-Hellman key pair. */
|
||||
#define PSA_KEY_TYPE_IS_DH_KEY_PAIR(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
|
||||
PSA_KEY_TYPE_DH_KEY_PAIR_BASE)
|
||||
/** Whether a key type is a Diffie-Hellman public key. */
|
||||
#define PSA_KEY_TYPE_IS_DH_PUBLIC_KEY(type) \
|
||||
(((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
|
||||
PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE)
|
||||
|
||||
/** Extract the group from a Diffie-Hellman key type. */
|
||||
#define PSA_KEY_TYPE_GET_GROUP(type) \
|
||||
((psa_dh_group_t) (PSA_KEY_TYPE_IS_DH(type) ? \
|
||||
((type) & PSA_KEY_TYPE_DH_GROUP_MASK) : \
|
||||
0))
|
||||
|
||||
/* The encoding of group identifiers is currently aligned with the
|
||||
* TLS Supported Groups Registry (formerly known as the
|
||||
* TLS EC Named Curve Registry)
|
||||
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
|
||||
* The values are defined by RFC 7919. */
|
||||
#define PSA_DH_GROUP_FFDHE2048 ((psa_dh_group_t) 0x0100)
|
||||
#define PSA_DH_GROUP_FFDHE3072 ((psa_dh_group_t) 0x0101)
|
||||
#define PSA_DH_GROUP_FFDHE4096 ((psa_dh_group_t) 0x0102)
|
||||
#define PSA_DH_GROUP_FFDHE6144 ((psa_dh_group_t) 0x0103)
|
||||
#define PSA_DH_GROUP_FFDHE8192 ((psa_dh_group_t) 0x0104)
|
||||
|
||||
/** The block size of a block cipher.
|
||||
*
|
||||
* \param type A cipher key type (value of type #psa_key_type_t).
|
||||
|
@ -517,9 +569,8 @@
|
|||
#define PSA_ALG_CATEGORY_AEAD ((psa_algorithm_t)0x06000000)
|
||||
#define PSA_ALG_CATEGORY_SIGN ((psa_algorithm_t)0x10000000)
|
||||
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x12000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x22000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x30000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_SELECTION ((psa_algorithm_t)0x31000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x20000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x30000000)
|
||||
|
||||
#define PSA_ALG_IS_VENDOR_DEFINED(alg) \
|
||||
(((alg) & PSA_ALG_VENDOR_FLAG) != 0)
|
||||
|
@ -591,7 +642,6 @@
|
|||
#define PSA_ALG_IS_ASYMMETRIC_ENCRYPTION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION)
|
||||
|
||||
#define PSA_ALG_KEY_SELECTION_FLAG ((psa_algorithm_t)0x01000000)
|
||||
/** Whether the specified algorithm is a key agreement algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
|
@ -601,8 +651,7 @@
|
|||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_KEY_AGREEMENT(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK & ~PSA_ALG_KEY_SELECTION_FLAG) == \
|
||||
PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
|
||||
/** Whether the specified algorithm is a key derivation algorithm.
|
||||
*
|
||||
|
@ -615,17 +664,6 @@
|
|||
#define PSA_ALG_IS_KEY_DERIVATION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
/** Whether the specified algorithm is a key selection algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is a key selection algorithm, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_KEY_SELECTION(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_KEY_SELECTION)
|
||||
|
||||
#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
|
||||
|
||||
#define PSA_ALG_MD2 ((psa_algorithm_t)0x01000001)
|
||||
|
@ -663,15 +701,12 @@
|
|||
*
|
||||
* That is, suppose that `PSA_xxx_SIGNATURE` is one of the following macros:
|
||||
* - #PSA_ALG_RSA_PKCS1V15_SIGN, #PSA_ALG_RSA_PSS,
|
||||
* - #PSA_ALG_DSA, #PSA_ALG_DETERMINISTIC_DSA,
|
||||
* - #PSA_ALG_ECDSA, #PSA_ALG_DETERMINISTIC_ECDSA.
|
||||
* Then you may create and use a key as follows:
|
||||
* - Set the key usage field using #PSA_ALG_ANY_HASH, for example:
|
||||
* ```
|
||||
* psa_key_policy_set_usage(&policy,
|
||||
* PSA_KEY_USAGE_SIGN, //or PSA_KEY_USAGE_VERIFY
|
||||
* PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
|
||||
* psa_set_key_policy(handle, &policy);
|
||||
* psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN); // or VERIFY
|
||||
* psa_set_key_algorithm(&attributes, PSA_xxx_SIGNATURE(PSA_ALG_ANY_HASH));
|
||||
* ```
|
||||
* - Import or generate key material.
|
||||
* - Call psa_asymmetric_sign() or psa_asymmetric_verify(), passing
|
||||
|
@ -685,7 +720,7 @@
|
|||
*
|
||||
* This value may not be used to build other algorithms that are
|
||||
* parametrized over a hash. For any valid use of this macro to build
|
||||
* an algorithm `\p alg`, #PSA_ALG_IS_HASH_AND_SIGN(\p alg) is true.
|
||||
* an algorithm \c alg, #PSA_ALG_IS_HASH_AND_SIGN(\c alg) is true.
|
||||
*
|
||||
* This value may not be used to build an algorithm specification to
|
||||
* perform an operation. It is only valid to build policies.
|
||||
|
@ -702,7 +737,7 @@
|
|||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding HMAC algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_HMAC(hash_alg) \
|
||||
|
@ -802,9 +837,14 @@
|
|||
(((mac_alg) & PSA_ALG_MAC_TRUNCATION_MASK) >> PSA_MAC_TRUNCATION_OFFSET)
|
||||
|
||||
#define PSA_ALG_CIPHER_MAC_BASE ((psa_algorithm_t)0x02c00000)
|
||||
/** The CBC-MAC construction over a block cipher
|
||||
*
|
||||
* \warning CBC-MAC is insecure in many cases.
|
||||
* A more secure mode, such as #PSA_ALG_CMAC, is recommended.
|
||||
*/
|
||||
#define PSA_ALG_CBC_MAC ((psa_algorithm_t)0x02c00001)
|
||||
/** The CMAC construction over a block cipher */
|
||||
#define PSA_ALG_CMAC ((psa_algorithm_t)0x02c00002)
|
||||
#define PSA_ALG_GMAC ((psa_algorithm_t)0x02c00003)
|
||||
|
||||
/** Whether the specified algorithm is a MAC algorithm based on a block cipher.
|
||||
*
|
||||
|
@ -841,6 +881,18 @@
|
|||
*/
|
||||
#define PSA_ALG_ARC4 ((psa_algorithm_t)0x04800001)
|
||||
|
||||
/** The ChaCha20 stream cipher.
|
||||
*
|
||||
* ChaCha20 is defined in RFC 7539.
|
||||
*
|
||||
* The nonce size for psa_cipher_set_iv() or psa_cipher_generate_iv()
|
||||
* must be 12.
|
||||
*
|
||||
* The initial block counter is always 0.
|
||||
*
|
||||
*/
|
||||
#define PSA_ALG_CHACHA20 ((psa_algorithm_t)0x04800005)
|
||||
|
||||
/** The CTR stream cipher mode.
|
||||
*
|
||||
* CTR is a stream cipher which is built from a block cipher.
|
||||
|
@ -850,8 +902,16 @@
|
|||
*/
|
||||
#define PSA_ALG_CTR ((psa_algorithm_t)0x04c00001)
|
||||
|
||||
/** The CFB stream cipher mode.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_CFB ((psa_algorithm_t)0x04c00002)
|
||||
|
||||
/** The OFB stream cipher mode.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_OFB ((psa_algorithm_t)0x04c00003)
|
||||
|
||||
/** The XTS cipher mode.
|
||||
|
@ -879,8 +939,43 @@
|
|||
*/
|
||||
#define PSA_ALG_CBC_PKCS7 ((psa_algorithm_t)0x04600101)
|
||||
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06001001)
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06001002)
|
||||
#define PSA_ALG_AEAD_FROM_BLOCK_FLAG ((psa_algorithm_t)0x00400000)
|
||||
|
||||
/** Whether the specified algorithm is an AEAD mode on a block cipher.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is an AEAD algorithm which is an AEAD mode based on
|
||||
* a block cipher, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_AEAD_ON_BLOCK_CIPHER(alg) \
|
||||
(((alg) & (PSA_ALG_CATEGORY_MASK | PSA_ALG_AEAD_FROM_BLOCK_FLAG)) == \
|
||||
(PSA_ALG_CATEGORY_AEAD | PSA_ALG_AEAD_FROM_BLOCK_FLAG))
|
||||
|
||||
/** The CCM authenticated encryption algorithm.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_CCM ((psa_algorithm_t)0x06401001)
|
||||
|
||||
/** The GCM authenticated encryption algorithm.
|
||||
*
|
||||
* The underlying block cipher is determined by the key type.
|
||||
*/
|
||||
#define PSA_ALG_GCM ((psa_algorithm_t)0x06401002)
|
||||
|
||||
/** The Chacha20-Poly1305 AEAD algorithm.
|
||||
*
|
||||
* The ChaCha20_Poly1305 construction is defined in RFC 7539.
|
||||
*
|
||||
* Implementations must support 12-byte nonces, may support 8-byte nonces,
|
||||
* and should reject other sizes.
|
||||
*
|
||||
* Implementations must support 16-byte tags and should reject other sizes.
|
||||
*/
|
||||
#define PSA_ALG_CHACHA20_POLY1305 ((psa_algorithm_t)0x06001005)
|
||||
|
||||
/* In the encoding of a AEAD algorithm, the bits corresponding to
|
||||
* PSA_ALG_AEAD_TAG_LENGTH_MASK encode the length of the AEAD tag.
|
||||
|
@ -924,6 +1019,7 @@
|
|||
( \
|
||||
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_CCM) \
|
||||
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_GCM) \
|
||||
PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, PSA_ALG_CHACHA20_POLY1305) \
|
||||
0)
|
||||
#define PSA__ALG_AEAD_WITH_DEFAULT_TAG_LENGTH__CASE(aead_alg, ref) \
|
||||
PSA_ALG_AEAD_WITH_TAG_LENGTH(aead_alg, 0) == \
|
||||
|
@ -943,7 +1039,7 @@
|
|||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding RSA PKCS#1 v1.5 signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg) \
|
||||
|
@ -974,7 +1070,7 @@
|
|||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding RSA PSS signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_PSS(hash_alg) \
|
||||
|
@ -982,37 +1078,6 @@
|
|||
#define PSA_ALG_IS_RSA_PSS(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
|
||||
|
||||
#define PSA_ALG_DSA_BASE ((psa_algorithm_t)0x10040000)
|
||||
/** DSA signature with hashing.
|
||||
*
|
||||
* This is the signature scheme defined by FIPS 186-4,
|
||||
* with a random per-message secret number (*k*).
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
* This includes #PSA_ALG_ANY_HASH
|
||||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding DSA signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DSA(hash_alg) \
|
||||
(PSA_ALG_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_DETERMINISTIC_DSA_BASE ((psa_algorithm_t)0x10050000)
|
||||
#define PSA_ALG_DSA_DETERMINISTIC_FLAG ((psa_algorithm_t)0x00010000)
|
||||
#define PSA_ALG_DETERMINISTIC_DSA(hash_alg) \
|
||||
(PSA_ALG_DETERMINISTIC_DSA_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
|
||||
#define PSA_ALG_IS_DSA(alg) \
|
||||
(((alg) & ~PSA_ALG_HASH_MASK & ~PSA_ALG_DSA_DETERMINISTIC_FLAG) == \
|
||||
PSA_ALG_DSA_BASE)
|
||||
#define PSA_ALG_DSA_IS_DETERMINISTIC(alg) \
|
||||
(((alg) & PSA_ALG_DSA_DETERMINISTIC_FLAG) != 0)
|
||||
#define PSA_ALG_IS_DETERMINISTIC_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
#define PSA_ALG_IS_RANDOMIZED_DSA(alg) \
|
||||
(PSA_ALG_IS_DSA(alg) && !PSA_ALG_DSA_IS_DETERMINISTIC(alg))
|
||||
|
||||
#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
|
||||
/** ECDSA signature with hashing.
|
||||
*
|
||||
|
@ -1031,7 +1096,7 @@
|
|||
* when specifying the algorithm in a usage policy.
|
||||
*
|
||||
* \return The corresponding ECDSA signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_ECDSA(hash_alg) \
|
||||
|
@ -1066,7 +1131,7 @@
|
|||
*
|
||||
* \return The corresponding deterministic ECDSA signature
|
||||
* algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_DETERMINISTIC_ECDSA(hash_alg) \
|
||||
|
@ -1096,7 +1161,7 @@
|
|||
*/
|
||||
#define PSA_ALG_IS_HASH_AND_SIGN(alg) \
|
||||
(PSA_ALG_IS_RSA_PSS(alg) || PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || \
|
||||
PSA_ALG_IS_DSA(alg) || PSA_ALG_IS_ECDSA(alg))
|
||||
PSA_ALG_IS_ECDSA(alg))
|
||||
|
||||
/** Get the hash used by a hash-and-sign signature algorithm.
|
||||
*
|
||||
|
@ -1138,7 +1203,7 @@
|
|||
* for MGF1.
|
||||
*
|
||||
* \return The corresponding RSA OAEP signature algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_RSA_OAEP(hash_alg) \
|
||||
|
@ -1150,16 +1215,25 @@
|
|||
((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH : \
|
||||
0)
|
||||
|
||||
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x30000100)
|
||||
#define PSA_ALG_HKDF_BASE ((psa_algorithm_t)0x20000100)
|
||||
/** Macro to build an HKDF algorithm.
|
||||
*
|
||||
* For example, `PSA_ALG_HKDF(PSA_ALG_SHA256)` is HKDF using HMAC-SHA-256.
|
||||
*
|
||||
* This key derivation algorithm uses the following inputs:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SALT is the salt used in the "extract" step.
|
||||
* It is optional; if omitted, the derivation uses an empty salt.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key used in the "extract" step.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_INFO is the info string used in the "expand" step.
|
||||
* You must pass #PSA_KEY_DERIVATION_INPUT_SALT before #PSA_KEY_DERIVATION_INPUT_SECRET.
|
||||
* You may pass #PSA_KEY_DERIVATION_INPUT_INFO at any time after steup and before
|
||||
* starting to generate output.
|
||||
*
|
||||
* \param hash_alg A hash algorithm (\c PSA_ALG_XXX value such that
|
||||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding HKDF algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_HKDF(hash_alg) \
|
||||
|
@ -1180,18 +1254,22 @@
|
|||
#define PSA_ALG_HKDF_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x30000200)
|
||||
#define PSA_ALG_TLS12_PRF_BASE ((psa_algorithm_t)0x20000200)
|
||||
/** Macro to build a TLS-1.2 PRF algorithm.
|
||||
*
|
||||
* TLS 1.2 uses a custom pseudorandom function (PRF) for key schedule,
|
||||
* specified in Section 5 of RFC 5246. It is based on HMAC and can be
|
||||
* used with either SHA-256 or SHA-384.
|
||||
*
|
||||
* For the application to TLS-1.2, the salt and label arguments passed
|
||||
* to psa_key_derivation() are what's called 'seed' and 'label' in RFC 5246,
|
||||
* respectively. For example, for TLS key expansion, the salt is the
|
||||
* This key derivation algorithm uses the following inputs, which must be
|
||||
* passed in the order given here:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
|
||||
*
|
||||
* For the application to TLS-1.2 key expansion, the seed is the
|
||||
* concatenation of ServerHello.Random + ClientHello.Random,
|
||||
* while the label is "key expansion".
|
||||
* and the label is "key expansion".
|
||||
*
|
||||
* For example, `PSA_ALG_TLS12_PRF(PSA_ALG_SHA256)` represents the
|
||||
* TLS 1.2 PRF using HMAC-SHA-256.
|
||||
|
@ -1200,7 +1278,7 @@
|
|||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding TLS-1.2 PRF algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_TLS12_PRF(hash_alg) \
|
||||
|
@ -1219,7 +1297,7 @@
|
|||
#define PSA_ALG_TLS12_PRF_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x30000300)
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS_BASE ((psa_algorithm_t)0x20000300)
|
||||
/** Macro to build a TLS-1.2 PSK-to-MasterSecret algorithm.
|
||||
*
|
||||
* In a pure-PSK handshake in TLS 1.2, the master secret is derived
|
||||
|
@ -1228,10 +1306,16 @@
|
|||
* The latter is based on HMAC and can be used with either SHA-256
|
||||
* or SHA-384.
|
||||
*
|
||||
* For the application to TLS-1.2, the salt passed to psa_key_derivation()
|
||||
* (and forwarded to the TLS-1.2 PRF) is the concatenation of the
|
||||
* ClientHello.Random + ServerHello.Random, while the label is "master secret"
|
||||
* or "extended master secret".
|
||||
* This key derivation algorithm uses the following inputs, which must be
|
||||
* passed in the order given here:
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SEED is the seed.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_SECRET is the secret key.
|
||||
* - #PSA_KEY_DERIVATION_INPUT_LABEL is the label.
|
||||
*
|
||||
* For the application to TLS-1.2, the seed (which is
|
||||
* forwarded to the TLS-1.2 PRF) is the concatenation of the
|
||||
* ClientHello.Random + ServerHello.Random,
|
||||
* and the label is "master secret" or "extended master secret".
|
||||
*
|
||||
* For example, `PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA256)` represents the
|
||||
* TLS-1.2 PSK to MasterSecret derivation PRF using HMAC-SHA-256.
|
||||
|
@ -1240,7 +1324,7 @@
|
|||
* #PSA_ALG_IS_HASH(\p hash_alg) is true).
|
||||
*
|
||||
* \return The corresponding TLS-1.2 PSK to MS algorithm.
|
||||
* \return Unspecified if \p alg is not a supported
|
||||
* \return Unspecified if \p hash_alg is not a supported
|
||||
* hash algorithm.
|
||||
*/
|
||||
#define PSA_ALG_TLS12_PSK_TO_MS(hash_alg) \
|
||||
|
@ -1259,55 +1343,67 @@
|
|||
#define PSA_ALG_TLS12_PSK_TO_MS_GET_HASH(hkdf_alg) \
|
||||
(PSA_ALG_CATEGORY_HASH | ((hkdf_alg) & PSA_ALG_HASH_MASK))
|
||||
|
||||
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x010fffff)
|
||||
#define PSA_ALG_KEY_DERIVATION_MASK ((psa_algorithm_t)0x0803ffff)
|
||||
#define PSA_ALG_KEY_AGREEMENT_MASK ((psa_algorithm_t)0x10fc0000)
|
||||
|
||||
/** Use a shared secret as is.
|
||||
/** Macro to build a combined algorithm that chains a key agreement with
|
||||
* a key derivation.
|
||||
*
|
||||
* Specify this algorithm as the selection component of a key agreement
|
||||
* to use the raw result of the key agreement as key material.
|
||||
* \param ka_alg A key agreement algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_AGREEMENT(\p ka_alg) is true).
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p kdf_alg) is true).
|
||||
*
|
||||
* \warning The raw result of a key agreement algorithm such as finite-field
|
||||
* Diffie-Hellman or elliptic curve Diffie-Hellman has biases and should
|
||||
* not be used directly as key material. It can however be used as the secret
|
||||
* input in a key derivation algorithm.
|
||||
* \return The corresponding key agreement and derivation
|
||||
* algorithm.
|
||||
* \return Unspecified if \p ka_alg is not a supported
|
||||
* key agreement algorithm or \p kdf_alg is not a
|
||||
* supported key derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_SELECT_RAW ((psa_algorithm_t)0x31000001)
|
||||
#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \
|
||||
((ka_alg) | (kdf_alg))
|
||||
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) \
|
||||
(((alg) & PSA_ALG_KEY_DERIVATION_MASK) | PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
|
||||
((alg) & ~PSA_ALG_KEY_DERIVATION_MASK)
|
||||
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) \
|
||||
(((alg) & PSA_ALG_KEY_AGREEMENT_MASK) | PSA_ALG_CATEGORY_KEY_AGREEMENT)
|
||||
|
||||
#define PSA_ALG_FFDH_BASE ((psa_algorithm_t)0x22100000)
|
||||
/** The Diffie-Hellman key agreement algorithm.
|
||||
/** Whether the specified algorithm is a raw key agreement algorithm.
|
||||
*
|
||||
* This algorithm combines the finite-field Diffie-Hellman (DH) key
|
||||
* agreement, also known as Diffie-Hellman-Merkle (DHM) key agreement,
|
||||
* to produce a shared secret from a private key and the peer's
|
||||
* public key, with a key selection or key derivation algorithm to produce
|
||||
* one or more shared keys and other shared cryptographic material.
|
||||
* A raw key agreement algorithm is one that does not specify
|
||||
* a key derivation function.
|
||||
* Usually, raw key agreement algorithms are constructed directly with
|
||||
* a \c PSA_ALG_xxx macro while non-raw key agreement algorithms are
|
||||
* constructed with PSA_ALG_KEY_AGREEMENT().
|
||||
*
|
||||
* The shared secret produced by key agreement and passed as input to the
|
||||
* derivation or selection algorithm \p kdf_alg is the shared secret
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is a raw key agreement algorithm, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) \
|
||||
(PSA_ALG_IS_KEY_AGREEMENT(alg) && \
|
||||
PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) == PSA_ALG_CATEGORY_KEY_DERIVATION)
|
||||
|
||||
#define PSA_ALG_IS_KEY_DERIVATION_OR_AGREEMENT(alg) \
|
||||
((PSA_ALG_IS_KEY_DERIVATION(alg) || PSA_ALG_IS_KEY_AGREEMENT(alg)))
|
||||
|
||||
/** The finite-field Diffie-Hellman (DH) key agreement algorithm.
|
||||
*
|
||||
* The shared secret produced by key agreement is
|
||||
* `g^{ab}` in big-endian format.
|
||||
* It is `ceiling(m / 8)` bytes long where `m` is the size of the prime `p`
|
||||
* in bits.
|
||||
*
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
|
||||
* or a key selection algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
|
||||
*
|
||||
* \return The Diffie-Hellman algorithm with the specified
|
||||
* selection or derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_FFDH(kdf_alg) \
|
||||
(PSA_ALG_FFDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
|
||||
#define PSA_ALG_FFDH ((psa_algorithm_t)0x30100000)
|
||||
|
||||
/** Whether the specified algorithm is a finite field Diffie-Hellman algorithm.
|
||||
*
|
||||
* This includes every supported key selection or key agreement algorithm
|
||||
* for the output of the Diffie-Hellman calculation.
|
||||
* This includes the raw finite field Diffie-Hellman algorithm as well as
|
||||
* finite-field Diffie-Hellman followed by any supporter key derivation
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
|
@ -1316,18 +1412,11 @@
|
|||
* key agreement algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_FFDH(alg) \
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH_BASE)
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_FFDH)
|
||||
|
||||
#define PSA_ALG_ECDH_BASE ((psa_algorithm_t)0x22200000)
|
||||
/** The elliptic curve Diffie-Hellman (ECDH) key agreement algorithm.
|
||||
*
|
||||
* This algorithm combines the elliptic curve Diffie-Hellman key
|
||||
* agreement to produce a shared secret from a private key and the peer's
|
||||
* public key, with a key selection or key derivation algorithm to produce
|
||||
* one or more shared keys and other shared cryptographic material.
|
||||
*
|
||||
* The shared secret produced by key agreement and passed as input to the
|
||||
* derivation or selection algorithm \p kdf_alg is the x-coordinate of
|
||||
* The shared secret produced by key agreement is the x-coordinate of
|
||||
* the shared secret point. It is always `ceiling(m / 8)` bytes long where
|
||||
* `m` is the bit size associated with the curve, i.e. the bit size of the
|
||||
* order of the curve's coordinate field. When `m` is not a multiple of 8,
|
||||
|
@ -1349,22 +1438,15 @@
|
|||
* the shared secret is the x-coordinate of `d_A Q_B = d_B Q_A`
|
||||
* in big-endian byte order.
|
||||
* The bit size is `m` for the field `F_{2^m}`.
|
||||
*
|
||||
* \param kdf_alg A key derivation algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_DERIVATION(\p hash_alg) is true)
|
||||
* or a selection algorithm (\c PSA_ALG_XXX value such
|
||||
* that #PSA_ALG_IS_KEY_SELECTION(\p hash_alg) is true).
|
||||
*
|
||||
* \return The Diffie-Hellman algorithm with the specified
|
||||
* selection or derivation algorithm.
|
||||
*/
|
||||
#define PSA_ALG_ECDH(kdf_alg) \
|
||||
(PSA_ALG_ECDH_BASE | ((kdf_alg) & PSA_ALG_KEY_DERIVATION_MASK))
|
||||
#define PSA_ALG_ECDH ((psa_algorithm_t)0x30200000)
|
||||
|
||||
/** Whether the specified algorithm is an elliptic curve Diffie-Hellman
|
||||
* algorithm.
|
||||
*
|
||||
* This includes every supported key selection or key agreement algorithm
|
||||
* for the output of the Diffie-Hellman calculation.
|
||||
* This includes the raw elliptic curve Diffie-Hellman algorithm as well as
|
||||
* elliptic curve Diffie-Hellman followed by any supporter key derivation
|
||||
* algorithm.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
|
@ -1374,7 +1456,7 @@
|
|||
* key agreement algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_ECDH(alg) \
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH_BASE)
|
||||
(PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) == PSA_ALG_ECDH)
|
||||
|
||||
/** Whether the specified algorithm encoding is a wildcard.
|
||||
*
|
||||
|
@ -1419,6 +1501,19 @@
|
|||
*/
|
||||
#define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001)
|
||||
|
||||
/** The minimum value for a key identifier chosen by the application.
|
||||
*/
|
||||
#define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001)
|
||||
/** The maximum value for a key identifier chosen by the application.
|
||||
*/
|
||||
#define PSA_KEY_ID_USER_MAX ((psa_key_id_t)0x3fffffff)
|
||||
/** The minimum value for a key identifier chosen by the implementation.
|
||||
*/
|
||||
#define PSA_KEY_ID_VENDOR_MIN ((psa_key_id_t)0x40000000)
|
||||
/** The maximum value for a key identifier chosen by the implementation.
|
||||
*/
|
||||
#define PSA_KEY_ID_VENDOR_MAX ((psa_key_id_t)0x7fffffff)
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup policy Key policies
|
||||
|
@ -1438,6 +1533,22 @@
|
|||
*/
|
||||
#define PSA_KEY_USAGE_EXPORT ((psa_key_usage_t)0x00000001)
|
||||
|
||||
/** Whether the key may be copied.
|
||||
*
|
||||
* This flag allows the use of psa_copy_key() to make a copy of the key
|
||||
* with the same policy or a more restrictive policy.
|
||||
*
|
||||
* For lifetimes for which the key is located in a secure element which
|
||||
* enforce the non-exportability of keys, copying a key outside the secure
|
||||
* element also requires the usage flag #PSA_KEY_USAGE_EXPORT.
|
||||
* Copying the key inside the secure element is permitted with just
|
||||
* #PSA_KEY_USAGE_COPY if the secure element supports it.
|
||||
* For keys with the lifetime #PSA_KEY_LIFETIME_VOLATILE or
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT, the usage flag #PSA_KEY_USAGE_COPY
|
||||
* is sufficient to permit the copy.
|
||||
*/
|
||||
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002)
|
||||
|
||||
/** Whether the key may be used to encrypt a message.
|
||||
*
|
||||
* This flag allows the key to be used for a symmetric encryption operation,
|
||||
|
@ -1486,4 +1597,40 @@
|
|||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup derivation Key derivation
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** A secret input for key derivation.
|
||||
*
|
||||
* This must be a key of type #PSA_KEY_TYPE_DERIVE.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SECRET ((psa_key_derivation_step_t)0x0101)
|
||||
|
||||
/** A label for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_LABEL ((psa_key_derivation_step_t)0x0201)
|
||||
|
||||
/** A salt for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SALT ((psa_key_derivation_step_t)0x0202)
|
||||
|
||||
/** An information string for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_INFO ((psa_key_derivation_step_t)0x0203)
|
||||
|
||||
/** A seed for key derivation.
|
||||
*
|
||||
* This must be a direct input.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_INPUT_SEED ((psa_key_derivation_step_t)0x0204)
|
||||
|
||||
/**@}*/
|
||||
|
||||
#endif /* PSA_CRYPTO_VALUES_H */
|
||||
|
|
|
@ -61,6 +61,7 @@ set(src_crypto
|
|||
platform_util.c
|
||||
poly1305.c
|
||||
psa_crypto.c
|
||||
psa_crypto_se.c
|
||||
psa_crypto_slot_management.c
|
||||
psa_crypto_storage.c
|
||||
psa_its_file.c
|
||||
|
|
|
@ -80,7 +80,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
|
|||
pk.o pk_wrap.o pkcs12.o \
|
||||
pkcs5.o pkparse.o pkwrite.o \
|
||||
platform.o platform_util.o poly1305.o \
|
||||
psa_crypto.o \
|
||||
psa_crypto.o psa_crypto_se.o \
|
||||
psa_crypto_slot_management.o \
|
||||
psa_crypto_storage.o \
|
||||
psa_its_file.o \
|
||||
|
|
|
@ -297,8 +297,7 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
|||
|
||||
psa_status_t status;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_usage_t key_usage;
|
||||
psa_key_policy_t key_policy;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
/* PSA Crypto API only accepts byte-aligned keys. */
|
||||
if( key_bitlen % 8 != 0 )
|
||||
|
@ -312,40 +311,33 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
|
|||
ctx->cipher_info->type );
|
||||
if( key_type == 0 )
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
|
||||
/* Allocate a key slot to use. */
|
||||
status = psa_allocate_key( &cipher_psa->slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
|
||||
/* Indicate that we own the key slot and need to
|
||||
* destroy it in mbedtls_cipher_free(). */
|
||||
cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
|
||||
|
||||
/* From that point on, the responsibility for destroying the
|
||||
* key slot is on mbedtls_cipher_free(). This includes the case
|
||||
* where the policy setup or key import below fail, as
|
||||
* mbedtls_cipher_free() needs to be called in any case. */
|
||||
|
||||
/* Setup policy for the new key slot. */
|
||||
key_policy = psa_key_policy_init();
|
||||
psa_set_key_type( &attributes, key_type );
|
||||
|
||||
/* Mbed TLS' cipher layer doesn't enforce the mode of operation
|
||||
* (encrypt vs. decrypt): it is possible to setup a key for encryption
|
||||
* and use it for AEAD decryption. Until tests relying on this
|
||||
* are changed, allow any usage in PSA. */
|
||||
/* key_usage = mbedtls_psa_translate_cipher_operation( operation ); */
|
||||
key_usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
psa_key_policy_set_usage( &key_policy, key_usage, cipher_psa->alg );
|
||||
status = psa_set_key_policy( cipher_psa->slot, &key_policy );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
/* mbedtls_psa_translate_cipher_operation( operation ); */
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||
psa_set_key_algorithm( &attributes, cipher_psa->alg );
|
||||
|
||||
/* Populate new key slot. */
|
||||
status = psa_import_key( cipher_psa->slot,
|
||||
key_type, key, key_bytelen );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
status = psa_import_key( &attributes, key, key_bytelen,
|
||||
&cipher_psa->slot );
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS:
|
||||
break;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
|
||||
default:
|
||||
return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
|
||||
}
|
||||
/* Indicate that we own the key slot and need to
|
||||
* destroy it in mbedtls_cipher_free(). */
|
||||
cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
|
||||
|
||||
ctx->key_bitlen = key_bitlen;
|
||||
ctx->operation = operation;
|
||||
|
|
37
library/pk.c
37
library/pk.c
|
@ -158,17 +158,20 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
|
|||
int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx, const psa_key_handle_t key )
|
||||
{
|
||||
const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t *pk_ctx;
|
||||
psa_key_type_t type;
|
||||
|
||||
if( ctx == NULL || ctx->pk_info != NULL )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
|
||||
if( PSA_SUCCESS != psa_get_key_information( key, &type, NULL ) )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
type = psa_get_key_type( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
/* Current implementation of can_do() relies on this. */
|
||||
if( ! PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ) )
|
||||
if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
|
||||
|
||||
if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
|
||||
|
@ -589,19 +592,18 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
|
|||
* Currently only works for EC private keys.
|
||||
*/
|
||||
int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
||||
psa_key_handle_t *slot,
|
||||
psa_key_handle_t *handle,
|
||||
psa_algorithm_t hash_alg )
|
||||
{
|
||||
#if !defined(MBEDTLS_ECP_C)
|
||||
return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
|
||||
#else
|
||||
psa_key_handle_t key;
|
||||
const mbedtls_ecp_keypair *ec;
|
||||
unsigned char d[MBEDTLS_ECP_MAX_BYTES];
|
||||
size_t d_len;
|
||||
psa_ecc_curve_t curve_id;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_policy_t policy;
|
||||
int ret;
|
||||
|
||||
/* export the private key material in the format PSA wants */
|
||||
|
@ -614,32 +616,23 @@ int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
|
|||
return( ret );
|
||||
|
||||
curve_id = mbedtls_ecp_curve_info_from_grp_id( ec->grp.id )->tls_id;
|
||||
key_type = PSA_KEY_TYPE_ECC_KEYPAIR(
|
||||
key_type = PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
mbedtls_psa_parse_tls_ecc_group ( curve_id ) );
|
||||
|
||||
/* allocate a key slot */
|
||||
if( PSA_SUCCESS != psa_allocate_key( &key ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
/* prepare the key attributes */
|
||||
psa_set_key_type( &attributes, key_type );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
|
||||
psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
|
||||
|
||||
/* set policy */
|
||||
policy = psa_key_policy_init();
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN,
|
||||
PSA_ALG_ECDSA(hash_alg) );
|
||||
if( PSA_SUCCESS != psa_set_key_policy( key, &policy ) )
|
||||
/* import private key into PSA */
|
||||
if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, handle ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
|
||||
/* import private key in slot */
|
||||
if( PSA_SUCCESS != psa_import_key( key, key_type, d, d_len ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
|
||||
/* remember slot number to be destroyed later by caller */
|
||||
*slot = key;
|
||||
|
||||
/* make PK context wrap the key slot */
|
||||
mbedtls_pk_free( pk );
|
||||
mbedtls_pk_init( pk );
|
||||
|
||||
return( mbedtls_pk_setup_opaque( pk, key ) );
|
||||
return( mbedtls_pk_setup_opaque( pk, *handle ) );
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
|
|
@ -546,9 +546,9 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
const unsigned char *sig, size_t sig_len )
|
||||
{
|
||||
int ret;
|
||||
psa_key_handle_t key_slot;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_type_t psa_type;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t key_handle = 0;
|
||||
psa_status_t status;
|
||||
mbedtls_pk_context key;
|
||||
int key_len;
|
||||
/* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
|
||||
|
@ -576,23 +576,17 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
if( psa_md == 0 )
|
||||
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
|
||||
psa_sig_md = PSA_ALG_ECDSA( psa_md );
|
||||
psa_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
|
||||
|
||||
if( ( ret = psa_allocate_key( &key_slot ) ) != PSA_SUCCESS )
|
||||
return( mbedtls_psa_err_translate_pk( ret ) );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY );
|
||||
psa_set_key_algorithm( &attributes, psa_sig_md );
|
||||
|
||||
policy = psa_key_policy_init();
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_VERIFY, psa_sig_md );
|
||||
if( ( ret = psa_set_key_policy( key_slot, &policy ) ) != PSA_SUCCESS )
|
||||
status = psa_import_key( &attributes,
|
||||
buf + sizeof( buf ) - key_len, key_len,
|
||||
&key_handle );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
ret = mbedtls_psa_err_translate_pk( ret );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if( psa_import_key( key_slot, psa_type, buf + sizeof( buf ) - key_len, key_len )
|
||||
!= PSA_SUCCESS )
|
||||
{
|
||||
ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
|
||||
ret = mbedtls_psa_err_translate_pk( status );
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -611,7 +605,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if( psa_asymmetric_verify( key_slot, psa_sig_md,
|
||||
if( psa_asymmetric_verify( key_handle, psa_sig_md,
|
||||
hash, hash_len,
|
||||
buf, 2 * signature_part_size )
|
||||
!= PSA_SUCCESS )
|
||||
|
@ -628,7 +622,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
psa_destroy_key( key_slot );
|
||||
psa_destroy_key( key_handle );
|
||||
return( ret );
|
||||
}
|
||||
#else /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -898,10 +892,13 @@ static size_t pk_opaque_get_bitlen( const void *ctx )
|
|||
{
|
||||
const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
|
||||
size_t bits;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
if( PSA_SUCCESS != psa_get_key_information( *key, NULL, &bits ) )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) )
|
||||
return( 0 );
|
||||
|
||||
bits = psa_get_key_bits( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
return( bits );
|
||||
}
|
||||
|
||||
|
@ -1002,8 +999,9 @@ static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
|
||||
{
|
||||
const psa_key_handle_t *key = (const psa_key_handle_t *) ctx;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
|
||||
size_t bits, buf_len;
|
||||
size_t buf_len;
|
||||
psa_status_t status;
|
||||
|
||||
/* PSA has its own RNG */
|
||||
|
@ -1014,11 +1012,11 @@ static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
|
|||
* that information. Assume that the buffer is large enough for a
|
||||
* maximal-length signature with that key (otherwise the application is
|
||||
* buggy anyway). */
|
||||
status = psa_get_key_information( *key, NULL, &bits );
|
||||
status = psa_get_key_attributes( *key, &attributes );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( mbedtls_psa_err_translate_pk( status ) );
|
||||
|
||||
buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( bits );
|
||||
buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
/* make the signature */
|
||||
status = psa_asymmetric_sign( *key, alg, hash, hash_len,
|
||||
|
|
|
@ -246,17 +246,16 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
|
|||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( pk_type == MBEDTLS_PK_OPAQUE )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t key_type;
|
||||
psa_key_handle_t handle;
|
||||
psa_ecc_curve_t curve;
|
||||
|
||||
handle = *((psa_key_handle_t*) key->pk_ctx );
|
||||
|
||||
status = psa_get_key_information( handle, &key_type,
|
||||
NULL /* bitsize not needed */ );
|
||||
if( status != PSA_SUCCESS )
|
||||
if( PSA_SUCCESS != psa_get_key_attributes( handle, &attributes ) )
|
||||
return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
|
||||
key_type = psa_get_key_type( &attributes );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
curve = PSA_KEY_TYPE_GET_CURVE( key_type );
|
||||
if( curve == 0 )
|
||||
|
|
2461
library/psa_crypto.c
2461
library/psa_crypto.c
File diff suppressed because it is too large
Load diff
|
@ -29,6 +29,7 @@
|
|||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/rsa.h"
|
||||
|
@ -38,27 +39,95 @@
|
|||
*/
|
||||
typedef struct
|
||||
{
|
||||
psa_key_type_t type;
|
||||
psa_key_policy_t policy;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_file_id_t persistent_storage_id;
|
||||
unsigned allocated : 1;
|
||||
psa_core_key_attributes_t attr;
|
||||
union
|
||||
{
|
||||
/* Raw-data key (key_type_is_raw_bytes() in psa_crypto.c) */
|
||||
struct raw_data
|
||||
{
|
||||
uint8_t *data;
|
||||
size_t bytes;
|
||||
} raw;
|
||||
#if defined(MBEDTLS_RSA_C)
|
||||
/* RSA public key or key pair */
|
||||
mbedtls_rsa_context *rsa;
|
||||
#endif /* MBEDTLS_RSA_C */
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
/* EC public key or key pair */
|
||||
mbedtls_ecp_keypair *ecp;
|
||||
#endif /* MBEDTLS_ECP_C */
|
||||
/* Any key type in a secure element */
|
||||
struct se
|
||||
{
|
||||
psa_key_slot_number_t slot_number;
|
||||
} se;
|
||||
} data;
|
||||
} psa_key_slot_t;
|
||||
|
||||
/** Test whether a key slot is occupied.
|
||||
*
|
||||
* A key slot is occupied iff the key type is nonzero. This works because
|
||||
* no valid key can have 0 as its key type.
|
||||
*
|
||||
* \param[in] slot The key slot to test.
|
||||
*
|
||||
* \return 1 if the slot is occupied, 0 otherwise.
|
||||
*/
|
||||
static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot )
|
||||
{
|
||||
return( slot->attr.type != 0 );
|
||||
}
|
||||
|
||||
/** Retrieve flags from psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in] slot The key slot to query.
|
||||
* \param mask The mask of bits to extract.
|
||||
*
|
||||
* \return The key attribute flags in the given slot,
|
||||
* bitwise-anded with \p mask.
|
||||
*/
|
||||
static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
return( slot->attr.flags & mask );
|
||||
}
|
||||
|
||||
/** Set flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to modify.
|
||||
* \param value The new value of the selected bits.
|
||||
*/
|
||||
static inline void psa_key_slot_set_flags( psa_key_slot_t *slot,
|
||||
uint16_t mask,
|
||||
uint16_t value )
|
||||
{
|
||||
slot->attr.flags = ( ( ~mask & slot->attr.flags ) |
|
||||
( mask & value ) );
|
||||
}
|
||||
|
||||
/** Turn on flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to set.
|
||||
*/
|
||||
static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
slot->attr.flags |= mask;
|
||||
}
|
||||
|
||||
/** Turn off flags in psa_key_slot_t::attr::core::flags.
|
||||
*
|
||||
* \param[in,out] slot The key slot to modify.
|
||||
* \param mask The mask of bits to clear.
|
||||
*/
|
||||
static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot,
|
||||
uint16_t mask )
|
||||
{
|
||||
slot->attr.flags &= ~mask;
|
||||
}
|
||||
|
||||
/** Completely wipe a slot in memory, including its policy.
|
||||
*
|
||||
* Persistent storage is not affected.
|
||||
|
@ -68,7 +137,7 @@ typedef struct
|
|||
* \retval PSA_SUCCESS
|
||||
* Success. This includes the case of a key slot that was
|
||||
* already fully wiped.
|
||||
* \retval PSA_ERROR_TAMPERING_DETECTED
|
||||
* \retval PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot );
|
||||
|
||||
|
|
339
library/psa_crypto_se.c
Normal file
339
library/psa_crypto_se.c
Normal file
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/* Copyright (C) 2019, 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_SE_C)
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "psa_crypto_se.h"
|
||||
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include "psa_crypto_its.h"
|
||||
#else /* Native ITS implementation */
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#if !defined(MBEDTLS_PLATFORM_C)
|
||||
#define mbedtls_calloc calloc
|
||||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver lookup */
|
||||
/****************************************************************/
|
||||
|
||||
/* This structure is identical to psa_drv_se_context_t declared in
|
||||
* `crypto_se_driver.h`, except that some parts are writable here
|
||||
* (non-const, or pointer to non-const). */
|
||||
typedef struct
|
||||
{
|
||||
void *persistent_data;
|
||||
size_t persistent_data_size;
|
||||
uintptr_t transient_data;
|
||||
} psa_drv_se_internal_context_t;
|
||||
|
||||
typedef struct psa_se_drv_table_entry_s
|
||||
{
|
||||
psa_key_lifetime_t lifetime;
|
||||
const psa_drv_se_t *methods;
|
||||
union
|
||||
{
|
||||
psa_drv_se_internal_context_t internal;
|
||||
psa_drv_se_context_t context;
|
||||
};
|
||||
} psa_se_drv_table_entry_t;
|
||||
|
||||
static psa_se_drv_table_entry_t driver_table[PSA_MAX_SE_DRIVERS];
|
||||
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime )
|
||||
{
|
||||
size_t i;
|
||||
/* In the driver table, lifetime=0 means an entry that isn't used.
|
||||
* No driver has a lifetime of 0 because it's a reserved value
|
||||
* (which designates volatile keys). Make sure we never return
|
||||
* a driver entry for lifetime 0. */
|
||||
if( lifetime == 0 )
|
||||
return( NULL );
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].lifetime == lifetime )
|
||||
return( &driver_table[i] );
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
return( driver->methods );
|
||||
}
|
||||
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
return( &driver->context );
|
||||
}
|
||||
|
||||
int psa_get_se_driver( psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context)
|
||||
{
|
||||
psa_se_drv_table_entry_t *driver = psa_get_se_driver_entry( lifetime );
|
||||
if( p_methods != NULL )
|
||||
*p_methods = ( driver ? driver->methods : NULL );
|
||||
if( p_drv_context != NULL )
|
||||
*p_drv_context = ( driver ? &driver->context : NULL );
|
||||
return( driver != NULL );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Persistent data management */
|
||||
/****************************************************************/
|
||||
|
||||
static psa_status_t psa_get_se_driver_its_file_uid(
|
||||
const psa_se_drv_table_entry_t *driver,
|
||||
psa_storage_uid_t *uid )
|
||||
{
|
||||
if( driver->lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
#if SIZE_MAX > UINT32_MAX
|
||||
/* ITS file sizes are limited to 32 bits. */
|
||||
if( driver->internal.persistent_data_size > UINT32_MAX )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif
|
||||
|
||||
/* See the documentation of PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE. */
|
||||
*uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + driver->lifetime;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
size_t length;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid( driver, &uid );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* Read the amount of persistent data that the driver requests.
|
||||
* If the data in storage is larger, it is truncated. If the data
|
||||
* in storage is smaller, silently keep what is already at the end
|
||||
* of the output buffer. */
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return( psa_its_get( uid, 0,
|
||||
(uint32_t) driver->internal.persistent_data_size,
|
||||
driver->internal.persistent_data,
|
||||
&length ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_storage_uid_t uid;
|
||||
|
||||
status = psa_get_se_driver_its_file_uid( driver, &uid );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
/* psa_get_se_driver_its_file_uid ensures that the size_t
|
||||
* persistent_data_size is in range, but compilers don't know that,
|
||||
* so cast to reassure them. */
|
||||
return( psa_its_set( uid,
|
||||
(uint32_t) driver->internal.persistent_data_size,
|
||||
driver->internal.persistent_data,
|
||||
0 ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime )
|
||||
{
|
||||
psa_storage_uid_t uid;
|
||||
if( lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
uid = PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE + lifetime;
|
||||
return( psa_its_remove( uid ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_drv_se_allocate_key_t p_allocate = NULL;
|
||||
|
||||
/* If the lifetime is wrong, it's a bug in the library. */
|
||||
if( driver->lifetime != psa_get_key_lifetime( attributes ) )
|
||||
return( PSA_ERROR_CORRUPTION_DETECTED );
|
||||
|
||||
/* If the driver doesn't support key creation in any way, give up now. */
|
||||
if( driver->methods->key_management == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
p_allocate = driver->methods->key_management->p_allocate;
|
||||
|
||||
/* If the driver doesn't tell us how to allocate a slot, that's
|
||||
* not supported for the time being. */
|
||||
if( p_allocate == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
status = p_allocate( &driver->context,
|
||||
driver->internal.persistent_data,
|
||||
attributes,
|
||||
slot_number );
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_status_t storage_status;
|
||||
/* Normally a missing method would mean that the action is not
|
||||
* supported. But psa_destroy_key() is not supposed to return
|
||||
* PSA_ERROR_NOT_SUPPORTED: if you can create a key, you should
|
||||
* be able to destroy it. The only use case for a driver that
|
||||
* does not have a way to destroy keys at all is if the keys are
|
||||
* locked in a read-only state: we can use the keys but not
|
||||
* destroy them. Hence, if the driver doesn't support destroying
|
||||
* keys, it's really a lack of permission. */
|
||||
if( driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_destroy == NULL )
|
||||
return( PSA_ERROR_NOT_PERMITTED );
|
||||
status = driver->methods->key_management->p_destroy(
|
||||
&driver->context,
|
||||
driver->internal.persistent_data,
|
||||
slot_number );
|
||||
storage_status = psa_save_se_persistent_data( driver );
|
||||
return( status == PSA_SUCCESS ? storage_status : status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Driver registration */
|
||||
/****************************************************************/
|
||||
|
||||
psa_status_t psa_register_se_driver(
|
||||
psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t *methods)
|
||||
{
|
||||
size_t i;
|
||||
psa_status_t status;
|
||||
|
||||
if( methods->hal_version != PSA_DRV_SE_HAL_VERSION )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
/* Driver table entries are 0-initialized. 0 is not a valid driver
|
||||
* lifetime because it means a volatile key. */
|
||||
#if defined(static_assert)
|
||||
static_assert( PSA_KEY_LIFETIME_VOLATILE == 0,
|
||||
"Secure element support requires 0 to mean a volatile key" );
|
||||
#endif
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE ||
|
||||
lifetime == PSA_KEY_LIFETIME_PERSISTENT )
|
||||
{
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
if( lifetime > PSA_MAX_SE_LIFETIME )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].lifetime == 0 )
|
||||
break;
|
||||
/* Check that lifetime isn't already in use up to the first free
|
||||
* entry. Since entries are created in order and never deleted,
|
||||
* there can't be a used entry after the first free entry. */
|
||||
if( driver_table[i].lifetime == lifetime )
|
||||
return( PSA_ERROR_ALREADY_EXISTS );
|
||||
}
|
||||
if( i == PSA_MAX_SE_DRIVERS )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
driver_table[i].lifetime = lifetime;
|
||||
driver_table[i].methods = methods;
|
||||
|
||||
if( methods->persistent_data_size != 0 )
|
||||
{
|
||||
driver_table[i].internal.persistent_data =
|
||||
mbedtls_calloc( 1, methods->persistent_data_size );
|
||||
if( driver_table[i].internal.persistent_data == NULL )
|
||||
{
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* Load the driver's persistent data. On first use, the persistent
|
||||
* data does not exist in storage, and is initialized to
|
||||
* all-bits-zero by the calloc call just above. */
|
||||
status = psa_load_se_persistent_data( &driver_table[i] );
|
||||
if( status != PSA_SUCCESS && status != PSA_ERROR_DOES_NOT_EXIST )
|
||||
goto error;
|
||||
}
|
||||
driver_table[i].internal.persistent_data_size =
|
||||
methods->persistent_data_size;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
error:
|
||||
memset( &driver_table[i], 0, sizeof( driver_table[i] ) );
|
||||
return( status );
|
||||
}
|
||||
|
||||
void psa_unregister_all_se_drivers( void )
|
||||
{
|
||||
size_t i;
|
||||
for( i = 0; i < PSA_MAX_SE_DRIVERS; i++ )
|
||||
{
|
||||
if( driver_table[i].internal.persistent_data != NULL )
|
||||
mbedtls_free( driver_table[i].internal.persistent_data );
|
||||
}
|
||||
memset( driver_table, 0, sizeof( driver_table ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
183
library/psa_crypto_se.h
Normal file
183
library/psa_crypto_se.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* PSA crypto support for secure element drivers
|
||||
*/
|
||||
/* Copyright (C) 2019, 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_SE_H
|
||||
#define PSA_CRYPTO_SE_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/** The maximum lifetime value that this implementation supports
|
||||
* for a secure element.
|
||||
*
|
||||
* This is not a characteristic that each PSA implementation has, but a
|
||||
* limitation of the current implementation due to the constraints imposed
|
||||
* by storage. See #PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE.
|
||||
*
|
||||
* The minimum lifetime value for a secure element is 2, like on any
|
||||
* PSA implementation (0=volatile and 1=internal-storage are taken).
|
||||
*/
|
||||
#define PSA_MAX_SE_LIFETIME 255
|
||||
|
||||
/** The base of the range of ITS file identifiers for secure element
|
||||
* driver persistent data.
|
||||
*
|
||||
* We use a slice of the implemenation reserved range 0xffff0000..0xffffffff,
|
||||
* specifically the range 0xfffffe00..0xfffffeff. The length of this range
|
||||
* drives the value of #PSA_MAX_SE_LIFETIME.
|
||||
* The identifiers 0xfffffe00 and 0xfffffe01 are actually not used since
|
||||
* they correspond to #PSA_KEY_LIFETIME_VOLATILE and
|
||||
* #PSA_KEY_LIFETIME_PERSISTENT which don't have a driver.
|
||||
*/
|
||||
#define PSA_CRYPTO_SE_DRIVER_ITS_UID_BASE ( (psa_key_id_t) 0xfffffe00 )
|
||||
|
||||
/** The maximum number of registered secure element driver lifetimes. */
|
||||
#define PSA_MAX_SE_DRIVERS 4
|
||||
|
||||
/** Unregister all secure element drivers.
|
||||
*
|
||||
* \warning Do not call this function while the library is in the initialized
|
||||
* state. This function is only intended to be called at the end
|
||||
* of mbedtls_psa_crypto_free().
|
||||
*/
|
||||
void psa_unregister_all_se_drivers( void );
|
||||
|
||||
/** A structure that describes a registered secure element driver.
|
||||
*
|
||||
* A secure element driver table entry contains a pointer to the
|
||||
* driver's method table as well as the driver context structure.
|
||||
*/
|
||||
typedef struct psa_se_drv_table_entry_s psa_se_drv_table_entry_t;
|
||||
|
||||
/** Return the secure element driver information for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
* \param[out] p_methods On output, if there is a driver,
|
||||
* \c *methods points to its method table.
|
||||
* Otherwise \c *methods is \c NULL.
|
||||
* \param[out] p_drv_context On output, if there is a driver,
|
||||
* \c *drv_context points to its context
|
||||
* structure.
|
||||
* Otherwise \c *drv_context is \c NULL.
|
||||
*
|
||||
* \retval 1
|
||||
* \p lifetime corresponds to a registered driver.
|
||||
* \retval 0
|
||||
* \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
int psa_get_se_driver( psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context);
|
||||
|
||||
/** Return the secure element driver table entry for a lifetime value.
|
||||
*
|
||||
* \param lifetime The lifetime value to query.
|
||||
*
|
||||
* \return The driver table entry for \p lifetime, or
|
||||
* \p NULL if \p lifetime does not correspond to a registered driver.
|
||||
*/
|
||||
psa_se_drv_table_entry_t *psa_get_se_driver_entry(
|
||||
psa_key_lifetime_t lifetime );
|
||||
|
||||
/** Return the method table for a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return The driver's method table.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Return the context of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry to access, or \c NULL.
|
||||
*
|
||||
* \return A pointer to the driver context.
|
||||
* \c NULL if \p driver is \c NULL.
|
||||
*/
|
||||
psa_drv_se_context_t *psa_get_se_driver_context(
|
||||
psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Find a free slot for a key that is to be created.
|
||||
*
|
||||
* This function calls the relevant method in the driver to find a suitable
|
||||
* slot for a key with the given attributes.
|
||||
*
|
||||
* \param[in] attributes Metadata about the key that is about to be created.
|
||||
* \param[in] driver The driver table entry to query.
|
||||
* \param[out] slot_number On success, a slot number that is free in this
|
||||
* secure element.
|
||||
*/
|
||||
psa_status_t psa_find_se_slot_for_key(
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t *slot_number );
|
||||
|
||||
/** Destoy a key in a secure element.
|
||||
*
|
||||
* This function calls the relevant driver method to destroy a key
|
||||
* and updates the driver's persistent data.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_key( psa_se_drv_table_entry_t *driver,
|
||||
psa_key_slot_number_t slot_number );
|
||||
|
||||
/** Load the persistent data of a secure element driver.
|
||||
*
|
||||
* \param driver The driver table entry containing the persistent
|
||||
* data to load from storage.
|
||||
*/
|
||||
psa_status_t psa_load_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Save the persistent data of a secure element driver.
|
||||
*
|
||||
* \param[in] driver The driver table entry containing the persistent
|
||||
* data to save to storage.
|
||||
*/
|
||||
psa_status_t psa_save_se_persistent_data(
|
||||
const psa_se_drv_table_entry_t *driver );
|
||||
|
||||
/** Destroy the persistent data of a secure element driver.
|
||||
*
|
||||
* This is currently only used for testing.
|
||||
*
|
||||
* \param[in] lifetime The driver lifetime whose persistent data should
|
||||
* be erased.
|
||||
*/
|
||||
psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime );
|
||||
|
||||
|
||||
/** The storage representation of a key whose data is in a secure element.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot_number[sizeof( psa_key_slot_number_t )];
|
||||
uint8_t bits[sizeof( psa_key_bits_t )];
|
||||
} psa_se_key_data_storage_t;
|
||||
|
||||
#endif /* PSA_CRYPTO_SE_H */
|
|
@ -33,6 +33,9 @@
|
|||
#include "psa_crypto_core.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
#include "psa_crypto_se.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -71,8 +74,8 @@ psa_status_t psa_get_key_slot( psa_key_handle_t handle,
|
|||
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 )
|
||||
/* If the slot isn't occupied, the handle is invalid. */
|
||||
if( ! psa_is_key_slot_occupied( slot ) )
|
||||
return( PSA_ERROR_INVALID_HANDLE );
|
||||
|
||||
*p_slot = slot;
|
||||
|
@ -99,71 +102,55 @@ void psa_wipe_all_key_slots( void )
|
|||
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 )
|
||||
psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle,
|
||||
psa_key_slot_t **p_slot )
|
||||
{
|
||||
if( ! global_data.key_slots_initialized )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
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;
|
||||
*p_slot = &global_data.key_slots[*handle - 1];
|
||||
if( ! psa_is_key_slot_occupied( *p_slot ) )
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
}
|
||||
*p_slot = NULL;
|
||||
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_handle_t *handle )
|
||||
{
|
||||
*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 )
|
||||
static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *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 );
|
||||
status = psa_load_persistent_key( &slot->attr,
|
||||
&key_data, &key_data_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
status = psa_import_key_into_slot( p_slot,
|
||||
key_data, key_data_length );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( psa_key_lifetime_is_external( slot->attr.lifetime ) )
|
||||
{
|
||||
psa_se_key_data_storage_t *data;
|
||||
if( key_data_length != sizeof( *data ) )
|
||||
{
|
||||
status = PSA_ERROR_STORAGE_FAILURE;
|
||||
goto exit;
|
||||
}
|
||||
data = (psa_se_key_data_storage_t *) key_data;
|
||||
memcpy( &slot->data.se.slot_number, &data->slot_number,
|
||||
sizeof( slot->data.se.slot_number ) );
|
||||
memcpy( &slot->attr.bits, &data->bits,
|
||||
sizeof( slot->attr.bits ) );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
{
|
||||
status = psa_import_key_into_slot( slot, key_data, key_data_length );
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_free_persistent_key_data( key_data, key_data_length );
|
||||
return( status );
|
||||
|
@ -176,120 +163,132 @@ exit:
|
|||
* is provided.
|
||||
*
|
||||
* \param file_id The key identifier to check.
|
||||
* \param vendor_ok Nonzero to allow key ids in the vendor range.
|
||||
* 0 to allow only key ids in the application range.
|
||||
*
|
||||
* \return 1 if \p file_id is acceptable, otherwise 0.
|
||||
*/
|
||||
static int psa_is_key_id_valid( psa_key_file_id_t file_id )
|
||||
static int psa_is_key_id_valid( psa_key_file_id_t file_id,
|
||||
int vendor_ok )
|
||||
{
|
||||
psa_app_key_id_t key_id = PSA_KEY_FILE_GET_KEY_ID( file_id );
|
||||
/* Reject id=0 because by general library conventions, 0 is an invalid
|
||||
* value wherever possible. */
|
||||
if( key_id == 0 )
|
||||
if( PSA_KEY_ID_USER_MIN <= key_id && key_id <= PSA_KEY_ID_USER_MAX )
|
||||
return( 1 );
|
||||
else if( vendor_ok &&
|
||||
PSA_KEY_ID_VENDOR_MIN <= key_id &&
|
||||
key_id <= PSA_KEY_ID_VENDOR_MAX )
|
||||
return( 1 );
|
||||
else
|
||||
return( 0 );
|
||||
/* Reject high values because the file names are reserved for the
|
||||
* library's internal use. */
|
||||
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
|
||||
return( 0 );
|
||||
return( 1 );
|
||||
}
|
||||
#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_DOES_NOT_EXIST
|
||||
* 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_file_id_t id )
|
||||
psa_status_t psa_validate_persistent_key_parameters(
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_se_drv_table_entry_t **p_drv,
|
||||
int creating )
|
||||
{
|
||||
if( p_drv != NULL )
|
||||
*p_drv = NULL;
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( psa_key_lifetime_is_external( lifetime ) )
|
||||
{
|
||||
*p_drv = psa_get_se_driver_entry( lifetime );
|
||||
if( *p_drv == NULL )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
if( lifetime != PSA_KEY_LIFETIME_PERSISTENT )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
if( ! psa_is_key_id_valid( id, ! creating ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
return( PSA_SUCCESS );
|
||||
|
||||
#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
(void) id;
|
||||
(void) creating;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* !MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
}
|
||||
|
||||
psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle )
|
||||
{
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_key_slot_t *slot;
|
||||
psa_status_t status;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
if( ! psa_is_key_id_valid( id ) )
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
*handle = 0;
|
||||
|
||||
status = psa_validate_persistent_key_parameters(
|
||||
PSA_KEY_LIFETIME_PERSISTENT, id, NULL, 0 );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
status = psa_internal_allocate_key_slot( handle, &slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT;
|
||||
slot->attr.id = id;
|
||||
|
||||
status = psa_load_persistent_key_into_slot( slot );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_wipe_key_slot( slot );
|
||||
*handle = 0;
|
||||
}
|
||||
return( status );
|
||||
|
||||
#else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
(void) id;
|
||||
*handle = 0;
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
#endif /* !defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
|
||||
}
|
||||
|
||||
psa_status_t psa_close_key( psa_key_handle_t handle )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_slot_t *slot;
|
||||
|
||||
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 */
|
||||
return( psa_wipe_key_slot( slot ) );
|
||||
}
|
||||
|
||||
static psa_status_t persistent_key_setup( psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_key_handle_t *handle,
|
||||
psa_status_t wanted_load_status )
|
||||
void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats )
|
||||
{
|
||||
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_key_handle_t key;
|
||||
memset( stats, 0, sizeof( *stats ) );
|
||||
for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ )
|
||||
{
|
||||
psa_internal_release_key_slot( *handle );
|
||||
*handle = 0;
|
||||
const psa_key_slot_t *slot = &global_data.key_slots[key - 1];
|
||||
if( ! psa_is_key_slot_occupied( slot ) )
|
||||
{
|
||||
++stats->empty_slots;
|
||||
continue;
|
||||
}
|
||||
if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
++stats->volatile_slots;
|
||||
else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT )
|
||||
{
|
||||
++stats->persistent_slots;
|
||||
if( slot->attr.id > stats->max_open_internal_key_id )
|
||||
stats->max_open_internal_key_id = slot->attr.id;
|
||||
}
|
||||
else
|
||||
{
|
||||
++stats->external_slots;
|
||||
if( slot->attr.id > stats->max_open_external_key_id )
|
||||
stats->max_open_external_key_id = slot->attr.id;
|
||||
}
|
||||
}
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_open_key( psa_key_lifetime_t lifetime,
|
||||
psa_key_file_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_file_id_t id,
|
||||
psa_key_handle_t *handle )
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
status = persistent_key_setup( lifetime, id, handle,
|
||||
PSA_ERROR_DOES_NOT_EXIST );
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS: return( PSA_ERROR_ALREADY_EXISTS );
|
||||
case PSA_ERROR_DOES_NOT_EXIST: 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 */
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se.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
|
||||
|
@ -55,4 +58,72 @@ psa_status_t psa_initialize_key_slots( void );
|
|||
* This does not affect persistent storage. */
|
||||
void psa_wipe_all_key_slots( void );
|
||||
|
||||
/** Find a free key slot.
|
||||
*
|
||||
* This function returns a key slot that is available for use and is in its
|
||||
* ground state (all-bits-zero).
|
||||
*
|
||||
* \param[out] handle On success, a slot number that can be used as a
|
||||
* handle to the slot.
|
||||
* \param[out] p_slot On success, a pointer to the slot.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* \retval #PSA_ERROR_BAD_STATE
|
||||
*/
|
||||
psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle,
|
||||
psa_key_slot_t **p_slot );
|
||||
|
||||
/** Test whether a lifetime designates a key in an external cryptoprocessor.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
*
|
||||
* \retval 1
|
||||
* The lifetime designates an external key. There should be a
|
||||
* registered driver for this lifetime, otherwise the key cannot
|
||||
* be created or manipulated.
|
||||
* \retval 0
|
||||
* The lifetime designates a key that is volatile or in internal
|
||||
* storage.
|
||||
*/
|
||||
static inline int psa_key_lifetime_is_external( psa_key_lifetime_t lifetime )
|
||||
{
|
||||
return( lifetime != PSA_KEY_LIFETIME_VOLATILE &&
|
||||
lifetime != PSA_KEY_LIFETIME_PERSISTENT );
|
||||
}
|
||||
|
||||
/** Test whether the given parameters are acceptable for a persistent key.
|
||||
*
|
||||
* This function does not access the storage in any way. It only tests
|
||||
* whether the parameters are meaningful and permitted by general policy.
|
||||
* It does not test whether the a file by the given id exists or could be
|
||||
* created.
|
||||
*
|
||||
* If the key is in external storage, this function returns the corresponding
|
||||
* driver.
|
||||
*
|
||||
* \param lifetime The lifetime to test.
|
||||
* \param id The key id to test.
|
||||
* \param[out] p_drv On output, if \p lifetime designates a key
|
||||
* in an external processor, \c *p_drv is a pointer
|
||||
* to the driver table entry fot this lifetime.
|
||||
* If \p lifetime designates a transparent key,
|
||||
* \c *p_drv is \c NULL.
|
||||
* \param creating 0 if attempting to open an existing key.
|
||||
* Nonzero if attempting to create a key.
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* The given parameters are valid.
|
||||
* \retval PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p lifetime is volatile or is invalid.
|
||||
* \retval PSA_ERROR_INVALID_ARGUMENT
|
||||
* \p id is invalid.
|
||||
*/
|
||||
psa_status_t psa_validate_persistent_key_parameters(
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_file_id_t id,
|
||||
psa_se_drv_table_entry_t **p_drv,
|
||||
int creating );
|
||||
|
||||
|
||||
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|
||||
|
|
|
@ -50,6 +50,12 @@
|
|||
#define mbedtls_free free
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key storage */
|
||||
/****************************************************************/
|
||||
|
||||
/* Determine a file name (ITS file identifier) for the given key file
|
||||
* identifier. The file name must be distinct from any file that is used
|
||||
* for a purpose other than storing a key. Currently, the only such file
|
||||
|
@ -224,7 +230,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
|||
* 32-bit integer manipulation macros (little endian)
|
||||
*/
|
||||
#ifndef GET_UINT32_LE
|
||||
#define GET_UINT32_LE(n,b,i) \
|
||||
#define GET_UINT32_LE( n, b, i ) \
|
||||
{ \
|
||||
(n) = ( (uint32_t) (b)[(i) ] ) \
|
||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \
|
||||
|
@ -234,7 +240,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
|||
#endif
|
||||
|
||||
#ifndef PUT_UINT32_LE
|
||||
#define PUT_UINT32_LE(n,b,i) \
|
||||
#define PUT_UINT32_LE( n, b, i ) \
|
||||
{ \
|
||||
(b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
|
||||
(b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
|
||||
|
@ -252,6 +258,7 @@ static psa_status_t psa_crypto_storage_get_data_length(
|
|||
typedef struct {
|
||||
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
||||
uint8_t version[4];
|
||||
uint8_t lifetime[sizeof( psa_key_lifetime_t )];
|
||||
uint8_t type[sizeof( psa_key_type_t )];
|
||||
uint8_t policy[sizeof( psa_key_policy_t )];
|
||||
uint8_t data_len[4];
|
||||
|
@ -260,20 +267,20 @@ typedef struct {
|
|||
|
||||
void psa_format_key_data_for_storage( const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
uint8_t *storage_data )
|
||||
{
|
||||
psa_persistent_key_storage_format *storage_format =
|
||||
(psa_persistent_key_storage_format *) storage_data;
|
||||
|
||||
memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH );
|
||||
PUT_UINT32_LE(0, storage_format->version, 0);
|
||||
PUT_UINT32_LE(type, storage_format->type, 0);
|
||||
PUT_UINT32_LE(policy->usage, storage_format->policy, 0);
|
||||
PUT_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
|
||||
PUT_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE(data_length, storage_format->data_len, 0);
|
||||
PUT_UINT32_LE( 0, storage_format->version, 0 );
|
||||
PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
|
||||
PUT_UINT32_LE( attr->type, storage_format->type, 0 );
|
||||
PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
|
||||
PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
PUT_UINT32_LE( data_length, storage_format->data_len, 0 );
|
||||
memcpy( storage_format->key_data, data, data_length );
|
||||
}
|
||||
|
||||
|
@ -289,8 +296,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
|||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy )
|
||||
psa_core_key_attributes_t *attr )
|
||||
{
|
||||
psa_status_t status;
|
||||
const psa_persistent_key_storage_format *storage_format =
|
||||
|
@ -304,32 +310,37 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
|||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
|
||||
GET_UINT32_LE(version, storage_format->version, 0);
|
||||
GET_UINT32_LE( version, storage_format->version, 0 );
|
||||
if( version != 0 )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
|
||||
GET_UINT32_LE(*key_data_length, storage_format->data_len, 0);
|
||||
GET_UINT32_LE( *key_data_length, storage_format->data_len, 0 );
|
||||
if( *key_data_length > ( storage_data_length - sizeof(*storage_format) ) ||
|
||||
*key_data_length > PSA_CRYPTO_MAX_STORAGE_SIZE )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
|
||||
*key_data = mbedtls_calloc( 1, *key_data_length );
|
||||
if( *key_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
if( *key_data_length == 0 )
|
||||
{
|
||||
*key_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*key_data = mbedtls_calloc( 1, *key_data_length );
|
||||
if( *key_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
memcpy( *key_data, storage_format->key_data, *key_data_length );
|
||||
}
|
||||
|
||||
GET_UINT32_LE(*type, storage_format->type, 0);
|
||||
GET_UINT32_LE(policy->usage, storage_format->policy, 0);
|
||||
GET_UINT32_LE(policy->alg, storage_format->policy, sizeof( uint32_t ));
|
||||
GET_UINT32_LE(policy->alg2, storage_format->policy, 2 * sizeof( uint32_t ));
|
||||
|
||||
memcpy( *key_data, storage_format->key_data, *key_data_length );
|
||||
GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 );
|
||||
GET_UINT32_LE( attr->type, storage_format->type, 0 );
|
||||
GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 );
|
||||
GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) );
|
||||
GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) );
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length )
|
||||
{
|
||||
|
@ -345,10 +356,9 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
|||
if( storage_data == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
psa_format_key_data_for_storage( data, data_length, type, policy,
|
||||
storage_data );
|
||||
psa_format_key_data_for_storage( data, data_length, attr, storage_data );
|
||||
|
||||
status = psa_crypto_storage_store( key,
|
||||
status = psa_crypto_storage_store( attr->id,
|
||||
storage_data, storage_data_length );
|
||||
|
||||
mbedtls_free( storage_data );
|
||||
|
@ -365,15 +375,14 @@ 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_file_id_t key,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy,
|
||||
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
uint8_t *loaded_data;
|
||||
size_t storage_data_length = 0;
|
||||
psa_key_id_t key = attr->id;
|
||||
|
||||
status = psa_crypto_storage_get_data_length( key, &storage_data_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
|
@ -389,13 +398,74 @@ psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
|
|||
goto exit;
|
||||
|
||||
status = psa_parse_key_data_from_storage( loaded_data, storage_data_length,
|
||||
data, data_length, type, policy );
|
||||
data, data_length, attr );
|
||||
|
||||
exit:
|
||||
mbedtls_free( loaded_data );
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Transactions */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
psa_status_t psa_crypto_save_transaction( void )
|
||||
{
|
||||
struct psa_storage_info_t p_info;
|
||||
psa_status_t status;
|
||||
status = psa_its_get_info( PSA_CRYPTO_ITS_RANDOM_SEED_UID, &p_info );
|
||||
if( status == PSA_SUCCESS )
|
||||
{
|
||||
/* This shouldn't happen: we're trying to start a transaction while
|
||||
* there is still a transaction that hasn't been replayed. */
|
||||
return( PSA_ERROR_CORRUPTION_DETECTED );
|
||||
}
|
||||
else if( status != PSA_ERROR_DOES_NOT_EXIST )
|
||||
return( status );
|
||||
return( psa_its_set( PSA_CRYPTO_ITS_TRANSACTION_UID,
|
||||
sizeof( psa_crypto_transaction ),
|
||||
&psa_crypto_transaction,
|
||||
0 ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_load_transaction( void )
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t length;
|
||||
status = psa_its_get( PSA_CRYPTO_ITS_TRANSACTION_UID, 0,
|
||||
sizeof( psa_crypto_transaction ),
|
||||
&psa_crypto_transaction, &length );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
if( length != sizeof( psa_crypto_transaction ) )
|
||||
return( PSA_ERROR_STORAGE_FAILURE );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_crypto_stop_transaction( void )
|
||||
{
|
||||
psa_status_t status = psa_its_remove( PSA_CRYPTO_ITS_TRANSACTION_UID );
|
||||
/* Whether or not updating the storage succeeded, the transaction is
|
||||
* finished now. It's too late to go back, so zero out the in-memory
|
||||
* data. */
|
||||
memset( &psa_crypto_transaction, 0, sizeof( psa_crypto_transaction ) );
|
||||
return( status );
|
||||
}
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Random generator state */
|
||||
/****************************************************************/
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
|
||||
size_t seed_size )
|
||||
|
@ -418,4 +488,10 @@ psa_status_t mbedtls_psa_storage_inject_entropy( const unsigned char *seed,
|
|||
}
|
||||
#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* The end */
|
||||
/****************************************************************/
|
||||
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
|
|
|
@ -29,20 +29,20 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Include the Mbed TLS configuration file, the way Mbed TLS does it
|
||||
* in each of its header files. */
|
||||
#if defined(MBEDTLS_CONFIG_FILE)
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#else
|
||||
#include "mbedtls/config.h"
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include <stdint.h>
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
/* Limit the maximum key size to 30kB (just in case someone tries to
|
||||
* inadvertently store an obscene amount of data) */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 )
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Limit the maximum key size in storage. This should have no effect
|
||||
* since the key size is limited in memory. */
|
||||
#define PSA_CRYPTO_MAX_STORAGE_SIZE ( PSA_BITS_TO_BYTES( PSA_MAX_KEY_BITS ) )
|
||||
/* Sanity check: a file size must fit in 32 bits. Allow a generous
|
||||
* 64kB of metadata. */
|
||||
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#error PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000
|
||||
#endif
|
||||
|
||||
/** The maximum permitted persistent slot number.
|
||||
*
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
|||
* This limitation will probably become moot when we implement client
|
||||
* separation for key storage.
|
||||
*/
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER 0xfffeffff
|
||||
#define PSA_MAX_PERSISTENT_KEY_IDENTIFIER PSA_KEY_ID_VENDOR_MAX
|
||||
|
||||
/**
|
||||
* \brief Checks if persistent data is stored for the given key slot number
|
||||
|
@ -88,12 +88,11 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
|
|||
* already occupied non-persistent key, as well as validating the key data.
|
||||
*
|
||||
*
|
||||
* \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.
|
||||
* \param[in] attr The attributes of the key to save.
|
||||
* The key identifier field in the attributes
|
||||
* determines the key's location.
|
||||
* \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
|
||||
|
@ -101,9 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key );
|
|||
* \retval PSA_ERROR_STORAGE_FAILURE
|
||||
* \retval PSA_ERROR_ALREADY_EXISTS
|
||||
*/
|
||||
psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr,
|
||||
const uint8_t *data,
|
||||
const size_t data_length );
|
||||
|
||||
|
@ -119,11 +116,10 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
|||
* this function to zeroize and free this buffer, regardless of whether this
|
||||
* function succeeds or fails.
|
||||
*
|
||||
* \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.
|
||||
* \param[in,out] attr On input, the key identifier field identifies
|
||||
* the key to load. Other fields are ignored.
|
||||
* On success, the attribute structure contains
|
||||
* the key metadata that was loaded from storage.
|
||||
* \param[out] data Pointer to an allocated key data buffer on return.
|
||||
* \param[out] data_length The number of bytes that make up the key data.
|
||||
*
|
||||
|
@ -132,9 +128,7 @@ psa_status_t psa_save_persistent_key( const psa_key_file_id_t key,
|
|||
* \retval PSA_ERROR_STORAGE_FAILURE
|
||||
* \retval PSA_ERROR_DOES_NOT_EXIST
|
||||
*/
|
||||
psa_status_t psa_load_persistent_key( psa_key_file_id_t key,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy,
|
||||
psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr,
|
||||
uint8_t **data,
|
||||
size_t *data_length );
|
||||
|
||||
|
@ -166,17 +160,15 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length );
|
|||
/**
|
||||
* \brief Formats key data and metadata for persistent storage
|
||||
*
|
||||
* \param[in] data Buffer for the key data.
|
||||
* \param[in] data Buffer containing the key data.
|
||||
* \param data_length Length of the key data buffer.
|
||||
* \param type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param policy The key policy.
|
||||
* \param[in] attr The core attributes of the key.
|
||||
* \param[out] storage_data Output buffer for the formatted data.
|
||||
*
|
||||
*/
|
||||
void psa_format_key_data_for_storage( const uint8_t *data,
|
||||
const size_t data_length,
|
||||
const psa_key_type_t type,
|
||||
const psa_key_policy_t *policy,
|
||||
const psa_core_key_attributes_t *attr,
|
||||
uint8_t *storage_data );
|
||||
|
||||
/**
|
||||
|
@ -188,8 +180,8 @@ void psa_format_key_data_for_storage( const uint8_t *data,
|
|||
* containing the key data. This must be freed
|
||||
* using psa_free_persistent_key_data()
|
||||
* \param[out] key_data_length Length of the key data buffer
|
||||
* \param[out] type Key type (a \c PSA_KEY_TYPE_XXX value).
|
||||
* \param[out] policy The key policy.
|
||||
* \param[out] attr On success, the attribute structure is filled
|
||||
* with the loaded key metadata.
|
||||
*
|
||||
* \retval PSA_SUCCESS
|
||||
* \retval PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
|
@ -200,8 +192,180 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data,
|
|||
size_t storage_data_length,
|
||||
uint8_t **key_data,
|
||||
size_t *key_data_length,
|
||||
psa_key_type_t *type,
|
||||
psa_key_policy_t *policy );
|
||||
psa_core_key_attributes_t *attr );
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
/** This symbol is defined if transaction support is required. */
|
||||
#define PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS
|
||||
#endif
|
||||
|
||||
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
|
||||
|
||||
/** The type of transaction that is in progress.
|
||||
*/
|
||||
/* This is an integer type rather than an enum for two reasons: to support
|
||||
* unknown values when loading a transaction file, and to ensure that the
|
||||
* type has a known size.
|
||||
*/
|
||||
typedef uint16_t psa_crypto_transaction_type_t;
|
||||
|
||||
/** No transaction is in progress.
|
||||
*
|
||||
* This has the value 0, so zero-initialization sets a transaction's type to
|
||||
* this value.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_NONE ( (psa_crypto_transaction_type_t) 0x0000 )
|
||||
|
||||
/** A key creation transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are created atomically in storage
|
||||
* (simple file creation), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_CREATE_KEY ( (psa_crypto_transaction_type_t) 0x0001 )
|
||||
|
||||
/** A key destruction transaction.
|
||||
*
|
||||
* This is only used for keys in an external cryptoprocessor (secure element).
|
||||
* Keys in RAM or in internal storage are destroyed atomically in storage
|
||||
* (simple file deletion), so they do not need a transaction mechanism.
|
||||
*/
|
||||
#define PSA_CRYPTO_TRANSACTION_DESTROY_KEY ( (psa_crypto_transaction_type_t) 0x0002 )
|
||||
|
||||
/** Transaction data.
|
||||
*
|
||||
* This type is designed to be serialized by writing the memory representation
|
||||
* and reading it back on the same device.
|
||||
*
|
||||
* \note The transaction mechanism is designed for a single active transaction
|
||||
* at a time. The transaction object is #psa_crypto_transaction.
|
||||
*
|
||||
* \note If an API call starts a transaction, it must complete this transaction
|
||||
* before returning to the application.
|
||||
*
|
||||
* The lifetime of a transaction is the following (note that only one
|
||||
* transaction may be active at a time):
|
||||
*
|
||||
* -# Call psa_crypto_prepare_transaction() to initialize the transaction
|
||||
* object in memory and declare the type of transaction that is starting.
|
||||
* -# Fill in the type-specific fields of #psa_crypto_transaction.
|
||||
* -# Call psa_crypto_save_transaction() to start the transaction. This
|
||||
* saves the transaction data to internal storage.
|
||||
* -# Perform the work of the transaction by modifying files, contacting
|
||||
* external entities, or whatever needs doing. Note that the transaction
|
||||
* may be interrupted by a power failure, so you need to have a way
|
||||
* recover from interruptions either by undoing what has been done
|
||||
* so far or by resuming where you left off.
|
||||
* -# If there are intermediate stages in the transaction, update
|
||||
* the fields of #psa_crypto_transaction and call
|
||||
* psa_crypto_save_transaction() again when each stage is reached.
|
||||
* -# When the transaction is over, call psa_crypto_stop_transaction() to
|
||||
* remove the transaction data in storage and in memory.
|
||||
*
|
||||
* If the system crashes while a transaction is in progress, psa_crypto_init()
|
||||
* calls psa_crypto_load_transaction() and takes care of completing or
|
||||
* rewinding the transaction. This is done in psa_crypto_recover_transaction()
|
||||
* in psa_crypto.c. If you add a new type of transaction, be
|
||||
* sure to add code for it in psa_crypto_recover_transaction().
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/* Each element of this union must have the following properties
|
||||
* to facilitate serialization and deserialization:
|
||||
*
|
||||
* - The element is a struct.
|
||||
* - The first field of the struct is `psa_crypto_transaction_type_t type`.
|
||||
* - Elements of the struct are arranged such a way that there is
|
||||
* no padding.
|
||||
*/
|
||||
struct psa_crypto_transaction_unknown_s
|
||||
{
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
uint32_t unused2;
|
||||
uint64_t unused3;
|
||||
uint64_t unused4;
|
||||
} unknown;
|
||||
/* ::type is #PSA_CRYPTO_TRANSACTION_CREATE_KEY or
|
||||
* #PSA_CRYPTO_TRANSACTION_DESTROY_KEY. */
|
||||
struct psa_crypto_transaction_key_s
|
||||
{
|
||||
psa_crypto_transaction_type_t type;
|
||||
uint16_t unused1;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_slot_number_t slot;
|
||||
psa_key_id_t id;
|
||||
} key;
|
||||
} psa_crypto_transaction_t;
|
||||
|
||||
/** The single active transaction.
|
||||
*/
|
||||
extern psa_crypto_transaction_t psa_crypto_transaction;
|
||||
|
||||
/** Prepare for a transaction.
|
||||
*
|
||||
* There must not be an ongoing transaction.
|
||||
*
|
||||
* \param type The type of transaction to start.
|
||||
*/
|
||||
static inline void psa_crypto_prepare_transaction(
|
||||
psa_crypto_transaction_type_t type )
|
||||
{
|
||||
psa_crypto_transaction.unknown.type = type;
|
||||
}
|
||||
|
||||
/** Save the transaction data to storage.
|
||||
*
|
||||
* You may call this function multiple times during a transaction to
|
||||
* atomically update the transaction state.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
*/
|
||||
psa_status_t psa_crypto_save_transaction( void );
|
||||
|
||||
/** Load the transaction data from storage, if any.
|
||||
*
|
||||
* This function is meant to be called from psa_crypto_init() to recover
|
||||
* in case a transaction was interrupted by a system crash.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* The data about the ongoing transaction has been loaded to
|
||||
* #psa_crypto_transaction.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There is no ongoing transaction.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
*/
|
||||
psa_status_t psa_crypto_load_transaction( void );
|
||||
|
||||
/** Indicate that the current transaction is finished.
|
||||
*
|
||||
* Call this function at the very end of transaction processing.
|
||||
* This function does not "commit" or "abort" the transaction: the storage
|
||||
* subsystem has no concept of "commit" and "abort", just saving and
|
||||
* removing the transaction information in storage.
|
||||
*
|
||||
* This function erases the transaction data in storage (if any) and
|
||||
* resets the transaction data in memory.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* There was transaction data in storage.
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST
|
||||
* There was no transaction data in storage.
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE
|
||||
* It was impossible to determine whether there was transaction data
|
||||
* in storage, or the transaction data could not be erased.
|
||||
*/
|
||||
psa_status_t psa_crypto_stop_transaction( void );
|
||||
|
||||
/** The ITS file identifier for the transaction data.
|
||||
*
|
||||
* 0xffffffNN = special file; 0x74 = 't' for transaction.
|
||||
*/
|
||||
#define PSA_CRYPTO_ITS_TRANSACTION_UID ( (psa_key_id_t) 0xffffff74 )
|
||||
|
||||
#endif /* PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS */
|
||||
|
||||
#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
|
||||
/** Backend side of mbedtls_psa_inject_entropy().
|
||||
|
|
|
@ -558,6 +558,9 @@ static const char * const features[] = {
|
|||
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||
"MBEDTLS_PSA_CRYPTO_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
"MBEDTLS_PSA_CRYPTO_SE_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
"MBEDTLS_PSA_CRYPTO_STORAGE_C",
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
|
|
|
@ -39,20 +39,6 @@ int main( void )
|
|||
}
|
||||
#else
|
||||
|
||||
static psa_status_t set_key_policy( psa_key_handle_t key_handle,
|
||||
psa_key_usage_t key_usage,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
|
||||
psa_key_policy_set_usage( &policy, key_usage, alg );
|
||||
status = psa_set_key_policy( key_handle, &policy );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
exit:
|
||||
return( status );
|
||||
}
|
||||
|
||||
static psa_status_t cipher_operation( psa_cipher_operation_t *operation,
|
||||
const uint8_t * input,
|
||||
size_t input_size,
|
||||
|
@ -161,6 +147,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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t key_handle = 0;
|
||||
size_t output_len = 0;
|
||||
uint8_t iv[block_size];
|
||||
|
@ -171,16 +158,13 @@ cipher_example_encrypt_decrypt_aes_cbc_nopad_1_block( void )
|
|||
status = psa_generate_random( input, sizeof( input ) );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
|
||||
status = psa_allocate_key( &key_handle );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
|
||||
psa_set_key_bits( &attributes, key_bits );
|
||||
|
||||
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_handle, PSA_KEY_TYPE_AES, key_bits,
|
||||
NULL, 0 );
|
||||
status = psa_generate_key( &attributes, &key_handle );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
|
||||
status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
|
||||
|
@ -213,6 +197,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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t key_handle = 0;
|
||||
size_t output_len = 0;
|
||||
uint8_t iv[block_size], input[input_size],
|
||||
|
@ -221,16 +206,13 @@ 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 = psa_allocate_key( &key_handle );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
|
||||
psa_set_key_bits( &attributes, key_bits );
|
||||
|
||||
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_handle, PSA_KEY_TYPE_AES, key_bits,
|
||||
NULL, 0 );
|
||||
status = psa_generate_key( &attributes, &key_handle );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
|
||||
status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
|
||||
|
@ -262,6 +244,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_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t key_handle = 0;
|
||||
size_t output_len = 0;
|
||||
uint8_t iv[block_size], input[input_size], encrypt[input_size],
|
||||
|
@ -270,15 +253,13 @@ 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 = psa_allocate_key( &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 );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
|
||||
psa_set_key_bits( &attributes, key_bits );
|
||||
|
||||
status = psa_generate_key( key_handle, PSA_KEY_TYPE_AES, key_bits,
|
||||
NULL, 0 );
|
||||
status = psa_generate_key( &attributes, &key_handle );
|
||||
ASSERT_STATUS( status, PSA_SUCCESS );
|
||||
|
||||
status = cipher_encrypt( key_handle, alg, iv, sizeof( iv ),
|
||||
|
|
|
@ -63,25 +63,25 @@
|
|||
|
||||
#include "mbedtls/platform_util.h" // for mbedtls_platform_zeroize
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/* If the build options we need are not enabled, compile a placeholder. */
|
||||
#if !defined(MBEDTLS_SHA256_C) || !defined(MBEDTLS_MD_C) || \
|
||||
!defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CCM_C) || \
|
||||
!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_FS_IO)
|
||||
!defined(MBEDTLS_PSA_CRYPTO_C) || !defined(MBEDTLS_FS_IO) ||\
|
||||
defined(PSA_PRE_1_0_KEY_DERIVATION)
|
||||
int main( void )
|
||||
{
|
||||
printf("MBEDTLS_SHA256_C and/or MBEDTLS_MD_C and/or "
|
||||
"MBEDTLS_AES_C and/or MBEDTLS_CCM_C and/or "
|
||||
"MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_FS_IO not defined.\n");
|
||||
"MBEDTLS_PSA_CRYPTO_C and/or MBEDTLS_FS_IO and/or "
|
||||
"not defined and/or PSA_PRE_1_0_KEY_DERIVATION defined.\n");
|
||||
return( 0 );
|
||||
}
|
||||
#else
|
||||
|
||||
/* The real program starts here. */
|
||||
|
||||
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/* Run a system function and bail out if it fails. */
|
||||
#define SYS_CHECK( expr ) \
|
||||
do \
|
||||
|
@ -200,18 +200,15 @@ 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_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
PSA_CHECK( psa_allocate_key( &key_handle ) );
|
||||
psa_key_policy_set_usage( &policy,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT,
|
||||
KDF_ALG );
|
||||
PSA_CHECK( psa_set_key_policy( key_handle, &policy ) );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, KDF_ALG );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
|
||||
psa_set_key_bits( &attributes, PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ) );
|
||||
|
||||
PSA_CHECK( psa_generate_key( key_handle,
|
||||
PSA_KEY_TYPE_DERIVE,
|
||||
PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ),
|
||||
NULL, 0 ) );
|
||||
PSA_CHECK( psa_generate_key( &attributes, &key_handle ) );
|
||||
|
||||
PSA_CHECK( save_key( key_handle, key_file_name ) );
|
||||
|
||||
|
@ -231,7 +228,7 @@ static psa_status_t import_key_from_file( psa_key_usage_t usage,
|
|||
psa_key_handle_t *master_key_handle )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t key_data[KEY_SIZE_BYTES];
|
||||
size_t key_size;
|
||||
FILE *key_file = NULL;
|
||||
|
@ -252,19 +249,18 @@ static psa_status_t import_key_from_file( psa_key_usage_t usage,
|
|||
SYS_CHECK( fclose( key_file ) == 0 );
|
||||
key_file = NULL;
|
||||
|
||||
PSA_CHECK( psa_allocate_key( master_key_handle ) );
|
||||
psa_key_policy_set_usage( &policy, usage, alg );
|
||||
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 ) );
|
||||
psa_set_key_usage_flags( &attributes, usage );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
|
||||
PSA_CHECK( psa_import_key( &attributes, key_data, key_size,
|
||||
master_key_handle ) );
|
||||
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,
|
||||
/* If the key creation hasn't happened 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 );
|
||||
|
@ -282,43 +278,43 @@ static psa_status_t derive_key_ladder( const char *ladder[],
|
|||
psa_key_handle_t *key_handle )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
size_t i;
|
||||
psa_key_policy_set_usage( &policy,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT,
|
||||
KDF_ALG );
|
||||
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, KDF_ALG );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_DERIVE );
|
||||
psa_set_key_bits( &attributes, PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ) );
|
||||
|
||||
/* For each label in turn, ... */
|
||||
for( i = 0; i < ladder_depth; i++ )
|
||||
{
|
||||
/* Start deriving material from the master key (if i=0) or from
|
||||
* the current intermediate key (if i>0). */
|
||||
PSA_CHECK( psa_key_derivation(
|
||||
&generator,
|
||||
*key_handle,
|
||||
KDF_ALG,
|
||||
DERIVE_KEY_SALT, DERIVE_KEY_SALT_LENGTH,
|
||||
(uint8_t*) ladder[i], strlen( ladder[i] ),
|
||||
KEY_SIZE_BYTES ) );
|
||||
PSA_CHECK( psa_key_derivation_setup( &operation, KDF_ALG ) );
|
||||
PSA_CHECK( psa_key_derivation_input_bytes(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_SALT,
|
||||
DERIVE_KEY_SALT, DERIVE_KEY_SALT_LENGTH ) );
|
||||
PSA_CHECK( psa_key_derivation_input_key(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
*key_handle ) );
|
||||
PSA_CHECK( psa_key_derivation_input_bytes(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_INFO,
|
||||
(uint8_t*) ladder[i], strlen( ladder[i] ) ) );
|
||||
/* When the parent key is not the master key, destroy it,
|
||||
* since it is no longer needed. */
|
||||
PSA_CHECK( psa_close_key( *key_handle ) );
|
||||
*key_handle = 0;
|
||||
PSA_CHECK( psa_allocate_key( 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(
|
||||
*key_handle,
|
||||
PSA_KEY_TYPE_DERIVE,
|
||||
PSA_BYTES_TO_BITS( KEY_SIZE_BYTES ),
|
||||
&generator ) );
|
||||
PSA_CHECK( psa_generator_abort( &generator ) );
|
||||
/* Derive the next intermediate key from the parent key. */
|
||||
PSA_CHECK( psa_key_derivation_output_key( &attributes, &operation,
|
||||
key_handle ) );
|
||||
PSA_CHECK( psa_key_derivation_abort( &operation ) );
|
||||
}
|
||||
|
||||
exit:
|
||||
psa_generator_abort( &generator );
|
||||
psa_key_derivation_abort( &operation );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_close_key( *key_handle );
|
||||
|
@ -333,34 +329,34 @@ static psa_status_t derive_wrapping_key( psa_key_usage_t usage,
|
|||
psa_key_handle_t *wrapping_key_handle )
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
*wrapping_key_handle = 0;
|
||||
PSA_CHECK( psa_allocate_key( wrapping_key_handle ) );
|
||||
psa_key_policy_set_usage( &policy, usage, WRAPPING_ALG );
|
||||
PSA_CHECK( psa_set_key_policy( *wrapping_key_handle, &policy ) );
|
||||
|
||||
PSA_CHECK( psa_key_derivation(
|
||||
&generator,
|
||||
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_handle,
|
||||
PSA_KEY_TYPE_AES,
|
||||
WRAPPING_KEY_BITS,
|
||||
&generator ) );
|
||||
/* Set up a key derivation operation from the key derived from
|
||||
* the master key. */
|
||||
PSA_CHECK( psa_key_derivation_setup( &operation, KDF_ALG ) );
|
||||
PSA_CHECK( psa_key_derivation_input_bytes(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_SALT,
|
||||
WRAPPING_KEY_SALT, WRAPPING_KEY_SALT_LENGTH ) );
|
||||
PSA_CHECK( psa_key_derivation_input_key(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
derived_key_handle ) );
|
||||
PSA_CHECK( psa_key_derivation_input_bytes(
|
||||
&operation, PSA_KEY_DERIVATION_INPUT_INFO,
|
||||
NULL, 0 ) );
|
||||
|
||||
/* Create the wrapping key. */
|
||||
psa_set_key_usage_flags( &attributes, usage );
|
||||
psa_set_key_algorithm( &attributes, WRAPPING_ALG );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_AES );
|
||||
psa_set_key_bits( &attributes, WRAPPING_KEY_BITS );
|
||||
PSA_CHECK( psa_key_derivation_output_key( &attributes, &operation,
|
||||
wrapping_key_handle ) );
|
||||
|
||||
exit:
|
||||
psa_generator_abort( &generator );
|
||||
if( status != PSA_SUCCESS )
|
||||
{
|
||||
psa_close_key( *wrapping_key_handle );
|
||||
*wrapping_key_handle = 0;
|
||||
}
|
||||
psa_key_derivation_abort( &operation );
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ static void append_integer(char **buffer, size_t buffer_size,
|
|||
|
||||
/* The code of these function is automatically generated and included below. */
|
||||
static const char *psa_ecc_curve_name(psa_ecc_curve_t curve);
|
||||
static const char *psa_dh_group_name(psa_dh_group_t group);
|
||||
static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg);
|
||||
|
||||
static void append_with_curve(char **buffer, size_t buffer_size,
|
||||
|
@ -84,24 +85,41 @@ static void append_with_curve(char **buffer, size_t buffer_size,
|
|||
append(buffer, buffer_size, required_size, ")", 1);
|
||||
}
|
||||
|
||||
static void append_with_hash(char **buffer, size_t buffer_size,
|
||||
size_t *required_size,
|
||||
const char *string, size_t length,
|
||||
psa_algorithm_t hash_alg)
|
||||
static void append_with_group(char **buffer, size_t buffer_size,
|
||||
size_t *required_size,
|
||||
const char *string, size_t length,
|
||||
psa_dh_group_t group)
|
||||
{
|
||||
const char *hash_name = psa_hash_algorithm_name(hash_alg);
|
||||
const char *group_name = psa_dh_group_name(group);
|
||||
append(buffer, buffer_size, required_size, string, length);
|
||||
append(buffer, buffer_size, required_size, "(", 1);
|
||||
if (hash_name != NULL) {
|
||||
if (group_name != NULL) {
|
||||
append(buffer, buffer_size, required_size,
|
||||
hash_name, strlen(hash_name));
|
||||
group_name, strlen(group_name));
|
||||
} else {
|
||||
append_integer(buffer, buffer_size, required_size,
|
||||
"0x%08lx", hash_alg);
|
||||
"0x%04x", group);
|
||||
}
|
||||
append(buffer, buffer_size, required_size, ")", 1);
|
||||
}
|
||||
|
||||
typedef const char *(*psa_get_algorithm_name_func_ptr)(psa_algorithm_t alg);
|
||||
|
||||
static void append_with_alg(char **buffer, size_t buffer_size,
|
||||
size_t *required_size,
|
||||
psa_get_algorithm_name_func_ptr get_name,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
const char *name = get_name(alg);
|
||||
if (name != NULL) {
|
||||
append(buffer, buffer_size, required_size,
|
||||
name, strlen(name));
|
||||
} else {
|
||||
append_integer(buffer, buffer_size, required_size,
|
||||
"0x%08lx", alg);
|
||||
}
|
||||
}
|
||||
|
||||
#include "psa_constant_names_generated.c"
|
||||
|
||||
static int psa_snprint_status(char *buffer, size_t buffer_size,
|
||||
|
@ -138,6 +156,23 @@ static int psa_snprint_ecc_curve(char *buffer, size_t buffer_size,
|
|||
}
|
||||
}
|
||||
|
||||
static int psa_snprint_dh_group(char *buffer, size_t buffer_size,
|
||||
psa_dh_group_t group)
|
||||
{
|
||||
const char *name = psa_dh_group_name(group);
|
||||
if (name == NULL) {
|
||||
return snprintf(buffer, buffer_size, "0x%04x", (unsigned) group);
|
||||
} else {
|
||||
size_t length = strlen(name);
|
||||
if (length < buffer_size) {
|
||||
memcpy(buffer, name, length + 1);
|
||||
return (int) length;
|
||||
} else {
|
||||
return (int) buffer_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char *program_name)
|
||||
{
|
||||
printf("Usage: %s TYPE VALUE [VALUE...]\n",
|
||||
|
@ -146,6 +181,7 @@ static void usage(const char *program_name)
|
|||
printf("Supported types (with = between aliases):\n");
|
||||
printf(" alg=algorithm Algorithm (psa_algorithm_t)\n");
|
||||
printf(" curve=ecc_curve Elliptic curve identifier (psa_ecc_curve_t)\n");
|
||||
printf(" group=dh_group Diffie-Hellman group identifier (psa_dh_group_t)\n");
|
||||
printf(" type=key_type Key type (psa_key_type_t)\n");
|
||||
printf(" usage=key_usage Key usage (psa_key_usage_t)\n");
|
||||
printf(" error=status Status code (psa_status_t)\n");
|
||||
|
@ -189,6 +225,7 @@ int process_signed(signed_value_type type, long min, long max, char **argp)
|
|||
typedef enum {
|
||||
TYPE_ALGORITHM,
|
||||
TYPE_ECC_CURVE,
|
||||
TYPE_DH_GROUP,
|
||||
TYPE_KEY_TYPE,
|
||||
TYPE_KEY_USAGE,
|
||||
} unsigned_value_type;
|
||||
|
@ -217,6 +254,10 @@ int process_unsigned(unsigned_value_type type, unsigned long max, char **argp)
|
|||
psa_snprint_ecc_curve(buffer, sizeof(buffer),
|
||||
(psa_ecc_curve_t) value);
|
||||
break;
|
||||
case TYPE_DH_GROUP:
|
||||
psa_snprint_dh_group(buffer, sizeof(buffer),
|
||||
(psa_dh_group_t) value);
|
||||
break;
|
||||
case TYPE_KEY_TYPE:
|
||||
psa_snprint_key_type(buffer, sizeof(buffer),
|
||||
(psa_key_type_t) value);
|
||||
|
@ -253,6 +294,9 @@ int main(int argc, char *argv[])
|
|||
} else if (!strcmp(argv[1], "curve") || !strcmp(argv[1], "ecc_curve")) {
|
||||
return process_unsigned(TYPE_ECC_CURVE, (psa_ecc_curve_t) (-1),
|
||||
argv + 2);
|
||||
} else if (!strcmp(argv[1], "group") || !strcmp(argv[1], "dh_group")) {
|
||||
return process_unsigned(TYPE_DH_GROUP, (psa_dh_group_t) (-1),
|
||||
argv + 2);
|
||||
} else if (!strcmp(argv[1], "type") || !strcmp(argv[1], "key_type")) {
|
||||
return process_unsigned(TYPE_KEY_TYPE, (psa_key_type_t) (-1),
|
||||
argv + 2);
|
||||
|
|
|
@ -1516,6 +1516,14 @@ int query_config( const char *config )
|
|||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
|
||||
if( strcmp( "MBEDTLS_PSA_CRYPTO_SE_C", config ) == 0 )
|
||||
{
|
||||
MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_SE_C );
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
if( strcmp( "MBEDTLS_PSA_CRYPTO_STORAGE_C", config ) == 0 )
|
||||
{
|
||||
|
|
|
@ -86,6 +86,7 @@ MBEDTLS_NO_PLATFORM_ENTROPY
|
|||
MBEDTLS_RSA_NO_CRT
|
||||
MBEDTLS_NO_UDBL_DIVISION
|
||||
MBEDTLS_NO_64BIT_MULTIPLICATION
|
||||
MBEDTLS_PSA_CRYPTO_SE_C
|
||||
MBEDTLS_PSA_CRYPTO_SPM
|
||||
MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER
|
||||
MBEDTLS_PSA_INJECT_ENTROPY
|
||||
|
@ -109,6 +110,7 @@ MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
|||
MBEDTLS_PLATFORM_TIME_ALT
|
||||
MBEDTLS_PLATFORM_FPRINTF_ALT
|
||||
MBEDTLS_PSA_ITS_FILE_C
|
||||
MBEDTLS_PSA_CRYPTO_SE_C
|
||||
MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
);
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Generate programs/psa/psa_constant_names_generated.c
|
||||
which is included by programs/psa/psa_constant_names.c.
|
||||
The code generated by this module is only meant to be used in the context
|
||||
of that program.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
output_template = '''\
|
||||
OUTPUT_TEMPLATE = '''\
|
||||
/* Automatically generated by generate_psa_constant.py. DO NOT EDIT. */
|
||||
|
||||
static const char *psa_strerror(psa_status_t status)
|
||||
|
@ -22,6 +28,14 @@ static const char *psa_ecc_curve_name(psa_ecc_curve_t curve)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *psa_dh_group_name(psa_dh_group_t group)
|
||||
{
|
||||
switch (group) {
|
||||
%(dh_group_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg)
|
||||
{
|
||||
switch (hash_alg) {
|
||||
|
@ -30,6 +44,14 @@ static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *psa_ka_algorithm_name(psa_algorithm_t ka_alg)
|
||||
{
|
||||
switch (ka_alg) {
|
||||
%(ka_algorithm_cases)s
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int psa_snprint_key_type(char *buffer, size_t buffer_size,
|
||||
psa_key_type_t type)
|
||||
{
|
||||
|
@ -47,12 +69,13 @@ static int psa_snprint_key_type(char *buffer, size_t buffer_size,
|
|||
return (int) required_size;
|
||||
}
|
||||
|
||||
#define NO_LENGTH_MODIFIER 0xfffffffflu
|
||||
static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
size_t required_size = 0;
|
||||
psa_algorithm_t core_alg = alg;
|
||||
unsigned long length_modifier = 0;
|
||||
unsigned long length_modifier = NO_LENGTH_MODIFIER;
|
||||
if (PSA_ALG_IS_MAC(alg)) {
|
||||
core_alg = PSA_ALG_TRUNCATED_MAC(alg, 0);
|
||||
if (core_alg != alg) {
|
||||
|
@ -70,6 +93,15 @@ static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
|
|||
"PSA_ALG_AEAD_WITH_TAG_LENGTH(", 29);
|
||||
length_modifier = PSA_AEAD_TAG_LENGTH(alg);
|
||||
}
|
||||
} else if (PSA_ALG_IS_KEY_AGREEMENT(alg) &&
|
||||
!PSA_ALG_IS_RAW_KEY_AGREEMENT(alg)) {
|
||||
core_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF(alg);
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"PSA_ALG_KEY_AGREEMENT(", 22);
|
||||
append_with_alg(&buffer, buffer_size, &required_size,
|
||||
psa_ka_algorithm_name,
|
||||
PSA_ALG_KEY_AGREEMENT_GET_BASE(alg));
|
||||
append(&buffer, buffer_size, &required_size, ", ", 2);
|
||||
}
|
||||
switch (core_alg) {
|
||||
%(algorithm_cases)s
|
||||
|
@ -81,9 +113,11 @@ static int psa_snprint_algorithm(char *buffer, size_t buffer_size,
|
|||
break;
|
||||
}
|
||||
if (core_alg != alg) {
|
||||
append(&buffer, buffer_size, &required_size, ", ", 2);
|
||||
append_integer(&buffer, buffer_size, &required_size,
|
||||
"%%lu", length_modifier);
|
||||
if (length_modifier != NO_LENGTH_MODIFIER) {
|
||||
append(&buffer, buffer_size, &required_size, ", ", 2);
|
||||
append_integer(&buffer, buffer_size, &required_size,
|
||||
"%%lu", length_modifier);
|
||||
}
|
||||
append(&buffer, buffer_size, &required_size, ")", 1);
|
||||
}
|
||||
buffer[0] = 0;
|
||||
|
@ -119,19 +153,28 @@ static int psa_snprint_key_usage(char *buffer, size_t buffer_size,
|
|||
/* End of automatically generated file. */
|
||||
'''
|
||||
|
||||
key_type_from_curve_template = '''if (%(tester)s(type)) {
|
||||
KEY_TYPE_FROM_CURVE_TEMPLATE = '''if (%(tester)s(type)) {
|
||||
append_with_curve(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s", %(builder_length)s,
|
||||
PSA_KEY_TYPE_GET_CURVE(type));
|
||||
} else '''
|
||||
|
||||
algorithm_from_hash_template = '''if (%(tester)s(core_alg)) {
|
||||
append_with_hash(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s", %(builder_length)s,
|
||||
PSA_ALG_GET_HASH(core_alg));
|
||||
KEY_TYPE_FROM_GROUP_TEMPLATE = '''if (%(tester)s(type)) {
|
||||
append_with_group(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s", %(builder_length)s,
|
||||
PSA_KEY_TYPE_GET_GROUP(type));
|
||||
} else '''
|
||||
|
||||
bit_test_template = '''\
|
||||
ALGORITHM_FROM_HASH_TEMPLATE = '''if (%(tester)s(core_alg)) {
|
||||
append(&buffer, buffer_size, &required_size,
|
||||
"%(builder)s(", %(builder_length)s + 1);
|
||||
append_with_alg(&buffer, buffer_size, &required_size,
|
||||
psa_hash_algorithm_name,
|
||||
PSA_ALG_GET_HASH(core_alg));
|
||||
append(&buffer, buffer_size, &required_size, ")", 1);
|
||||
} else '''
|
||||
|
||||
BIT_TEST_TEMPLATE = '''\
|
||||
if (%(var)s & %(flag)s) {
|
||||
if (required_size != 0) {
|
||||
append(&buffer, buffer_size, &required_size, " | ", 3);
|
||||
|
@ -142,13 +185,22 @@ bit_test_template = '''\
|
|||
'''
|
||||
|
||||
class MacroCollector:
|
||||
"""Collect PSA crypto macro definitions from C header files.
|
||||
|
||||
1. Call `read_file` on the input header file(s).
|
||||
2. Call `write_file` to write ``psa_constant_names_generated.c``.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.statuses = set()
|
||||
self.key_types = set()
|
||||
self.key_types_from_curve = {}
|
||||
self.key_types_from_group = {}
|
||||
self.ecc_curves = set()
|
||||
self.dh_groups = set()
|
||||
self.algorithms = set()
|
||||
self.hash_algorithms = set()
|
||||
self.ka_algorithms = set()
|
||||
self.algorithms_from_hash = {}
|
||||
self.key_usages = set()
|
||||
|
||||
|
@ -158,6 +210,11 @@ class MacroCollector:
|
|||
definition_re = re.compile(r'\s*#\s*define\s+(\w+)(?:\s+|\((\w+)\)\s*)(.+)(?:/[*/])?')
|
||||
|
||||
def read_line(self, line):
|
||||
"""Parse a C header line and record the PSA identifier it defines if any.
|
||||
This function analyzes lines that start with "#define PSA_"
|
||||
(up to non-significant whitespace) and skips all non-matching lines.
|
||||
"""
|
||||
# pylint: disable=too-many-branches
|
||||
m = re.match(self.definition_re, line)
|
||||
if not m:
|
||||
return
|
||||
|
@ -167,12 +224,11 @@ class MacroCollector:
|
|||
return
|
||||
elif (name.startswith('PSA_ERROR_') or name == 'PSA_SUCCESS') \
|
||||
and not parameter:
|
||||
if name in [
|
||||
'PSA_ERROR_UNKNOWN_ERROR',
|
||||
if name in ['PSA_ERROR_UNKNOWN_ERROR',
|
||||
'PSA_ERROR_OCCUPIED_SLOT',
|
||||
'PSA_ERROR_EMPTY_SLOT',
|
||||
'PSA_ERROR_INSUFFICIENT_CAPACITY',
|
||||
]:
|
||||
]:
|
||||
# Ad hoc skipping of deprecated error codes, which share
|
||||
# numerical values with non-deprecated error codes
|
||||
return
|
||||
|
@ -182,8 +238,12 @@ class MacroCollector:
|
|||
self.key_types.add(name)
|
||||
elif name.startswith('PSA_KEY_TYPE_') and parameter == 'curve':
|
||||
self.key_types_from_curve[name] = name[:13] + 'IS_' + name[13:]
|
||||
elif name.startswith('PSA_KEY_TYPE_') and parameter == 'group':
|
||||
self.key_types_from_group[name] = name[:13] + 'IS_' + name[13:]
|
||||
elif name.startswith('PSA_ECC_CURVE_') and not parameter:
|
||||
self.ecc_curves.add(name)
|
||||
elif name.startswith('PSA_DH_GROUP_') and not parameter:
|
||||
self.dh_groups.add(name)
|
||||
elif name.startswith('PSA_ALG_') and not parameter:
|
||||
if name in ['PSA_ALG_ECDSA_BASE',
|
||||
'PSA_ALG_RSA_PKCS1V15_SIGN_BASE']:
|
||||
|
@ -193,6 +253,9 @@ class MacroCollector:
|
|||
# Ad hoc detection of hash algorithms
|
||||
if re.search(r'0x010000[0-9A-Fa-f]{2}', definition):
|
||||
self.hash_algorithms.add(name)
|
||||
# Ad hoc detection of key agreement algorithms
|
||||
if re.search(r'0x30[0-9A-Fa-f]{2}0000', definition):
|
||||
self.ka_algorithms.add(name)
|
||||
elif name.startswith('PSA_ALG_') and parameter == 'hash_alg':
|
||||
if name in ['PSA_ALG_DSA', 'PSA_ALG_ECDSA']:
|
||||
# A naming irregularity
|
||||
|
@ -210,81 +273,105 @@ class MacroCollector:
|
|||
for line in header_file:
|
||||
self.read_line(line)
|
||||
|
||||
def make_return_case(self, name):
|
||||
@staticmethod
|
||||
def _make_return_case(name):
|
||||
return 'case %(name)s: return "%(name)s";' % {'name': name}
|
||||
|
||||
def make_append_case(self, name):
|
||||
@staticmethod
|
||||
def _make_append_case(name):
|
||||
template = ('case %(name)s: '
|
||||
'append(&buffer, buffer_size, &required_size, "%(name)s", %(length)d); '
|
||||
'break;')
|
||||
return template % {'name': name, 'length': len(name)}
|
||||
|
||||
def make_inner_append_case(self, name):
|
||||
template = ('case %(name)s: '
|
||||
'append(buffer, buffer_size, required_size, "%(name)s", %(length)d); '
|
||||
'break;')
|
||||
return template % {'name': name, 'length': len(name)}
|
||||
|
||||
def make_bit_test(self, var, flag):
|
||||
return bit_test_template % {'var': var,
|
||||
@staticmethod
|
||||
def _make_bit_test(var, flag):
|
||||
return BIT_TEST_TEMPLATE % {'var': var,
|
||||
'flag': flag,
|
||||
'length': len(flag)}
|
||||
|
||||
def make_status_cases(self):
|
||||
return '\n '.join(map(self.make_return_case,
|
||||
def _make_status_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.statuses)))
|
||||
|
||||
def make_ecc_curve_cases(self):
|
||||
return '\n '.join(map(self.make_return_case,
|
||||
def _make_ecc_curve_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.ecc_curves)))
|
||||
|
||||
def make_key_type_cases(self):
|
||||
return '\n '.join(map(self.make_append_case,
|
||||
def _make_dh_group_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.dh_groups)))
|
||||
|
||||
def _make_key_type_cases(self):
|
||||
return '\n '.join(map(self._make_append_case,
|
||||
sorted(self.key_types)))
|
||||
|
||||
def make_key_type_from_curve_code(self, builder, tester):
|
||||
return key_type_from_curve_template % {'builder': builder,
|
||||
@staticmethod
|
||||
def _make_key_type_from_curve_code(builder, tester):
|
||||
return KEY_TYPE_FROM_CURVE_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
def make_key_type_code(self):
|
||||
@staticmethod
|
||||
def _make_key_type_from_group_code(builder, tester):
|
||||
return KEY_TYPE_FROM_GROUP_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
def _make_ecc_key_type_code(self):
|
||||
d = self.key_types_from_curve
|
||||
make = self.make_key_type_from_curve_code
|
||||
make = self._make_key_type_from_curve_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def make_hash_algorithm_cases(self):
|
||||
return '\n '.join(map(self.make_return_case,
|
||||
def _make_dh_key_type_code(self):
|
||||
d = self.key_types_from_group
|
||||
make = self._make_key_type_from_group_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def _make_hash_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.hash_algorithms)))
|
||||
|
||||
def make_algorithm_cases(self):
|
||||
return '\n '.join(map(self.make_append_case,
|
||||
def _make_ka_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_return_case,
|
||||
sorted(self.ka_algorithms)))
|
||||
|
||||
def _make_algorithm_cases(self):
|
||||
return '\n '.join(map(self._make_append_case,
|
||||
sorted(self.algorithms)))
|
||||
|
||||
def make_algorithm_from_hash_code(self, builder, tester):
|
||||
return algorithm_from_hash_template % {'builder': builder,
|
||||
@staticmethod
|
||||
def _make_algorithm_from_hash_code(builder, tester):
|
||||
return ALGORITHM_FROM_HASH_TEMPLATE % {'builder': builder,
|
||||
'builder_length': len(builder),
|
||||
'tester': tester}
|
||||
|
||||
def make_algorithm_code(self):
|
||||
def _make_algorithm_code(self):
|
||||
d = self.algorithms_from_hash
|
||||
make = self.make_algorithm_from_hash_code
|
||||
make = self._make_algorithm_from_hash_code
|
||||
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
|
||||
|
||||
def make_key_usage_code(self):
|
||||
return '\n'.join([self.make_bit_test('usage', bit)
|
||||
def _make_key_usage_code(self):
|
||||
return '\n'.join([self._make_bit_test('usage', bit)
|
||||
for bit in sorted(self.key_usages)])
|
||||
|
||||
def write_file(self, output_file):
|
||||
"""Generate the pretty-printer function code from the gathered
|
||||
constant definitions.
|
||||
"""
|
||||
data = {}
|
||||
data['status_cases'] = self.make_status_cases()
|
||||
data['ecc_curve_cases'] = self.make_ecc_curve_cases()
|
||||
data['key_type_cases'] = self.make_key_type_cases()
|
||||
data['key_type_code'] = self.make_key_type_code()
|
||||
data['hash_algorithm_cases'] = self.make_hash_algorithm_cases()
|
||||
data['algorithm_cases'] = self.make_algorithm_cases()
|
||||
data['algorithm_code'] = self.make_algorithm_code()
|
||||
data['key_usage_code'] = self.make_key_usage_code()
|
||||
output_file.write(output_template % data)
|
||||
data['status_cases'] = self._make_status_cases()
|
||||
data['ecc_curve_cases'] = self._make_ecc_curve_cases()
|
||||
data['dh_group_cases'] = self._make_dh_group_cases()
|
||||
data['key_type_cases'] = self._make_key_type_cases()
|
||||
data['key_type_code'] = (self._make_ecc_key_type_code() +
|
||||
self._make_dh_key_type_code())
|
||||
data['hash_algorithm_cases'] = self._make_hash_algorithm_cases()
|
||||
data['ka_algorithm_cases'] = self._make_ka_algorithm_cases()
|
||||
data['algorithm_cases'] = self._make_algorithm_cases()
|
||||
data['algorithm_code'] = self._make_algorithm_code()
|
||||
data['key_usage_code'] = self._make_key_usage_code()
|
||||
output_file.write(OUTPUT_TEMPLATE % data)
|
||||
|
||||
def generate_psa_constants(header_file_names, output_file_name):
|
||||
collector = MacroCollector()
|
||||
|
|
|
@ -142,6 +142,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_se_driver_hal)
|
||||
add_test_suite(psa_crypto_slot_management)
|
||||
add_test_suite(psa_its)
|
||||
add_test_suite(shax)
|
||||
|
|
|
@ -104,6 +104,11 @@ $(BINARIES): %$(EXEXT): %.c $(DEP)
|
|||
echo " CC $<"
|
||||
$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
# Some test suites require additional header files.
|
||||
$(filter test_suite_psa_crypto%, $(BINARIES)): psa_crypto_helpers.h
|
||||
$(addprefix embedded_,$(filter test_suite_psa_crypto%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_crypto_helpers.h
|
||||
$(filter test_suite_psa_%, $(BINARIES)): psa_helpers.h
|
||||
$(addprefix embedded_,$(filter test_suite_psa_%, $(APPS))): embedded_%: TESTS/mbedtls/%/psa_helpers.h
|
||||
|
||||
clean:
|
||||
ifndef WINDOWS
|
||||
|
@ -141,3 +146,17 @@ $(EMBEDDED_TESTS): embedded_%: suites/$$(firstword $$(subst ., ,$$*)).function s
|
|||
|
||||
generate-target-tests: $(EMBEDDED_TESTS)
|
||||
|
||||
define copy_header_to_target
|
||||
TESTS/mbedtls/$(1)/$(2): $(2)
|
||||
echo " Copy ./$$@"
|
||||
ifndef WINDOWS
|
||||
mkdir -p $$(@D)
|
||||
cp $$< $$@
|
||||
else
|
||||
mkdir $$(@D)
|
||||
copy $$< $$@
|
||||
endif
|
||||
|
||||
endef
|
||||
$(foreach app, $(APPS), $(foreach file, $(wildcard *.h), \
|
||||
$(eval $(call copy_header_to_target,$(app),$(file)))))
|
||||
|
|
75
tests/psa_crypto_helpers.h
Normal file
75
tests/psa_crypto_helpers.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Helper functions for tests that use the PSA Crypto API.
|
||||
*/
|
||||
/* Copyright (C) 2019, 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_HELPERS_H
|
||||
#define PSA_CRYPTO_HELPERS_H
|
||||
|
||||
#include "psa_helpers.h"
|
||||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
static int test_helper_is_psa_pristine( int line, const char *file )
|
||||
{
|
||||
mbedtls_psa_stats_t stats;
|
||||
const char *msg = NULL;
|
||||
|
||||
mbedtls_psa_get_stats( &stats );
|
||||
|
||||
if( stats.volatile_slots != 0 )
|
||||
msg = "A volatile slot has not been closed properly.";
|
||||
else if( stats.persistent_slots != 0 )
|
||||
msg = "A persistent slot has not been closed properly.";
|
||||
else if( stats.external_slots != 0 )
|
||||
msg = "An external slot has not been closed properly.";
|
||||
else if( stats.half_filled_slots != 0 )
|
||||
msg = "A half-filled slot has not been cleared properly.";
|
||||
|
||||
/* If the test has already failed, don't overwrite the failure
|
||||
* information. Do keep the stats lookup above, because it can be
|
||||
* convenient to break on it when debugging a failure. */
|
||||
if( msg != NULL && test_info.failed == 0 )
|
||||
test_fail( msg, line, file );
|
||||
|
||||
return( msg == NULL );
|
||||
}
|
||||
|
||||
/** Check that no PSA Crypto key slots are in use.
|
||||
*/
|
||||
#define ASSERT_PSA_PRISTINE( ) \
|
||||
do \
|
||||
{ \
|
||||
if( ! test_helper_is_psa_pristine( __LINE__, __FILE__ ) ) \
|
||||
goto exit; \
|
||||
} \
|
||||
while( 0 )
|
||||
|
||||
static void test_helper_psa_done( int line, const char *file )
|
||||
{
|
||||
(void) test_helper_is_psa_pristine( line, file );
|
||||
mbedtls_psa_crypto_free( );
|
||||
}
|
||||
|
||||
/** Shut down the PSA Crypto subsystem. Expect a clean shutdown, with no slots
|
||||
* in use.
|
||||
*/
|
||||
#define PSA_DONE( ) test_helper_psa_done( __LINE__, __FILE__ )
|
||||
|
||||
#endif /* PSA_CRYPTO_HELPERS_H */
|
37
tests/psa_helpers.h
Normal file
37
tests/psa_helpers.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Helper functions for tests that use any PSA API.
|
||||
*/
|
||||
/* Copyright (C) 2019, 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_HELPERS_H
|
||||
#define PSA_HELPERS_H
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
||||
#include "spm/psa_defs.h"
|
||||
#endif
|
||||
|
||||
/** Evaluate an expression and fail the test case if it returns an error.
|
||||
*
|
||||
* \param expr The expression to evaluate. This is typically a call
|
||||
* to a \c psa_xxx function that returns a value of type
|
||||
* #psa_status_t.
|
||||
*/
|
||||
#define PSA_ASSERT( expr ) TEST_EQUAL( ( expr ), PSA_SUCCESS )
|
||||
|
||||
#endif /* PSA_HELPERS_H */
|
|
@ -756,6 +756,7 @@ component_test_no_platform () {
|
|||
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
|
||||
scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
scripts/config.pl unset MBEDTLS_FS_IO
|
||||
scripts/config.pl unset MBEDTLS_PSA_CRYPTO_SE_C
|
||||
scripts/config.pl unset MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
scripts/config.pl unset MBEDTLS_PSA_ITS_FILE_C
|
||||
# Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19,
|
||||
|
@ -828,6 +829,24 @@ component_test_aes_fewer_tables_and_rom_tables () {
|
|||
make test
|
||||
}
|
||||
|
||||
component_test_se_default () {
|
||||
msg "build: default config + MBEDTLS_PSA_CRYPTO_SE_C"
|
||||
scripts/config.pl set MBEDTLS_PSA_CRYPTO_SE_C
|
||||
make CC=clang CFLAGS='-Werror -Wall -Wextra -Wno-unused-function -Os -fsanitize=address' LDFLAGS='-fsanitize=address'
|
||||
|
||||
msg "test: default config + MBEDTLS_PSA_CRYPTO_SE_C"
|
||||
make test
|
||||
}
|
||||
|
||||
component_test_se_full () {
|
||||
msg "build: full config + MBEDTLS_PSA_CRYPTO_SE_C"
|
||||
scripts/config.pl set MBEDTLS_PSA_CRYPTO_SE_C
|
||||
make CC=gcc CFLAGS='-Werror -Wall -Wextra -O2 -fsanitize=address' LDFLAGS='-fsanitize=address'
|
||||
|
||||
msg "test: full config + MBEDTLS_PSA_CRYPTO_SE_C"
|
||||
make test
|
||||
}
|
||||
|
||||
component_test_make_shared () {
|
||||
msg "build/test: make shared" # ~ 40s
|
||||
make SHARED=1 all check -j1
|
||||
|
|
|
@ -41,7 +41,7 @@ rm -f identifiers
|
|||
|
||||
grep '^[^ /#{]' $HEADERS | \
|
||||
sed -e 's/^[^:]*://' | \
|
||||
egrep -v '^(extern "C"|(typedef )?(struct|enum)( {)?$|};?$)' \
|
||||
egrep -v '^(extern "C"|(typedef )?(struct|union|enum)( {)?$|};?$)' \
|
||||
> _decls
|
||||
|
||||
if true; then
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
'''Test the program psa_constant_names.
|
||||
"""Test the program psa_constant_names.
|
||||
Gather constant names from header files and test cases. Compile a C program
|
||||
to print out their numerical values, feed these numerical values to
|
||||
psa_constant_names, and check that the output is the original name.
|
||||
Return 0 if all test cases pass, 1 if the output was not always as expected,
|
||||
or 1 (with a Python backtrace) if there was an operational error.'''
|
||||
or 1 (with a Python backtrace) if there was an operational error.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
|
@ -23,19 +24,28 @@ class ReadFileLineException(Exception):
|
|||
self.line_number = line_number
|
||||
|
||||
class read_file_lines:
|
||||
'''Context manager to read a text file line by line.
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
process(line)
|
||||
is equivalent to
|
||||
with open(filename, 'r') as input_file:
|
||||
for line in input_file:
|
||||
process(line)
|
||||
except that if process(line) raises an exception, then the read_file_lines
|
||||
snippet annotates the exception with the file name and line number.'''
|
||||
# Dear Pylint, conventionally, a context manager class name is lowercase.
|
||||
# pylint: disable=invalid-name,too-few-public-methods
|
||||
"""Context manager to read a text file line by line.
|
||||
|
||||
```
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
process(line)
|
||||
```
|
||||
is equivalent to
|
||||
```
|
||||
with open(filename, 'r') as input_file:
|
||||
for line in input_file:
|
||||
process(line)
|
||||
```
|
||||
except that if process(line) raises an exception, then the read_file_lines
|
||||
snippet annotates the exception with the file name and line number.
|
||||
"""
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.line_number = 'entry'
|
||||
self.generator = None
|
||||
def __enter__(self):
|
||||
self.generator = enumerate(open(self.filename, 'r'))
|
||||
return self
|
||||
|
@ -44,26 +54,30 @@ snippet annotates the exception with the file name and line number.'''
|
|||
self.line_number = line_number
|
||||
yield content
|
||||
self.line_number = 'exit'
|
||||
def __exit__(self, type, value, traceback):
|
||||
if type is not None:
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
if exc_type is not None:
|
||||
raise ReadFileLineException(self.filename, self.line_number) \
|
||||
from value
|
||||
from exc_value
|
||||
|
||||
class Inputs:
|
||||
'''Accumulate information about macros to test.
|
||||
This includes macro names as well as information about their arguments
|
||||
when applicable.'''
|
||||
"""Accumulate information about macros to test.
|
||||
This includes macro names as well as information about their arguments
|
||||
when applicable.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# Sets of names per type
|
||||
self.statuses = set(['PSA_SUCCESS'])
|
||||
self.algorithms = set(['0xffffffff'])
|
||||
self.ecc_curves = set(['0xffff'])
|
||||
self.dh_groups = set(['0xffff'])
|
||||
self.key_types = set(['0xffffffff'])
|
||||
self.key_usage_flags = set(['0x80000000'])
|
||||
# Hard-coded value for unknown algorithms
|
||||
self.hash_algorithms = set(['0x010000fe'])
|
||||
self.mac_algorithms = set(['0x02ff00ff'])
|
||||
self.kdf_algorithms = set(['0x300000ff', '0x310000ff'])
|
||||
self.ka_algorithms = set(['0x30fc0000'])
|
||||
self.kdf_algorithms = set(['0x200000ff'])
|
||||
# For AEAD algorithms, the only variability is over the tag length,
|
||||
# and this only applies to known algorithms, so don't test an
|
||||
# unknown algorithm.
|
||||
|
@ -73,6 +87,7 @@ when applicable.'''
|
|||
'ERROR': self.statuses,
|
||||
'ALG': self.algorithms,
|
||||
'CURVE': self.ecc_curves,
|
||||
'GROUP': self.dh_groups,
|
||||
'KEY_TYPE': self.key_types,
|
||||
'KEY_USAGE': self.key_usage_flags,
|
||||
}
|
||||
|
@ -85,23 +100,29 @@ when applicable.'''
|
|||
}
|
||||
|
||||
def gather_arguments(self):
|
||||
'''Populate the list of values for macro arguments.
|
||||
Call this after parsing all the inputs.'''
|
||||
"""Populate the list of values for macro arguments.
|
||||
Call this after parsing all the inputs.
|
||||
"""
|
||||
self.arguments_for['hash_alg'] = sorted(self.hash_algorithms)
|
||||
self.arguments_for['mac_alg'] = sorted(self.mac_algorithms)
|
||||
self.arguments_for['ka_alg'] = sorted(self.ka_algorithms)
|
||||
self.arguments_for['kdf_alg'] = sorted(self.kdf_algorithms)
|
||||
self.arguments_for['aead_alg'] = sorted(self.aead_algorithms)
|
||||
self.arguments_for['curve'] = sorted(self.ecc_curves)
|
||||
self.arguments_for['group'] = sorted(self.dh_groups)
|
||||
|
||||
def format_arguments(self, name, arguments):
|
||||
'''Format a macro call with arguments..'''
|
||||
@staticmethod
|
||||
def _format_arguments(name, arguments):
|
||||
"""Format a macro call with arguments.."""
|
||||
return name + '(' + ', '.join(arguments) + ')'
|
||||
|
||||
def distribute_arguments(self, name):
|
||||
'''Generate macro calls with each tested argument set.
|
||||
If name is a macro without arguments, just yield "name".
|
||||
If name is a macro with arguments, yield a series of "name(arg1,...,argN)"
|
||||
where each argument takes each possible value at least once.'''
|
||||
"""Generate macro calls with each tested argument set.
|
||||
If name is a macro without arguments, just yield "name".
|
||||
If name is a macro with arguments, yield a series of
|
||||
"name(arg1,...,argN)" where each argument takes each possible
|
||||
value at least once.
|
||||
"""
|
||||
try:
|
||||
if name not in self.argspecs:
|
||||
yield name
|
||||
|
@ -112,60 +133,68 @@ where each argument takes each possible value at least once.'''
|
|||
return
|
||||
argument_lists = [self.arguments_for[arg] for arg in argspec]
|
||||
arguments = [values[0] for values in argument_lists]
|
||||
yield self.format_arguments(name, arguments)
|
||||
yield self._format_arguments(name, arguments)
|
||||
# Dear Pylint, enumerate won't work here since we're modifying
|
||||
# the array.
|
||||
# pylint: disable=consider-using-enumerate
|
||||
for i in range(len(arguments)):
|
||||
for value in argument_lists[i][1:]:
|
||||
arguments[i] = value
|
||||
yield self.format_arguments(name, arguments)
|
||||
yield self._format_arguments(name, arguments)
|
||||
arguments[i] = argument_lists[0][0]
|
||||
except BaseException as e:
|
||||
raise Exception('distribute_arguments({})'.format(name)) from e
|
||||
|
||||
_argument_split_re = re.compile(r' *, *')
|
||||
@classmethod
|
||||
def _argument_split(cls, arguments):
|
||||
return re.split(cls._argument_split_re, arguments)
|
||||
|
||||
# Regex for interesting header lines.
|
||||
# Groups: 1=macro name, 2=type, 3=argument list (optional).
|
||||
header_line_re = \
|
||||
_header_line_re = \
|
||||
re.compile(r'#define +' +
|
||||
r'(PSA_((?:KEY_)?[A-Z]+)_\w+)' +
|
||||
r'(?:\(([^\n()]*)\))?')
|
||||
# Regex of macro names to exclude.
|
||||
excluded_name_re = re.compile('_(?:GET|IS|OF)_|_(?:BASE|FLAG|MASK)\Z')
|
||||
_excluded_name_re = re.compile(r'_(?:GET|IS|OF)_|_(?:BASE|FLAG|MASK)\Z')
|
||||
# Additional excluded macros.
|
||||
# PSA_ALG_ECDH and PSA_ALG_FFDH are excluded for now as the script
|
||||
# currently doesn't support them. Deprecated errors are also excluded.
|
||||
excluded_names = set(['PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH',
|
||||
'PSA_ALG_FULL_LENGTH_MAC',
|
||||
'PSA_ALG_ECDH',
|
||||
'PSA_ALG_FFDH',
|
||||
'PSA_ERROR_UNKNOWN_ERROR',
|
||||
'PSA_ERROR_OCCUPIED_SLOT',
|
||||
'PSA_ERROR_EMPTY_SLOT',
|
||||
'PSA_ERROR_INSUFFICIENT_CAPACITY',
|
||||
_excluded_names = set(['PSA_ALG_AEAD_WITH_DEFAULT_TAG_LENGTH',
|
||||
'PSA_ALG_FULL_LENGTH_MAC',
|
||||
'PSA_ALG_ECDH',
|
||||
'PSA_ALG_FFDH',
|
||||
'PSA_ERROR_UNKNOWN_ERROR',
|
||||
'PSA_ERROR_OCCUPIED_SLOT',
|
||||
'PSA_ERROR_EMPTY_SLOT',
|
||||
'PSA_ERROR_INSUFFICIENT_CAPACITY',
|
||||
])
|
||||
argument_split_re = re.compile(r' *, *')
|
||||
|
||||
def parse_header_line(self, line):
|
||||
'''Parse a C header line, looking for "#define PSA_xxx".'''
|
||||
m = re.match(self.header_line_re, line)
|
||||
"""Parse a C header line, looking for "#define PSA_xxx"."""
|
||||
m = re.match(self._header_line_re, line)
|
||||
if not m:
|
||||
return
|
||||
name = m.group(1)
|
||||
if re.search(self.excluded_name_re, name) or \
|
||||
name in self.excluded_names:
|
||||
if re.search(self._excluded_name_re, name) or \
|
||||
name in self._excluded_names:
|
||||
return
|
||||
dest = self.table_by_prefix.get(m.group(2))
|
||||
if dest is None:
|
||||
return
|
||||
dest.add(name)
|
||||
if m.group(3):
|
||||
self.argspecs[name] = re.split(self.argument_split_re, m.group(3))
|
||||
self.argspecs[name] = self._argument_split(m.group(3))
|
||||
|
||||
def parse_header(self, filename):
|
||||
'''Parse a C header file, looking for "#define PSA_xxx".'''
|
||||
"""Parse a C header file, looking for "#define PSA_xxx"."""
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
self.parse_header_line(line)
|
||||
|
||||
def add_test_case_line(self, function, argument):
|
||||
'''Parse a test case data line, looking for algorithm metadata tests.'''
|
||||
"""Parse a test case data line, looking for algorithm metadata tests."""
|
||||
if function.endswith('_algorithm'):
|
||||
# As above, ECDH and FFDH algorithms are excluded for now.
|
||||
# Support for them will be added in the future.
|
||||
|
@ -182,21 +211,23 @@ where each argument takes each possible value at least once.'''
|
|||
self.key_types.add(argument)
|
||||
elif function == 'ecc_key_types':
|
||||
self.ecc_curves.add(argument)
|
||||
elif function == 'dh_key_types':
|
||||
self.dh_groups.add(argument)
|
||||
|
||||
# Regex matching a *.data line containing a test function call and
|
||||
# its arguments. The actual definition is partly positional, but this
|
||||
# regex is good enough in practice.
|
||||
test_case_line_re = re.compile('(?!depends_on:)(\w+):([^\n :][^:\n]*)')
|
||||
_test_case_line_re = re.compile(r'(?!depends_on:)(\w+):([^\n :][^:\n]*)')
|
||||
def parse_test_cases(self, filename):
|
||||
'''Parse a test case file (*.data), looking for algorithm metadata tests.'''
|
||||
"""Parse a test case file (*.data), looking for algorithm metadata tests."""
|
||||
with read_file_lines(filename) as lines:
|
||||
for line in lines:
|
||||
m = re.match(self.test_case_line_re, line)
|
||||
m = re.match(self._test_case_line_re, line)
|
||||
if m:
|
||||
self.add_test_case_line(m.group(1), m.group(2))
|
||||
|
||||
def gather_inputs(headers, test_suites):
|
||||
'''Read the list of inputs to test psa_constant_names with.'''
|
||||
"""Read the list of inputs to test psa_constant_names with."""
|
||||
inputs = Inputs()
|
||||
for header in headers:
|
||||
inputs.parse_header(header)
|
||||
|
@ -206,17 +237,17 @@ def gather_inputs(headers, test_suites):
|
|||
return inputs
|
||||
|
||||
def remove_file_if_exists(filename):
|
||||
'''Remove the specified file, ignoring errors.'''
|
||||
"""Remove the specified file, ignoring errors."""
|
||||
if not filename:
|
||||
return
|
||||
try:
|
||||
os.remove(filename)
|
||||
except:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def run_c(options, type, names):
|
||||
'''Generate and run a program to print out numerical values for names.'''
|
||||
if type == 'status':
|
||||
def run_c(options, type_word, names):
|
||||
"""Generate and run a program to print out numerical values for names."""
|
||||
if type_word == 'status':
|
||||
cast_to = 'long'
|
||||
printf_format = '%ld'
|
||||
else:
|
||||
|
@ -225,7 +256,7 @@ def run_c(options, type, names):
|
|||
c_name = None
|
||||
exe_name = None
|
||||
try:
|
||||
c_fd, c_name = tempfile.mkstemp(prefix='tmp-{}-'.format(type),
|
||||
c_fd, c_name = tempfile.mkstemp(prefix='tmp-{}-'.format(type_word),
|
||||
suffix='.c',
|
||||
dir='programs/psa')
|
||||
exe_suffix = '.exe' if platform.system() == 'Windows' else ''
|
||||
|
@ -233,7 +264,7 @@ def run_c(options, type, names):
|
|||
remove_file_if_exists(exe_name)
|
||||
c_file = os.fdopen(c_fd, 'w', encoding='ascii')
|
||||
c_file.write('/* Generated by test_psa_constant_names.py for {} values */'
|
||||
.format(type))
|
||||
.format(type_word))
|
||||
c_file.write('''
|
||||
#include <stdio.h>
|
||||
#include <psa/crypto.h>
|
||||
|
@ -253,7 +284,7 @@ int main(void)
|
|||
['-o', exe_name, c_name])
|
||||
if options.keep_c:
|
||||
sys.stderr.write('List of {} tests kept at {}\n'
|
||||
.format(type, c_name))
|
||||
.format(type_word, c_name))
|
||||
else:
|
||||
os.remove(c_name)
|
||||
output = subprocess.check_output([exe_name])
|
||||
|
@ -261,50 +292,55 @@ int main(void)
|
|||
finally:
|
||||
remove_file_if_exists(exe_name)
|
||||
|
||||
normalize_strip_re = re.compile(r'\s+')
|
||||
NORMALIZE_STRIP_RE = re.compile(r'\s+')
|
||||
def normalize(expr):
|
||||
'''Normalize the C expression so as not to care about trivial differences.
|
||||
Currently "trivial differences" means whitespace.'''
|
||||
expr = re.sub(normalize_strip_re, '', expr, len(expr))
|
||||
"""Normalize the C expression so as not to care about trivial differences.
|
||||
Currently "trivial differences" means whitespace.
|
||||
"""
|
||||
expr = re.sub(NORMALIZE_STRIP_RE, '', expr, len(expr))
|
||||
return expr.strip().split('\n')
|
||||
|
||||
def do_test(options, inputs, type, names):
|
||||
'''Test psa_constant_names for the specified type.
|
||||
Run program on names.
|
||||
Use inputs to figure out what arguments to pass to macros that take arguments.'''
|
||||
def do_test(options, inputs, type_word, names):
|
||||
"""Test psa_constant_names for the specified type.
|
||||
Run program on names.
|
||||
Use inputs to figure out what arguments to pass to macros that
|
||||
take arguments.
|
||||
"""
|
||||
names = sorted(itertools.chain(*map(inputs.distribute_arguments, names)))
|
||||
values = run_c(options, type, names)
|
||||
output = subprocess.check_output([options.program, type] + values)
|
||||
values = run_c(options, type_word, names)
|
||||
output = subprocess.check_output([options.program, type_word] + values)
|
||||
outputs = output.decode('ascii').strip().split('\n')
|
||||
errors = [(type, name, value, output)
|
||||
errors = [(type_word, name, value, output)
|
||||
for (name, value, output) in zip(names, values, outputs)
|
||||
if normalize(name) != normalize(output)]
|
||||
return len(names), errors
|
||||
|
||||
def report_errors(errors):
|
||||
'''Describe each case where the output is not as expected.'''
|
||||
for type, name, value, output in errors:
|
||||
"""Describe each case where the output is not as expected."""
|
||||
for type_word, name, value, output in errors:
|
||||
print('For {} "{}", got "{}" (value: {})'
|
||||
.format(type, name, output, value))
|
||||
.format(type_word, name, output, value))
|
||||
|
||||
def run_tests(options, inputs):
|
||||
'''Run psa_constant_names on all the gathered inputs.
|
||||
Return a tuple (count, errors) where count is the total number of inputs
|
||||
that were tested and errors is the list of cases where the output was
|
||||
not as expected.'''
|
||||
"""Run psa_constant_names on all the gathered inputs.
|
||||
Return a tuple (count, errors) where count is the total number of inputs
|
||||
that were tested and errors is the list of cases where the output was
|
||||
not as expected.
|
||||
"""
|
||||
count = 0
|
||||
errors = []
|
||||
for type, names in [('status', inputs.statuses),
|
||||
('algorithm', inputs.algorithms),
|
||||
('ecc_curve', inputs.ecc_curves),
|
||||
('key_type', inputs.key_types),
|
||||
('key_usage', inputs.key_usage_flags)]:
|
||||
c, e = do_test(options, inputs, type, names)
|
||||
for type_word, names in [('status', inputs.statuses),
|
||||
('algorithm', inputs.algorithms),
|
||||
('ecc_curve', inputs.ecc_curves),
|
||||
('dh_group', inputs.dh_groups),
|
||||
('key_type', inputs.key_types),
|
||||
('key_usage', inputs.key_usage_flags)]:
|
||||
c, e = do_test(options, inputs, type_word, names)
|
||||
count += c
|
||||
errors += e
|
||||
return count, errors
|
||||
|
||||
if __name__ == '__main__':
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=globals()['__doc__'])
|
||||
parser.add_argument('--include', '-I',
|
||||
action='append', default=['include'],
|
||||
|
@ -330,3 +366,6 @@ if __name__ == '__main__':
|
|||
else:
|
||||
print('{} test cases, {} FAIL'.format(count, len(errors)))
|
||||
exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -126,14 +126,6 @@ typedef enum
|
|||
#define TEST_EQUAL( expr1, expr2 ) \
|
||||
TEST_ASSERT( ( expr1 ) == ( expr2 ) )
|
||||
|
||||
/** Evaluate an expression and fail the test case if it returns an error.
|
||||
*
|
||||
* \param expr The expression to evaluate. This is typically a call
|
||||
* to a \c psa_xxx function that returns a value of type
|
||||
* #psa_status_t.
|
||||
*/
|
||||
#define PSA_ASSERT( expr ) TEST_EQUAL( ( expr ), PSA_SUCCESS )
|
||||
|
||||
/** Allocate memory dynamically and fail the test case if this fails.
|
||||
*
|
||||
* You must set \p pointer to \c NULL before calling this macro and
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
#if defined(MBEDTLS_GCM_C)
|
||||
#include "mbedtls/gcm.h"
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "psa_crypto_helpers.h"
|
||||
#endif
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
|
@ -982,7 +987,7 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv,
|
|||
#else
|
||||
if( use_psa == 1 )
|
||||
{
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* PSA requires that the tag immediately follows the ciphertext. */
|
||||
tmp_cipher = mbedtls_calloc( 1, cipher->len + tag->len );
|
||||
|
@ -1066,14 +1071,15 @@ void auth_crypt_tv( int cipher_id, data_t * key, data_t * iv,
|
|||
|
||||
exit:
|
||||
|
||||
mbedtls_cipher_free( &ctx );
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
if( use_psa == 1 )
|
||||
{
|
||||
mbedtls_free( tmp_cipher );
|
||||
PSA_DONE( );
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
||||
mbedtls_cipher_free( &ctx );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -1143,7 +1149,7 @@ void test_vec_crypt( int cipher_id, int operation, char *hex_key,
|
|||
#else
|
||||
if( use_psa == 1 )
|
||||
{
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
TEST_ASSERT( 0 == mbedtls_cipher_setup_psa( &ctx,
|
||||
mbedtls_cipher_info_from_type( cipher_id ), 0 ) );
|
||||
}
|
||||
|
@ -1172,6 +1178,9 @@ void test_vec_crypt( int cipher_id, int operation, char *hex_key,
|
|||
|
||||
exit:
|
||||
mbedtls_cipher_free( &ctx );
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
PSA_DONE( );
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
|
|
@ -10,6 +10,18 @@
|
|||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
#include "mbedtls/psa_util.h"
|
||||
#include "psa_crypto_helpers.h"
|
||||
#define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) )
|
||||
#else
|
||||
/* Define empty macros so that we can use them in the preamble and teardown
|
||||
* of every test function that uses PSA conditionally based on
|
||||
* MBEDTLS_USE_PSA_CRYPTO. */
|
||||
#define PSA_INIT( ) ( (void) 0 )
|
||||
#define PSA_DONE( ) ( (void) 0 )
|
||||
#endif
|
||||
|
||||
static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len );
|
||||
|
||||
#define RSA_KEY_SIZE 512
|
||||
|
@ -67,39 +79,26 @@ size_t mbedtls_rsa_key_len_func( void *ctx )
|
|||
|
||||
#if defined(MBEDTLS_USE_PSA_CRYPTO)
|
||||
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#define PK_PSA_INVALID_SLOT 0 /* guaranteed invalid */
|
||||
|
||||
/*
|
||||
* Generate a key in a free key slot and return this key slot,
|
||||
* or PK_PSA_INVALID_SLOT if no slot was available.
|
||||
* Generate a key using PSA and return a handle to that key,
|
||||
* or 0 if the key generation failed.
|
||||
* The key uses NIST P-256 and is usable for signing with SHA-256.
|
||||
*/
|
||||
psa_key_handle_t pk_psa_genkey( void )
|
||||
{
|
||||
psa_key_handle_t key;
|
||||
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
const int curve = PSA_ECC_CURVE_SECP256R1;
|
||||
const psa_key_type_t type = PSA_KEY_TYPE_ECC_KEYPAIR(curve);
|
||||
const psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(curve);
|
||||
const size_t bits = 256;
|
||||
psa_key_policy_t policy;
|
||||
|
||||
/* Allocate a key slot */
|
||||
if( PSA_SUCCESS != psa_allocate_key( &key ) )
|
||||
return( PK_PSA_INVALID_SLOT );
|
||||
|
||||
/* set up policy on key slot */
|
||||
policy = psa_key_policy_init();
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_SIGN,
|
||||
PSA_ALG_ECDSA(PSA_ALG_SHA_256) );
|
||||
if( PSA_SUCCESS != psa_set_key_policy( key, &policy ) )
|
||||
return( PK_PSA_INVALID_SLOT );
|
||||
|
||||
/* generate key */
|
||||
if( PSA_SUCCESS != psa_generate_key( key, type, bits, NULL, 0 ) )
|
||||
return( PK_PSA_INVALID_SLOT );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN );
|
||||
psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256) );
|
||||
psa_set_key_type( &attributes, type );
|
||||
psa_set_key_bits( &attributes, bits );
|
||||
PSA_ASSERT( psa_generate_key( &attributes, &key ) );
|
||||
|
||||
exit:
|
||||
return( key );
|
||||
}
|
||||
#endif /* MBEDTLS_USE_PSA_CRYPTO */
|
||||
|
@ -115,6 +114,7 @@ void pk_psa_utils( )
|
|||
{
|
||||
mbedtls_pk_context pk, pk2;
|
||||
psa_key_handle_t key;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
const char * const name = "Opaque";
|
||||
const size_t bitlen = 256; /* harcoded in genkey() */
|
||||
|
@ -124,7 +124,7 @@ void pk_psa_utils( )
|
|||
size_t len;
|
||||
mbedtls_pk_debug_item dbg;
|
||||
|
||||
TEST_ASSERT( psa_crypto_init() == 0 );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
mbedtls_pk_init( &pk );
|
||||
mbedtls_pk_init( &pk2 );
|
||||
|
@ -136,7 +136,8 @@ void pk_psa_utils( )
|
|||
mbedtls_pk_init( &pk );
|
||||
|
||||
key = pk_psa_genkey();
|
||||
TEST_ASSERT( key != 0 );
|
||||
if( key == 0 )
|
||||
goto exit;
|
||||
|
||||
TEST_ASSERT( mbedtls_pk_setup_opaque( &pk, key ) == 0 );
|
||||
|
||||
|
@ -173,12 +174,13 @@ void pk_psa_utils( )
|
|||
|
||||
/* test that freeing the context does not destroy the key */
|
||||
mbedtls_pk_free( &pk );
|
||||
TEST_ASSERT( PSA_SUCCESS == psa_get_key_information( key, NULL, NULL ) );
|
||||
TEST_ASSERT( PSA_SUCCESS == psa_get_key_attributes( key, &attributes ) );
|
||||
TEST_ASSERT( PSA_SUCCESS == psa_destroy_key( key ) );
|
||||
|
||||
exit:
|
||||
mbedtls_pk_free( &pk ); /* redundant except upon error */
|
||||
mbedtls_pk_free( &pk2 );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -769,7 +771,7 @@ void pk_ec_test_vec( int type, int id, data_t * key, data_t * hash,
|
|||
mbedtls_ecp_keypair *eckey;
|
||||
|
||||
mbedtls_pk_init( &pk );
|
||||
|
||||
PSA_INIT( );
|
||||
|
||||
TEST_ASSERT( mbedtls_pk_setup( &pk, mbedtls_pk_info_from_type( type ) ) == 0 );
|
||||
|
||||
|
@ -786,6 +788,7 @@ void pk_ec_test_vec( int type, int id, data_t * key, data_t * hash,
|
|||
|
||||
exit:
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -910,6 +913,7 @@ void pk_sign_verify( int type, int sign_ret, int verify_ret )
|
|||
#endif
|
||||
|
||||
mbedtls_pk_init( &pk );
|
||||
PSA_INIT( );
|
||||
|
||||
memset( hash, 0x2a, sizeof hash );
|
||||
memset( sig, 0, sizeof sig );
|
||||
|
@ -961,6 +965,7 @@ exit:
|
|||
mbedtls_pk_restart_free( rs_ctx );
|
||||
#endif
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -1216,6 +1221,8 @@ void pk_psa_sign( )
|
|||
* - parse it to a PK context and verify the signature this way
|
||||
*/
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Create legacy EC public/private key in PK context. */
|
||||
mbedtls_pk_init( &pk );
|
||||
TEST_ASSERT( mbedtls_pk_setup( &pk,
|
||||
|
@ -1233,7 +1240,6 @@ void pk_psa_sign( )
|
|||
pkey_legacy_start = pkey_legacy + sizeof( pkey_legacy ) - klen_legacy;
|
||||
|
||||
/* Turn PK context into an opaque one. */
|
||||
TEST_ASSERT( psa_allocate_key( &handle ) == PSA_SUCCESS );
|
||||
TEST_ASSERT( mbedtls_pk_wrap_as_opaque( &pk, &handle,
|
||||
PSA_ALG_SHA_256 ) == 0 );
|
||||
|
||||
|
@ -1266,5 +1272,6 @@ void pk_psa_sign( )
|
|||
|
||||
exit:
|
||||
mbedtls_pk_free( &pk );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,10 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/entropy_poll.h"
|
||||
|
||||
#include "psa_crypto_helpers.h"
|
||||
#if defined(MBEDTLS_PSA_ITS_FILE_C)
|
||||
#include <stdio.h>
|
||||
#else
|
||||
|
@ -77,7 +77,7 @@ void validate_entropy_seed_injection( int seed_length_a,
|
|||
exit:
|
||||
mbedtls_free( seed );
|
||||
remove_seed_file( );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -105,12 +105,12 @@ void run_entropy_inject_with_crypto_init( )
|
|||
PSA_ASSERT( status );
|
||||
status = psa_crypto_init( );
|
||||
PSA_ASSERT( status );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
/* The seed is written by nv_seed callback functions therefore the injection will fail */
|
||||
status = mbedtls_psa_inject_entropy( seed, sizeof( seed ) );
|
||||
TEST_EQUAL( status, PSA_ERROR_NOT_PERMITTED );
|
||||
exit:
|
||||
remove_seed_file( );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -2,11 +2,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
||||
#include "spm/psa_defs.h"
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_helpers.h"
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
|
@ -35,7 +31,7 @@ void hash_finish( int alg_arg, data_t *input, data_t *expected_hash )
|
|||
actual_hash, actual_hash_length );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -56,7 +52,7 @@ void hash_verify( int alg_arg, data_t *input, data_t *expected_hash )
|
|||
expected_hash->len ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -99,6 +95,6 @@ void hash_multi_part( int alg_arg, data_t *input, data_t *expected_hash )
|
|||
} while( len++ != input->len );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
||||
#include "spm/psa_defs.h"
|
||||
#endif
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa_crypto_helpers.h"
|
||||
/* Some tests in this module configure entropy sources. */
|
||||
#include "psa_crypto_invasive.h"
|
||||
|
||||
|
@ -142,7 +138,7 @@ void init_deinit( int count )
|
|||
PSA_ASSERT( status );
|
||||
status = psa_crypto_init( );
|
||||
PSA_ASSERT( status );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -154,9 +150,9 @@ void deinit_without_init( int count )
|
|||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -170,7 +166,7 @@ void validate_module_init_generate_random( int count )
|
|||
{
|
||||
status = psa_crypto_init( );
|
||||
PSA_ASSERT( status );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
status = psa_generate_random( random, sizeof( random ) );
|
||||
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||
|
@ -182,15 +178,20 @@ void validate_module_init_key_based( int count )
|
|||
{
|
||||
psa_status_t status;
|
||||
uint8_t data[10] = { 0 };
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_handle_t handle = 0xdead;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
status = psa_crypto_init( );
|
||||
PSA_ASSERT( status );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
status = psa_import_key( 1, PSA_KEY_TYPE_RAW_DATA, data, sizeof( data ) );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
status = psa_import_key( &attributes, data, sizeof( data ), &handle );
|
||||
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||
TEST_EQUAL( handle, 0 );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -211,7 +212,7 @@ void custom_entropy_sources( int sources_arg, int expected_init_status_arg )
|
|||
PSA_ASSERT( psa_generate_random( random, sizeof( random ) ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -251,7 +252,7 @@ void fake_entropy_source( int threshold,
|
|||
PSA_ASSERT( psa_generate_random( random, sizeof( random ) ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -279,6 +280,6 @@ void entropy_from_nv_seed( int seed_size_arg,
|
|||
|
||||
exit:
|
||||
mbedtls_free( seed );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -150,22 +150,14 @@ MAC: CMAC-3DES
|
|||
depends_on:MBEDTLS_DES_C:MBEDTLS_CMAC_C
|
||||
mac_algorithm:PSA_ALG_CMAC:ALG_IS_BLOCK_CIPHER_MAC:8:PSA_KEY_TYPE_DES:192
|
||||
|
||||
MAC: GMAC-AES-128
|
||||
depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
|
||||
mac_algorithm:PSA_ALG_GMAC:ALG_IS_BLOCK_CIPHER_MAC:16:PSA_KEY_TYPE_AES:128
|
||||
|
||||
MAC: GMAC-AES-192
|
||||
depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
|
||||
mac_algorithm:PSA_ALG_GMAC:ALG_IS_BLOCK_CIPHER_MAC:16:PSA_KEY_TYPE_AES:192
|
||||
|
||||
MAC: GMAC-AES-256
|
||||
depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C
|
||||
mac_algorithm:PSA_ALG_GMAC:ALG_IS_BLOCK_CIPHER_MAC:16:PSA_KEY_TYPE_AES:256
|
||||
|
||||
Cipher: ARC4
|
||||
depends_on:MBEDTLS_ARC4_C
|
||||
cipher_algorithm:PSA_ALG_ARC4:ALG_IS_STREAM_CIPHER
|
||||
|
||||
Cipher: ChaCha20
|
||||
depends_on:MBEDTLS_CHACHA_C
|
||||
cipher_algorithm:PSA_ALG_CHACHA20:ALG_IS_STREAM_CIPHER
|
||||
|
||||
Cipher: CTR
|
||||
depends_on:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CTR
|
||||
cipher_algorithm:PSA_ALG_CTR:ALG_IS_STREAM_CIPHER
|
||||
|
@ -192,11 +184,15 @@ cipher_algorithm:PSA_ALG_XTS:0
|
|||
|
||||
AEAD: CCM
|
||||
depends_on:MBEDTLS_CCM_C
|
||||
aead_algorithm:PSA_ALG_CCM:0:16
|
||||
aead_algorithm:PSA_ALG_CCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16
|
||||
|
||||
AEAD: GCM
|
||||
depends_on:MBEDTLS_GCM_C
|
||||
aead_algorithm:PSA_ALG_GCM:0:16
|
||||
aead_algorithm:PSA_ALG_GCM:ALG_IS_AEAD_ON_BLOCK_CIPHER:16
|
||||
|
||||
AEAD: ChaCha20_Poly1305
|
||||
depends_on:MBEDTLS_CHACHAPOLY_C
|
||||
aead_algorithm:PSA_ALG_CHACHA20_POLY1305:0:16
|
||||
|
||||
Asymmetric signature: RSA PKCS#1 v1.5 raw
|
||||
depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15
|
||||
|
@ -266,24 +262,21 @@ Key derivation: HKDF using SHA-256
|
|||
depends_on:MBEDTLS_SHA256_C
|
||||
key_derivation_algorithm:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):ALG_IS_HKDF
|
||||
|
||||
Key selection: raw
|
||||
key_selection_algorithm:PSA_ALG_SELECT_RAW:0
|
||||
|
||||
Key agreement: FFDH, raw output
|
||||
depends_on:MBEDTLS_DHM_C
|
||||
key_agreement_algorithm:PSA_ALG_FFDH( PSA_ALG_SELECT_RAW ):ALG_IS_FFDH:PSA_ALG_SELECT_RAW
|
||||
key_agreement_algorithm:PSA_ALG_FFDH:ALG_IS_FFDH | ALG_IS_RAW_KEY_AGREEMENT:PSA_ALG_FFDH:PSA_ALG_CATEGORY_KEY_DERIVATION
|
||||
|
||||
Key agreement: FFDH, HKDF using SHA-256
|
||||
depends_on:MBEDTLS_DHM_C
|
||||
key_agreement_algorithm:PSA_ALG_FFDH( PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_FFDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 )
|
||||
key_agreement_algorithm:PSA_ALG_KEY_AGREEMENT( PSA_ALG_FFDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_FFDH:PSA_ALG_FFDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 )
|
||||
|
||||
Key agreement: ECDH, raw output
|
||||
depends_on:MBEDTLS_ECDH_C
|
||||
key_agreement_algorithm:PSA_ALG_ECDH( PSA_ALG_SELECT_RAW ):ALG_IS_ECDH:PSA_ALG_SELECT_RAW
|
||||
key_agreement_algorithm:PSA_ALG_ECDH:ALG_IS_ECDH | ALG_IS_RAW_KEY_AGREEMENT:PSA_ALG_ECDH:PSA_ALG_CATEGORY_KEY_DERIVATION
|
||||
|
||||
Key agreement: ECDH, HKDF using SHA-256
|
||||
depends_on:MBEDTLS_ECDH_C
|
||||
key_agreement_algorithm:PSA_ALG_ECDH( PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_ECDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 )
|
||||
key_agreement_algorithm:PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):ALG_IS_ECDH:PSA_ALG_ECDH:PSA_ALG_HKDF( PSA_ALG_SHA_256 )
|
||||
|
||||
Key type: raw data
|
||||
key_type:PSA_KEY_TYPE_RAW_DATA:KEY_TYPE_IS_UNSTRUCTURED
|
||||
|
@ -310,13 +303,17 @@ Key type: ARC4
|
|||
depends_on:MBEDTLS_ARC4_C
|
||||
key_type:PSA_KEY_TYPE_ARC4:KEY_TYPE_IS_UNSTRUCTURED
|
||||
|
||||
Key type: ChaCha20
|
||||
depends_on:MBEDTLS_CHACHA20_C
|
||||
key_type:PSA_KEY_TYPE_CHACHA20:KEY_TYPE_IS_UNSTRUCTURED
|
||||
|
||||
Key type: RSA public key
|
||||
depends_on:MBEDTLS_RSA_C
|
||||
key_type:PSA_KEY_TYPE_RSA_PUBLIC_KEY:KEY_TYPE_IS_PUBLIC_KEY | KEY_TYPE_IS_RSA
|
||||
|
||||
Key type: RSA key pair
|
||||
depends_on:MBEDTLS_RSA_C
|
||||
key_type:PSA_KEY_TYPE_RSA_KEYPAIR:KEY_TYPE_IS_KEYPAIR | KEY_TYPE_IS_RSA
|
||||
key_type:PSA_KEY_TYPE_RSA_KEY_PAIR:KEY_TYPE_IS_KEY_PAIR | KEY_TYPE_IS_RSA
|
||||
|
||||
Key type: DSA public key
|
||||
depends_on:MBEDTLS_DSA_C
|
||||
|
@ -324,7 +321,7 @@ key_type:PSA_KEY_TYPE_DSA_PUBLIC_KEY:KEY_TYPE_IS_PUBLIC_KEY | KEY_TYPE_IS_DSA
|
|||
|
||||
Key type: DSA key pair
|
||||
depends_on:MBEDTLS_DSA_C
|
||||
key_type:PSA_KEY_TYPE_DSA_KEYPAIR:KEY_TYPE_IS_KEYPAIR | KEY_TYPE_IS_DSA
|
||||
key_type:PSA_KEY_TYPE_DSA_KEY_PAIR:KEY_TYPE_IS_KEY_PAIR | KEY_TYPE_IS_DSA
|
||||
|
||||
ECC key types: sect163k1
|
||||
depends_on:MBEDTLS_ECP_DP_SECT163K1_ENABLED
|
||||
|
@ -445,3 +442,19 @@ ecc_key_types:PSA_ECC_CURVE_CURVE25519:255
|
|||
ECC key types: Curve448
|
||||
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
|
||||
ecc_key_types:PSA_ECC_CURVE_CURVE448:448
|
||||
|
||||
DH group types: FFDHE2048
|
||||
dh_key_types:PSA_DH_GROUP_FFDHE2048:2048
|
||||
|
||||
DH group types: FFDHE3072
|
||||
dh_key_types:PSA_DH_GROUP_FFDHE3072:2048
|
||||
|
||||
DH group types: FFDHE4096
|
||||
dh_key_types:PSA_DH_GROUP_FFDHE4096:2048
|
||||
|
||||
DH group types: FFDHE6144
|
||||
dh_key_types:PSA_DH_GROUP_FFDHE6144:2048
|
||||
|
||||
DH group types: FFDHE8192
|
||||
dh_key_types:PSA_DH_GROUP_FFDHE8192:2048
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#define ALG_IS_FFDH ( 1u << 17 )
|
||||
#define ALG_IS_ECDH ( 1u << 18 )
|
||||
#define ALG_IS_WILDCARD ( 1u << 19 )
|
||||
#define ALG_IS_RAW_KEY_AGREEMENT ( 1u << 20 )
|
||||
#define ALG_IS_AEAD_ON_BLOCK_CIPHER ( 1u << 21 )
|
||||
|
||||
/* Flags for key type classification macros. There is a flag for every
|
||||
* key type classification macro PSA_KEY_TYPE_IS_xxx except for some that
|
||||
|
@ -43,10 +45,11 @@
|
|||
#define KEY_TYPE_IS_VENDOR_DEFINED ( 1u << 0 )
|
||||
#define KEY_TYPE_IS_UNSTRUCTURED ( 1u << 1 )
|
||||
#define KEY_TYPE_IS_PUBLIC_KEY ( 1u << 2 )
|
||||
#define KEY_TYPE_IS_KEYPAIR ( 1u << 3 )
|
||||
#define KEY_TYPE_IS_KEY_PAIR ( 1u << 3 )
|
||||
#define KEY_TYPE_IS_RSA ( 1u << 4 )
|
||||
#define KEY_TYPE_IS_DSA ( 1u << 5 )
|
||||
#define KEY_TYPE_IS_ECC ( 1u << 6 )
|
||||
#define KEY_TYPE_IS_DH ( 1u << 7 )
|
||||
|
||||
#define TEST_CLASSIFICATION_MACRO( flag, alg, flags ) \
|
||||
TEST_ASSERT( PSA_##flag( alg ) == !! ( ( flags ) & flag ) )
|
||||
|
@ -73,6 +76,10 @@ void algorithm_classification( psa_algorithm_t alg, unsigned flags )
|
|||
TEST_CLASSIFICATION_MACRO( ALG_IS_RSA_OAEP, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_HKDF, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_WILDCARD, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_ECDH, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_FFDH, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_RAW_KEY_AGREEMENT, alg, flags );
|
||||
TEST_CLASSIFICATION_MACRO( ALG_IS_AEAD_ON_BLOCK_CIPHER, alg, flags );
|
||||
exit: ;
|
||||
}
|
||||
|
||||
|
@ -82,20 +89,27 @@ void key_type_classification( psa_key_type_t type, unsigned flags )
|
|||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_VENDOR_DEFINED, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_UNSTRUCTURED, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_PUBLIC_KEY, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_KEYPAIR, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_KEY_PAIR, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_RSA, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_ECC, type, flags );
|
||||
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_DH, type, flags );
|
||||
|
||||
/* Macros with derived semantics */
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_ASYMMETRIC( type ),
|
||||
( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ||
|
||||
PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_KEYPAIR( type ),
|
||||
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ),
|
||||
( PSA_KEY_TYPE_IS_ECC( type ) &&
|
||||
PSA_KEY_TYPE_IS_KEYPAIR( type ) ) );
|
||||
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( type ),
|
||||
( PSA_KEY_TYPE_IS_ECC( type ) &&
|
||||
PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_DH_KEY_PAIR( type ),
|
||||
( PSA_KEY_TYPE_IS_DH( type ) &&
|
||||
PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_IS_DH_PUBLIC_KEY( type ),
|
||||
( PSA_KEY_TYPE_IS_DH( type ) &&
|
||||
PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) ) );
|
||||
|
||||
exit: ;
|
||||
}
|
||||
|
@ -113,7 +127,6 @@ void mac_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Length */
|
||||
|
@ -134,7 +147,6 @@ void aead_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Tag length */
|
||||
|
@ -174,7 +186,6 @@ void hash_algorithm( int alg_arg, int length_arg )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, 0 );
|
||||
|
||||
/* Dependent algorithms */
|
||||
|
@ -271,7 +282,6 @@ void cipher_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -320,7 +330,6 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -350,7 +359,6 @@ void asymmetric_encryption_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -359,6 +367,8 @@ void asymmetric_encryption_algorithm( int alg_arg, int classification_flags )
|
|||
void key_derivation_algorithm( int alg_arg, int classification_flags )
|
||||
{
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
psa_algorithm_t ecdh_alg = PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, alg );
|
||||
psa_algorithm_t ffdh_alg = PSA_ALG_KEY_AGREEMENT( PSA_ALG_FFDH, alg );
|
||||
|
||||
/* Algorithm classification */
|
||||
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
||||
|
@ -369,49 +379,25 @@ void key_derivation_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Check combinations with key agreements */
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ), alg );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ), alg );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_selection_algorithm( int alg_arg, int classification_flags )
|
||||
{
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
|
||||
/* Algorithm classification */
|
||||
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Check combinations with key agreements */
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_FFDH( alg ) ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( PSA_ALG_ECDH( alg ) ) );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_ECDH( alg ) ), alg );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( PSA_ALG_FFDH( alg ) ), alg );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( ecdh_alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( ffdh_alg ) );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( ecdh_alg ), alg );
|
||||
TEST_EQUAL( PSA_ALG_KEY_AGREEMENT_GET_KDF( ffdh_alg ), alg );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_agreement_algorithm( int alg_arg, int classification_flags,
|
||||
int post_alg_arg )
|
||||
int ka_alg_arg, int kdf_alg_arg )
|
||||
{
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
psa_algorithm_t actual_post_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
|
||||
psa_algorithm_t expected_post_alg = post_alg_arg;
|
||||
psa_algorithm_t actual_ka_alg = PSA_ALG_KEY_AGREEMENT_GET_BASE( alg );
|
||||
psa_algorithm_t expected_ka_alg = ka_alg_arg;
|
||||
psa_algorithm_t actual_kdf_alg = PSA_ALG_KEY_AGREEMENT_GET_KDF( alg );
|
||||
psa_algorithm_t expected_kdf_alg = kdf_alg_arg;
|
||||
|
||||
/* Algorithm classification */
|
||||
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
||||
|
@ -422,13 +408,11 @@ void key_agreement_algorithm( int alg_arg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_SELECTION( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Shared secret derivation properties */
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( actual_post_alg ) ||
|
||||
PSA_ALG_IS_KEY_SELECTION( actual_post_alg ) );
|
||||
TEST_EQUAL( actual_post_alg, expected_post_alg );
|
||||
TEST_EQUAL( actual_ka_alg, expected_ka_alg );
|
||||
TEST_EQUAL( actual_kdf_alg, expected_kdf_alg );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -442,23 +426,23 @@ void key_type( int type_arg, int classification_flags )
|
|||
/* For asymmetric types, check the corresponding pair/public type */
|
||||
if( classification_flags & KEY_TYPE_IS_PUBLIC_KEY )
|
||||
{
|
||||
psa_key_type_t pair_type = PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( type );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( pair_type ), type );
|
||||
psa_key_type_t pair_type = PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( type );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( pair_type ), type );
|
||||
key_type_classification( pair_type,
|
||||
( classification_flags
|
||||
& ~KEY_TYPE_IS_PUBLIC_KEY )
|
||||
| KEY_TYPE_IS_KEYPAIR );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type ), type );
|
||||
| KEY_TYPE_IS_KEY_PAIR );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type ), type );
|
||||
}
|
||||
if( classification_flags & KEY_TYPE_IS_KEYPAIR )
|
||||
if( classification_flags & KEY_TYPE_IS_KEY_PAIR )
|
||||
{
|
||||
psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR( type );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( public_type ), type );
|
||||
psa_key_type_t public_type = PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR( type );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( public_type ), type );
|
||||
key_type_classification( public_type,
|
||||
( classification_flags
|
||||
& ~KEY_TYPE_IS_KEYPAIR )
|
||||
& ~KEY_TYPE_IS_KEY_PAIR )
|
||||
| KEY_TYPE_IS_PUBLIC_KEY );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_KEYPAIR_OF_PUBLIC_KEY( type ), type );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_KEY_PAIR_OF_PUBLIC_KEY( type ), type );
|
||||
}
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -469,10 +453,10 @@ void ecc_key_types( int curve_arg, int curve_bits_arg )
|
|||
psa_ecc_curve_t curve = curve_arg;
|
||||
size_t curve_bits = curve_bits_arg;
|
||||
psa_key_type_t public_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve );
|
||||
psa_key_type_t pair_type = PSA_KEY_TYPE_ECC_KEYPAIR( curve );
|
||||
psa_key_type_t pair_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve );
|
||||
|
||||
test_key_type( public_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_PUBLIC_KEY );
|
||||
test_key_type( pair_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_KEYPAIR );
|
||||
test_key_type( pair_type, KEY_TYPE_IS_ECC | KEY_TYPE_IS_KEY_PAIR );
|
||||
|
||||
TEST_EQUAL( PSA_KEY_TYPE_GET_CURVE( public_type ), curve );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_GET_CURVE( pair_type ), curve );
|
||||
|
@ -481,3 +465,22 @@ void ecc_key_types( int curve_arg, int curve_bits_arg )
|
|||
TEST_ASSERT( curve_bits <= PSA_VENDOR_ECC_MAX_CURVE_BITS );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_DHM_C */
|
||||
void dh_key_types( int group_arg, int group_bits_arg )
|
||||
{
|
||||
psa_dh_group_t group = group_arg;
|
||||
size_t group_bits = group_bits_arg;
|
||||
psa_key_type_t public_type = PSA_KEY_TYPE_DH_PUBLIC_KEY( group );
|
||||
psa_key_type_t pair_type = PSA_KEY_TYPE_DH_KEY_PAIR( group );
|
||||
|
||||
test_key_type( public_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_PUBLIC_KEY );
|
||||
test_key_type( pair_type, KEY_TYPE_IS_DH | KEY_TYPE_IS_KEY_PAIR );
|
||||
|
||||
TEST_EQUAL( PSA_KEY_TYPE_GET_GROUP( public_type ), group );
|
||||
TEST_EQUAL( PSA_KEY_TYPE_GET_GROUP( pair_type ), group );
|
||||
|
||||
/* We have nothing to validate about the group size yet. */
|
||||
(void) group_bits;
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -1,70 +1,103 @@
|
|||
PSA Storage format data for storage
|
||||
format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b4559000000000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
|
||||
format_storage_data_check:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"505341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN
|
||||
|
||||
PSA Storage parse stored data
|
||||
parse_storage_data_check:"505341004b4559000000000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_SUCCESS
|
||||
parse_storage_data_check:"505341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_SUCCESS
|
||||
|
||||
PSA Storage parse stored data wrong version, should fail
|
||||
parse_storage_data_check:"505341004b455900ffffffff00000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
parse_storage_data_check:"505341004b455900ffffffff0100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
|
||||
PSA Storage parse too big data, should fail
|
||||
parse_storage_data_check:"505341004b4559000000000000000170010000000000001200000010ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
parse_storage_data_check:"505341004b455900000000000100000000000170010000000000001200000010ffffffff3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
|
||||
PSA Storage parse bad magic, should fail
|
||||
parse_storage_data_check:"645341004b4559000000000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
parse_storage_data_check:"645341004b455900000000000100000000000170010000000000001200000010620200003082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
|
||||
PSA Storage parse not enough magic, should fail
|
||||
parse_storage_data_check:"505341004b4559":"":PSA_KEY_TYPE_RSA_KEYPAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
parse_storage_data_check:"505341004b4559":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION:PSA_ALG_CATEGORY_SIGN:PSA_ERROR_STORAGE_FAILURE
|
||||
|
||||
# Not specific to files, but only run this test in an environment where the maximum size could be reached.
|
||||
Save maximum size persistent raw key
|
||||
depends_on:MBEDTLS_PSA_ITS_FILE_C
|
||||
save_large_persistent_key:0:PSA_SUCCESS
|
||||
save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE:PSA_SUCCESS
|
||||
|
||||
Save larger than maximum size persistent raw key, should fail
|
||||
save_large_persistent_key:1:PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE + 1:PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
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"
|
||||
persistent_key_destroy:1:0:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RAW_DATA:"deadbeef"
|
||||
|
||||
Persistent key destroy missing key
|
||||
Persistent key destroy after restart
|
||||
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"
|
||||
persistent_key_destroy:1:1:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RAW_DATA:"deadbeef"
|
||||
|
||||
Persistent key import
|
||||
Persistent key import (RSA)
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEYPAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_SUCCESS
|
||||
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":0:PSA_SUCCESS
|
||||
|
||||
Persistent key import with restart (RSA)
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":1:PSA_SUCCESS
|
||||
|
||||
Persistent key import garbage data, should fail
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEYPAIR:"11111111":PSA_ERROR_INVALID_ARGUMENT
|
||||
persistent_key_import:1:PSA_KEY_TYPE_RSA_KEY_PAIR:"11111111":0:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
import/export persistent raw key: 0 byte
|
||||
import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:0
|
||||
import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:0:0
|
||||
|
||||
import/export persistent raw key: 1 byte
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:0
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:0:0
|
||||
|
||||
import/export persistent key RSA public key: good, 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:0
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:0:0
|
||||
|
||||
import/export persistent key RSA keypair: good, 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:1024:0
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:0:0
|
||||
|
||||
import/export persistent raw key file not exist: 1 byte
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:1
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:0:1
|
||||
|
||||
import/export persistent key RSA public key file not exist: 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:1
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:0:1
|
||||
|
||||
import/export persistent key RSA keypair file not exist: 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEYPAIR:1024:1
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:0:1
|
||||
|
||||
PSA import/export-persistent symmetric key: 16 bytes
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:0
|
||||
import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:0:0
|
||||
|
||||
import/export persistent raw key with restart: 0 byte
|
||||
import_export_persistent_key:"":PSA_KEY_TYPE_RAW_DATA:0:1:0
|
||||
|
||||
import/export persistent raw key with restart: 1 byte
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:1:0
|
||||
|
||||
import/export persistent key RSA public key with restart: good, 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:1:0
|
||||
|
||||
import/export persistent key RSA keypair with restart: good, 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:1:0
|
||||
|
||||
import/export persistent raw key file not exist with restart: 1 byte
|
||||
import_export_persistent_key:"2a":PSA_KEY_TYPE_RAW_DATA:8:1:1
|
||||
|
||||
import/export persistent key RSA public key file not exist with restart: 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:1024:1:1
|
||||
|
||||
import/export persistent key RSA keypair file not exist with restart: 1024-bit
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:1024:1:1
|
||||
|
||||
PSA import/export-persistent symmetric key: 16 bytes
|
||||
depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C
|
||||
import_export_persistent_key:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:1:0
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include <stdint.h>
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa_crypto_helpers.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
#define PSA_KEY_STORAGE_MAGIC_HEADER "PSA\0KEY"
|
||||
|
@ -10,6 +12,7 @@
|
|||
typedef struct {
|
||||
uint8_t magic[PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH];
|
||||
uint8_t version[4];
|
||||
uint8_t lifetime[sizeof( psa_key_lifetime_t )];
|
||||
uint8_t type[sizeof( psa_key_type_t )];
|
||||
uint8_t policy[sizeof( psa_key_policy_t )];
|
||||
uint8_t data_len[4];
|
||||
|
@ -26,21 +29,23 @@ typedef struct {
|
|||
/* BEGIN_CASE */
|
||||
void format_storage_data_check( data_t *key_data,
|
||||
data_t *expected_file_data,
|
||||
int key_type,
|
||||
int key_lifetime, int key_type,
|
||||
int key_usage, int key_alg, int key_alg2 )
|
||||
{
|
||||
uint8_t *file_data;
|
||||
size_t file_data_length;
|
||||
psa_key_policy_t key_policy;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
key_policy.usage = (psa_key_usage_t) key_usage;
|
||||
key_policy.alg = (psa_algorithm_t) key_alg;
|
||||
key_policy.alg2 = (psa_algorithm_t) key_alg2;
|
||||
psa_set_key_lifetime( &attributes, key_lifetime );
|
||||
psa_set_key_type( &attributes, key_type );
|
||||
psa_set_key_usage_flags( &attributes, key_usage );
|
||||
psa_set_key_algorithm( &attributes, key_alg );
|
||||
psa_set_key_enrollment_algorithm( &attributes, key_alg2 );
|
||||
|
||||
file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format );
|
||||
file_data = mbedtls_calloc( 1, file_data_length );
|
||||
psa_format_key_data_for_storage( key_data->x, key_data->len,
|
||||
(psa_key_type_t) key_type, &key_policy,
|
||||
&attributes.core,
|
||||
file_data );
|
||||
|
||||
ASSERT_COMPARE( expected_file_data->x, expected_file_data->len,
|
||||
|
@ -52,6 +57,7 @@ void format_storage_data_check( data_t *key_data,
|
|||
/* BEGIN_CASE */
|
||||
void parse_storage_data_check( data_t *file_data,
|
||||
data_t *expected_key_data,
|
||||
int expected_key_lifetime,
|
||||
int expected_key_type,
|
||||
int expected_key_usage,
|
||||
int expected_key_alg,
|
||||
|
@ -60,22 +66,27 @@ void parse_storage_data_check( data_t *file_data,
|
|||
{
|
||||
uint8_t *key_data = NULL;
|
||||
size_t key_data_length = 0;
|
||||
psa_key_type_t key_type = 0;
|
||||
psa_key_policy_t key_policy;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_parse_key_data_from_storage( file_data->x, file_data->len,
|
||||
&key_data, &key_data_length,
|
||||
&key_type, &key_policy );
|
||||
&attributes.core );
|
||||
|
||||
TEST_EQUAL( status, expected_status );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto exit;
|
||||
|
||||
TEST_EQUAL( key_type, (psa_key_type_t) expected_key_type );
|
||||
TEST_EQUAL( key_policy.usage, (uint32_t) expected_key_usage );
|
||||
TEST_EQUAL( key_policy.alg, (uint32_t) expected_key_alg );
|
||||
TEST_EQUAL( key_policy.alg2, (uint32_t) expected_key_alg2 );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ),
|
||||
(psa_key_type_t) expected_key_lifetime );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ),
|
||||
(psa_key_type_t) expected_key_type );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ),
|
||||
(uint32_t) expected_key_usage );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ),
|
||||
(uint32_t) expected_key_alg );
|
||||
TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ),
|
||||
(uint32_t) expected_key_alg2 );
|
||||
ASSERT_COMPARE( expected_key_data->x, expected_key_data->len,
|
||||
key_data, key_data_length );
|
||||
|
||||
|
@ -85,36 +96,36 @@ exit:
|
|||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void save_large_persistent_key( int data_too_large, int expected_status )
|
||||
void save_large_persistent_key( int data_length_arg, int expected_status )
|
||||
{
|
||||
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;
|
||||
|
||||
if( data_too_large )
|
||||
data_length += 1;
|
||||
size_t data_length = data_length_arg;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
ASSERT_ALLOC( data, data_length );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
|
||||
PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
|
||||
&handle ) );
|
||||
psa_set_key_id( &attributes, key_id );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
|
||||
TEST_EQUAL( psa_import_key( handle, PSA_KEY_TYPE_RAW_DATA,
|
||||
data, data_length ),
|
||||
TEST_EQUAL( psa_import_key( &attributes, data, data_length, &handle ),
|
||||
expected_status );
|
||||
|
||||
if( expected_status == PSA_SUCCESS )
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
exit:
|
||||
mbedtls_free( data );
|
||||
mbedtls_psa_crypto_free();
|
||||
PSA_DONE();
|
||||
psa_destroy_persistent_key( key_id );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void persistent_key_destroy( int key_id_arg, int should_store,
|
||||
void persistent_key_destroy( int key_id_arg, int restart,
|
||||
int first_type_arg, data_t *first_data,
|
||||
int second_type_arg, data_t *second_data )
|
||||
{
|
||||
|
@ -122,59 +133,65 @@ void persistent_key_destroy( int key_id_arg, int should_store,
|
|||
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;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
|
||||
PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
|
||||
psa_set_key_id( &attributes, key_id );
|
||||
psa_set_key_type( &attributes, first_type );
|
||||
|
||||
PSA_ASSERT( psa_import_key( &attributes, first_data->x, first_data->len,
|
||||
&handle ) );
|
||||
|
||||
if( should_store == 1 )
|
||||
if( restart )
|
||||
{
|
||||
PSA_ASSERT( psa_import_key(
|
||||
handle, first_type,
|
||||
first_data->x, first_data->len ) );
|
||||
psa_close_key( handle );
|
||||
PSA_DONE();
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
PSA_ASSERT( psa_open_key( key_id, &handle ) );
|
||||
}
|
||||
TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 1 );
|
||||
|
||||
/* Destroy the key */
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
/* Check key slot storage is removed */
|
||||
TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
|
||||
TEST_EQUAL( psa_open_key( PSA_KEY_LIFETIME_PERSISTENT, key_id, &handle ),
|
||||
PSA_ERROR_DOES_NOT_EXIST );
|
||||
TEST_EQUAL( psa_open_key( key_id, &handle ), PSA_ERROR_DOES_NOT_EXIST );
|
||||
TEST_EQUAL( handle, 0 );
|
||||
|
||||
/* Shutdown and restart */
|
||||
mbedtls_psa_crypto_free();
|
||||
PSA_DONE();
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
|
||||
/* Create another key in the same slot */
|
||||
PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
|
||||
psa_set_key_id( &attributes, key_id );
|
||||
psa_set_key_type( &attributes, second_type );
|
||||
PSA_ASSERT( psa_import_key( &attributes, second_data->x, second_data->len,
|
||||
&handle ) );
|
||||
PSA_ASSERT( psa_import_key(
|
||||
handle, second_type,
|
||||
second_data->x, second_data->len ) );
|
||||
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free();
|
||||
PSA_DONE();
|
||||
psa_destroy_persistent_key( key_id );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void persistent_key_import( int key_id_arg, int type_arg, data_t *data,
|
||||
int expected_status )
|
||||
int restart, int expected_status )
|
||||
{
|
||||
psa_key_lifetime_t lifetime;
|
||||
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;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
|
||||
PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
|
||||
&handle ) );
|
||||
TEST_EQUAL( psa_import_key( handle, type, data->x, data->len ),
|
||||
psa_set_key_id( &attributes, key_id );
|
||||
psa_set_key_type( &attributes, type );
|
||||
TEST_EQUAL( psa_import_key( &attributes, data->x, data->len, &handle ),
|
||||
expected_status );
|
||||
|
||||
if( expected_status != PSA_SUCCESS )
|
||||
|
@ -183,18 +200,36 @@ void persistent_key_import( int key_id_arg, int type_arg, data_t *data,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
PSA_ASSERT( psa_get_key_lifetime( handle, &lifetime ) );
|
||||
TEST_EQUAL( lifetime, PSA_KEY_LIFETIME_PERSISTENT );
|
||||
if( restart )
|
||||
{
|
||||
psa_close_key( handle );
|
||||
PSA_DONE();
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
PSA_ASSERT( psa_open_key( key_id, &handle ) );
|
||||
}
|
||||
|
||||
psa_reset_key_attributes( &attributes );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ),
|
||||
PSA_KEY_LIFETIME_PERSISTENT );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), type );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), 0 );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
|
||||
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
psa_destroy_persistent_key( key_id );
|
||||
mbedtls_psa_crypto_free();
|
||||
PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void import_export_persistent_key( data_t *data, int type_arg,
|
||||
int expected_bits, int key_not_exist )
|
||||
int expected_bits,
|
||||
int restart, int key_not_exist )
|
||||
{
|
||||
psa_key_id_t key_id = 42;
|
||||
psa_key_type_t type = (psa_key_type_t) type_arg;
|
||||
|
@ -202,34 +237,38 @@ void import_export_persistent_key( data_t *data, int type_arg,
|
|||
unsigned char *exported = NULL;
|
||||
size_t export_size = data->len;
|
||||
size_t exported_length;
|
||||
psa_key_type_t got_type;
|
||||
size_t got_bits;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_lifetime_t lifetime_get;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
ASSERT_ALLOC( exported, export_size );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
PSA_ASSERT( psa_create_key( PSA_KEY_LIFETIME_PERSISTENT, key_id,
|
||||
&handle ) );
|
||||
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT,
|
||||
PSA_ALG_VENDOR_FLAG );
|
||||
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
|
||||
psa_set_key_id( &attributes, key_id );
|
||||
psa_set_key_type( &attributes, type );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
|
||||
|
||||
/* Import the key */
|
||||
PSA_ASSERT( psa_import_key( handle, type,
|
||||
data->x, data->len ) );
|
||||
PSA_ASSERT( psa_import_key( &attributes, data->x, data->len, &handle ) );
|
||||
|
||||
PSA_ASSERT( psa_get_key_lifetime( handle, &lifetime_get ) );
|
||||
TEST_EQUAL( lifetime_get, PSA_KEY_LIFETIME_PERSISTENT );
|
||||
|
||||
if( restart )
|
||||
{
|
||||
psa_close_key( handle );
|
||||
PSA_DONE();
|
||||
PSA_ASSERT( psa_crypto_init() );
|
||||
PSA_ASSERT( psa_open_key( key_id, &handle ) );
|
||||
}
|
||||
|
||||
/* Test the key information */
|
||||
PSA_ASSERT( psa_get_key_information(
|
||||
handle, &got_type, &got_bits ) );
|
||||
TEST_EQUAL( got_type, type );
|
||||
TEST_EQUAL( got_bits, (size_t) expected_bits );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ), key_id );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ),
|
||||
PSA_KEY_LIFETIME_PERSISTENT );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), type );
|
||||
TEST_EQUAL( psa_get_key_bits( &attributes ), (size_t) expected_bits );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), PSA_KEY_USAGE_EXPORT );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
|
||||
|
||||
TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 1 );
|
||||
|
||||
|
@ -248,8 +287,9 @@ void import_export_persistent_key( data_t *data, int type_arg,
|
|||
TEST_EQUAL( psa_is_key_present_in_storage( key_id ), 0 );
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
mbedtls_free( exported );
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
psa_destroy_persistent_key( key_id );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
97
tests/suites/test_suite_psa_crypto_se_driver_hal.data
Normal file
97
tests/suites/test_suite_psa_crypto_se_driver_hal.data
Normal file
|
@ -0,0 +1,97 @@
|
|||
Register SE driver: good
|
||||
register_one:2:PSA_DRV_SE_HAL_VERSION:PSA_SUCCESS
|
||||
|
||||
# Run this test case a second time to verify that the library deinit
|
||||
# unregistered the first driver.
|
||||
Register SE driver: good, again
|
||||
register_one:2:PSA_DRV_SE_HAL_VERSION:PSA_SUCCESS
|
||||
|
||||
Register SE driver: invalid lifetime (0)
|
||||
register_one:0:PSA_DRV_SE_HAL_VERSION:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Register SE driver: invalid lifetime (VOLATILE)
|
||||
register_one:PSA_KEY_LIFETIME_VOLATILE:PSA_DRV_SE_HAL_VERSION:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Register SE driver: invalid lifetime (PERSISTENT)
|
||||
register_one:PSA_KEY_LIFETIME_PERSISTENT:PSA_DRV_SE_HAL_VERSION:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Register SE driver: invalid version (ancient)
|
||||
register_one:2:0x00000003:PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
Register SE driver: invalid version (future)
|
||||
register_one:2:PSA_DRV_SE_HAL_VERSION + 1:PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
Register SE driver: already registered
|
||||
register_twice:3
|
||||
|
||||
Register SE driver: maximum number of drivers
|
||||
register_max:
|
||||
|
||||
SE key import-export (p_allocate allows all slots)
|
||||
key_creation_import_export:0:0
|
||||
|
||||
SE key import-export (p_allocate allows 1 slot)
|
||||
key_creation_import_export:ARRAY_LENGTH( ram_slots ) - 1:0
|
||||
|
||||
SE key import-export, check after restart (slot 0)
|
||||
key_creation_import_export:0:1
|
||||
|
||||
SE key import-export, check after restart (slot 3)
|
||||
key_creation_import_export:3:1
|
||||
|
||||
Key creation smoke test: AES-CTR
|
||||
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: AES-CBC
|
||||
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: AES-CMAC
|
||||
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: AES-CCM
|
||||
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_CCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: AES-GCM
|
||||
key_creation_smoke:PSA_KEY_TYPE_AES:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: CAMELLIA-CTR
|
||||
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CTR:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: CAMELLIA-CBC
|
||||
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CBC_NO_PADDING:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: CAMELLIA-CMAC
|
||||
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_CMAC:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: CAMELLIA-CCM
|
||||
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: CAMELLIA-CCM
|
||||
key_creation_smoke:PSA_KEY_TYPE_CAMELLIA:PSA_ALG_GCM:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: HMAC-SHA-256
|
||||
key_creation_smoke:PSA_KEY_TYPE_HMAC:PSA_ALG_HMAC( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: HKDF-SHA-256
|
||||
key_creation_smoke:PSA_KEY_TYPE_DERIVE:PSA_ALG_HKDF( PSA_ALG_SHA_256 ):"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
Key creation smoke test: RSA PKCS#1v1.5 signature
|
||||
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
|
||||
|
||||
Key creation smoke test: RSA PKCS#1v1.5 encryption
|
||||
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_PKCS1V15_CRYPT:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
|
||||
|
||||
Key creation smoke test: RSA OAEP encryption
|
||||
key_creation_smoke:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_ALG_RSA_OAEP( PSA_ALG_SHA_256 ):"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001"
|
||||
|
||||
Key creation smoke test: ECDSA secp256r1
|
||||
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDSA_ANY:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
|
||||
|
||||
Key creation smoke test: ECDH secp256r1
|
||||
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_ECDH:"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
|
||||
|
||||
Key creation smoke test: ECDH secp256r1 with HKDF
|
||||
key_creation_smoke:PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_CURVE_SECP256R1 ):PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee"
|
||||
|
||||
Generate key: not supported
|
||||
generate_key_not_supported:PSA_KEY_TYPE_AES:128
|
604
tests/suites/test_suite_psa_crypto_se_driver_hal.function
Normal file
604
tests/suites/test_suite_psa_crypto_se_driver_hal.function
Normal file
|
@ -0,0 +1,604 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include "psa_crypto_helpers.h"
|
||||
#include "psa/crypto_se_driver.h"
|
||||
|
||||
#include "psa_crypto_se.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Test driver helpers */
|
||||
/****************************************************************/
|
||||
|
||||
/** The minimum valid lifetime value for a secure element driver. */
|
||||
#define MIN_DRIVER_LIFETIME 2
|
||||
|
||||
/** The driver detected a condition that shouldn't happen.
|
||||
* This is probably a bug in the library. */
|
||||
#define PSA_ERROR_DETECTED_BY_DRIVER ((psa_status_t)( -500 ))
|
||||
|
||||
/** Like #TEST_ASSERT for use in a driver method.
|
||||
*
|
||||
* Use this macro to assert on guarantees provided by the core.
|
||||
*/
|
||||
#define DRIVER_ASSERT( TEST ) \
|
||||
do { \
|
||||
if( ! (TEST) ) \
|
||||
{ \
|
||||
test_fail( #TEST, __LINE__, __FILE__ ); \
|
||||
return( PSA_ERROR_DETECTED_BY_DRIVER ); \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Miscellaneous driver methods */
|
||||
/****************************************************************/
|
||||
|
||||
/* Allocate slot numbers with a monotonic counter. */
|
||||
static psa_status_t counter_allocate( psa_drv_se_context_t *context,
|
||||
void *persistent_data,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t *slot_number )
|
||||
{
|
||||
psa_key_slot_number_t *p_counter = persistent_data;
|
||||
(void) attributes;
|
||||
if( context->persistent_data_size != sizeof( psa_key_slot_number_t ) )
|
||||
return( PSA_ERROR_DETECTED_BY_DRIVER );
|
||||
++*p_counter;
|
||||
if( *p_counter == 0 )
|
||||
return( PSA_ERROR_INSUFFICIENT_STORAGE );
|
||||
*slot_number = *p_counter;
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
/* Null import: do nothing, but pretend it worked. */
|
||||
static psa_status_t null_import( psa_drv_se_context_t *context,
|
||||
psa_key_slot_number_t slot_number,
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_type_t type,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_usage_t usage,
|
||||
const uint8_t *p_data,
|
||||
size_t data_length,
|
||||
size_t *bits )
|
||||
{
|
||||
(void) context;
|
||||
(void) slot_number;
|
||||
(void) lifetime;
|
||||
(void) type;
|
||||
(void) algorithm;
|
||||
(void) usage;
|
||||
(void) p_data;
|
||||
/* We're supposed to return a key size. Return one that's correct for
|
||||
* plain data keys. */
|
||||
*bits = PSA_BYTES_TO_BITS( data_length );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* RAM-based test driver */
|
||||
/****************************************************************/
|
||||
|
||||
#define RAM_MAX_KEY_SIZE 64
|
||||
typedef struct
|
||||
{
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_type_t type;
|
||||
size_t bits;
|
||||
uint8_t content[RAM_MAX_KEY_SIZE];
|
||||
} ram_slot_t;
|
||||
static ram_slot_t ram_slots[16];
|
||||
|
||||
/* A type with at least ARRAY_LENGTH(ram_slots) bits, containing a
|
||||
* bit vector indicating which slots are in use. */
|
||||
typedef uint16_t ram_slot_usage_t;
|
||||
|
||||
static uint8_t ram_min_slot = 0;
|
||||
|
||||
static void ram_slots_reset( void )
|
||||
{
|
||||
memset( ram_slots, 0, sizeof( ram_slots ) );
|
||||
ram_min_slot = 0;
|
||||
}
|
||||
|
||||
static psa_status_t ram_import( psa_drv_se_context_t *context,
|
||||
psa_key_slot_number_t slot_number,
|
||||
psa_key_lifetime_t lifetime,
|
||||
psa_key_type_t type,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_key_usage_t usage,
|
||||
const uint8_t *p_data,
|
||||
size_t data_length,
|
||||
size_t *bits )
|
||||
{
|
||||
(void) context;
|
||||
DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
|
||||
if( data_length > sizeof( ram_slots[slot_number].content ) )
|
||||
return( PSA_ERROR_INSUFFICIENT_STORAGE );
|
||||
ram_slots[slot_number].lifetime = lifetime;
|
||||
ram_slots[slot_number].type = type;
|
||||
ram_slots[slot_number].bits = PSA_BYTES_TO_BITS( data_length );
|
||||
*bits = PSA_BYTES_TO_BITS( data_length );
|
||||
(void) algorithm;
|
||||
(void) usage;
|
||||
memcpy( ram_slots[slot_number].content, p_data, data_length );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
static psa_status_t ram_export( psa_drv_se_context_t *context,
|
||||
psa_key_slot_number_t slot_number,
|
||||
uint8_t *p_data,
|
||||
size_t data_size,
|
||||
size_t *p_data_length )
|
||||
{
|
||||
size_t actual_size;
|
||||
(void) context;
|
||||
DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
|
||||
actual_size = PSA_BITS_TO_BYTES( ram_slots[slot_number].bits );
|
||||
if( actual_size > data_size )
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
*p_data_length = actual_size;
|
||||
memcpy( p_data, ram_slots[slot_number].content, actual_size );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
static psa_status_t ram_destroy( psa_drv_se_context_t *context,
|
||||
void *persistent_data,
|
||||
psa_key_slot_number_t slot_number )
|
||||
{
|
||||
ram_slot_usage_t *slot_usage = persistent_data;
|
||||
DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
|
||||
DRIVER_ASSERT( slot_number < ARRAY_LENGTH( ram_slots ) );
|
||||
memset( &ram_slots[slot_number], 0, sizeof( ram_slots[slot_number] ) );
|
||||
*slot_usage &= ~(ram_slot_usage_t)( 1 << slot_number );
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
static psa_status_t ram_allocate( psa_drv_se_context_t *context,
|
||||
void *persistent_data,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_number_t *slot_number )
|
||||
{
|
||||
ram_slot_usage_t *slot_usage = persistent_data;
|
||||
(void) attributes;
|
||||
DRIVER_ASSERT( context->persistent_data_size == sizeof( ram_slot_usage_t ) );
|
||||
for( *slot_number = ram_min_slot;
|
||||
*slot_number < ARRAY_LENGTH( ram_slots );
|
||||
++( *slot_number ) )
|
||||
{
|
||||
if( ! ( *slot_usage & 1 << *slot_number ) )
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
return( PSA_ERROR_INSUFFICIENT_STORAGE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Other test helper functions */
|
||||
/****************************************************************/
|
||||
|
||||
/* Check that the attributes of a key reported by psa_get_key_attributes()
|
||||
* are consistent with the attributes used when creating the key. */
|
||||
static int check_key_attributes(
|
||||
psa_key_handle_t handle,
|
||||
const psa_key_attributes_t *reference_attributes )
|
||||
{
|
||||
int ok = 0;
|
||||
psa_key_attributes_t actual_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &actual_attributes ) );
|
||||
|
||||
TEST_EQUAL( psa_get_key_id( &actual_attributes ),
|
||||
psa_get_key_id( reference_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &actual_attributes ),
|
||||
psa_get_key_lifetime( reference_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_type( &actual_attributes ),
|
||||
psa_get_key_type( reference_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &actual_attributes ),
|
||||
psa_get_key_usage_flags( reference_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &actual_attributes ),
|
||||
psa_get_key_algorithm( reference_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_enrollment_algorithm( &actual_attributes ),
|
||||
psa_get_key_enrollment_algorithm( reference_attributes ) );
|
||||
if( psa_get_key_bits( reference_attributes ) != 0 )
|
||||
{
|
||||
TEST_EQUAL( psa_get_key_bits( &actual_attributes ),
|
||||
psa_get_key_bits( reference_attributes ) );
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
exit:
|
||||
return( ok );
|
||||
}
|
||||
|
||||
/* Check that a function's return status is "smoke-free", i.e. that
|
||||
* it's an acceptable error code when calling an API function that operates
|
||||
* on a key with potentially bogus parameters. */
|
||||
static int is_status_smoke_free( psa_status_t status )
|
||||
{
|
||||
switch( status )
|
||||
{
|
||||
case PSA_SUCCESS:
|
||||
case PSA_ERROR_NOT_SUPPORTED:
|
||||
case PSA_ERROR_NOT_PERMITTED:
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
case PSA_ERROR_INVALID_SIGNATURE:
|
||||
case PSA_ERROR_INVALID_PADDING:
|
||||
return( 1 );
|
||||
default:
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
#define SMOKE_ASSERT( expr ) \
|
||||
TEST_ASSERT( is_status_smoke_free( expr ) )
|
||||
|
||||
/* Smoke test a key. There are mostly no wrong answers here since we pass
|
||||
* mostly bogus parameters: the goal is to ensure that there is no memory
|
||||
* corruption or crash. This test function is most useful when run under
|
||||
* an environment with sanity checks such as ASan or MSan. */
|
||||
static int smoke_test_key( psa_key_handle_t handle )
|
||||
{
|
||||
int ok = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_mac_operation_t mac_operation = PSA_MAC_OPERATION_INIT;
|
||||
psa_cipher_operation_t cipher_operation = PSA_CIPHER_OPERATION_INIT;
|
||||
psa_key_derivation_operation_t derivation_operation =
|
||||
PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
uint8_t buffer[80]; /* large enough for a public key for ECDH */
|
||||
size_t length;
|
||||
psa_key_handle_t handle2 = 0;
|
||||
|
||||
SMOKE_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
|
||||
SMOKE_ASSERT( psa_export_key( handle,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
SMOKE_ASSERT( psa_export_public_key( handle,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
|
||||
SMOKE_ASSERT( psa_copy_key( handle, &attributes, &handle2 ) );
|
||||
if( handle2 != 0 )
|
||||
PSA_ASSERT( psa_close_key( handle2 ) );
|
||||
|
||||
SMOKE_ASSERT( psa_mac_sign_setup( &mac_operation, handle, PSA_ALG_CMAC ) );
|
||||
PSA_ASSERT( psa_mac_abort( &mac_operation ) );
|
||||
SMOKE_ASSERT( psa_mac_verify_setup( &mac_operation, handle,
|
||||
PSA_ALG_HMAC( PSA_ALG_SHA_256 ) ) );
|
||||
PSA_ASSERT( psa_mac_abort( &mac_operation ) );
|
||||
|
||||
SMOKE_ASSERT( psa_cipher_encrypt_setup( &cipher_operation, handle,
|
||||
PSA_ALG_CTR ) );
|
||||
PSA_ASSERT( psa_cipher_abort( &cipher_operation ) );
|
||||
SMOKE_ASSERT( psa_cipher_decrypt_setup( &cipher_operation, handle,
|
||||
PSA_ALG_CTR ) );
|
||||
PSA_ASSERT( psa_cipher_abort( &cipher_operation ) );
|
||||
|
||||
SMOKE_ASSERT( psa_aead_encrypt( handle, PSA_ALG_CCM,
|
||||
buffer, sizeof( buffer ),
|
||||
NULL, 0,
|
||||
buffer, sizeof( buffer),
|
||||
buffer, sizeof( buffer), &length ) );
|
||||
SMOKE_ASSERT( psa_aead_decrypt( handle, PSA_ALG_CCM,
|
||||
buffer, sizeof( buffer ),
|
||||
NULL, 0,
|
||||
buffer, sizeof( buffer),
|
||||
buffer, sizeof( buffer), &length ) );
|
||||
|
||||
SMOKE_ASSERT( psa_asymmetric_sign( handle, PSA_ALG_ECDSA_ANY,
|
||||
buffer, 32,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
SMOKE_ASSERT( psa_asymmetric_verify( handle, PSA_ALG_ECDSA_ANY,
|
||||
buffer, 32,
|
||||
buffer, sizeof( buffer ) ) );
|
||||
|
||||
SMOKE_ASSERT( psa_asymmetric_encrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
buffer, 10, NULL, 0,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
SMOKE_ASSERT( psa_asymmetric_decrypt( handle, PSA_ALG_RSA_PKCS1V15_CRYPT,
|
||||
buffer, sizeof( buffer ), NULL, 0,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
|
||||
#if defined(MBEDTLS_SHA256_C)
|
||||
/* Try the key in a plain key derivation. */
|
||||
PSA_ASSERT( psa_key_derivation_setup( &derivation_operation,
|
||||
PSA_ALG_HKDF( PSA_ALG_SHA_256 ) ) );
|
||||
PSA_ASSERT( psa_key_derivation_input_bytes( &derivation_operation,
|
||||
PSA_KEY_DERIVATION_INPUT_SALT,
|
||||
NULL, 0 ) );
|
||||
SMOKE_ASSERT( psa_key_derivation_input_key( &derivation_operation,
|
||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
handle ) );
|
||||
PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) );
|
||||
|
||||
/* If the key is asymmetric, try it in a key agreement, both as
|
||||
* part of a derivation operation and standalone. */
|
||||
if( psa_export_public_key( handle, buffer, sizeof( buffer ), &length ) ==
|
||||
PSA_SUCCESS )
|
||||
{
|
||||
psa_algorithm_t alg =
|
||||
PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH,
|
||||
PSA_ALG_HKDF( PSA_ALG_SHA_256 ) );
|
||||
PSA_ASSERT( psa_key_derivation_setup( &derivation_operation, alg ) );
|
||||
PSA_ASSERT( psa_key_derivation_input_bytes(
|
||||
&derivation_operation, PSA_KEY_DERIVATION_INPUT_SALT,
|
||||
NULL, 0 ) );
|
||||
SMOKE_ASSERT( psa_key_derivation_key_agreement(
|
||||
&derivation_operation,
|
||||
PSA_KEY_DERIVATION_INPUT_SECRET,
|
||||
handle, buffer, length ) );
|
||||
PSA_ASSERT( psa_key_derivation_abort( &derivation_operation ) );
|
||||
|
||||
SMOKE_ASSERT( psa_raw_key_agreement(
|
||||
alg, handle, buffer, length,
|
||||
buffer, sizeof( buffer ), &length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_SHA256_C */
|
||||
|
||||
ok = 1;
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
return( ok );
|
||||
}
|
||||
|
||||
#define MAX_KEY_ID_FOR_TEST 10
|
||||
static void psa_purge_storage( void )
|
||||
{
|
||||
psa_key_id_t id;
|
||||
psa_key_lifetime_t lifetime;
|
||||
/* 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( id = 0; id <= MAX_KEY_ID_FOR_TEST; id++ )
|
||||
psa_destroy_persistent_key( id );
|
||||
/* Purge the transaction file. */
|
||||
psa_crypto_stop_transaction( );
|
||||
/* Purge driver persistent data. */
|
||||
for( lifetime = 0; lifetime < PSA_MAX_SE_LIFETIME; lifetime++ )
|
||||
psa_destroy_se_persistent_data( lifetime );
|
||||
}
|
||||
|
||||
/* END_HEADER */
|
||||
|
||||
/* BEGIN_DEPENDENCIES
|
||||
* depends_on:MBEDTLS_PSA_CRYPTO_SE_C
|
||||
* END_DEPENDENCIES
|
||||
*/
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void register_one( int lifetime, int version, int expected_status_arg )
|
||||
{
|
||||
psa_status_t expected_status = expected_status_arg;
|
||||
psa_drv_se_t driver;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
driver.hal_version = version;
|
||||
|
||||
TEST_EQUAL( psa_register_se_driver( lifetime, &driver ),
|
||||
expected_status );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void register_twice( int count )
|
||||
{
|
||||
psa_drv_se_t driver;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_lifetime_t max = MIN_DRIVER_LIFETIME + count;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
|
||||
|
||||
for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ )
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ )
|
||||
TEST_EQUAL( psa_register_se_driver( lifetime, &driver ),
|
||||
PSA_ERROR_ALREADY_EXISTS );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void register_max( )
|
||||
{
|
||||
psa_drv_se_t driver;
|
||||
psa_key_lifetime_t lifetime;
|
||||
psa_key_lifetime_t max = MIN_DRIVER_LIFETIME + PSA_MAX_SE_DRIVERS;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
|
||||
|
||||
for( lifetime = MIN_DRIVER_LIFETIME; lifetime < max; lifetime++ )
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
|
||||
TEST_EQUAL( psa_register_se_driver( lifetime, &driver ),
|
||||
PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_creation_import_export( int min_slot, int restart )
|
||||
{
|
||||
psa_drv_se_t driver;
|
||||
psa_drv_se_key_management_t key_management;
|
||||
psa_key_lifetime_t lifetime = 2;
|
||||
psa_key_id_t id = 1;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
const uint8_t key_material[3] = {0xfa, 0xca, 0xde};
|
||||
uint8_t exported[sizeof( key_material )];
|
||||
size_t exported_length;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
memset( &key_management, 0, sizeof( key_management ) );
|
||||
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
|
||||
driver.key_management = &key_management;
|
||||
driver.persistent_data_size = sizeof( ram_slot_usage_t );
|
||||
key_management.p_allocate = ram_allocate;
|
||||
key_management.p_import = ram_import;
|
||||
key_management.p_destroy = ram_destroy;
|
||||
key_management.p_export = ram_export;
|
||||
ram_min_slot = min_slot;
|
||||
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Create a key. */
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
key_material, sizeof( key_material ),
|
||||
&handle ) );
|
||||
|
||||
/* Maybe restart, to check that the information is saved correctly. */
|
||||
if( restart )
|
||||
{
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
PSA_ASSERT( psa_open_key( id, &handle ) );
|
||||
}
|
||||
|
||||
/* Test that the key was created in the expected slot. */
|
||||
TEST_ASSERT( ram_slots[min_slot].type == PSA_KEY_TYPE_RAW_DATA );
|
||||
|
||||
/* Test the key attributes and the key data. */
|
||||
psa_set_key_bits( &attributes,
|
||||
PSA_BYTES_TO_BITS( sizeof( key_material ) ) );
|
||||
if( ! check_key_attributes( handle, &attributes ) )
|
||||
goto exit;
|
||||
PSA_ASSERT( psa_export_key( handle,
|
||||
exported, sizeof( exported ),
|
||||
&exported_length ) );
|
||||
ASSERT_COMPARE( key_material, sizeof( key_material ),
|
||||
exported, exported_length );
|
||||
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
/* Test that the key has been erased from the designated slot. */
|
||||
TEST_ASSERT( ram_slots[min_slot].type == 0 );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
ram_slots_reset( );
|
||||
psa_purge_storage( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void key_creation_smoke( int type_arg, int alg_arg,
|
||||
data_t *key_material )
|
||||
{
|
||||
psa_key_type_t type = type_arg;
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
psa_drv_se_t driver;
|
||||
psa_drv_se_key_management_t key_management;
|
||||
psa_key_lifetime_t lifetime = 2;
|
||||
psa_key_id_t id = 1;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
memset( &key_management, 0, sizeof( key_management ) );
|
||||
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
|
||||
driver.key_management = &key_management;
|
||||
driver.persistent_data_size = sizeof( psa_key_slot_number_t );
|
||||
key_management.p_allocate = counter_allocate;
|
||||
key_management.p_import = null_import;
|
||||
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Create a key. */
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_usage_flags( &attributes,
|
||||
PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY |
|
||||
PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT |
|
||||
PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, type );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
key_material->x, key_material->len,
|
||||
&handle ) );
|
||||
|
||||
/* Do stuff with the key. */
|
||||
if( ! smoke_test_key( handle ) )
|
||||
goto exit;
|
||||
|
||||
/* Restart and try again. */
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
PSA_ASSERT( psa_open_key( id, &handle ) );
|
||||
if( ! smoke_test_key( handle ) )
|
||||
goto exit;
|
||||
|
||||
/* We're done. */
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
ram_slots_reset( );
|
||||
psa_purge_storage( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void generate_key_not_supported( int type_arg, int bits_arg )
|
||||
{
|
||||
psa_key_type_t type = type_arg;
|
||||
size_t bits = bits_arg;
|
||||
psa_drv_se_t driver;
|
||||
psa_drv_se_key_management_t key_management;
|
||||
psa_key_lifetime_t lifetime = 2;
|
||||
psa_key_id_t id = 1;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
memset( &driver, 0, sizeof( driver ) );
|
||||
memset( &key_management, 0, sizeof( key_management ) );
|
||||
driver.hal_version = PSA_DRV_SE_HAL_VERSION;
|
||||
driver.key_management = &key_management;
|
||||
driver.persistent_data_size = sizeof( psa_key_slot_number_t );
|
||||
key_management.p_allocate = counter_allocate;
|
||||
|
||||
PSA_ASSERT( psa_register_se_driver( lifetime, &driver ) );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_type( &attributes, type );
|
||||
psa_set_key_bits( &attributes, bits );
|
||||
TEST_EQUAL( psa_generate_key( &attributes, &handle ),
|
||||
PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
exit:
|
||||
PSA_DONE( );
|
||||
ram_slots_reset( );
|
||||
psa_purge_storage( );
|
||||
}
|
||||
/* END_CASE */
|
|
@ -1,36 +1,65 @@
|
|||
Transient slot, check after closing
|
||||
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
|
||||
|
||||
Transient slot, check after closing and restarting
|
||||
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE_WITH_SHUTDOWN
|
||||
|
||||
Transient slot, check after destroying
|
||||
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
|
||||
|
||||
Transient slot, check after restart
|
||||
Transient slot, check after destroying and restarting
|
||||
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY_WITH_SHUTDOWN
|
||||
|
||||
Transient slot, check after restart with live handles
|
||||
transient_slot_lifecycle:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
|
||||
|
||||
Persistent slot, check after closing
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
|
||||
Persistent slot, check after closing, id=min
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
|
||||
|
||||
Persistent slot, check after destroying
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
|
||||
Persistent slot, check after closing and restarting, id=min
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
|
||||
|
||||
Persistent slot, check after restart
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
|
||||
Persistent slot, check after destroying, id=min
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
|
||||
|
||||
Persistent slot, check after destroying and restarting, id=min
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
|
||||
|
||||
Persistent slot, check after restart with live handle, id=min
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MIN:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
|
||||
|
||||
Persistent slot, check after closing, id=max
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MAX:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_CLOSE
|
||||
|
||||
Persistent slot, check after destroying, id=max
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MAX:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_DESTROY
|
||||
|
||||
Persistent slot, check after restart, id=max
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MAX:0:0:0:PSA_KEY_TYPE_RAW_DATA:"0123456789abcdef0123456789abcdef":CLOSE_BY_SHUTDOWN
|
||||
|
||||
Persistent slot: ECP keypair (ECDSA, exportable); close
|
||||
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
|
||||
|
||||
Persistent slot: ECP keypair (ECDSA, exportable); close+restart
|
||||
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE_WITH_SHUTDOWN
|
||||
|
||||
Persistent slot: ECP keypair (ECDSA, exportable); restart
|
||||
depends_on:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:0:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN
|
||||
|
||||
Persistent slot: ECP keypair (ECDH+ECDSA, exportable); close
|
||||
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDH(PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE
|
||||
|
||||
Persistent slot: ECP keypair (ECDH+ECDSA, exportable); close+restart
|
||||
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_CLOSE_WITH_SHUTDOWN
|
||||
|
||||
Persistent slot: ECP keypair (ECDH+ECDSA, exportable); restart
|
||||
depends_on:MBEDTLS_ECDH_C:MBEDTLS_SHA256_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDH(PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN
|
||||
persistent_slot_lifecycle:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_ALG_ECDSA_ANY:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":CLOSE_BY_SHUTDOWN
|
||||
|
||||
Attempt to overwrite: close before
|
||||
create_existent:PSA_KEY_LIFETIME_PERSISTENT:1:CLOSE_BEFORE
|
||||
|
@ -43,24 +72,23 @@ create_existent:PSA_KEY_LIFETIME_PERSISTENT:1: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_fail: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_fail:PSA_CRYPTO_ITS_RANDOM_SEED_UID:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Open failure: invalid identifier (reserved range)
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
open_fail:PSA_KEY_ID_VENDOR_MAX + 1:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Open failure: invalid identifier (implementation range)
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
open_fail:PSA_KEY_ID_USER_MAX + 1:PSA_ERROR_DOES_NOT_EXIST
|
||||
|
||||
Open failure: non-existent identifier
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
open_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_DOES_NOT_EXIST
|
||||
|
||||
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_ERROR_INVALID_ARGUMENT
|
||||
open_fail:1:PSA_ERROR_DOES_NOT_EXIST
|
||||
|
||||
Create failure: invalid lifetime
|
||||
create_fail:0x7fffffff:0:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
@ -73,69 +101,52 @@ 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_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Create failure: invalid key id (reserved range)
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
create_fail:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_VENDOR_MAX + 1:PSA_ERROR_INVALID_ARGUMENT
|
||||
|
||||
Create failure: invalid key id (implementation range)
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
create_fail:PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY_ID_USER_MAX + 1: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
|
||||
open_fail:1:PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
Create not supported
|
||||
depends_on:!MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
create_fail:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_ERROR_NOT_SUPPORTED
|
||||
|
||||
Copy volatile to volatile
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
|
||||
Copy volatile to persistent
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
|
||||
Copy persistent to volatile
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
|
||||
Copy persistent to persistent
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:0:0:PSA_KEY_TYPE_RAW_DATA:"4142434445":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0:0:PSA_KEY_USAGE_EXPORT:0:0
|
||||
|
||||
Copy persistent to persistent with enrollment algorithm
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR:MBEDTLS_CIPHER_MODE_CBC
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING
|
||||
copy_across_lifetimes:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_ALG_CBC_NO_PADDING
|
||||
|
||||
Copy empty volatile to volatile
|
||||
copy_from_empty:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0
|
||||
|
||||
Copy empty volatile to persistent
|
||||
Copy volatile to occupied
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_from_empty:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy empty persistent to volatile
|
||||
Copy persistent to occupied
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_from_empty:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:0
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy empty persistent to persistent
|
||||
Copy persistent to same
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_from_empty:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:0:PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:0
|
||||
|
||||
Copy volatile to occupied volatile
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy volatile to occupied persistent
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy persistent to occupied volatile
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy persistent to occupied persistent
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:2:PSA_KEY_USAGE_EXPORT:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"606162636465666768696a6b6c6d6e6f"
|
||||
|
||||
Copy volatile to itself
|
||||
copy_to_same:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f"
|
||||
|
||||
Copy persistent to itself
|
||||
depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
copy_to_same:PSA_KEY_LIFETIME_VOLATILE:0:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f"
|
||||
copy_to_occupied:PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f":PSA_KEY_LIFETIME_PERSISTENT:1:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"404142434445464748494a4b4c4d4e4f"
|
||||
|
||||
Close/destroy invalid handle
|
||||
invalid_handle:
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_SPM)
|
||||
#include "spm/psa_defs.h"
|
||||
#endif
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "psa_crypto_helpers.h"
|
||||
#include "psa_crypto_storage.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOSE_BY_CLOSE,
|
||||
CLOSE_BY_DESTROY,
|
||||
CLOSE_BY_SHUTDOWN,
|
||||
CLOSE_BY_CLOSE, /**< Close the handle(s). */
|
||||
CLOSE_BY_DESTROY, /**< Destroy the handle(s). */
|
||||
CLOSE_BY_SHUTDOWN, /**< Deinit and reinit without closing handles. */
|
||||
CLOSE_BY_CLOSE_WITH_SHUTDOWN, /**< Close handle(s) then deinit/reinit. */
|
||||
CLOSE_BY_DESTROY_WITH_SHUTDOWN, /**< Destroy handle(s) then deinit/reinit. */
|
||||
} close_method_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -23,38 +21,99 @@ typedef enum
|
|||
} 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
|
||||
* `TEST_USES_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 )
|
||||
static psa_key_id_t key_ids_used_in_test[9];
|
||||
static size_t num_key_ids_used;
|
||||
|
||||
/* Record a key id as potentially used in a test case. */
|
||||
static int test_uses_key_id( psa_key_id_t key_id )
|
||||
{
|
||||
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 );
|
||||
size_t i;
|
||||
if( key_id > PSA_MAX_PERSISTENT_KEY_IDENTIFIER )
|
||||
{
|
||||
/* Don't touch key id values that designate non-key files. */
|
||||
return( 1 );
|
||||
}
|
||||
for( i = 0; i < num_key_ids_used ; i++ )
|
||||
{
|
||||
if( key_id == key_ids_used_in_test[i] )
|
||||
return( 1 );
|
||||
}
|
||||
if( num_key_ids_used == ARRAY_LENGTH( key_ids_used_in_test ) )
|
||||
return( 0 );
|
||||
key_ids_used_in_test[num_key_ids_used] = key_id;
|
||||
++num_key_ids_used;
|
||||
return( 1 );
|
||||
}
|
||||
#define TEST_USES_KEY_ID( key_id ) \
|
||||
TEST_ASSERT( test_uses_key_id( key_id ) )
|
||||
|
||||
/* Destroy all key ids that may have been created by the current test case. */
|
||||
static void psa_purge_key_storage( void )
|
||||
{
|
||||
size_t i;
|
||||
for( i = 0; i < num_key_ids_used; i++ )
|
||||
psa_destroy_persistent_key( key_ids_used_in_test[i] );
|
||||
num_key_ids_used = 0;
|
||||
}
|
||||
#else
|
||||
#define TEST_MAX_KEY_ID( key_id ) ( (void) ( key_id ) )
|
||||
#define TEST_USES_KEY_ID( key_id ) ( (void) ( key_id ) )
|
||||
#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
|
||||
|
||||
int psa_key_policy_equal( psa_key_policy_t *p1,
|
||||
psa_key_policy_t *p2 )
|
||||
/** Apply \p close_method to invalidate the specified handles:
|
||||
* close it, destroy it, or do nothing;
|
||||
*/
|
||||
static int invalidate_handle( close_method_t close_method,
|
||||
psa_key_handle_t handle )
|
||||
{
|
||||
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 ) );
|
||||
switch( close_method )
|
||||
{
|
||||
case CLOSE_BY_CLOSE:
|
||||
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
|
||||
PSA_ASSERT( psa_close_key( handle ) );
|
||||
break;
|
||||
case CLOSE_BY_DESTROY:
|
||||
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
|
||||
PSA_ASSERT( psa_destroy_key( handle ) );
|
||||
break;
|
||||
case CLOSE_BY_SHUTDOWN:
|
||||
break;
|
||||
}
|
||||
return( 1 );
|
||||
exit:
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/** Restart the PSA subsystem if \p close_method says so. */
|
||||
static int invalidate_psa( close_method_t close_method )
|
||||
{
|
||||
switch( close_method )
|
||||
{
|
||||
case CLOSE_BY_CLOSE:
|
||||
case CLOSE_BY_DESTROY:
|
||||
return( 1 );
|
||||
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
|
||||
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
|
||||
/* All keys must have been closed. */
|
||||
PSA_DONE( );
|
||||
break;
|
||||
case CLOSE_BY_SHUTDOWN:
|
||||
/* Some keys may remain behind, and we're testing that this
|
||||
* properly closes them. */
|
||||
mbedtls_psa_crypto_free( );
|
||||
break;
|
||||
}
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
ASSERT_PSA_PRISTINE( );
|
||||
return( 1 );
|
||||
|
||||
exit:
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* END_HEADER */
|
||||
|
@ -73,42 +132,34 @@ void transient_slot_lifecycle( int usage_arg, int alg_arg,
|
|||
psa_key_usage_t usage_flags = usage_arg;
|
||||
psa_key_type_t type = type_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_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Get a handle and import a key. */
|
||||
PSA_ASSERT( psa_allocate_key( &handle ) );
|
||||
/* Import a key. */
|
||||
psa_set_key_usage_flags( &attributes, usage_flags );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_type( &attributes, type );
|
||||
PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
|
||||
&handle ) );
|
||||
TEST_ASSERT( handle != 0 );
|
||||
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_EQUAL( read_type, type );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), 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;
|
||||
}
|
||||
if( ! invalidate_handle( close_method, handle ) )
|
||||
goto exit;
|
||||
if( ! invalidate_psa( close_method ) )
|
||||
goto exit;
|
||||
|
||||
/* Test that the handle is now invalid. */
|
||||
TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
|
||||
TEST_EQUAL( psa_get_key_attributes( handle, &attributes ),
|
||||
PSA_ERROR_INVALID_HANDLE );
|
||||
TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -124,53 +175,56 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
|
|||
psa_algorithm_t alg2 = alg2_arg;
|
||||
psa_key_usage_t usage_flags = usage_arg;
|
||||
psa_key_type_t type = type_arg;
|
||||
size_t bits;
|
||||
close_method_t close_method = close_method_arg;
|
||||
psa_key_type_t read_type;
|
||||
size_t read_bits;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_policy_t read_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_attributes_t read_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t *reexported = NULL;
|
||||
size_t reexported_length = -1;
|
||||
|
||||
TEST_MAX_KEY_ID( id );
|
||||
TEST_USES_KEY_ID( id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Get a handle and import a key. */
|
||||
PSA_ASSERT( psa_create_key( lifetime, id, &handle ) );
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_type( &attributes, type );
|
||||
psa_set_key_usage_flags( &attributes, usage_flags );
|
||||
psa_set_key_algorithm( &attributes, alg );
|
||||
psa_set_key_enrollment_algorithm( &attributes, alg2 );
|
||||
PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
|
||||
&handle ) );
|
||||
TEST_ASSERT( handle != 0 );
|
||||
psa_key_policy_set_usage( &policy, usage_flags, alg );
|
||||
psa_key_policy_set_enrollment_algorithm( &policy, alg2 );
|
||||
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, &bits ) );
|
||||
TEST_EQUAL( read_type, type );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ), id );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
|
||||
TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), 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_EQUAL( read_type, type );
|
||||
PSA_ASSERT( psa_open_key( id, &handle ) );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ), id );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ), alg );
|
||||
TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ), alg2 );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), 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;
|
||||
}
|
||||
if( ! invalidate_handle( close_method, handle ) )
|
||||
goto exit;
|
||||
if( ! invalidate_psa( close_method ) )
|
||||
goto exit;
|
||||
|
||||
/* Test that the handle is now invalid. */
|
||||
TEST_EQUAL( psa_get_key_information( handle, &read_type, NULL ),
|
||||
TEST_EQUAL( psa_get_key_attributes( handle, &read_attributes ),
|
||||
PSA_ERROR_INVALID_HANDLE );
|
||||
psa_reset_key_attributes( &read_attributes );
|
||||
TEST_EQUAL( psa_close_key( handle ), PSA_ERROR_INVALID_HANDLE );
|
||||
|
||||
/* Try to reopen the key. If we destroyed it, check that it doesn't
|
||||
|
@ -179,18 +233,24 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
|
|||
switch( close_method )
|
||||
{
|
||||
case CLOSE_BY_CLOSE:
|
||||
case CLOSE_BY_CLOSE_WITH_SHUTDOWN:
|
||||
case CLOSE_BY_SHUTDOWN:
|
||||
PSA_ASSERT( psa_open_key( lifetime, id, &handle ) );
|
||||
PSA_ASSERT( psa_get_key_policy( handle, &read_policy ) );
|
||||
PSA_ASSERT( psa_get_key_information( handle,
|
||||
&read_type, &read_bits ) );
|
||||
TEST_EQUAL( read_type, type );
|
||||
TEST_EQUAL( read_bits, bits );
|
||||
TEST_EQUAL( psa_key_policy_get_usage( &read_policy ), usage_flags );
|
||||
TEST_EQUAL( psa_key_policy_get_algorithm( &read_policy ), alg );
|
||||
TEST_EQUAL( psa_key_policy_get_enrollment_algorithm( &read_policy ),
|
||||
alg2 );
|
||||
if( policy.usage & PSA_KEY_USAGE_EXPORT )
|
||||
PSA_ASSERT( psa_open_key( id, &handle ) );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle, &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ),
|
||||
psa_get_key_lifetime( &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ),
|
||||
psa_get_key_id( &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), usage_flags );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ),
|
||||
psa_get_key_algorithm( &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_enrollment_algorithm( &attributes ),
|
||||
psa_get_key_enrollment_algorithm( &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ),
|
||||
psa_get_key_type( &read_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_bits( &attributes ),
|
||||
psa_get_key_bits( &read_attributes ) );
|
||||
if( usage_flags & PSA_KEY_USAGE_EXPORT )
|
||||
{
|
||||
ASSERT_ALLOC( reexported, key_data->len );
|
||||
PSA_ASSERT( psa_export_key( handle,
|
||||
|
@ -206,15 +266,18 @@ void persistent_slot_lifecycle( int lifetime_arg, int id_arg,
|
|||
&reexported_length ),
|
||||
PSA_ERROR_NOT_PERMITTED );
|
||||
}
|
||||
PSA_ASSERT( psa_close_key( handle ) );
|
||||
break;
|
||||
|
||||
case CLOSE_BY_DESTROY:
|
||||
TEST_EQUAL( psa_open_key( lifetime, id, &handle ),
|
||||
case CLOSE_BY_DESTROY_WITH_SHUTDOWN:
|
||||
TEST_EQUAL( psa_open_key( id, &handle ),
|
||||
PSA_ERROR_DOES_NOT_EXIST );
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
psa_purge_key_storage( );
|
||||
mbedtls_free( reexported );
|
||||
}
|
||||
|
@ -227,76 +290,82 @@ void create_existent( int lifetime_arg, int id_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 = PSA_KEY_POLICY_INIT;
|
||||
psa_key_policy_t read_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t type1 = PSA_KEY_TYPE_RAW_DATA;
|
||||
psa_key_type_t read_type;
|
||||
const uint8_t material1[16] = "test material #1";
|
||||
const uint8_t material1[5] = "a key";
|
||||
const uint8_t material2[5] = "b key";
|
||||
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 );
|
||||
TEST_USES_KEY_ID( id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Create a key. */
|
||||
PSA_ASSERT( psa_create_key( lifetime, id, &handle1 ) );
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_type( &attributes, type1 );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, 0 );
|
||||
PSA_ASSERT( psa_import_key( &attributes, material1, sizeof( material1 ),
|
||||
&handle1 ) );
|
||||
TEST_ASSERT( handle1 != 0 );
|
||||
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_EQUAL( psa_create_key( lifetime, id, &handle2 ),
|
||||
TEST_EQUAL( psa_import_key( &attributes, material2, sizeof( material2 ),
|
||||
&handle2 ),
|
||||
PSA_ERROR_ALREADY_EXISTS );
|
||||
TEST_EQUAL( 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 ) );
|
||||
PSA_ASSERT( psa_open_key( 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_EQUAL( read_type, type1 );
|
||||
TEST_EQUAL( read_bits, bits1 );
|
||||
psa_reset_key_attributes( &attributes );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle1, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes ), id );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes ), lifetime );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), type1 );
|
||||
TEST_EQUAL( psa_get_key_bits( &attributes ), bits1 );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes ), PSA_KEY_USAGE_EXPORT );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes ), 0 );
|
||||
|
||||
PSA_ASSERT( psa_export_key( handle1,
|
||||
reexported, sizeof( reexported ),
|
||||
&reexported_length ) );
|
||||
ASSERT_COMPARE( material1, sizeof( material1 ),
|
||||
reexported, reexported_length );
|
||||
|
||||
PSA_ASSERT( psa_close_key( handle1 ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
psa_purge_key_storage( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void open_fail( int lifetime_arg, int id_arg,
|
||||
void open_fail( 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_EQUAL( psa_open_key( lifetime, id, &handle ), expected_status );
|
||||
TEST_EQUAL( psa_open_key( id, &handle ), expected_status );
|
||||
TEST_EQUAL( handle, 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -306,19 +375,25 @@ void create_fail( int lifetime_arg, int id_arg,
|
|||
{
|
||||
psa_key_lifetime_t lifetime = lifetime_arg;
|
||||
psa_key_id_t id = id_arg;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t expected_status = expected_status_arg;
|
||||
psa_key_handle_t handle = 0xdead;
|
||||
uint8_t material[1] = {'k'};
|
||||
|
||||
TEST_MAX_KEY_ID( id );
|
||||
TEST_USES_KEY_ID( id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
TEST_EQUAL( psa_create_key( lifetime, id, &handle ),
|
||||
psa_set_key_id( &attributes, id );
|
||||
psa_set_key_lifetime( &attributes, lifetime );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
TEST_EQUAL( psa_import_key( &attributes, material, sizeof( material ),
|
||||
&handle ),
|
||||
expected_status );
|
||||
TEST_EQUAL( handle, 0 );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_purge_key_storage( );
|
||||
#endif
|
||||
|
@ -340,56 +415,54 @@ void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
|
|||
psa_key_id_t source_id = source_id_arg;
|
||||
psa_key_usage_t source_usage = source_usage_arg;
|
||||
psa_algorithm_t source_alg = source_alg_arg;
|
||||
psa_algorithm_t source_alg2 = source_alg2_arg;
|
||||
psa_key_handle_t source_handle = 0;
|
||||
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t source_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_type_t source_type = type_arg;
|
||||
size_t source_bits;
|
||||
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
||||
psa_key_id_t target_id = target_id_arg;
|
||||
psa_key_usage_t target_usage = target_usage_arg;
|
||||
psa_algorithm_t target_alg = target_alg_arg;
|
||||
psa_algorithm_t target_alg2 = target_alg2_arg;
|
||||
psa_key_handle_t target_handle = 0;
|
||||
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_type_t target_type;
|
||||
size_t target_bits;
|
||||
psa_key_attributes_t target_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_usage_t expected_usage = expected_usage_arg;
|
||||
psa_algorithm_t expected_alg = expected_alg_arg;
|
||||
psa_algorithm_t expected_alg2 = expected_alg2_arg;
|
||||
uint8_t *export_buffer = NULL;
|
||||
|
||||
TEST_MAX_KEY_ID( source_id );
|
||||
TEST_MAX_KEY_ID( target_id );
|
||||
TEST_USES_KEY_ID( source_id );
|
||||
TEST_USES_KEY_ID( target_id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Populate the source slot. */
|
||||
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
||||
&source_handle ) );
|
||||
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
||||
psa_key_policy_set_enrollment_algorithm( &source_policy, source_alg2 );
|
||||
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
||||
PSA_ASSERT( psa_import_key( source_handle, source_type,
|
||||
material->x, material->len ) );
|
||||
PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
|
||||
if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
||||
{
|
||||
psa_set_key_id( &source_attributes, source_id );
|
||||
psa_set_key_lifetime( &source_attributes, source_lifetime );
|
||||
}
|
||||
psa_set_key_type( &source_attributes, source_type );
|
||||
psa_set_key_usage_flags( &source_attributes, source_usage );
|
||||
psa_set_key_algorithm( &source_attributes, source_alg );
|
||||
psa_set_key_enrollment_algorithm( &source_attributes, source_alg2_arg );
|
||||
PSA_ASSERT( psa_import_key( &source_attributes,
|
||||
material->x, material->len,
|
||||
&source_handle ) );
|
||||
/* Update the attributes with the bit size. */
|
||||
PSA_ASSERT( psa_get_key_attributes( source_handle, &source_attributes ) );
|
||||
|
||||
/* Prepare the target slot. */
|
||||
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
||||
&target_handle ) );
|
||||
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
||||
psa_key_policy_set_enrollment_algorithm( &target_policy, target_alg2 );
|
||||
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
||||
target_policy = psa_key_policy_init();
|
||||
if( target_lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
||||
{
|
||||
psa_set_key_id( &target_attributes, target_id );
|
||||
psa_set_key_lifetime( &target_attributes, target_lifetime );
|
||||
}
|
||||
psa_set_key_usage_flags( &target_attributes, target_usage );
|
||||
psa_set_key_algorithm( &target_attributes, target_alg );
|
||||
psa_set_key_enrollment_algorithm( &target_attributes, target_alg2_arg );
|
||||
|
||||
/* Copy the key. */
|
||||
PSA_ASSERT( psa_copy_key( source_handle, target_handle, NULL ) );
|
||||
PSA_ASSERT( psa_copy_key( source_handle,
|
||||
&target_attributes, &target_handle ) );
|
||||
|
||||
/* Destroy the source to ensure that this doesn't affect the target. */
|
||||
PSA_ASSERT( psa_destroy_key( source_handle ) );
|
||||
|
@ -400,20 +473,21 @@ void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
|
|||
{
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
PSA_ASSERT( psa_open_key( target_lifetime, target_id,
|
||||
&target_handle ) );
|
||||
PSA_ASSERT( psa_open_key( target_id, &target_handle ) );
|
||||
}
|
||||
|
||||
/* Test that the target slot has the expected content. */
|
||||
PSA_ASSERT( psa_get_key_information( target_handle,
|
||||
&target_type, &target_bits ) );
|
||||
TEST_EQUAL( source_type, target_type );
|
||||
TEST_EQUAL( source_bits, target_bits );
|
||||
PSA_ASSERT( psa_get_key_policy( target_handle, &target_policy ) );
|
||||
TEST_EQUAL( expected_usage, psa_key_policy_get_usage( &target_policy ) );
|
||||
TEST_EQUAL( expected_alg, psa_key_policy_get_algorithm( &target_policy ) );
|
||||
psa_reset_key_attributes( &target_attributes );
|
||||
PSA_ASSERT( psa_get_key_attributes( target_handle, &target_attributes ) );
|
||||
TEST_EQUAL( target_id, psa_get_key_id( &target_attributes ) );
|
||||
TEST_EQUAL( target_lifetime, psa_get_key_lifetime( &target_attributes ) );
|
||||
TEST_EQUAL( source_type, psa_get_key_type( &target_attributes ) );
|
||||
TEST_EQUAL( psa_get_key_bits( &source_attributes ),
|
||||
psa_get_key_bits( &target_attributes ) );
|
||||
TEST_EQUAL( expected_usage, psa_get_key_usage_flags( &target_attributes ) );
|
||||
TEST_EQUAL( expected_alg, psa_get_key_algorithm( &target_attributes ) );
|
||||
TEST_EQUAL( expected_alg2,
|
||||
psa_key_policy_get_enrollment_algorithm( &target_policy ) );
|
||||
psa_get_key_enrollment_algorithm( &target_attributes ) );
|
||||
if( expected_usage & PSA_KEY_USAGE_EXPORT )
|
||||
{
|
||||
size_t length;
|
||||
|
@ -423,9 +497,19 @@ void copy_across_lifetimes( int source_lifetime_arg, int source_id_arg,
|
|||
ASSERT_COMPARE( material->x, material->len,
|
||||
export_buffer, length );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t length;
|
||||
/* Check that the key is actually non-exportable. */
|
||||
TEST_EQUAL( psa_export_key( target_handle, export_buffer,
|
||||
material->len, &length ),
|
||||
PSA_ERROR_NOT_PERMITTED );
|
||||
}
|
||||
|
||||
PSA_ASSERT( psa_destroy_key( target_handle ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
mbedtls_free( export_buffer );
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_purge_key_storage( );
|
||||
|
@ -433,69 +517,6 @@ exit:
|
|||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void copy_from_empty( int source_lifetime_arg, int source_id_arg,
|
||||
int source_usage_arg, int source_alg_arg,
|
||||
int target_lifetime_arg, int target_id_arg,
|
||||
int target_usage_arg, int target_alg_arg )
|
||||
{
|
||||
psa_key_lifetime_t source_lifetime = source_lifetime_arg;
|
||||
psa_key_id_t source_id = source_id_arg;
|
||||
psa_key_usage_t source_usage = source_usage_arg;
|
||||
psa_algorithm_t source_alg = source_alg_arg;
|
||||
psa_key_handle_t source_handle = 0;
|
||||
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
||||
psa_key_id_t target_id = target_id_arg;
|
||||
psa_key_usage_t target_usage = target_usage_arg;
|
||||
psa_algorithm_t target_alg = target_alg_arg;
|
||||
psa_key_handle_t target_handle = 0;
|
||||
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_policy_t got_policy;
|
||||
|
||||
TEST_MAX_KEY_ID( source_id );
|
||||
TEST_MAX_KEY_ID( target_id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Prepare the source slot. */
|
||||
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
||||
&source_handle ) );
|
||||
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
||||
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
||||
|
||||
/* Prepare the target slot. */
|
||||
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
||||
&target_handle ) );
|
||||
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
||||
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
||||
|
||||
/* Copy the key. */
|
||||
TEST_EQUAL( psa_copy_key( source_handle, target_handle, NULL ),
|
||||
PSA_ERROR_DOES_NOT_EXIST );
|
||||
|
||||
/* Test that the slots are unaffected. */
|
||||
PSA_ASSERT( psa_get_key_policy( source_handle, &got_policy ) );
|
||||
TEST_EQUAL( source_usage, psa_key_policy_get_usage( &got_policy ) );
|
||||
TEST_EQUAL( source_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
||||
PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
|
||||
TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
|
||||
TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_purge_key_storage( );
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
|
||||
int source_usage_arg, int source_alg_arg,
|
||||
|
@ -509,63 +530,77 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
|
|||
psa_key_usage_t source_usage = source_usage_arg;
|
||||
psa_algorithm_t source_alg = source_alg_arg;
|
||||
psa_key_handle_t source_handle = 0;
|
||||
psa_key_policy_t source_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_type_t source_type = source_type_arg;
|
||||
size_t source_bits;
|
||||
psa_key_lifetime_t target_lifetime = target_lifetime_arg;
|
||||
psa_key_id_t target_id = target_id_arg;
|
||||
psa_key_usage_t target_usage = target_usage_arg;
|
||||
psa_algorithm_t target_alg = target_alg_arg;
|
||||
psa_key_handle_t target_handle = 0;
|
||||
psa_key_policy_t target_policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_type_t target_type = target_type_arg;
|
||||
size_t target_bits;
|
||||
psa_key_policy_t got_policy;
|
||||
psa_key_type_t got_type;
|
||||
size_t got_bits;
|
||||
psa_key_handle_t new_handle = 0xdead;
|
||||
uint8_t *export_buffer = NULL;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_attributes_t attributes1 = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_attributes_t attributes2 = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
TEST_MAX_KEY_ID( source_id );
|
||||
TEST_MAX_KEY_ID( target_id );
|
||||
TEST_USES_KEY_ID( source_id );
|
||||
TEST_USES_KEY_ID( target_id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Populate the source slot. */
|
||||
if( source_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &source_handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( source_lifetime, source_id,
|
||||
&source_handle ) );
|
||||
psa_key_policy_set_usage( &source_policy, source_usage, source_alg );
|
||||
PSA_ASSERT( psa_set_key_policy( source_handle, &source_policy ) );
|
||||
PSA_ASSERT( psa_import_key( source_handle, source_type,
|
||||
source_material->x, source_material->len ) );
|
||||
PSA_ASSERT( psa_get_key_information( source_handle, NULL, &source_bits ) );
|
||||
if( source_lifetime != PSA_KEY_LIFETIME_VOLATILE )
|
||||
{
|
||||
psa_set_key_id( &attributes, source_id );
|
||||
psa_set_key_lifetime( &attributes, source_lifetime );
|
||||
}
|
||||
psa_set_key_type( &attributes, source_type );
|
||||
psa_set_key_usage_flags( &attributes, source_usage );
|
||||
psa_set_key_algorithm( &attributes, source_alg );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
source_material->x, source_material->len,
|
||||
&source_handle ) );
|
||||
|
||||
/* Populate the target slot. */
|
||||
if( target_lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &target_handle ) );
|
||||
if( target_id == source_id )
|
||||
{
|
||||
target_handle = source_handle;
|
||||
}
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( target_lifetime, target_id,
|
||||
{
|
||||
psa_set_key_id( &attributes1, target_id );
|
||||
psa_set_key_lifetime( &attributes1, target_lifetime );
|
||||
psa_set_key_type( &attributes1, target_type );
|
||||
psa_set_key_usage_flags( &attributes1, target_usage );
|
||||
psa_set_key_algorithm( &attributes1, target_alg );
|
||||
PSA_ASSERT( psa_import_key( &attributes1,
|
||||
target_material->x, target_material->len,
|
||||
&target_handle ) );
|
||||
psa_key_policy_set_usage( &target_policy, target_usage, target_alg );
|
||||
PSA_ASSERT( psa_set_key_policy( target_handle, &target_policy ) );
|
||||
PSA_ASSERT( psa_import_key( target_handle, target_type,
|
||||
target_material->x, target_material->len ) );
|
||||
PSA_ASSERT( psa_get_key_information( target_handle, NULL, &target_bits ) );
|
||||
}
|
||||
PSA_ASSERT( psa_get_key_attributes( target_handle, &attributes1 ) );
|
||||
|
||||
/* Copy the key. */
|
||||
TEST_EQUAL( psa_copy_key( source_handle, target_handle, NULL ),
|
||||
/* Make a copy attempt. */
|
||||
psa_set_key_id( &attributes, target_id );
|
||||
psa_set_key_lifetime( &attributes, target_lifetime );
|
||||
TEST_EQUAL( psa_copy_key( source_handle,
|
||||
&attributes, &new_handle ),
|
||||
PSA_ERROR_ALREADY_EXISTS );
|
||||
TEST_EQUAL( new_handle , 0 );
|
||||
|
||||
/* Test that the target slot is unaffected. */
|
||||
PSA_ASSERT( psa_get_key_information( target_handle,
|
||||
&got_type, &got_bits ) );
|
||||
TEST_EQUAL( target_type, got_type );
|
||||
TEST_EQUAL( target_bits, got_bits );
|
||||
PSA_ASSERT( psa_get_key_policy( target_handle, &got_policy ) );
|
||||
TEST_EQUAL( target_usage, psa_key_policy_get_usage( &got_policy ) );
|
||||
TEST_EQUAL( target_alg, psa_key_policy_get_algorithm( &got_policy ) );
|
||||
PSA_ASSERT( psa_get_key_attributes( target_handle, &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_id( &attributes1 ),
|
||||
psa_get_key_id( &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_lifetime( &attributes1 ),
|
||||
psa_get_key_lifetime( &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes1 ),
|
||||
psa_get_key_type( &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_bits( &attributes1 ),
|
||||
psa_get_key_bits( &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_usage_flags( &attributes1 ),
|
||||
psa_get_key_usage_flags( &attributes2 ) );
|
||||
TEST_EQUAL( psa_get_key_algorithm( &attributes1 ),
|
||||
psa_get_key_algorithm( &attributes2 ) );
|
||||
if( target_usage & PSA_KEY_USAGE_EXPORT )
|
||||
{
|
||||
size_t length;
|
||||
|
@ -576,73 +611,12 @@ void copy_to_occupied( int source_lifetime_arg, int source_id_arg,
|
|||
export_buffer, length );
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
mbedtls_free( export_buffer );
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_purge_key_storage( );
|
||||
#endif
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void copy_to_same( int lifetime_arg, int id_arg,
|
||||
int usage_arg, int alg_arg,
|
||||
int type_arg, data_t *material )
|
||||
{
|
||||
psa_key_lifetime_t lifetime = lifetime_arg;
|
||||
psa_key_id_t id = id_arg;
|
||||
psa_key_usage_t usage = usage_arg;
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
psa_key_handle_t handle = 0;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_type_t type = type_arg;
|
||||
size_t bits;
|
||||
psa_key_policy_t got_policy;
|
||||
psa_key_type_t got_type;
|
||||
size_t got_bits;
|
||||
uint8_t *export_buffer = NULL;
|
||||
|
||||
TEST_MAX_KEY_ID( id );
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Populate the slot. */
|
||||
if( lifetime == PSA_KEY_LIFETIME_VOLATILE )
|
||||
PSA_ASSERT( psa_allocate_key( &handle ) );
|
||||
else
|
||||
PSA_ASSERT( psa_create_key( lifetime, id,
|
||||
&handle ) );
|
||||
psa_key_policy_set_usage( &policy, usage, alg );
|
||||
PSA_ASSERT( psa_set_key_policy( handle, &policy ) );
|
||||
PSA_ASSERT( psa_import_key( handle, type,
|
||||
material->x, material->len ) );
|
||||
PSA_ASSERT( psa_get_key_information( handle, NULL, &bits ) );
|
||||
|
||||
/* Copy the key. */
|
||||
TEST_EQUAL( psa_copy_key( handle, handle, NULL ),
|
||||
PSA_ERROR_ALREADY_EXISTS );
|
||||
|
||||
/* Test that the slot is unaffected. */
|
||||
PSA_ASSERT( psa_get_key_information( handle,
|
||||
&got_type, &got_bits ) );
|
||||
TEST_EQUAL( type, got_type );
|
||||
TEST_EQUAL( bits, got_bits );
|
||||
PSA_ASSERT( psa_get_key_policy( handle, &got_policy ) );
|
||||
TEST_EQUAL( usage, psa_key_policy_get_usage( &got_policy ) );
|
||||
TEST_EQUAL( alg, psa_key_policy_get_algorithm( &got_policy ) );
|
||||
if( usage & PSA_KEY_USAGE_EXPORT )
|
||||
{
|
||||
size_t length;
|
||||
ASSERT_ALLOC( export_buffer, material->len );
|
||||
PSA_ASSERT( psa_export_key( handle, export_buffer,
|
||||
material->len, &length ) );
|
||||
ASSERT_COMPARE( material->x, material->len,
|
||||
export_buffer, length );
|
||||
}
|
||||
PSA_ASSERT( psa_destroy_key( source_handle ) );
|
||||
if( target_handle != source_handle )
|
||||
PSA_ASSERT( psa_destroy_key( target_handle ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
mbedtls_free( export_buffer );
|
||||
#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
|
||||
psa_purge_key_storage( );
|
||||
|
@ -654,20 +628,19 @@ exit:
|
|||
void invalid_handle( )
|
||||
{
|
||||
psa_key_handle_t handle1 = 0;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_type_t read_type;
|
||||
size_t read_bits;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t material[1] = "a";
|
||||
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
|
||||
/* Allocate a handle and store a key in it. */
|
||||
PSA_ASSERT( psa_allocate_key( &handle1 ) );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
psa_set_key_usage_flags( &attributes, 0 );
|
||||
psa_set_key_algorithm( &attributes, 0 );
|
||||
PSA_ASSERT( psa_import_key( &attributes,
|
||||
material, sizeof( material ),
|
||||
&handle1 ) );
|
||||
TEST_ASSERT( handle1 != 0 );
|
||||
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_EQUAL( psa_close_key( 0 ), PSA_ERROR_INVALID_HANDLE );
|
||||
|
@ -678,13 +651,14 @@ void invalid_handle( )
|
|||
TEST_EQUAL( 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_EQUAL( read_type, PSA_KEY_TYPE_RAW_DATA );
|
||||
TEST_EQUAL( read_bits, PSA_BYTES_TO_BITS( sizeof( material ) ) );
|
||||
PSA_ASSERT( psa_get_key_attributes( handle1, &attributes ) );
|
||||
TEST_EQUAL( psa_get_key_type( &attributes ), PSA_KEY_TYPE_RAW_DATA );
|
||||
TEST_EQUAL( psa_get_key_bits( &attributes ),
|
||||
PSA_BYTES_TO_BITS( sizeof( material ) ) );
|
||||
PSA_ASSERT( psa_close_key( handle1 ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
|
@ -695,26 +669,28 @@ void many_transient_handles( int max_handles_arg )
|
|||
size_t max_handles = max_handles_arg;
|
||||
size_t i, j;
|
||||
psa_status_t status;
|
||||
psa_key_policy_t policy = PSA_KEY_POLICY_INIT;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
uint8_t exported[sizeof( size_t )];
|
||||
size_t exported_length;
|
||||
|
||||
ASSERT_ALLOC( handles, max_handles );
|
||||
PSA_ASSERT( psa_crypto_init( ) );
|
||||
psa_key_policy_set_usage( &policy, PSA_KEY_USAGE_EXPORT, 0 );
|
||||
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT );
|
||||
psa_set_key_algorithm( &attributes, 0 );
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
|
||||
|
||||
for( i = 0; i < max_handles; i++ )
|
||||
{
|
||||
status = psa_allocate_key( &handles[i] );
|
||||
status = psa_import_key( &attributes,
|
||||
(uint8_t *) &i, sizeof( i ),
|
||||
&handles[i] );
|
||||
if( status == PSA_ERROR_INSUFFICIENT_MEMORY )
|
||||
break;
|
||||
PSA_ASSERT( status );
|
||||
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;
|
||||
|
||||
|
@ -730,7 +706,7 @@ void many_transient_handles( int max_handles_arg )
|
|||
PSA_ASSERT( psa_close_key( handles[i - 1] ) );
|
||||
|
||||
exit:
|
||||
mbedtls_psa_crypto_free( );
|
||||
PSA_DONE( );
|
||||
mbedtls_free( handles );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* BEGIN_HEADER */
|
||||
#include "../library/psa_crypto_its.h"
|
||||
|
||||
#include "psa_helpers.h"
|
||||
|
||||
/* Internal definitions of the implementation, copied for the sake of
|
||||
* some of the tests and of the cleanup code. */
|
||||
#define PSA_ITS_STORAGE_PREFIX ""
|
||||
|
|
|
@ -224,6 +224,7 @@
|
|||
<ClInclude Include="..\..\library/psa_crypto_core.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_invasive.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_its.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_se.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_service_integration.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_slot_management.h" />
|
||||
<ClInclude Include="..\..\library/psa_crypto_storage.h" />
|
||||
|
@ -280,6 +281,7 @@
|
|||
<ClCompile Include="..\..\library\platform_util.c" />
|
||||
<ClCompile Include="..\..\library\poly1305.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_se.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_slot_management.c" />
|
||||
<ClCompile Include="..\..\library\psa_crypto_storage.c" />
|
||||
<ClCompile Include="..\..\library\psa_its_file.c" />
|
||||
|
|
Loading…
Reference in a new issue