Merge pull request #112 from gilles-peskine-arm/psa-remove_domain_parameters
Remove domain parameters from API 1.0
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 84026c9..c6a13ac 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -105,8 +105,7 @@
* 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 @@
*
* - 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 @@
* 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_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 @@
/** 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 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 @@
* \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
@@ -738,10 +641,6 @@
* coefficient INTEGER, -- (inverse of q) mod p
* }
* ```
- * - For DSA private keys (#PSA_KEY_TYPE_DSA_KEYPAIR), the 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).
* - For elliptic curve key pairs (key types for which
* #PSA_KEY_TYPE_IS_ECC_KEYPAIR is true), the format is
* a representation of the private value as a `ceiling(m/8)`-byte string
@@ -753,7 +652,8 @@
* and `PSA_ECC_CURVE_BRAINPOOL_PXXX`).
* This is the content of the `privateKey` field of the `ECPrivateKey`
* format defined by RFC 5915.
- * - For Diffie-Hellman key exchange key pairs (#PSA_KEY_TYPE_DH_KEYPAIR), the
+ * - For Diffie-Hellman key exchange key pairs (key types for which
+ * #PSA_KEY_TYPE_IS_DH_KEYPAIR is true), the
* 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).
@@ -822,11 +722,8 @@
* - The byte 0x04;
* - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
* - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
- * - For DSA public keys (#PSA_KEY_TYPE_DSA_PUBLIC_KEY), the 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.
- * - For Diffie-Hellman key exchange public keys (#PSA_KEY_TYPE_DH_PUBLIC_KEY),
+ * - For Diffie-Hellman key exchange public keys (key types for which
+ * #PSA_KEY_TYPE_IS_DH_PUBLIC_KEY is true),
* the 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.
@@ -910,9 +807,6 @@
* - 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 +830,7 @@
* 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.
@@ -3353,8 +3247,8 @@
* discard the first 8 bytes, use the next 8 bytes as the first key,
* and continue reading output from the operation to derive the other
* two keys).
- * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEYPAIR),
- * DSA keys (#PSA_KEY_TYPE_DSA_KEYPAIR), and
+ * - Finite-field Diffie-Hellman keys (#PSA_KEY_TYPE_DH_KEYPAIR(\c group)
+ * where \c group designates any Diffie-Hellman group) and
* ECC keys on a Weierstrass elliptic curve
* (#PSA_KEY_TYPE_ECC_KEYPAIR(\c curve) where \c curve designates a
* Weierstrass curve).
@@ -3529,19 +3423,12 @@
* 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().
+ * The following type-specific considerations apply:
+ * - For RSA keys (#PSA_KEY_TYPE_RSA_KEYPAIR),
+ * the public exponent is 65537.
+ * The modulus is a product of two probabilistic primes
+ * between 2^{n-1} and 2^n where n is the bit size specified in the
+ * attributes.
*
* \param[in] attributes The attributes for the new key.
* \param[out] handle On success, a handle to the newly created key.
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 45655dd..4ffd858 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -444,6 +444,248 @@
/**@}*/
+
+/** \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_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)
+
+#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_KEYPAIR(#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_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(#PSA_DH_GROUP_CUSTOM) or
+ * #PSA_KEY_TYPE_DH_KEYPAIR(#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
}
#endif
diff --git a/include/psa/crypto_sizes.h b/include/psa/crypto_sizes.h
index cab896e..d7eb482 100644
--- a/include/psa/crypto_sizes.h
+++ b/include/psa/crypto_sizes.h
@@ -447,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.
@@ -478,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.
@@ -509,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.
@@ -680,7 +680,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.
@@ -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 01d3069..885d908 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -331,6 +331,13 @@
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)
{
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index ced42de..02c2678 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -68,6 +68,9 @@
/** 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
diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h
index c54fc9a..bab7063 100644
--- a/include/psa/crypto_values.h
+++ b/include/psa/crypto_values.h
@@ -419,14 +419,6 @@
#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)
-
#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_CURVE_MASK ((psa_key_type_t)0x0000ffff)
@@ -492,14 +484,45 @@
#define PSA_ECC_CURVE_CURVE25519 ((psa_ecc_curve_t) 0x001d)
#define PSA_ECC_CURVE_CURVE448 ((psa_ecc_curve_t) 0x001e)
-/** Diffie-Hellman key exchange public key. */
-#define PSA_KEY_TYPE_DH_PUBLIC_KEY ((psa_key_type_t)0x60040000)
-/** Diffie-Hellman key exchange key pair (private and public key). */
-#define PSA_KEY_TYPE_DH_KEYPAIR ((psa_key_type_t)0x70040000)
-/** Whether a key type is a Diffie-Hellman key exchange key (pair or
- * public-only). */
-#define PSA_KEY_TYPE_IS_DH(type) \
- (PSA_KEY_TYPE_PUBLIC_KEY_OF_KEYPAIR(type) == PSA_KEY_TYPE_DH_PUBLIC_KEY)
+#define PSA_KEY_TYPE_DH_PUBLIC_KEY_BASE ((psa_key_type_t)0x60040000)
+#define PSA_KEY_TYPE_DH_KEYPAIR_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_KEYPAIR(group) \
+ (PSA_KEY_TYPE_DH_KEYPAIR_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_KEYPAIR(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_KEYPAIR(type) \
+ (((type) & ~PSA_KEY_TYPE_DH_GROUP_MASK) == \
+ PSA_KEY_TYPE_DH_KEYPAIR_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.
*
@@ -667,7 +690,6 @@
*
* 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:
@@ -1028,51 +1050,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 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))
-
#define PSA_ALG_ECDSA_BASE ((psa_algorithm_t)0x10060000)
/** ECDSA signature with hashing.
*
@@ -1156,7 +1133,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.
*
diff --git a/programs/psa/psa_constant_names.c b/programs/psa/psa_constant_names.c
index 5240b08..73692d0 100644
--- a/programs/psa/psa_constant_names.c
+++ b/programs/psa/psa_constant_names.c
@@ -64,6 +64,7 @@
/* 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,6 +85,24 @@
append(buffer, buffer_size, required_size, ")", 1);
}
+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 *group_name = psa_dh_group_name(group);
+ append(buffer, buffer_size, required_size, string, length);
+ append(buffer, buffer_size, required_size, "(", 1);
+ if (group_name != NULL) {
+ append(buffer, buffer_size, required_size,
+ group_name, strlen(group_name));
+ } else {
+ append_integer(buffer, buffer_size, required_size,
+ "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,
@@ -137,6 +156,23 @@
}
}
+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",
@@ -145,6 +181,7 @@
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");
@@ -188,6 +225,7 @@
typedef enum {
TYPE_ALGORITHM,
TYPE_ECC_CURVE,
+ TYPE_DH_GROUP,
TYPE_KEY_TYPE,
TYPE_KEY_USAGE,
} unsigned_value_type;
@@ -216,6 +254,10 @@
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);
@@ -252,6 +294,9 @@
} 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);
diff --git a/scripts/generate_psa_constants.py b/scripts/generate_psa_constants.py
index dac6003..ab7f134 100755
--- a/scripts/generate_psa_constants.py
+++ b/scripts/generate_psa_constants.py
@@ -22,6 +22,14 @@
}
}
+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) {
@@ -145,6 +153,12 @@
PSA_KEY_TYPE_GET_CURVE(type));
} else '''
+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 '''
+
algorithm_from_hash_template = '''if (%(tester)s(core_alg)) {
append(&buffer, buffer_size, &required_size,
"%(builder)s(", %(builder_length)s + 1);
@@ -169,7 +183,9 @@
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()
@@ -206,8 +222,12 @@
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']:
@@ -265,6 +285,10 @@
return '\n '.join(map(self.make_return_case,
sorted(self.ecc_curves)))
+ 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)))
@@ -274,11 +298,21 @@
'builder_length': len(builder),
'tester': tester}
- def make_key_type_code(self):
+ def make_key_type_from_group_code(self, 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
return ''.join([make(k, d[k]) for k in sorted(d.keys())])
+ 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)))
@@ -309,8 +343,10 @@
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_key_type_code()
+ 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()
diff --git a/tests/scripts/test_psa_constant_names.py b/tests/scripts/test_psa_constant_names.py
index 421cf4e..cbe68b1 100755
--- a/tests/scripts/test_psa_constant_names.py
+++ b/tests/scripts/test_psa_constant_names.py
@@ -58,6 +58,7 @@
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
@@ -74,6 +75,7 @@
'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,
}
@@ -94,6 +96,7 @@
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..'''
@@ -184,6 +187,8 @@
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
@@ -299,6 +304,7 @@
for type, 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, names)
diff --git a/tests/suites/test_suite_psa_crypto_metadata.data b/tests/suites/test_suite_psa_crypto_metadata.data
index 94b80ac..165b866 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.data
+++ b/tests/suites/test_suite_psa_crypto_metadata.data
@@ -454,3 +454,19 @@
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
+
diff --git a/tests/suites/test_suite_psa_crypto_metadata.function b/tests/suites/test_suite_psa_crypto_metadata.function
index e1eb1c5..81b2937 100644
--- a/tests/suites/test_suite_psa_crypto_metadata.function
+++ b/tests/suites/test_suite_psa_crypto_metadata.function
@@ -49,6 +49,7 @@
#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 ) )
@@ -91,6 +92,7 @@
TEST_CLASSIFICATION_MACRO( KEY_TYPE_IS_KEYPAIR, 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 ),
@@ -102,6 +104,12 @@
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_KEYPAIR( type ),
+ ( PSA_KEY_TYPE_IS_DH( type ) &&
+ PSA_KEY_TYPE_IS_KEYPAIR( 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: ;
}
@@ -457,3 +465,22 @@
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_KEYPAIR( 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_KEYPAIR );
+
+ 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 */