psa: Add mbedtls_psa_cipher_encrypt/decrypt_setup functions
Signed-off-by: Ronald Cron <ronald.cron@arm.com>
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 94d0c05..1c9905c 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -29,6 +29,7 @@
#include "psa_crypto_service_integration.h"
#include "psa/crypto.h"
+#include "psa_crypto_cipher.h"
#include "psa_crypto_core.h"
#include "psa_crypto_invasive.h"
#include "psa_crypto_driver_wrappers.h"
@@ -3379,100 +3380,6 @@
/* Symmetric cryptography */
/****************************************************************/
-static psa_status_t psa_cipher_setup_internal(
- psa_cipher_operation_t *operation,
- const psa_key_attributes_t *attributes,
- const uint8_t *key_buffer, size_t key_buffer_size,
- psa_algorithm_t alg,
- mbedtls_operation_t cipher_operation )
-{
- int ret = 0;
- size_t key_bits;
- const mbedtls_cipher_info_t *cipher_info = NULL;
- psa_key_type_t key_type = attributes->core.type;
-
- (void)key_buffer_size;
-
- /* Proceed with initializing an mbed TLS cipher context if no driver is
- * available for the given algorithm & key. */
- mbedtls_cipher_init( &operation->ctx.cipher );
-
- /* Once the cipher context is initialised, it needs to be freed using
- * psa_cipher_abort. Indicate there is something to be freed through setting
- * alg, and indicate the operation is being done using mbedtls crypto through
- * setting mbedtls_in_use. */
- operation->alg = alg;
- operation->mbedtls_in_use = 1;
-
- key_bits = attributes->core.bits;
- cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
- key_bits, NULL );
- if( cipher_info == NULL )
- return( PSA_ERROR_NOT_SUPPORTED );
-
- ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
- if( ret != 0 )
- goto exit;
-
-#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
- if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
- {
- /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
- uint8_t keys[24];
- memcpy( keys, key_buffer, 16 );
- memcpy( keys + 16, key_buffer, 8 );
- ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
- keys,
- 192, cipher_operation );
- }
- else
-#endif
- {
- ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
- (int) key_bits, cipher_operation );
- }
- if( ret != 0 )
- goto exit;
-
-#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
- defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
- switch( alg )
- {
- case PSA_ALG_CBC_NO_PADDING:
- ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
- MBEDTLS_PADDING_NONE );
- break;
- case PSA_ALG_CBC_PKCS7:
- ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
- MBEDTLS_PADDING_PKCS7 );
- break;
- default:
- /* The algorithm doesn't involve padding. */
- ret = 0;
- break;
- }
- if( ret != 0 )
- goto exit;
-#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
-
- operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
- PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
- if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
- alg != PSA_ALG_ECB_NO_PADDING )
- {
- operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type );
- }
-#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
- else
- if( ( alg == PSA_ALG_STREAM_CIPHER ) &&
- ( key_type == PSA_KEY_TYPE_CHACHA20 ) )
- operation->iv_size = 12;
-#endif
-
-exit:
- return( mbedtls_to_psa_error( ret ) );
-}
-
static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
@@ -3535,10 +3442,17 @@
psa_key_attributes_t attributes = {
.core = slot->attr
};
- status = psa_cipher_setup_internal( operation, &attributes,
- slot->key.data,
- slot->key.bytes,
- alg, cipher_operation );
+ /* Try doing the operation through a driver before using software fallback. */
+ if( cipher_operation == MBEDTLS_ENCRYPT )
+ status = mbedtls_psa_cipher_encrypt_setup( operation, &attributes,
+ slot->key.data,
+ slot->key.bytes,
+ alg );
+ else
+ status = mbedtls_psa_cipher_decrypt_setup( operation, &attributes,
+ slot->key.data,
+ slot->key.bytes,
+ alg );
exit:
if( status == PSA_SUCCESS )
diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c
index d6ad902..73a2dab 100644
--- a/library/psa_crypto_cipher.c
+++ b/library/psa_crypto_cipher.c
@@ -23,5 +23,124 @@
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa_crypto_cipher.h>
+#include "psa_crypto_core.h"
+#include "mbedtls/cipher.h"
+#include <string.h>
+
+static psa_status_t cipher_setup(
+ psa_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg,
+ mbedtls_operation_t cipher_operation )
+{
+ int ret = 0;
+ size_t key_bits;
+ const mbedtls_cipher_info_t *cipher_info = NULL;
+ psa_key_type_t key_type = attributes->core.type;
+
+ (void)key_buffer_size;
+
+ /* Proceed with initializing an mbed TLS cipher context if no driver is
+ * available for the given algorithm & key. */
+ mbedtls_cipher_init( &operation->ctx.cipher );
+
+ /* Once the cipher context is initialised, it needs to be freed using
+ * psa_cipher_abort. Indicate there is something to be freed through setting
+ * alg, and indicate the operation is being done using mbedtls crypto through
+ * setting mbedtls_in_use. */
+ operation->alg = alg;
+ operation->mbedtls_in_use = 1;
+
+ key_bits = attributes->core.bits;
+ cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
+ key_bits, NULL );
+ if( cipher_info == NULL )
+ return( PSA_ERROR_NOT_SUPPORTED );
+
+ ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
+ if( ret != 0 )
+ goto exit;
+
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
+ if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
+ {
+ /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
+ uint8_t keys[24];
+ memcpy( keys, key_buffer, 16 );
+ memcpy( keys + 16, key_buffer, 8 );
+ ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
+ keys,
+ 192, cipher_operation );
+ }
+ else
+#endif
+ {
+ ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
+ (int) key_bits, cipher_operation );
+ }
+ if( ret != 0 )
+ goto exit;
+
+#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
+ defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
+ switch( alg )
+ {
+ case PSA_ALG_CBC_NO_PADDING:
+ ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
+ MBEDTLS_PADDING_NONE );
+ break;
+ case PSA_ALG_CBC_PKCS7:
+ ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
+ MBEDTLS_PADDING_PKCS7 );
+ break;
+ default:
+ /* The algorithm doesn't involve padding. */
+ ret = 0;
+ break;
+ }
+ if( ret != 0 )
+ goto exit;
+#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING || MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
+
+ operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
+ if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
+ alg != PSA_ALG_ECB_NO_PADDING )
+ {
+ operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type );
+ }
+#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
+ else
+ if( ( alg == PSA_ALG_STREAM_CIPHER ) &&
+ ( key_type == PSA_KEY_TYPE_CHACHA20 ) )
+ operation->iv_size = 12;
+#endif
+
+exit:
+ return( mbedtls_to_psa_error( ret ) );
+}
+
+psa_status_t mbedtls_psa_cipher_encrypt_setup(
+ psa_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg )
+{
+ return( cipher_setup( operation, attributes,
+ key_buffer, key_buffer_size,
+ alg, MBEDTLS_ENCRYPT ) );
+}
+
+psa_status_t mbedtls_psa_cipher_decrypt_setup(
+ psa_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg )
+{
+ return( cipher_setup( operation, attributes,
+ key_buffer, key_buffer_size,
+ alg, MBEDTLS_DECRYPT ) );
+}
#endif /* MBEDTLS_PSA_CRYPTO_C */
diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h
index 223da77..e3231fc 100644
--- a/library/psa_crypto_cipher.h
+++ b/library/psa_crypto_cipher.h
@@ -23,4 +23,64 @@
#include <psa/crypto.h>
+/**
+ * \brief Set the key for a multipart symmetric encryption operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * cipher_encrypt_setup entry point. This function behaves as a
+ * cipher_encrypt_setup entry point as defined in the PSA driver
+ * interface specification for transparent drivers.
+ *
+ * \param[in,out] operation The operation object to set up. It has been
+ * initialized as per the documentation for
+ * #psa_cipher_operation_t and not yet in use.
+ * \param[in] attributes The attributes of the key to use for the
+ * operation.
+ * \param[in] key_buffer The buffer containing the key context.
+ * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
+ * \param[in] alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_cipher_encrypt_setup(
+ psa_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg );
+
+/**
+ * \brief Set the key for a multipart symmetric decryption operation.
+ *
+ * \note The signature of this function is that of a PSA driver
+ * cipher_decrypt_setup entry point. This function behaves as a
+ * cipher_decrypt_setup entry point as defined in the PSA driver
+ * interface specification for transparent drivers.
+ *
+ * \param[in,out] operation The operation object to set up. It has been
+ * initialized as per the documentation for
+ * #psa_cipher_operation_t and not yet in use.
+ * \param[in] attributes The attributes of the key to use for the
+ * operation.
+ * \param[in] key_buffer The buffer containing the key context.
+ * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
+ * \param[in] alg The cipher algorithm to compute
+ * (\c PSA_ALG_XXX value such that
+ * #PSA_ALG_IS_CIPHER(\p alg) is true).
+ *
+ * \retval #PSA_SUCCESS
+ * \retval #PSA_ERROR_NOT_SUPPORTED
+ * \retval #PSA_ERROR_INSUFFICIENT_MEMORY
+ * \retval #PSA_ERROR_CORRUPTION_DETECTED
+ */
+psa_status_t mbedtls_psa_cipher_decrypt_setup(
+ psa_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg );
+
#endif /* PSA_CRYPTO_CIPHER_H */