diff --git a/doc/crypto/api.db/psa/crypto.h b/doc/crypto/api.db/psa/crypto.h index 3aa3bc8a..1e695243 100644 --- a/doc/crypto/api.db/psa/crypto.h +++ b/doc/crypto/api.db/psa/crypto.h @@ -24,6 +24,9 @@ typedef uint32_t psa_pake_primitive_t; typedef uint8_t psa_pake_primitive_type_t; typedef uint8_t psa_pake_role_t; typedef uint8_t psa_pake_step_t; +typedef struct psa_custom_key_parameters_t { + uint32_t flags; +} psa_custom_key_parameters_t; #define PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(ciphertext_length) \ /* implementation-defined value */ #define PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, ciphertext_length) \ @@ -206,6 +209,7 @@ typedef uint8_t psa_pake_step_t; /* implementation-defined value */ #define PSA_CRYPTO_API_VERSION_MAJOR 1 #define PSA_CRYPTO_API_VERSION_MINOR 3 +#define PSA_CUSTOM_KEY_PARAMETERS_INIT { 0 } #define PSA_DH_FAMILY_RFC7919 ((psa_dh_family_t) 0x03) #define PSA_ECC_FAMILY_BRAINPOOL_P_R1 ((psa_ecc_family_t) 0x30) #define PSA_ECC_FAMILY_FRP ((psa_ecc_family_t) 0x33) @@ -505,6 +509,11 @@ psa_status_t psa_export_public_key(psa_key_id_t key, size_t * data_length); psa_status_t psa_generate_key(const psa_key_attributes_t * attributes, psa_key_id_t * key); +psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes, + const psa_custom_key_parameters_t *custom, + const uint8_t *custom_data, + size_t custom_data_length, + mbedtls_svc_key_id_t *key); psa_status_t psa_generate_random(uint8_t * output, size_t output_size); psa_algorithm_t psa_get_key_algorithm(const psa_key_attributes_t * attributes); @@ -585,6 +594,12 @@ psa_status_t psa_key_derivation_output_bytes(psa_key_derivation_operation_t * op psa_status_t psa_key_derivation_output_key(const psa_key_attributes_t * attributes, psa_key_derivation_operation_t * operation, psa_key_id_t * key); +psa_status_t psa_key_derivation_output_key_custom(const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + const psa_custom_key_parameters_t *custom, + const uint8_t *custom_data, + size_t custom_data_length, + mbedtls_svc_key_id_t *key); psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t * operation, size_t capacity); psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t * operation, diff --git a/doc/crypto/api/keys/attributes.rst b/doc/crypto/api/keys/attributes.rst index fc886c30..71a00fc8 100644 --- a/doc/crypto/api/keys/attributes.rst +++ b/doc/crypto/api/keys/attributes.rst @@ -111,8 +111,8 @@ Managing key attributes #. 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()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key. + #. When generating a random key with `psa_generate_key()` or `psa_generate_key_custom()`, or deriving a key with `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`, set the desired key size with `psa_set_key_bits()`. + #. Call a key creation function: `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. This function reads the attribute object, creates a key with these attributes, and outputs an identifier for the newly created key. #. Optionally call `psa_reset_key_attributes()`, now that the attribute object is no longer needed. Currently this call is not required as the attributes defined in this specification do not require additional resources beyond the object itself. A typical sequence to query a key's attributes is as follows: diff --git a/doc/crypto/api/keys/ids.rst b/doc/crypto/api/keys/ids.rst index 9e9ce070..84c09b52 100644 --- a/doc/crypto/api/keys/ids.rst +++ b/doc/crypto/api/keys/ids.rst @@ -92,7 +92,7 @@ Attribute accessors If the attribute object currently declares the key as volatile, which is the default lifetime of an attribute object, this function sets the lifetime attribute to `PSA_KEY_LIFETIME_PERSISTENT`. - This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. + This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. .. admonition:: Implementation note diff --git a/doc/crypto/api/keys/lifetimes.rst b/doc/crypto/api/keys/lifetimes.rst index b57d09b8..a554b15f 100644 --- a/doc/crypto/api/keys/lifetimes.rst +++ b/doc/crypto/api/keys/lifetimes.rst @@ -273,7 +273,7 @@ Attribute accessors To make a key persistent, give it a persistent key identifier by using `psa_set_key_id()`. By default, a key that has a persistent identifier is stored in the default storage area identifier by `PSA_KEY_LIFETIME_PERSISTENT`. Call this function to choose a storage area, or to explicitly declare the key as volatile. - This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_key_derivation_output_key()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. + This function does not access storage, it merely stores the given value in the attribute object. The persistent key will be written to storage when the attribute object is passed to a key creation function such as `psa_import_key()`, `psa_generate_key()`, `psa_generate_key_custom()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_agreement()`, `psa_pake_get_shared_key()`, or `psa_copy_key()`. .. admonition:: Implementation note diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index 917eb189..b514c105 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -15,8 +15,8 @@ Key creation New keys can be created in the following ways: * `psa_import_key()` creates a key from a data buffer provided by the application. -* `psa_generate_key()` creates a key from randomly generated data. -* `psa_key_derivation_output_key()` creates a key from data generated by a pseudorandom derivation process. See :secref:`kdf`. +* `psa_generate_key()` and `psa_generate_key_custom()` create a key from randomly generated data. +* `psa_key_derivation_output_key()` and `psa_key_derivation_output_key_custom()` create a key from data generated by a pseudorandom derivation process. See :secref:`kdf`. * `psa_key_agreement()` creates a key from the shared secret result of a key agreement process. See :secref:`key-agreement`. * `psa_pake_get_shared_key()` creates a key from the shared secret result of a password-authenticated key exchange. See :secref:`pake`. * `psa_copy_key()` duplicates an existing key with a different lifetime or with a more restrictive usage policy. @@ -114,6 +114,50 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ .. note:: The |API| does not support asymmetric private key objects outside of a key pair. To import a private key, the ``attributes`` must specify the corresponding key pair type. Depending on the key type, either the import format contains the public key data or the implementation will reconstruct the public key from the private key as needed. +.. struct:: psa_custom_key_parameters_t + :type: + + .. summary:: + Custom production parameters for key generation or key derivation. + + .. field:: uint32_t flags + Flags to control the key production process. + ``0`` for the default production parameters. + + .. note:: + + Future versions of the specification, and implementations, may add other fields in this structure. + + The interpretation of this structure depends on the type of the key. :numref:`tab-custom-key-parameters` shows the custom production parameters for each type of key. See the key type definitions for details of the valid parameter values. + + .. list-table:: Custom key parameters + :name: tab-custom-key-parameters + :widths: 1 4 + :header-rows: 1 + + * - Key type + - Custom key parameters + + * - RSA + + - Use the production parameters to select an exponent value that is different from the default value of ``65537``. + + See `PSA_KEY_TYPE_RSA_KEY_PAIR`. + + * - Other key types + - Reserved for future use. + + ``flags`` must be ``0``. + +.. macro:: PSA_CUSTOM_KEY_PARAMETERS_INIT + :definition: { 0 } + + .. summary:: + The default production parameters for key generation or key derivation. + + Calling `psa_generate_key_custom()` or `psa_key_derivation_output_key_custom()` with :code:`custom == PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` is equivalent to calling `psa_generate_key()` or `psa_key_derivation_output_key()` + respectively. + .. function:: psa_generate_key .. summary:: @@ -142,7 +186,9 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. .. param:: psa_key_id_t * key - On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. .. return:: psa_status_t .. retval:: PSA_SUCCESS @@ -179,9 +225,95 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ Implementations must reject an attempt to generate a key of size ``0``. - The following type-specific considerations apply: + The key type definitions in :secref:`key-types` provide specific details relating to generation of the key. + + .. note:: + + This function is equivalent to calling `psa_generate_key_custom()` with the production parameters `PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` (``custom_data`` is ignored). + +.. function:: psa_generate_key_custom + + .. summary:: + Generate a key or key pair using custom production parameters. + + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. + + The following attributes are required for all keys: + + * The key type. It must not be an asymmetric public key. + * The key size. It must be a valid size for the key type. + + The following attributes must be set for keys used in cryptographic operations: + + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. + + The following attributes must be set for keys that do not use the default volatile lifetime: + + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + + .. param:: const psa_custom_key_parameters_t *custom + Customized production parameters for the key generation. + + When this is `PSA_CUSTOM_KEY_PARAMETERS_INIT` with ``custom_data_length == 0``, this function is equivalent to `psa_generate_key()`. + .. param:: const uint8_t *custom_data + A buffer containing additional variable-sized production parameters. + .. param:: size_t custom_data_length + Length of ``custom_data`` in bytes. + .. param:: mbedtls_svc_key_id_t *key + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the key is persistent, the key material and the key's metadata have been saved to persistent storage. + .. retval:: PSA_ERROR_ALREADY_EXISTS + This is an attempt to create a persistent key, and there is already a persistent key with the given identifier. + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + * The production parameters are not supported by the implementation. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * The key type is invalid, or is an asymmetric public key type. + * The key size is not valid for the key type. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The production parameters are invalid. + .. retval:: PSA_ERROR_NOT_PERMITTED + The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + Use this function to provide explicit production parameters when generating a key. + See the description of `psa_generate_key()` for the operation of this function with the default production parameters. + + The key is generated randomly. Its location, policy, type and size are taken from ``attributes``. + + Implementations must reject an attempt to generate a key of size ``0``. - * For RSA keys (`PSA_KEY_TYPE_RSA_KEY_PAIR`), the public exponent is 65537. The modulus is a product of two probabilistic primes between :math:`2^{n-1}` and :math:`2^n` where :math:`n` is the bit size specified in the attributes. + See the documentation of `psa_custom_key_parameters_t` for a list of non-default production parameters. See the key type definitions in :secref:`key-types` for details of the custom production parameters used for key generation. .. function:: psa_copy_key diff --git a/doc/crypto/api/keys/policy.rst b/doc/crypto/api/keys/policy.rst index fdbbe250..614cb78b 100644 --- a/doc/crypto/api/keys/policy.rst +++ b/doc/crypto/api/keys/policy.rst @@ -236,7 +236,7 @@ The usage flags are encoded in a bitmask, which has the type `psa_key_usage_t`. * `psa_key_derivation_key_agreement()` * `psa_raw_key_agreement()` - If this flag is present on all keys used in calls to `psa_key_derivation_input_key()` for a key derivation operation, then it permits calling `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_verify_bytes()`, or `psa_key_derivation_verify_key()` at the end of the operation. + If this flag is present on all keys used in calls to `psa_key_derivation_input_key()` for a key derivation operation, then it permits calling `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, `psa_key_derivation_output_key_custom()`, `psa_key_derivation_verify_bytes()`, or `psa_key_derivation_verify_key()` at the end of the operation. .. macro:: PSA_KEY_USAGE_VERIFY_DERIVATION :definition: ((psa_key_usage_t)0x00008000) diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index 71e0adca..03359411 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -643,6 +643,23 @@ RSA keys See `PSA_KEY_TYPE_RSA_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. + .. subsection:: Key generation + + A call to `psa_generate_key()` will generate an RSA key-pair with the default public exponent of ``65537``. The modulus :math:`n=pq` is a product of two probabilistic primes :math:`p\ \text{and}\ q`, where :math:`2^{r-1} \le n < 2^r` and :math:`r` is the bit size specified in the attributes. + + The exponent can be explicitly specified in non-default production parameters in a call to `psa_generate_key_custom()`. Use the following custom production parameters: + + * The production parameters structure, ``custom``, must have ``flags`` set to zero. + + * If ``custom_data_length == 0``, the default exponent value ``65537`` is used. + + * The additional production parameter buffer ``custom_data`` is the public exponent, in little-endian byte order. + + The exponent must be an odd integer greater than ``1``. + An implementation must support an exponent of ``65537``, and is recommended to support an exponent of ``3``, and can support other values. + + The maximum supported exponent value is :scterm:`implementation defined`. + .. subsection:: Key derivation The method used by `psa_key_derivation_output_key()` to derive an RSA key-pair is :term:`implementation defined`. diff --git a/doc/crypto/api/ops/key-derivation.rst b/doc/crypto/api/ops/key-derivation.rst index cad2cc4b..ac67977f 100644 --- a/doc/crypto/api/ops/key-derivation.rst +++ b/doc/crypto/api/ops/key-derivation.rst @@ -37,7 +37,7 @@ Applications use the `psa_key_derivation_operation_t` type to create key derivat #. Optionally, call `psa_key_derivation_set_capacity()` to set a limit on the amount of data that can be output from the key derivation operation. #. Call an output or verification function: - * `psa_key_derivation_output_key()` to create a derived key. + * `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()` to create a derived key. * `psa_key_derivation_output_bytes()` to export the derived data. * `psa_key_derivation_verify_key()` to compare a derived key with an existing key value. * `psa_key_derivation_verify_bytes()` to compare derived data with a buffer. @@ -341,7 +341,7 @@ Key derivation algorithms The shared secret can be obtained by calling :code:`psa_pake_get_shared_key()` on a PAKE operation that is performing the EC J-PAKE algorithm. See :secref:`pake`. - The 32-byte output has to be read in a single call to either `psa_key_derivation_output_bytes()` or `psa_key_derivation_output_key()`. The size of the output is defined as `PSA_TLS12_ECJPAKE_TO_PMS_OUTPUT_SIZE`. + The 32-byte output has to be read in a single call to either `psa_key_derivation_output_bytes()`, `psa_key_derivation_output_key()`, or `psa_key_derivation_output_key_custom()`. The size of the output is defined as `PSA_TLS12_ECJPAKE_TO_PMS_OUTPUT_SIZE`. .. subsection:: Compatible key types @@ -422,7 +422,7 @@ Input step types For some algorithms, a specific type of key is required. For example, see `PSA_ALG_SP800_108_COUNTER_CMAC`. - The secret can also be a direct input passed to `psa_key_derivation_input_bytes()`. In this case, the derivation operation cannot be used to derive keys: the operation will not permit a call to `psa_key_derivation_output_key()`. + The secret can also be a direct input passed to `psa_key_derivation_input_bytes()`. In this case, the derivation operation cannot be used to derive keys: the operation will not permit a call to `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`. .. macro:: PSA_KEY_DERIVATION_INPUT_OTHER_SECRET :definition: /* implementation-defined value */ @@ -440,7 +440,7 @@ Input step types This is usually a key of type `PSA_KEY_TYPE_PASSWORD` passed to `psa_key_derivation_input_key()` or a direct input passed to `psa_key_derivation_input_bytes()` that is a password or passphrase. It can also be high-entropy secret, for example, a key of type `PSA_KEY_TYPE_DERIVE`, or the shared secret resulting from a key agreement. - If the secret is a direct input, the derivation operation cannot be used to derive keys: the operation will not permit a call to `psa_key_derivation_output_key()`. + If the secret is a direct input, the derivation operation cannot be used to derive keys: the operation will not permit a call to `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`. .. macro:: PSA_KEY_DERIVATION_INPUT_LABEL :definition: /* implementation-defined value */ @@ -581,7 +581,7 @@ Key derivation functions #. Call `psa_key_derivation_setup()` to specify the algorithm. #. Provide the inputs for the key derivation by calling `psa_key_derivation_input_bytes()` or `psa_key_derivation_input_key()` as appropriate. Which inputs are needed, in what order, whether keys are permitted, and what type of keys depends on the algorithm. #. Optionally set the operation's maximum capacity with `psa_key_derivation_set_capacity()`. This can be done before, in the middle of, or after providing inputs. For some algorithms, this step is mandatory because the output depends on the maximum capacity. - #. To derive a key, call `psa_key_derivation_output_key()`. To derive a byte string for a different purpose, call `psa_key_derivation_output_bytes()`. Successive calls to these functions use successive output bytes calculated by the key derivation algorithm. + #. To derive a key, call `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`. To derive a byte string for a different purpose, call `psa_key_derivation_output_bytes()`. Successive calls to these functions use successive output bytes calculated by the key derivation algorithm. #. Clean up the key derivation operation object with `psa_key_derivation_abort()`. After a successful call to `psa_key_derivation_setup()`, the operation is active, and the application must eventually terminate the operation with a call to `psa_key_derivation_abort()`. @@ -616,7 +616,7 @@ Key derivation functions The capacity of a key derivation is the maximum number of bytes that it can return. Reading :math:`N` bytes of output from a key derivation operation reduces its capacity by at least :math:`N`. The capacity can be reduced by more than :math:`N` in the following situations: - * Calling `psa_key_derivation_output_key()` can reduce the capacity by more than the key size, depending on the type of key being generated. See `psa_key_derivation_output_key()` for details of the key derivation process. + * Calling `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()` can reduce the capacity by more than the key size, depending on the type of key being generated. See `psa_key_derivation_output_key()` for details of the key derivation process. * When the `psa_key_derivation_operation_t` object is operating as a deterministic random bit generator (DBRG), which reduces capacity in whole blocks, even when less than a block is read. .. function:: psa_key_derivation_set_capacity @@ -791,7 +791,7 @@ Key derivation functions Once all inputs steps are completed, the following operations are permitted: * `psa_key_derivation_output_bytes()` --- if each input was either a direct input or a key with usage flag `PSA_KEY_USAGE_DERIVE`. - * `psa_key_derivation_output_key()` --- if the input for step `PSA_KEY_DERIVATION_INPUT_SECRET` or `PSA_KEY_DERIVATION_INPUT_PASSWORD` was a key with usage flag `PSA_KEY_USAGE_DERIVE`, and every other input was either a direct input or a key with usage flag `PSA_KEY_USAGE_DERIVE`. + * `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()` --- if the input for step `PSA_KEY_DERIVATION_INPUT_SECRET` or `PSA_KEY_DERIVATION_INPUT_PASSWORD` was a key with usage flag `PSA_KEY_USAGE_DERIVE`, and every other input was either a direct input or a key with usage flag `PSA_KEY_USAGE_DERIVE`. * `psa_key_derivation_verify_bytes()` --- if each input was either a direct input, a key with usage flag `PSA_KEY_USAGE_DERIVE`, or a key with usage flag `PSA_KEY_USAGE_VERIFY_DERIVATION`. * `psa_key_derivation_verify_key()` --- under the same conditions as `psa_key_derivation_verify_bytes()`. @@ -872,7 +872,9 @@ Key derivation functions .. param:: psa_key_derivation_operation_t * operation The key derivation operation object to read from. .. param:: psa_key_id_t * key - On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. .. return:: psa_status_t .. retval:: PSA_SUCCESS @@ -933,6 +935,106 @@ Key derivation functions For algorithms that take an input step `PSA_KEY_DERIVATION_INPUT_SECRET`, the input to that step must be provided with `psa_key_derivation_input_key()`. Future versions of this specification might include additional restrictions on the derived key based on the attributes and strength of the secret key. + .. note:: + + This function is equivalent to calling `psa_key_derivation_output_key_custom()` with the production parameters `PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` (``custom_data`` is ignored). + +.. function:: psa_key_derivation_output_key_custom + + .. summary:: Derive a key from an ongoing key derivation operation with custom production parameters. + + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. + + The following attributes are required for all keys: + + * The key type. It must not be an asymmetric public key. + * The key size. It must be a valid size for the key type. + + The following attributes must be set for keys used in cryptographic operations: + + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + + If the key type to be created is `PSA_KEY_TYPE_PASSWORD_HASH`, then the permitted-algorithm policy must be either the same as the current operation's algorithm, or `PSA_ALG_NONE`. + * The key usage flags, see :secref:`key-usage-flags`. + + The following attributes must be set for keys that do not use the default volatile lifetime: + + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + + .. param:: psa_key_derivation_operation_t *operation + The key derivation operation object to read from. + .. param:: const psa_custom_key_parameters_t *custom + Customized production parameters for the key derivation. + + When this is `PSA_CUSTOM_KEY_PARAMETERS_INIT` with ``custom_data_length == 0``, + this function is equivalent to `psa_key_derivation_output_key()`. + .. param:: const uint8_t *custom_data + A buffer containing additional variable-sized production parameters. + .. param:: size_t custom_data_length + Length of ``custom_data`` in bytes. + .. param:: mbedtls_svc_key_id_t *key + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the key is persistent, the key material and the key's metadata have been saved to persistent storage. + .. retval:: PSA_ERROR_ALREADY_EXISTS + This is an attempt to create a persistent key, and there is already a persistent key with the given identifier. + .. retval:: PSA_ERROR_INSUFFICIENT_DATA + There was not enough data to create the desired key. In this case, the following occurs: + + * No key is generated. + * The operation's capacity is set to zero. + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + * The production parameters are not supported by the implementation. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * The key type is invalid, or is an asymmetric public key type. + * The key type is `PSA_KEY_TYPE_PASSWORD_HASH`, and the permitted-algorithm policy is not the same as the current operation's algorithm. + * The key size is not valid for the key type. Implementations must reject an attempt to derive a key of size ``0``. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The production parameters are invalid. + .. retval:: PSA_ERROR_NOT_PERMITTED + The following conditions can result in this error: + + * The `PSA_KEY_DERIVATION_INPUT_SECRET` input step was neither provided through a key, nor the result of a key agreement. + * One of the inputs was a key whose policy did not permit `PSA_KEY_USAGE_DERIVE`. + * The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_BAD_STATE + The following conditions can result in this error: + + * The operation state is not valid: it must be active, with all required input steps complete. + * The library requires initializing by a call to `psa_crypto_init()`. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + + Use this function to provide explicit production parameters when deriving a key. + See the description of `psa_key_derivation_output_key()` for the operation of this function with the default production parameters. + + See the documentation of `psa_custom_key_parameters_t` for a list of non-default production parameters. See the key type definitions in :secref:`key-types` for details of the custom production parameters used for key derivation. + .. function:: psa_key_derivation_verify_bytes .. summary:: @@ -1005,7 +1107,7 @@ Key derivation functions A key of type `PSA_KEY_TYPE_PASSWORD_HASH` containing the expected output. The key must permit the usage `PSA_KEY_USAGE_VERIFY_DERIVATION`, and the permitted algorithm must match the operation's algorithm. - The value of this key is typically computed by a previous call to psa_key_derivation_output_key(). + The value of this key is typically computed by a previous call to `psa_key_derivation_output_key()` or `psa_key_derivation_output_key_custom()`. .. return:: psa_status_t .. retval:: PSA_SUCCESS diff --git a/doc/crypto/api/ops/rng.rst b/doc/crypto/api/ops/rng.rst index 86d7022b..ffb2202c 100644 --- a/doc/crypto/api/ops/rng.rst +++ b/doc/crypto/api/ops/rng.rst @@ -38,4 +38,4 @@ Random number generation This function **can** fail! Callers MUST check the return status and MUST NOT use the content of the output buffer if the return status is not :code:`PSA_SUCCESS`. .. note:: - To generate a key, use `psa_generate_key()` instead. + To generate a random key, use `psa_generate_key()` or `psa_generate_key_custom()` instead. diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index c9c0cd98..d49fae64 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -21,6 +21,9 @@ Changes to the API * Added `PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE` to evaluate the export buffer size for any asymmetric key pair or public key. +* Add extended key generation and derivation functions, `psa_generate_key_custom()` and `psa_key_derivation_output_key_custom()`, that accept additional parameters to control the key creation process. +* Define a key production parameter to select a non-default exponent for RSA key generation. + Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/crypto/overview/functionality.rst b/doc/crypto/overview/functionality.rst index 7be012c7..9de78add 100644 --- a/doc/crypto/overview/functionality.rst +++ b/doc/crypto/overview/functionality.rst @@ -48,7 +48,9 @@ Keys are created using one of the *key creation functions*: * `psa_import_key()` * `psa_generate_key()` +* `psa_generate_key_custom()` * `psa_key_derivation_output_key()` +* `psa_key_derivation_output_key_custom()` * `psa_key_agreement()` * `psa_pake_get_shared_key()` * `psa_copy_key()`