Remove domain parameters from the official API

Move psa_get_key_domain_parameters() and
psa_set_key_domain_parameters() out of the official API and declare
them to be implementation-specific extensions.

Expand the documentation of psa_set_key_domain_parameters() a bit to
explain how domain parameters are used.

Remove all mentions of domain parameters from the documentation of API
functions. This leaves DH and DSA effectively unusable.
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 84026c9..487fce8 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
@@ -910,9 +813,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 +836,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.
@@ -3529,20 +3429,6 @@
  * 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 45655dd..5016ba8 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -444,6 +444,147 @@
 
 /**@}*/
 
+
+/** \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 cab896e..11c73a9 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 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)
 {