Add generator API

Add an API for byte generators: psa_crypto_generator_t,
PSA_CRYPTO_GENERATOR_INIT, psa_crypto_generator_init,
psa_get_generator_capacity, psa_generator_read,
psa_generator_import_key, psa_generator_abort.

This commit does not yet implement any generator algorithm, it only
provides the framework. This code may not compile with -Wunused.
diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index 8ac817a..4dbbded 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -285,12 +285,18 @@
  * depend on the validity of the padding. */
 #define PSA_ERROR_INVALID_PADDING       ((psa_status_t)16)
 
+/** The generator has insufficient capacity left.
+ *
+ * Once a function returns this error, attempts to read from the
+ * generator will always return this error. */
+#define PSA_ERROR_INSUFFICIENT_CAPACITY ((psa_status_t)17)
+
 /** An error occurred that does not correspond to any defined
  * failure cause.
  *
  * Implementations may use this error code if none of the other standard
  * error codes are applicable. */
-#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)17)
+#define PSA_ERROR_UNKNOWN_ERROR         ((psa_status_t)18)
 
 /**
  * \brief Library initialization.
@@ -2440,6 +2446,175 @@
 
 /**@}*/
 
+/** \defgroup generation Generators
+ * @{
+ */
+
+/** The type of the state data structure for generators.
+ *
+ * Before calling any function on a generator, the application must
+ * initialize it by any of the following means:
+ * - Set the structure to all-bits-zero, for example:
+ *   \code
+ *   psa_crypto_generator_t generator;
+ *   memset(&generator, 0, sizeof(generator));
+ *   \endcode
+ * - Initialize the structure to logical zero values, for example:
+ *   \code
+ *   psa_crypto_generator_t generator = {0};
+ *   \endcode
+ * - Initialize the structure to the initializer #PSA_CRYPTO_GENERATOR_INIT,
+ *   for example:
+ *   \code
+ *   psa_crypto_generator_t generator = PSA_CRYPTO_GENERATOR_INIT;
+ *   \endcode
+ * - Assign the result of the function psa_crypto_generator_init()
+ *   to the structure, for example:
+ *   \code
+ *   psa_crypto_generator_t generator;
+ *   generator = psa_crypto_generator_init();
+ *   \endcode
+ *
+ * This is an implementation-defined \c struct. Applications should not
+ * make any assumptions about the content of this structure except
+ * as directed by the documentation of a specific implementation.
+ */
+typedef struct psa_crypto_generator_s psa_crypto_generator_t;
+
+/** \def PSA_CRYPTO_GENERATOR_INIT
+ *
+ * This macro returns a suitable initializer for a generator object
+ * of type #psa_crypto_generator_t.
+ */
+#ifdef __DOXYGEN_ONLY__
+/* This is an example definition for documentation purposes.
+ * Implementations should define a suitable value in `crypto_struct.h`.
+ */
+#define PSA_CRYPTO_GENERATOR_INIT {0}
+#endif
+
+/** Return an initial value for a generator object.
+ */
+static psa_crypto_generator_t psa_crypto_generator_init(void);
+
+/** Retrieve the current capacity of a generator.
+ *
+ * The capacity of a generator is the maximum number of bytes that it can
+ * return. Reading *N* bytes from a generator reduces its capacity by *N*.
+ *
+ * \param[in] generator     The generator to query.
+ * \param[out] capacity     On success, the capacity of the generator.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ */
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity);
+
+/** Read some data from a generator.
+ *
+ * This function reads and returns a sequence of bytes from a generator.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * \param[in,out] generator The generator object to read from.
+ * \param[out] output       Buffer where the generator output will be
+ *                          written.
+ * \param output_length     Number of bytes to output.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ *                          There were fewer than \p output_length bytes
+ *                          in the generator. Note that in this case, no
+ *                          output is written to the output buffer.
+ *                          The generator's capacity is set to 0, thus
+ *                          subsequent calls to this function will not
+ *                          succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_read(psa_crypto_generator_t *generator,
+                                uint8_t *output,
+                                size_t output_length);
+
+/** Create a symmetric key from data read from a generator.
+ *
+ * This function reads a sequence of bytes from a generator and imports
+ * these bytes as a key.
+ * The data that is read is discarded from the generator. The generator's
+ * capacity is decreased by the number of bytes read.
+ *
+ * This function is equivalent to calling #psa_generator_read and
+ * passing the resulting output to #psa_import_key, but
+ * if the implementation provides an isolation boundary then
+ * the key material is not exposed outside the isolation boundary.
+ *
+ * \param key               Slot where the key will be stored. This must be a
+ *                          valid slot for a key of the chosen type. It must
+ *                          be unoccupied.
+ * \param type              Key type (a \c PSA_KEY_TYPE_XXX value).
+ *                          This must be a symmetric key type.
+ * \param bits              Key size in bits.
+ * \param[in,out] generator The generator object to read from.
+ *
+ * \retval PSA_SUCCESS
+ *         Success.
+ * \retval PSA_ERROR_INSUFFICIENT_CAPACITY
+ *                          There were fewer than \p output_length bytes
+ *                          in the generator. Note that in this case, no
+ *                          output is written to the output buffer.
+ *                          The generator's capacity is set to 0, thus
+ *                          subsequent calls to this function will not
+ *                          succeed, even with a smaller output buffer.
+ * \retval PSA_ERROR_NOT_SUPPORTED
+ *         The key type or key size is not supported, either by the
+ *         implementation in general or in this particular slot.
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_INVALID_ARGUMENT
+ *         The key slot is invalid.
+ * \retval PSA_ERROR_OCCUPIED_SLOT
+ *         There is already a key in the specified slot.
+ * \retval PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval PSA_ERROR_INSUFFICIENT_STORAGE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_import_key(psa_key_slot_t key,
+                                      psa_key_type_t type,
+                                      size_t bits,
+                                      psa_crypto_generator_t *generator);
+
+/** Abort a generator.
+ *
+ * Once a generator has been aborted, its capacity is zero.
+ * Aborting a generator frees all associated resources except for the
+ * \c generator structure itself.
+ *
+ * This function may be called at any time as long as the generator
+ * object has been initialized to #PSA_CRYPTO_GENERATOR_INIT, to
+ * psa_crypto_generator_init() or a zero value. In particular, it is valid
+ * to call psa_generator_abort() twice, or to call psa_generator_abort()
+ * on a generator that has not been set up.
+ *
+ * Once aborted, the generator object may be called.
+ *
+ * \param[in,out] generator    The generator to abort.
+ *
+ * \retval PSA_SUCCESS
+ * \retval PSA_ERROR_BAD_STATE
+ * \retval PSA_ERROR_COMMUNICATION_FAILURE
+ * \retval PSA_ERROR_HARDWARE_FAILURE
+ * \retval PSA_ERROR_TAMPERING_DETECTED
+ */
+psa_status_t psa_generator_abort(psa_crypto_generator_t *generator);
+
+/**@}*/
+
 /** \defgroup generation Key generation
  * @{
  */
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 85c9974..27a9f1e 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -130,6 +130,27 @@
     } ctx;
 };
 
