Implement multipart AEAD PSA interface
Signed-off-by: Paul Elliott <paul.elliott@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 2583735..6598cf4 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -3214,6 +3214,255 @@
return( status );
}
+/* Set the key for a multipart authenticated encryption operation. */
+psa_status_t psa_aead_encrypt_setup( psa_aead_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg )
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_key_slot_t *slot;
+
+ if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+ return( PSA_ERROR_NOT_SUPPORTED );
+
+ status = psa_get_and_lock_key_slot_with_policy(
+ key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
+
+ if( status != PSA_SUCCESS )
+ {
+ return( status );
+ }
+
+ psa_key_attributes_t attributes = {
+ .core = slot->attr
+ };
+
+ status = psa_driver_wrapper_aead_encrypt_setup( operation,
+ &attributes, slot->key.data,
+ slot->key.bytes, alg );
+
+
+ unlock_status = psa_unlock_key_slot( slot );
+
+ if( unlock_status != PSA_SUCCESS )
+ {
+ return( unlock_status );
+ }
+
+ return( status );
+}
+
+/* Set the key for a multipart authenticated decryption operation. */
+psa_status_t psa_aead_decrypt_setup( psa_aead_operation_t *operation,
+ mbedtls_svc_key_id_t key,
+ psa_algorithm_t alg )
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_key_slot_t *slot;
+
+ if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) )
+ return( PSA_ERROR_NOT_SUPPORTED );
+
+ status = psa_get_and_lock_key_slot_with_policy(
+ key, &slot, PSA_KEY_USAGE_DECRYPT, alg );
+
+ if( status != PSA_SUCCESS )
+ {
+ return( status );
+ }
+
+ psa_key_attributes_t attributes = {
+ .core = slot->attr
+ };
+
+ status = psa_driver_wrapper_aead_decrypt_setup( operation,
+ &attributes, slot->key.data,
+ slot->key.bytes, alg );
+
+
+ unlock_status = psa_unlock_key_slot( slot );
+
+ if( unlock_status != PSA_SUCCESS )
+ {
+ return( unlock_status );
+ }
+
+ return( status );
+}
+
+/* Generate a random nonce / IV for multipart AEAD operation */
+psa_status_t psa_aead_generate_nonce( psa_aead_operation_t *operation,
+ uint8_t *nonce,
+ size_t nonce_size,
+ size_t *nonce_length )
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ size_t required_nonce_size = nonce_size;
+
+ *nonce_length = 0;
+
+ if( !operation->key_set || operation->nonce_set ||
+ operation->ad_started || operation->body_started )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ required_nonce_size = PSA_AEAD_NONCE_LENGTH(operation->key_type, operation->alg);
+
+ if( nonce_size == 0 || nonce_size < required_nonce_size )
+ {
+ return( PSA_ERROR_BUFFER_TOO_SMALL );
+ }
+
+ status = psa_generate_random( nonce, required_nonce_size );
+
+ if( status != PSA_SUCCESS )
+ {
+ return status;
+ }
+
+ status = psa_driver_wrapper_aead_set_nonce( operation, nonce, required_nonce_size );
+
+ if( status == PSA_SUCCESS )
+ {
+ *nonce_length = required_nonce_size;
+ }
+
+ return status;
+}
+
+/* Set the nonce for a multipart authenticated encryption or decryption
+ operation.*/
+psa_status_t psa_aead_set_nonce( psa_aead_operation_t *operation,
+ const uint8_t *nonce,
+ size_t nonce_length )
+{
+ if( !operation->key_set || operation->nonce_set ||
+ operation->ad_started || operation->body_started )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_set_nonce( operation, nonce, nonce_length ) );
+}
+
+/* Declare the lengths of the message and additional data for multipart AEAD. */
+psa_status_t psa_aead_set_lengths( psa_aead_operation_t *operation,
+ size_t ad_length,
+ size_t plaintext_length )
+{
+ if( !operation->key_set || operation->lengths_set )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_set_lengths( operation, ad_length, plaintext_length ) );
+}
+ /* Pass additional data to an active multipart AEAD operation. */
+psa_status_t psa_aead_update_ad( psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length )
+{
+ if( !operation->nonce_set || !operation->key_set )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_update_ad( operation, input, input_length ) );
+}
+
+/* Encrypt or decrypt a message fragment in an active multipart AEAD
+ operation.*/
+psa_status_t psa_aead_update( psa_aead_operation_t *operation,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length )
+{
+
+ *output_length = 0;
+
+ if( !operation->nonce_set || !operation->key_set || !operation->ad_started )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_update( operation, input, input_length, output, output_size,
+ output_length ) );
+}
+
+/* Finish encrypting a message in a multipart AEAD operation. */
+psa_status_t psa_aead_finish( psa_aead_operation_t *operation,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length,
+ uint8_t *tag,
+ size_t tag_size,
+ size_t *tag_length )
+{
+ *ciphertext_length = 0;
+ *tag_length = 0;
+
+ if( !operation->key_set || !operation->nonce_set ||
+ !operation->ad_started || !operation->body_started )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_finish( operation, ciphertext, ciphertext_size,
+ ciphertext_length, tag, tag_size, tag_length ) );
+}
+
+/* Finish authenticating and decrypting a message in a multipart AEAD
+ operation.*/
+psa_status_t psa_aead_verify( psa_aead_operation_t *operation,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length,
+ const uint8_t *tag,
+ size_t tag_length )
+{
+ *plaintext_length = 0;
+
+ if( !operation->key_set || !operation->nonce_set ||
+ !operation->ad_started || !operation->body_started )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
+
+ return( psa_driver_wrapper_aead_verify( operation, plaintext, plaintext_size, plaintext_length,
+ tag, tag_length ) );
+}
+
+/* Abort an AEAD operation. */
+psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ if( operation->id == 0 )
+ {
+ /* The object has (apparently) been initialized but it is not (yet)
+ * in use. It's ok to call abort on such an object, and there's
+ * nothing to do. */
+ return( PSA_SUCCESS );
+ }
+
+ status = psa_driver_wrapper_aead_abort( operation );
+
+ operation->id = 0;
+ operation->key_set = 0;
+ operation->nonce_set = 0;
+ operation->lengths_set = 0;
+ operation->is_encrypt = 0;
+ operation->ad_started = 0;
+ operation->body_started = 0;
+
+ return( status );
+}
+
/****************************************************************/
/* Generators */
/****************************************************************/
diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c
index 47b0e7b..f8cceae 100644
--- a/library/psa_crypto_aead.c
+++ b/library/psa_crypto_aead.c
@@ -394,45 +394,6 @@
return ( status );
}
-/* Generate a random nonce / IV for multipart AEAD operation */
-psa_status_t mbedtls_psa_aead_generate_nonce( psa_aead_operation_t *operation,
- uint8_t *nonce,
- size_t nonce_size,
- size_t *nonce_length )
-{
- psa_status_t status;
- size_t required_nonce_size = nonce_size;
-
- if( !operation->key_set || operation->nonce_set ||
- operation->ad_started || operation->body_started )
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
- required_nonce_size = PSA_AEAD_NONCE_LENGTH(operation->key_type, operation->alg);
-
- if( nonce_size == 0 || nonce_size < required_nonce_size )
- {
- return( PSA_ERROR_BUFFER_TOO_SMALL );
- }
-
- status = psa_generate_random( nonce, required_nonce_size );
-
- if( status != PSA_SUCCESS )
- {
- return status;
- }
-
- status = mbedtls_psa_aead_set_nonce( operation, nonce, required_nonce_size );
-
- if( status == PSA_SUCCESS )
- {
- *nonce_length = required_nonce_size;
- }
-
- return status;
-}
-
/* Set a nonce for the multipart AEAD operation*/
psa_status_t mbedtls_psa_aead_set_nonce( psa_aead_operation_t *operation,
const uint8_t *nonce,
@@ -440,19 +401,6 @@
{
psa_status_t status;
- if( !operation->key_set || operation->nonce_set ||
- operation->ad_started || operation->body_started )
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
- /* Restricting to a nominal safe length for nonces even though some
- algorithms can handle longer nonces, but not without collision */
- if( nonce_length > PSA_AEAD_NONCE_MAX_SIZE )
- {
- return( PSA_ERROR_INVALID_ARGUMENT );
- }
-
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
if( operation->alg == PSA_ALG_GCM )
{
@@ -514,11 +462,6 @@
size_t plaintext_length )
{
- if( !operation->key_set || operation->lengths_set )
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
if( operation->alg == PSA_ALG_GCM )
{
@@ -570,11 +513,6 @@
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- if( !operation->nonce_set || !operation->key_set )
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
if( operation->lengths_set )
{
if ( operation->ad_remaining < input_length )
@@ -675,11 +613,6 @@
size_t update_output_size;
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
- if( !operation->nonce_set || !operation->key_set || !operation->ad_started )
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
update_output_size = PSA_AEAD_UPDATE_OUTPUT_SIZE(operation->key_type,
operation->alg, input_length);
@@ -791,12 +724,6 @@
size_t *finish_output_size,
size_t *output_tag_length )
{
- if( !operation->key_set || !operation->nonce_set
- || !operation->ad_started || !operation->body_started)
- {
- return( PSA_ERROR_BAD_STATE );
- }
-
if( operation->lengths_set )
{
if( operation->ad_remaining != 0 || operation->body_remaining != 0 )
diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h
index d7aac24..a9d2687 100644
--- a/library/psa_crypto_aead.h
+++ b/library/psa_crypto_aead.h
@@ -167,9 +167,9 @@
* the inputs to the subsequent calls to mbedtls_psa_aead_update_ad() and
* mbedtls_psa_aead_update(). See the documentation of mbedtls_psa_aead_set_lengths()
* for details.
- * -# Call either mbedtls_psa_aead_generate_nonce() or mbedtls_psa_aead_set_nonce() to
- * generate or set the nonce. You should use
- * mbedtls_psa_aead_generate_nonce() unless the protocol you are implementing
+ * -# Call either psa_aead_generate_nonce() or
+ * mbedtls_psa_aead_set_nonce() to generate or set the nonce. You should use
+ * psa_aead_generate_nonce() unless the protocol you are implementing
* requires a specific nonce value.
* -# Call mbedtls_psa_aead_update_ad() zero, one or more times, passing a fragment
* of the non-encrypted additional authenticated data each time.
@@ -297,52 +297,6 @@
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg);
-/** Generate a random nonce for an authenticated encryption operation.
- *
- * \note The signature of this function is that of a PSA driver
- * aead_generate_nonce entry point. This function behaves as an
- * aead_generate_nonce entry point as defined in the PSA driver interface
- * specification for transparent drivers.
- *
- * This function generates a random nonce for the authenticated encryption
- * operation with an appropriate size for the chosen algorithm, key type
- * and key size.
- *
- * The application must call mbedtls_psa_aead_encrypt_setup() before
- * calling this function.
- *
- * If this function returns an error status, the operation enters an error
- * state and must be aborted by calling mbedtls_psa_aead_abort().
- *
- * \param[in,out] operation Active AEAD operation.
- * \param[out] nonce Buffer where the generated nonce is to be
- * written.
- * \param nonce_size Size of the \p nonce buffer in bytes.
- * \param[out] nonce_length On success, the number of bytes of the
- * generated nonce.
- *
- * \retval #PSA_SUCCESS
- * Success.
- * \retval #PSA_ERROR_BAD_STATE
- * The operation state is not valid (it must be an active aead encrypt
- * operation, with no nonce set).
- * \retval #PSA_ERROR_BUFFER_TOO_SMALL
- * The size of the \p nonce buffer is too small.
- * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
- * \retval #PSA_ERROR_COMMUNICATION_FAILURE
- * \retval #PSA_ERROR_HARDWARE_FAILURE
- * \retval #PSA_ERROR_CORRUPTION_DETECTED
- * \retval #PSA_ERROR_STORAGE_FAILURE
- * \retval #PSA_ERROR_BAD_STATE
- * The library has not been previously initialized by psa_crypto_init().
- * It is implementation-dependent whether a failure to initialize
- * results in this error code.
- */
-psa_status_t mbedtls_psa_aead_generate_nonce(psa_aead_operation_t *operation,
- uint8_t *nonce,
- size_t nonce_size,
- size_t *nonce_length);
-
/** Set the nonce for an authenticated encryption or decryption operation.
*
* \note The signature of this function is that of a PSA driver
@@ -402,7 +356,7 @@
* then the implementation must enforce the lengths.
*
* You may call this function before or after setting the nonce with
- * mbedtls_psa_aead_set_nonce() or mbedtls_psa_aead_generate_nonce().
+ * mbedtls_psa_aead_set_nonce() or psa_aead_generate_nonce().
*
* - For #PSA_ALG_CCM, calling this function is required.
* - For the other AEAD algorithms defined in this specification, calling
@@ -454,7 +408,7 @@
*
* Before calling this function, you must:
* 1. Call either mbedtls_psa_aead_encrypt_setup() or mbedtls_psa_aead_decrypt_setup().
- * 2. Set the nonce with mbedtls_psa_aead_generate_nonce() or
+ * 2. Set the nonce with psa_aead_generate_nonce() or
* mbedtls_psa_aead_set_nonce().
*
* If this function returns an error status, the operation enters an error
@@ -509,8 +463,9 @@
* 1. Call either mbedtls_psa_aead_encrypt_setup() or mbedtls_psa_aead_decrypt_setup().
* The choice of setup function determines whether this function
* encrypts or decrypts its input.
- * 2. Set the nonce with mbedtls_psa_aead_generate_nonce() or mbedtls_psa_aead_set_nonce().
- * 3. Call mbedtls_psa_aead_update_ad() to pass all the additional data.
+ * 2. Set the nonce with psa_aead_generate_nonce() or
+ * mbedtls_psa_aead_set_nonce(). 3. Call mbedtls_psa_aead_update_ad() to pass
+ * all the additional data.
*
* If this function returns an error status, the operation enters an error
* state and must be aborted by calling mbedtls_psa_aead_abort().
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 59a00a6..5e09fd2 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -1394,39 +1394,6 @@
}
}
-psa_status_t psa_driver_wrapper_aead_generate_nonce(
- psa_aead_operation_t *operation,
- uint8_t *nonce,
- size_t nonce_size,
- size_t *nonce_length )
-{
- switch( operation->id )
- {
-#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
- case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
- return( mbedtls_psa_aead_generate_nonce( operation, nonce, nonce_size,
- nonce_length ) );
-#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
-
-#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT)
-#if defined(PSA_CRYPTO_DRIVER_TEST)
- case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
-// return( test_transparent_aead_generate_nonce(
-// operation, nonce, nonce_size, nonce_length ) );
-
- /* Add cases for opaque driver here */
-
-#endif /* PSA_CRYPTO_DRIVER_TEST */
-#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */
- }
-
- (void)nonce;
- (void)nonce_size;
- (void)nonce_length;
-
- return( PSA_ERROR_INVALID_ARGUMENT );
-}
-
psa_status_t psa_driver_wrapper_aead_set_nonce(
psa_aead_operation_t *operation,
const uint8_t *nonce,
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index bdb2eba..05adb53 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -195,12 +195,6 @@
const uint8_t *key_buffer, size_t key_buffer_size,
psa_algorithm_t alg );
-psa_status_t psa_driver_wrapper_aead_generate_nonce(
- psa_aead_operation_t *operation,
- uint8_t *nonce,
- size_t nonce_size,
- size_t *nonce_length );
-
psa_status_t psa_driver_wrapper_aead_set_nonce(
psa_aead_operation_t *operation,
const uint8_t *nonce,