Move the definition of psa_key_attributes_t to crypto_types.h

psa_key_attributes_t is used in the SE driver HAL, so it must be
defined in a common header, not in the API-only header crypto.h.
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 3036d17..ea7d18d 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -93,117 +93,10 @@
 
 /**@}*/
 
-/** \defgroup attributes Key attributes
+/** \addtogroup attributes
  * @{
  */
 
-/** The type of a structure containing key attributes.
- *
- * This is an opaque structure that can represent the metadata of a key
- * object. Metadata that can be stored in attributes includes:
- * - The location of the key in storage, indicated by its key identifier
- *   and its lifetime.
- * - The key's policy, comprising usage flags and a specification of
- *   the permitted algorithm(s).
- * - Information about the key itself: the key type and its size.
- * - Implementations may define additional attributes.
- *
- * The actual key material is not considered an attribute of a key.
- * Key attributes do not contain information that is generally considered
- * highly confidential.
- *
- * An attribute structure can be a simple data structure where each function
- * `psa_set_key_xxx` sets a field and the corresponding function
- * `psa_get_key_xxx` retrieves the value of the corresponding field.
- * However, implementations may report values that are equivalent to the
- * original one, but have a different encoding. For example, an
- * implementation may use a more compact representation for types where
- * many bit-patterns are invalid or not supported, and store all values
- * that it does not support as a special marker value. In such an
- * implementation, after setting an invalid value, the corresponding
- * get function returns an invalid value which may not be the one that
- * was originally stored.
- *
- * An attribute structure may contain references to auxiliary resources,
- * for example pointers to allocated memory or indirect references to
- * pre-calculated values. In order to free such resources, the application
- * must call psa_reset_key_attributes(). As an exception, calling
- * psa_reset_key_attributes() on an attribute structure is optional if
- * the structure has only been modified by the following functions
- * since it was initialized or last reset with psa_reset_key_attributes():
- * - psa_set_key_id()
- * - psa_set_key_lifetime()
- * - psa_set_key_type()
- * - psa_set_key_bits()
- * - psa_set_key_usage_flags()
- * - psa_set_key_algorithm()
- *
- * Before calling any function on a key attribute structure, the application
- * must initialize it by any of the following means:
- * - Set the structure to all-bits-zero, for example:
- *   \code
- *   psa_key_attributes_t attributes;
- *   memset(&attributes, 0, sizeof(attributes));
- *   \endcode
- * - Initialize the structure to logical zero values, for example:
- *   \code
- *   psa_key_attributes_t attributes = {0};
- *   \endcode
- * - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
- *   for example:
- *   \code
- *   psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
- *   \endcode
- * - Assign the result of the function psa_key_attributes_init()
- *   to the structure, for example:
- *   \code
- *   psa_key_attributes_t attributes;
- *   attributes = psa_key_attributes_init();
- *   \endcode
- *
- * A freshly initialized attribute structure contains the following
- * values:
- *
- * - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
- * - key identifier: unspecified.
- * - type: \c 0.
- * - key size: \c 0.
- * - usage flags: \c 0.
- * - algorithm: \c 0.
- *
- * A typical sequence to create a key is as follows:
- * -# Create and initialize an attribute structure.
- * -# If the key is persistent, call psa_set_key_id().
- *    Also call psa_set_key_lifetime() to place the key in a non-default
- *    location.
- * -# Set the key policy with psa_set_key_usage_flags() and
- *    psa_set_key_algorithm().
- * -# Set the key type with psa_set_key_type().
- *    Skip this step if copying an existing key with psa_copy_key().
- * -# When generating a random key with psa_generate_key() or deriving a key
- *    with psa_key_derivation_output_key(), set the desired key size with
- *    psa_set_key_bits().
- * -# Call a key creation function: psa_import_key(), psa_generate_key(),
- *    psa_key_derivation_output_key() or psa_copy_key(). This function reads
- *    the attribute structure, creates a key with these attributes, and
- *    outputs a handle to the newly created key.
- * -# The attribute structure is now no longer necessary.
- *    You may call psa_reset_key_attributes(), although this is optional
- *    with the workflow presented here because the attributes currently
- *    defined in this specification do not require any additional resources
- *    beyond the structure itself.
- *
- * A typical sequence to query a key's attributes is as follows:
- * -# Call psa_get_key_attributes().
- * -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
- *    you are interested in.
- * -# Call psa_reset_key_attributes() to free any resources that may be
- *    used by the attribute structure.
- *
- * Once a key has been created, it is impossible to change its attributes.
- */
-typedef struct psa_key_attributes_s psa_key_attributes_t;
-
 /** \def PSA_KEY_ATTRIBUTES_INIT
  *
  * This macro returns a suitable initializer for a key attribute structure
diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h
index 3f3d7ca..57d077c 100644
--- a/include/psa/crypto_se_driver.h
+++ b/include/psa/crypto_se_driver.h
@@ -782,10 +782,6 @@
  */
 /**@{*/
 