+struct psa_crypto_generator_s
+{
+    psa_algorithm_t alg;
+    size_t capacity;
+    union
+    {
+        struct
+        {
+            uint8_t *data;
+            size_t size;
+        } buffer;
+    } ctx;
+};
+
+#define PSA_CRYPTO_GENERATOR_INIT {0, 0, {{0, 0}}}
+static inline struct psa_crypto_generator_s psa_crypto_generator_init( void )
+{
+    const struct psa_crypto_generator_s v = PSA_CRYPTO_GENERATOR_INIT;
+    return( v );
+}
+
 struct psa_key_policy_s
 {
     psa_key_usage_t usage;
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 67536f2..6cc42c6 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -2988,7 +2988,105 @@
 
 
 /****************************************************************/
-/* Key generation */
+/* Generators */
+/****************************************************************/
+
+psa_status_t psa_generator_abort( psa_crypto_generator_t *generator )
+{
+    psa_status_t status = PSA_SUCCESS;
+    if( generator->alg == 0 )
+    {
+        /* The object has (apparently) been initialized but it is not
+         * in use. It's ok to call abort on such an object, and there's
+         * nothing to do. */
+    }
+    else
+    {
+        status = PSA_ERROR_BAD_STATE;
+    }
+    memset( generator, 0, sizeof( *generator ) );
+    return( status );
+}
+
+
+psa_status_t psa_get_generator_capacity(const psa_crypto_generator_t *generator,
+                                        size_t *capacity)
+{
+    *capacity = generator->capacity;
+    return( PSA_SUCCESS );
+}
+
+psa_status_t psa_generator_read( psa_crypto_generator_t *generator,
+                                 uint8_t *output,
+                                 size_t output_length )
+{
+    psa_status_t status;
+
+    if( output_length > generator->capacity )
+    {
+        generator->capacity = 0;
+        /* Go through the error path to wipe all confidential data now
+         * that the generator object is useless. */
+        status = PSA_ERROR_INSUFFICIENT_CAPACITY;
+        goto exit;
+    }
+    if( output_length == 0 &&
+        generator->capacity == 0 && generator->alg == 0 )
+    {
+        /* Edge case: this is a blank or finished generator, and 0
+         * bytes were requested. The right error in this case could
+         * be either INSUFFICIENT_CAPACITY or BAD_STATE. Return
+         * INSUFFICIENT_CAPACITY, which is right for a finished
+         * generator, for consistency with the case when
+         * output_length > 0. */
+        return( PSA_ERROR_INSUFFICIENT_CAPACITY );
+    }
+    generator->capacity -= output_length;
+
+    {
+        return( PSA_ERROR_BAD_STATE );
+    }
+
+exit:
+    if( status != PSA_SUCCESS )
+    {
+        psa_generator_abort( generator );
+        memset( output, '!', output_length );
+    }
+    return( status );
+}
+
+psa_status_t psa_generator_import_key( psa_key_slot_t key,
+                                       psa_key_type_t type,
+                                       size_t bits,
+                                       psa_crypto_generator_t *generator )
+{
+    uint8_t *data = NULL;
+    size_t bytes = PSA_BITS_TO_BYTES( bits );
+    psa_status_t status;
+
+    if( ! key_type_is_raw_bytes( type ) )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    if( bits % 8 != 0 )
+        return( PSA_ERROR_INVALID_ARGUMENT );
+    data = mbedtls_calloc( 1, bytes );
+    if( data == NULL )
+        return( PSA_ERROR_INSUFFICIENT_MEMORY );
+
+    status = psa_generator_read( generator, data, bytes );
+    if( status != PSA_SUCCESS )
+        goto exit;
+    status = psa_import_key( key, type, data, bytes );
+
+exit:
+    mbedtls_free( data );
+    return( status );
+}
+
+
+
+/****************************************************************/
+/* Random generation */
 /****************************************************************/
 
 psa_status_t psa_generate_random( uint8_t *output,