Initial implementation of the AEAD decrypt/encrypt APIs
Initial implementation for the AEAD APIs, missing the following:
* Concatenation of the tag to the output buffer.
* Updated documentation of the new functions.
* argument validations
* tests
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index edb81c4..9efad55 100755
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1466,6 +1466,191 @@
}
+/****************************************************************/
+/* AEAD */
+/****************************************************************/
+psa_status_t psa_aead_encrypt( psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *plaintext,
+ size_t plaintext_length,
+ uint8_t *ciphertext,
+ size_t ciphertext_size,
+ size_t *ciphertext_length )
+{
+ int ret;
+ psa_status_t status;
+ key_slot_t *slot;
+ psa_key_type_t key_type;
+ size_t key_bits;
+ const mbedtls_cipher_info_t *cipher_info = NULL;
+ unsigned char tag[16];
+
+ status = psa_get_key_information( key, &key_type, &key_bits );
+ if( status != PSA_SUCCESS )
+ return( status );
+ slot = &global_data.key_slots[key];
+
+ //TODO: check key policy
+
+ cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits );
+ if( cipher_info == NULL )
+ return( PSA_ERROR_NOT_SUPPORTED );
+
+ if ( key_type != PSA_KEY_TYPE_RAW_DATA)
+ return( PSA_ERROR_BAD_STATE );
+
+ operation->block_size = cipher_info->block_size;
+
+ if( alg == PSA_ALG_GCM )
+ {
+ mbedtls_gcm_context gcm;
+ mbedtls_gcm_init( &gcm );
+ ret = mbedtls_gcm_setkey( &gcm, cipher_info->base->cipher,
+ ( const unsigned char * )slot->data.raw.data, key_bits );
+ if( ret != 0 )
+ {
+ mbedtls_gcm_free( &gcm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+ ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT,
+ plaintext_length, ( const unsigned char* )nonce ,
+ nonce_length, ( const unsigned char* )additional_data,
+ additional_data_length,
+ ( const unsigned char* ) plaintext,
+ ( unsigned char* )ciphertext, sizeof( tag ), tag );
+ if( ret != 0 )
+ {
+ mbedtls_gcm_free( &gcm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+
+ //TODO: append the tag to the output buffer and update the output buffer length.
+ mbedtls_gcm_free( &gcm );
+ }
+ else if( alg == PSA_ALG_CCM )
+ {
+ mbedtls_ccm_context ccm;
+ mbedtls_ccm_init( &ccm );
+ ret = mbedtls_ccm_setkey( &ccm, cipher_info->base->cipher,
+ ( const unsigned char * )slot->data.raw.data, key_bits );
+ if( ret != 0 )
+ {
+ mbedtls_ccm_free( &ccm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+ ret = mbedtls_ccm_encrypt_and_tag( &ccm, plaintext_length,
+ ( const unsigned char* )nonce ,
+ nonce_length, ( const unsigned char* )additional_data,
+ additional_data_length,
+ ( const unsigned char* ) plaintext,
+ ( unsigned char* )ciphertext, sizeof( tag ), tag );
+ if( ret != 0 )
+ {
+ mbedtls_ccm_free( &ccm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+
+ //TODO: append the tag to the output buffer and update the output buffer length.
+ mbedtls_ccm_free( &ccm );
+ }
+}
+
+psa_status_t psa_aead_decrypt( psa_key_slot_t key,
+ psa_algorithm_t alg,
+ const uint8_t *nonce,
+ size_t nonce_length,
+ const uint8_t *additional_data,
+ size_t additional_data_length,
+ const uint8_t *ciphertext,
+ size_t ciphertext_length,
+ uint8_t *plaintext,
+ size_t plaintext_size,
+ size_t *plaintext_length )
+{
+ int ret;
+ psa_status_t status;
+ key_slot_t *slot;
+ psa_key_type_t key_type;
+ size_t key_bits;
+ const mbedtls_cipher_info_t *cipher_info = NULL;
+ unsigned char tag[16];
+
+ status = psa_get_key_information( key, &key_type, &key_bits );
+ if( status != PSA_SUCCESS )
+ return( status );
+ slot = &global_data.key_slots[key];
+
+ //TODO: check key policy
+
+ cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits );
+ if( cipher_info == NULL )
+ return( PSA_ERROR_NOT_SUPPORTED );
+
+ if ( key_type != PSA_KEY_TYPE_RAW_DATA)
+ return( PSA_ERROR_BAD_STATE );
+
+ operation->block_size = cipher_info->block_size;
+
+ if( alg == PSA_ALG_GCM )
+ {
+ mbedtls_gcm_context gcm;
+ mbedtls_gcm_init( &gcm );
+ ret = mbedtls_gcm_setkey( &gcm, cipher_info->base->cipher,
+ ( const unsigned char * )slot->data.raw.data, key_bits );
+ if( ret != 0 )
+ {
+ mbedtls_gcm_free( &gcm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+ ret = mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_DECRYPT,
+ ciphertext_length, ( const unsigned char* )nonce ,
+ nonce_length, ( const unsigned char* )additional_data,
+ additional_data_length,
+ ( const unsigned char* )ciphertext,
+ ( unsigned char* )plaintext, sizeof( tag ), tag );
+ if( ret != 0 )
+ {
+ mbedtls_gcm_free( &gcm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+
+ //TODO: append the tag to the output buffer and update the output buffer length.
+ mbedtls_gcm_free( &gcm );
+ }
+ else if( alg == PSA_ALG_CCM )
+ {
+ mbedtls_ccm_context ccm;
+ mbedtls_ccm_init( &ccm );
+ ret = mbedtls_ccm_setkey( &ccm, cipher_info->base->cipher,
+ ( const unsigned char * )slot->data.raw.data, key_bits );
+ if( ret != 0 )
+ {
+ mbedtls_ccm_free( &ccm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+ ret = mbedtls_ccm_auth_decrypt( &ccm, ciphertext_length,
+ ( const unsigned char* )nonce ,
+ nonce_length, ( const unsigned char* )additional_data,
+ additional_data_length,
+ ( const unsigned char* )ciphertext ,
+ ( unsigned char* )plaintext, sizeof( tag ), tag );
+ if( ret != 0 )
+ {
+ mbedtls_ccm_free( &ccm );
+ return( mbedtls_to_psa_error( ret ) );
+ }
+
+ //TODO: append the tag to the output buffer and update the output buffer length.
+ mbedtls_ccm_free( &ccm );
+ }
+
+ return( PSA_SUCCESS );
+}
+
/****************************************************************/
/* Module setup */