diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 84026c91c8..487fce8222 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -105,8 +105,7 @@ psa_status_t psa_crypto_init(void); * 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, the key size, and - * for some key type additional domain parameters. + * - 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. @@ -167,7 +166,7 @@ psa_status_t psa_crypto_init(void); * * - lifetime: #PSA_KEY_LIFETIME_VOLATILE. * - key identifier: unspecified. - * - type: \c 0, with no domain parameters. + * - type: \c 0. * - key size: \c 0. * - usage flags: \c 0. * - algorithm: \c 0. @@ -179,8 +178,7 @@ psa_status_t psa_crypto_init(void); * 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(). If the key type requires - * domain parameters, call psa_set_key_domain_parameters() instead. + * -# 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_random_key() or deriving a key * with psa_key_derivation_output_key(), set the desired key size with @@ -189,11 +187,11 @@ psa_status_t psa_crypto_init(void); * 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. If you called - * psa_set_key_domain_parameters() earlier, you must call - * psa_reset_key_attributes() to free any resources used by the - * domain parameters. Otherwise calling psa_reset_key_attributes() - * is optional. + * -# 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(). @@ -349,10 +347,7 @@ static psa_algorithm_t psa_get_key_algorithm( /** Declare the type of a key. * - * If a type requires domain parameters, you must call - * psa_set_key_domain_parameters() instead of this function. - * - * This function overwrites any key type and domain parameters + * This function overwrites any key type * previously set in \p attributes. * * This function may be declared as `static` (i.e. without external @@ -403,97 +398,6 @@ static psa_key_type_t psa_get_key_type(const psa_key_attributes_t *attributes); */ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); -/** - * \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. - * The format for the required domain parameters varies by the key type. - * - * - For RSA keys (#PSA_KEY_TYPE_RSA_PUBLIC_KEY or #PSA_KEY_TYPE_RSA_KEYPAIR), - * 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_KEYPAIR), - * 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 or - * #PSA_KEY_TYPE_DH_KEYPAIR), 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. - * - * \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(). - * - * \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); - /** Retrieve the attributes of a key. * * This function first resets the attribute structure as with @@ -617,9 +521,8 @@ psa_status_t psa_close_key(psa_key_handle_t handle); * \param[out] handle On success, a handle to the newly created key. * \c 0 on failure. * \param[in] data Buffer containing the key data. The content of this - * buffer is interpreted according to the type and, - * if applicable, domain parameters declared in - * \p attributes. + * buffer is interpreted according to the type declared + * in \p attributes. * All implementations must support at least the format * described in the documentation * of psa_export_key() or psa_export_public_key() for @@ -910,9 +813,6 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, * - The key type and size may be 0. If either is * nonzero, it must match the corresponding * attribute of the source key. - * - If \p attributes contains domain parameters, - * they must match the domain parameters of - * the source key. * - The key location (the lifetime and, for * persistent keys, the key identifier) is * used directly. @@ -936,7 +836,7 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, * The policy constraints on the source and specified in * \p attributes are incompatible. * \retval #PSA_ERROR_INVALID_ARGUMENT - * \p attributes specifies a key type, domain parameters or key size + * \p attributes specifies a key type or key size * which does not match the attributes of the source key. * \retval #PSA_ERROR_NOT_PERMITTED * The source key does not have the #PSA_KEY_USAGE_COPY usage flag. @@ -3529,20 +3429,6 @@ psa_status_t psa_generate_random(uint8_t *output, * The key is generated randomly. * Its location, policy, type and size are taken from \p attributes. * - * If the type requires additional domain parameters, these are taken - * from \p attributes as well. The following types use domain parameters: - * - When generating an RSA key (#PSA_KEY_TYPE_RSA_KEYPAIR), - * the default public exponent is 65537. This value is used if - * \p attributes was set with psa_set_key_type() or by passing an empty - * byte string as domain parameters to psa_set_key_domain_parameters(). - * If psa_set_key_domain_parameters() was used to set a non-empty - * domain parameter string in \p attributes, this string is read as - * a big-endian integer which is used as the public exponent. - * - When generating a DSA key (#PSA_KEY_TYPE_DSA_KEYPAIR) or a - * Diffie-Hellman key (#PSA_KEY_TYPE_DH_KEYPAIR), the domain parameters - * from \p attributes are interpreted as described for - * psa_set_key_domain_parameters(). - * * \param[in] attributes The attributes for the new key. * \param[out] handle On success, a handle to the newly created key. * \c 0 on failure. diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 45655ddfc4..5016ba87ca 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -444,6 +444,147 @@ psa_status_t psa_generate_random_key_to_handle(psa_key_handle_t handle, /**@}*/ + +/** \addtogroup attributes + * @{ + */ + +/** + * \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_KEYPAIR), + * 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_KEYPAIR), + * 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 or + * #PSA_KEY_TYPE_DH_KEYPAIR), 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 either 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 } #endif diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h index cab896e8a4..11c73a9de8 100644 --- a/include/psa/crypto_sizes.h +++ b/include/psa/crypto_sizes.h @@ -695,36 +695,4 @@ PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type) ? PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(key_bits) : \ 0) -/** 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. - * - * \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 either 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*/) - #endif /* PSA_CRYPTO_SIZES_H */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 01d3069bf8..885d90888d 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -331,6 +331,13 @@ static inline psa_algorithm_t psa_get_key_algorithm( return( attributes->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) {