From d6d28885f0b06f4d126ef64ba9e4016b3cf510cc Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 14 Dec 2020 14:56:02 +0100 Subject: [PATCH] psa: Add mbedtls_psa_cipher_encrypt/decrypt_setup functions Signed-off-by: Ronald Cron --- library/psa_crypto.c | 110 ++++----------------------------- library/psa_crypto_cipher.c | 119 ++++++++++++++++++++++++++++++++++++ library/psa_crypto_cipher.h | 60 ++++++++++++++++++ 3 files changed, 191 insertions(+), 98 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 94d0c05c2..1c9905c9f 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 @@ exit: /* 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 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, 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 d6ad9025d..73a2dabf8 100644 --- a/library/psa_crypto_cipher.c +++ b/library/psa_crypto_cipher.c @@ -23,5 +23,124 @@ #if defined(MBEDTLS_PSA_CRYPTO_C) #include +#include "psa_crypto_core.h" +#include "mbedtls/cipher.h" +#include + +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 223da775d..e3231fc7c 100644 --- a/library/psa_crypto_cipher.h +++ b/library/psa_crypto_cipher.h @@ -23,4 +23,64 @@ #include +/** + * \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 */