-/* This type is documented in crypto.h. As far as drivers are concerned,
- * this is an opaque type. */
-typedef struct psa_key_attributes_s psa_key_attributes_t;
-
 /** \brief A function that allocates a slot for a key.
  *
  * \param[in,out] drv_context       The driver context structure.
diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h
index 7f0f38c..1944be4 100644
--- a/include/psa/crypto_types.h
+++ b/include/psa/crypto_types.h
@@ -133,6 +133,119 @@
 
 /**@}*/
 
+/** \defgroup attributes Key attributes
+ * @{
+ */
+
+/** The type of a structure containing key attributes.
+ *
+ * This is an opaque structure that can represent the metadata of a key
+ * object. Metadata that can be stored in attributes includes:
+ * - The location of the key in storage, indicated by its key identifier
+ *   and its lifetime.
+ * - The key's policy, comprising usage flags and a specification of
+ *   the permitted algorithm(s).
+ * - Information about the key itself: the key type and its size.
+ * - Implementations may define additional attributes.
+ *
+ * The actual key material is not considered an attribute of a key.
+ * Key attributes do not contain information that is generally considered
+ * highly confidential.
+ *
+ * An attribute structure can be a simple data structure where each function
+ * `psa_set_key_xxx` sets a field and the corresponding function
+ * `psa_get_key_xxx` retrieves the value of the corresponding field.
+ * However, implementations may report values that are equivalent to the
+ * original one, but have a different encoding. For example, an
+ * implementation may use a more compact representation for types where
+ * many bit-patterns are invalid or not supported, and store all values
+ * that it does not support as a special marker value. In such an
+ * implementation, after setting an invalid value, the corresponding
+ * get function returns an invalid value which may not be the one that
+ * was originally stored.
+ *
+ * An attribute structure may contain references to auxiliary resources,
+ * for example pointers to allocated memory or indirect references to
+ * pre-calculated values. In order to free such resources, the application
+ * must call psa_reset_key_attributes(). As an exception, calling
+ * psa_reset_key_attributes() on an attribute structure is optional if
+ * the structure has only been modified by the following functions
+ * since it was initialized or last reset with psa_reset_key_attributes():
+ * - psa_set_key_id()
+ * - psa_set_key_lifetime()
+ * - psa_set_key_type()
+ * - psa_set_key_bits()
+ * - psa_set_key_usage_flags()
+ * - psa_set_key_algorithm()
+ *
+ * Before calling any function on a key attribute structure, the application
+ * must initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ *   \code
+ *   psa_key_attributes_t attributes;
+ *   memset(&attributes, 0, sizeof(attributes));
+ *   \endcode
+ * - Initialize the structure to logical zero values, for example:
+ *   \code
+ *   psa_key_attributes_t attributes = {0};
+ *   \endcode
+ * - Initialize the structure to the initializer #PSA_KEY_ATTRIBUTES_INIT,
+ *   for example:
+ *   \code
+ *   psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ *   \endcode
+ * - Assign the result of the function psa_key_attributes_init()
+ *   to the structure, for example:
+ *   \code
+ *   psa_key_attributes_t attributes;
+ *   attributes = psa_key_attributes_init();
+ *   \endcode
+ *
+ * A freshly initialized attribute structure contains the following
+ * values:
+ *
+ * - lifetime: #PSA_KEY_LIFETIME_VOLATILE.
+ * - key identifier: unspecified.
+ * - type: \c 0.
+ * - key size: \c 0.
+ * - usage flags: \c 0.
+ * - algorithm: \c 0.
+ *
+ * A typical sequence to create a key is as follows:
+ * -# Create and initialize an attribute structure.
+ * -# If the key is persistent, call psa_set_key_id().
+ *    Also call psa_set_key_lifetime() to place the key in a non-default
+ *    location.
+ * -# Set the key policy with psa_set_key_usage_flags() and
+ *    psa_set_key_algorithm().
+ * -# Set the key type with psa_set_key_type().
+ *    Skip this step if copying an existing key with psa_copy_key().
+ * -# When generating a random key with psa_generate_key() or deriving a key
+ *    with psa_key_derivation_output_key(), set the desired key size with
+ *    psa_set_key_bits().
+ * -# Call a key creation function: psa_import_key(), psa_generate_key(),
+ *    psa_key_derivation_output_key() or psa_copy_key(). This function reads
+ *    the attribute structure, creates a key with these attributes, and
+ *    outputs a handle to the newly created key.
+ * -# The attribute structure is now no longer necessary.
+ *    You may call psa_reset_key_attributes(), although this is optional
+ *    with the workflow presented here because the attributes currently
+ *    defined in this specification do not require any additional resources
+ *    beyond the structure itself.
+ *
+ * A typical sequence to query a key's attributes is as follows:
+ * -# Call psa_get_key_attributes().
+ * -# Call `psa_get_key_xxx` functions to retrieve the attribute(s) that
+ *    you are interested in.
+ * -# Call psa_reset_key_attributes() to free any resources that may be
+ *    used by the attribute structure.
+ *
+ * Once a key has been created, it is impossible to change its attributes.
+ */
+typedef struct psa_key_attributes_s psa_key_attributes_t;
+
+/**@}*/
+
 /** \defgroup derivation Key derivation
  * @{
  */