diff --git a/include/psa/crypto_builtin_cipher.h b/include/psa/crypto_builtin_cipher.h new file mode 100644 index 000000000..0fd577af3 --- /dev/null +++ b/include/psa/crypto_builtin_cipher.h @@ -0,0 +1,70 @@ +/* + * Context structure declaration of the software-based driver which performs + * cipher operations through the PSA Crypto driver dispatch layer. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_BUILTIN_CIPHER_H +#define PSA_CRYPTO_BUILTIN_CIPHER_H + +#include +#include "mbedtls/cipher.h" + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CTR) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CFB) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_OFB) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_XTS) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) +#define MBEDTLS_PSA_BUILTIN_CIPHER 1 +#endif + +typedef struct { + /* Context structure for the Mbed TLS cipher implementation. */ + psa_algorithm_t alg; + uint8_t iv_size; + uint8_t block_size; + mbedtls_cipher_context_t cipher; +} mbedtls_psa_cipher_operation_t; + +#define MBEDTLS_PSA_CIPHER_OPERATION_INIT {0, 0, 0, {0}} + +/* + * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. + */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + +typedef mbedtls_psa_cipher_operation_t + mbedtls_transparent_test_driver_cipher_operation_t; + +typedef struct { + unsigned int initialised : 1; + mbedtls_transparent_test_driver_cipher_operation_t ctx; +} mbedtls_opaque_test_driver_cipher_operation_t; + +#define MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT \ + MBEDTLS_PSA_CIPHER_OPERATION_INIT + +#define MBEDTLS_OPAQUE_TEST_DRIVER_CIPHER_OPERATION_INIT \ + { 0, MBEDTLS_TRANSPARENT_TEST_DRIVER_CIPHER_OPERATION_INIT } + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* PSA_CRYPTO_BUILTIN_CIPHER_H */ diff --git a/include/psa/crypto_driver_contexts.h b/include/psa/crypto_driver_contexts.h index fdf178f94..bee6895e8 100644 --- a/include/psa/crypto_driver_contexts.h +++ b/include/psa/crypto_driver_contexts.h @@ -30,6 +30,7 @@ * declared during the autogeneration process. */ /* Include the context structure definitions for the Mbed TLS software drivers */ +#include "psa/crypto_builtin_cipher.h" #include "psa/crypto_builtin_hash.h" /* Define the context to be used for an operation that is executed through the @@ -47,5 +48,14 @@ typedef union { #endif } psa_driver_hash_context_t; +typedef union { + unsigned dummy; /* Make sure this structure is always non-empty */ + mbedtls_psa_cipher_operation_t mbedtls_ctx; +#if defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_transparent_test_driver_cipher_operation_t transparent_test_driver_ctx; + mbedtls_opaque_test_driver_cipher_operation_t opaque_test_driver_ctx; +#endif +} psa_driver_cipher_context_t; + #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_H */ /* End of automatically generated file. */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 87eefb9b1..0ef885df8 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -65,23 +65,12 @@ extern "C" { #include MBEDTLS_CONFIG_FILE #endif -#include "mbedtls/cipher.h" #include "mbedtls/cmac.h" #include "mbedtls/gcm.h" /* Include the context definition for the compiled-in drivers */ #include "psa/crypto_driver_contexts.h" -typedef struct { - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_driver_wrappers.h */ - unsigned int id; - /** Context structure for the assigned driver, when id is not zero. */ - void* ctx; -} psa_operation_driver_context_t; - struct psa_hash_operation_s { /** Unique ID indicating which driver got assigned to do the @@ -143,22 +132,21 @@ static inline struct psa_mac_operation_s psa_mac_operation_init( void ) struct psa_cipher_operation_s { - psa_algorithm_t alg; - unsigned int key_set : 1; + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_crypto_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int id; + unsigned int iv_required : 1; unsigned int iv_set : 1; - unsigned int mbedtls_in_use : 1; /* Indicates mbed TLS is handling the operation. */ - uint8_t iv_size; - uint8_t block_size; - union - { - unsigned dummy; /* Enable easier initializing of the union. */ - mbedtls_cipher_context_t cipher; - psa_operation_driver_context_t driver; - } ctx; + + psa_driver_cipher_context_t ctx; }; -#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}} +#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, {0}} static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) { const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 2b2672e2c..cff4cf975 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -61,6 +61,7 @@ set(src_crypto platform_util.c poly1305.c psa_crypto.c + psa_crypto_cipher.c psa_crypto_client.c psa_crypto_driver_wrappers.c psa_crypto_ecp.c diff --git a/library/Makefile b/library/Makefile index e9829cc4c..55af96e8f 100644 --- a/library/Makefile +++ b/library/Makefile @@ -118,6 +118,7 @@ OBJS_CRYPTO= \ platform_util.o \ poly1305.o \ psa_crypto.o \ + psa_crypto_cipher.o \ psa_crypto_client.o \ psa_crypto_driver_wrappers.o \ psa_crypto_ecp.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 37389f8d0..5dd93af9b 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" @@ -523,31 +524,31 @@ static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type, case PSA_KEY_TYPE_HMAC: case PSA_KEY_TYPE_DERIVE: break; -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES) +#if defined(PSA_WANT_KEY_TYPE_AES) case PSA_KEY_TYPE_AES: if( bits != 128 && bits != 192 && bits != 256 ) return( PSA_ERROR_INVALID_ARGUMENT ); break; #endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA) +#if defined(PSA_WANT_KEY_TYPE_CAMELLIA) case PSA_KEY_TYPE_CAMELLIA: if( bits != 128 && bits != 192 && bits != 256 ) return( PSA_ERROR_INVALID_ARGUMENT ); break; #endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) +#if defined(PSA_WANT_KEY_TYPE_DES) case PSA_KEY_TYPE_DES: if( bits != 64 && bits != 128 && bits != 192 ) return( PSA_ERROR_INVALID_ARGUMENT ); break; #endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARC4) +#if defined(PSA_WANT_KEY_TYPE_ARC4) case PSA_KEY_TYPE_ARC4: if( bits < 8 || bits > 2048 ) return( PSA_ERROR_INVALID_ARGUMENT ); break; #endif -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) +#if defined(PSA_WANT_KEY_TYPE_CHACHA20) case PSA_KEY_TYPE_CHACHA20: if( bits != 256 ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -2310,98 +2311,6 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, /* MAC */ /****************************************************************/ -static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( - psa_algorithm_t alg, - psa_key_type_t key_type, - size_t key_bits, - mbedtls_cipher_id_t* cipher_id ) -{ - mbedtls_cipher_mode_t mode; - mbedtls_cipher_id_t cipher_id_tmp; - - if( PSA_ALG_IS_AEAD( alg ) ) - alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ); - - if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ) - { - switch( alg ) - { - case PSA_ALG_STREAM_CIPHER: - mode = MBEDTLS_MODE_STREAM; - break; - case PSA_ALG_CTR: - mode = MBEDTLS_MODE_CTR; - break; - case PSA_ALG_CFB: - mode = MBEDTLS_MODE_CFB; - break; - case PSA_ALG_OFB: - mode = MBEDTLS_MODE_OFB; - break; - case PSA_ALG_ECB_NO_PADDING: - mode = MBEDTLS_MODE_ECB; - break; - case PSA_ALG_CBC_NO_PADDING: - mode = MBEDTLS_MODE_CBC; - break; - case PSA_ALG_CBC_PKCS7: - mode = MBEDTLS_MODE_CBC; - break; - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): - mode = MBEDTLS_MODE_CCM; - break; - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ): - mode = MBEDTLS_MODE_GCM; - break; - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ): - mode = MBEDTLS_MODE_CHACHAPOLY; - break; - default: - return( NULL ); - } - } - else if( alg == PSA_ALG_CMAC ) - mode = MBEDTLS_MODE_ECB; - else - return( NULL ); - - switch( key_type ) - { - case PSA_KEY_TYPE_AES: - cipher_id_tmp = MBEDTLS_CIPHER_ID_AES; - break; - case PSA_KEY_TYPE_DES: - /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES, - * and 192 for three-key Triple-DES. */ - if( key_bits == 64 ) - cipher_id_tmp = MBEDTLS_CIPHER_ID_DES; - else - cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES; - /* mbedtls doesn't recognize two-key Triple-DES as an algorithm, - * but two-key Triple-DES is functionally three-key Triple-DES - * with K1=K3, so that's how we present it to mbedtls. */ - if( key_bits == 128 ) - key_bits = 192; - break; - case PSA_KEY_TYPE_CAMELLIA: - cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA; - break; - case PSA_KEY_TYPE_ARC4: - cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4; - break; - case PSA_KEY_TYPE_CHACHA20: - cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20; - break; - default: - return( NULL ); - } - if( cipher_id != NULL ) - *cipher_id = cipher_id_tmp; - - return( mbedtls_cipher_info_from_values( cipher_id_tmp, - (int) key_bits, mode ) ); -} - #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) static size_t psa_get_hash_block_size( psa_algorithm_t alg ) { @@ -3386,16 +3295,13 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - int ret = 0; psa_key_slot_t *slot; - size_t key_bits; - const mbedtls_cipher_info_t *cipher_info = NULL; psa_key_usage_t usage = ( cipher_operation == MBEDTLS_ENCRYPT ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT ); /* A context must be freshly initialized before it can be set up. */ - if( operation->alg != 0 ) + if( operation->id != 0 ) return( PSA_ERROR_BAD_STATE ); /* The requested algorithm must be one that can be processed by cipher. */ @@ -3407,129 +3313,36 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, if( status != PSA_SUCCESS ) goto exit; - /* Initialize the operation struct members, except for alg. The alg member + /* Initialize the operation struct members, except for id. The id member * is used to indicate to psa_cipher_abort that there are resources to free, - * so we only set it after resources have been allocated/initialized. */ - operation->key_set = 0; + * so we only set it (in the driver wrapper) after resources have been + * allocated/initialized. */ operation->iv_set = 0; - operation->mbedtls_in_use = 0; - operation->iv_size = 0; - operation->block_size = 0; if( alg == PSA_ALG_ECB_NO_PADDING ) operation->iv_required = 0; else operation->iv_required = 1; + psa_key_attributes_t attributes = { + .core = slot->attr + }; + /* Try doing the operation through a driver before using software fallback. */ if( cipher_operation == MBEDTLS_ENCRYPT ) - status = psa_driver_wrapper_cipher_encrypt_setup( &operation->ctx.driver, - slot, + status = psa_driver_wrapper_cipher_encrypt_setup( operation, + &attributes, + slot->key.data, + slot->key.bytes, alg ); else - status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver, - slot, + status = psa_driver_wrapper_cipher_decrypt_setup( operation, + &attributes, + slot->key.data, + slot->key.bytes, alg ); - if( status == PSA_SUCCESS ) - { - /* Once the driver context is initialised, it needs to be freed using - * psa_cipher_abort. Indicate this through setting alg. */ - operation->alg = alg; - } - - if( status != PSA_ERROR_NOT_SUPPORTED || - psa_key_lifetime_is_external( slot->attr.lifetime ) ) - goto exit; - - /* 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 = psa_get_key_slot_bits( slot ); - cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL ); - if( cipher_info == NULL ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info ); - if( ret != 0 ) - goto exit; - -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) - if( slot->attr.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, slot->key.data, 16 ); - memcpy( keys + 16, slot->key.data, 8 ); - ret = mbedtls_cipher_setkey( &operation->ctx.cipher, - keys, - 192, cipher_operation ); - } - else -#endif - { - ret = mbedtls_cipher_setkey( &operation->ctx.cipher, - slot->key.data, - (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( slot->attr.type ) ); - if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 && - alg != PSA_ALG_ECB_NO_PADDING ) - { - operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH( slot->attr.type ); - } -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) - else - if( alg == PSA_ALG_STREAM_CIPHER && slot->attr.type == PSA_KEY_TYPE_CHACHA20 ) - operation->iv_size = 12; -#endif - - status = PSA_SUCCESS; - exit: - if( ret != 0 ) - status = mbedtls_to_psa_error( ret ); - if( status == PSA_SUCCESS ) - { - /* Update operation flags for both driver and software implementations */ - operation->key_set = 1; - } - else + if( status != PSA_SUCCESS ) psa_cipher_abort( operation ); unlock_status = psa_unlock_key_slot( slot ); @@ -3556,43 +3369,28 @@ psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation, size_t iv_size, size_t *iv_length ) { - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if( operation->id == 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + if( operation->iv_set || ! operation->iv_required ) { return( PSA_ERROR_BAD_STATE ); } - if( operation->mbedtls_in_use == 0 ) - { - status = psa_driver_wrapper_cipher_generate_iv( &operation->ctx.driver, - iv, - iv_size, - iv_length ); - goto exit; - } + status = psa_driver_wrapper_cipher_generate_iv( operation, + iv, + iv_size, + iv_length ); - if( iv_size < operation->iv_size ) - { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - ret = mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE, - iv, operation->iv_size ); - if( ret != 0 ) - { - status = mbedtls_to_psa_error( ret ); - goto exit; - } - - *iv_length = operation->iv_size; - status = psa_cipher_set_iv( operation, iv, *iv_length ); - -exit: if( status == PSA_SUCCESS ) operation->iv_set = 1; else psa_cipher_abort( operation ); + return( status ); } @@ -3600,29 +3398,22 @@ psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation, const uint8_t *iv, size_t iv_length ) { - psa_status_t status; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if( operation->id == 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + if( operation->iv_set || ! operation->iv_required ) { return( PSA_ERROR_BAD_STATE ); } - if( operation->mbedtls_in_use == 0 ) - { - status = psa_driver_wrapper_cipher_set_iv( &operation->ctx.driver, - iv, - iv_length ); - goto exit; - } + status = psa_driver_wrapper_cipher_set_iv( operation, + iv, + iv_length ); - if( iv_length != operation->iv_size ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length ); - status = mbedtls_to_psa_error( ret ); -exit: if( status == PSA_SUCCESS ) operation->iv_set = 1; else @@ -3630,94 +3421,6 @@ exit: return( status ); } -/* Process input for which the algorithm is set to ECB mode. This requires - * manual processing, since the PSA API is defined as being able to process - * arbitrary-length calls to psa_cipher_update() with ECB mode, but the - * underlying mbedtls_cipher_update only takes full blocks. */ -static psa_status_t psa_cipher_update_ecb_internal( - mbedtls_cipher_context_t *ctx, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t block_size = ctx->cipher_info->block_size; - size_t internal_output_length = 0; - *output_length = 0; - - if( input_length == 0 ) - { - status = PSA_SUCCESS; - goto exit; - } - - if( ctx->unprocessed_len > 0 ) - { - /* Fill up to block size, and run the block if there's a full one. */ - size_t bytes_to_copy = block_size - ctx->unprocessed_len; - - if( input_length < bytes_to_copy ) - bytes_to_copy = input_length; - - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), - input, bytes_to_copy ); - input_length -= bytes_to_copy; - input += bytes_to_copy; - ctx->unprocessed_len += bytes_to_copy; - - if( ctx->unprocessed_len == block_size ) - { - status = mbedtls_to_psa_error( - mbedtls_cipher_update( ctx, - ctx->unprocessed_data, - block_size, - output, &internal_output_length ) ); - - if( status != PSA_SUCCESS ) - goto exit; - - output += internal_output_length; - output_size -= internal_output_length; - *output_length += internal_output_length; - ctx->unprocessed_len = 0; - } - } - - while( input_length >= block_size ) - { - /* Run all full blocks we have, one by one */ - status = mbedtls_to_psa_error( - mbedtls_cipher_update( ctx, input, - block_size, - output, &internal_output_length ) ); - - if( status != PSA_SUCCESS ) - goto exit; - - input_length -= block_size; - input += block_size; - - output += internal_output_length; - output_size -= internal_output_length; - *output_length += internal_output_length; - } - - if( input_length > 0 ) - { - /* Save unprocessed bytes for later processing */ - memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), - input, input_length ); - ctx->unprocessed_len += input_length; - } - - status = PSA_SUCCESS; - -exit: - return( status ); -} - psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, const uint8_t *input, size_t input_length, @@ -3726,8 +3429,8 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, size_t *output_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t expected_output_size; - if( operation->alg == 0 ) + + if( operation->id == 0 ) { return( PSA_ERROR_BAD_STATE ); } @@ -3736,59 +3439,15 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation, return( PSA_ERROR_BAD_STATE ); } - if( operation->mbedtls_in_use == 0 ) - { - status = psa_driver_wrapper_cipher_update( &operation->ctx.driver, - input, - input_length, - output, - output_size, - output_length ); - goto exit; - } - - if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) ) - { - /* Take the unprocessed partial block left over from previous - * update calls, if any, plus the input to this call. Remove - * the last partial block, if any. You get the data that will be - * output in this call. */ - expected_output_size = - ( operation->ctx.cipher.unprocessed_len + input_length ) - / operation->block_size * operation->block_size; - } - else - { - expected_output_size = input_length; - } - - if( output_size < expected_output_size ) - { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - - if( operation->alg == PSA_ALG_ECB_NO_PADDING ) - { - /* mbedtls_cipher_update has an API inconsistency: it will only - * process a single block at a time in ECB mode. Abstract away that - * inconsistency here to match the PSA API behaviour. */ - status = psa_cipher_update_ecb_internal( &operation->ctx.cipher, - input, - input_length, - output, - output_size, - output_length ); - } - else - { - status = mbedtls_to_psa_error( - mbedtls_cipher_update( &operation->ctx.cipher, input, - input_length, output, output_length ) ); - } -exit: + status = psa_driver_wrapper_cipher_update( operation, + input, + input_length, + output, + output_size, + output_length ); if( status != PSA_SUCCESS ) psa_cipher_abort( operation ); + return( status ); } @@ -3798,8 +3457,8 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, size_t *output_length ) { psa_status_t status = PSA_ERROR_GENERIC_ERROR; - uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; - if( operation->alg == 0 ) + + if( operation->id == 0 ) { return( PSA_ERROR_BAD_STATE ); } @@ -3808,43 +3467,10 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, return( PSA_ERROR_BAD_STATE ); } - if( operation->mbedtls_in_use == 0 ) - { - status = psa_driver_wrapper_cipher_finish( &operation->ctx.driver, - output, - output_size, - output_length ); - goto exit; - } - - if( operation->ctx.cipher.unprocessed_len != 0 ) - { - if( operation->alg == PSA_ALG_ECB_NO_PADDING || - operation->alg == PSA_ALG_CBC_NO_PADDING ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - } - - status = mbedtls_to_psa_error( - mbedtls_cipher_finish( &operation->ctx.cipher, - temp_output_buffer, - output_length ) ); - if( status != PSA_SUCCESS ) - goto exit; - - if( *output_length == 0 ) - ; /* Nothing to copy. Note that output may be NULL in this case. */ - else if( output_size >= *output_length ) - memcpy( output, temp_output_buffer, *output_length ); - else - status = PSA_ERROR_BUFFER_TOO_SMALL; - -exit: - if( operation->mbedtls_in_use == 1 ) - mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) ); - + status = psa_driver_wrapper_cipher_finish( operation, + output, + output_size, + output_length ); if( status == PSA_SUCCESS ) return( psa_cipher_abort( operation ) ); else @@ -3858,7 +3484,7 @@ exit: psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) { - if( operation->alg == 0 ) + 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 @@ -3866,30 +3492,15 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) return( PSA_SUCCESS ); } - /* Sanity check (shouldn't happen: operation->alg should - * always have been initialized to a valid value). */ - if( ! PSA_ALG_IS_CIPHER( operation->alg ) ) - return( PSA_ERROR_BAD_STATE ); + psa_driver_wrapper_cipher_abort( operation ); - if( operation->mbedtls_in_use == 0 ) - psa_driver_wrapper_cipher_abort( &operation->ctx.driver ); - else - mbedtls_cipher_free( &operation->ctx.cipher ); - - operation->alg = 0; - operation->key_set = 0; + operation->id = 0; operation->iv_set = 0; - operation->mbedtls_in_use = 0; - operation->iv_size = 0; - operation->block_size = 0; operation->iv_required = 0; return( PSA_SUCCESS ); } - - - /****************************************************************/ /* AEAD */ /****************************************************************/ diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c new file mode 100644 index 000000000..dac9d7f41 --- /dev/null +++ b/library/psa_crypto_cipher.c @@ -0,0 +1,603 @@ +/* + * PSA cipher driver entry points + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#include +#include "psa_crypto_core.h" +#include "psa_crypto_random_impl.h" + +#include "mbedtls/cipher.h" +#include "mbedtls/error.h" + +#include + +#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES) ) ) +#define BUILTIN_KEY_TYPE_DES 1 +#endif + +#if ( defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && \ + defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING) ) ) +#define BUILTIN_ALG_CBC_NO_PADDING 1 +#endif + +#if ( defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && \ + defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7) ) ) +#define BUILTIN_ALG_CBC_PKCS7 1 +#endif + +#if ( defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20) ) ) +#define BUILTIN_KEY_TYPE_CHACHA20 1 +#endif + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( + psa_algorithm_t alg, + psa_key_type_t key_type, + size_t key_bits, + mbedtls_cipher_id_t* cipher_id ) +{ + mbedtls_cipher_mode_t mode; + mbedtls_cipher_id_t cipher_id_tmp; + + if( PSA_ALG_IS_AEAD( alg ) ) + alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ); + + if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) ) + { + switch( alg ) + { + case PSA_ALG_STREAM_CIPHER: + mode = MBEDTLS_MODE_STREAM; + break; + case PSA_ALG_CTR: + mode = MBEDTLS_MODE_CTR; + break; + case PSA_ALG_CFB: + mode = MBEDTLS_MODE_CFB; + break; + case PSA_ALG_OFB: + mode = MBEDTLS_MODE_OFB; + break; + case PSA_ALG_ECB_NO_PADDING: + mode = MBEDTLS_MODE_ECB; + break; + case PSA_ALG_CBC_NO_PADDING: + mode = MBEDTLS_MODE_CBC; + break; + case PSA_ALG_CBC_PKCS7: + mode = MBEDTLS_MODE_CBC; + break; + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): + mode = MBEDTLS_MODE_CCM; + break; + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ): + mode = MBEDTLS_MODE_GCM; + break; + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ): + mode = MBEDTLS_MODE_CHACHAPOLY; + break; + default: + return( NULL ); + } + } + else if( alg == PSA_ALG_CMAC ) + mode = MBEDTLS_MODE_ECB; + else + return( NULL ); + + switch( key_type ) + { + case PSA_KEY_TYPE_AES: + cipher_id_tmp = MBEDTLS_CIPHER_ID_AES; + break; + case PSA_KEY_TYPE_DES: + /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES, + * and 192 for three-key Triple-DES. */ + if( key_bits == 64 ) + cipher_id_tmp = MBEDTLS_CIPHER_ID_DES; + else + cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES; + /* mbedtls doesn't recognize two-key Triple-DES as an algorithm, + * but two-key Triple-DES is functionally three-key Triple-DES + * with K1=K3, so that's how we present it to mbedtls. */ + if( key_bits == 128 ) + key_bits = 192; + break; + case PSA_KEY_TYPE_CAMELLIA: + cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA; + break; + case PSA_KEY_TYPE_ARC4: + cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4; + break; + case PSA_KEY_TYPE_CHACHA20: + cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20; + break; + default: + return( NULL ); + } + if( cipher_id != NULL ) + *cipher_id = cipher_id_tmp; + + return( mbedtls_cipher_info_from_values( cipher_id_tmp, + (int) key_bits, mode ) ); +} + +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) || defined(PSA_CRYPTO_DRIVER_TEST) + +static psa_status_t cipher_setup( + mbedtls_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->cipher ); + + operation->alg = alg; + 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->cipher, cipher_info ); + if( ret != 0 ) + goto exit; + +#if defined(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->cipher, + keys, + 192, cipher_operation ); + } + else +#endif + { + ret = mbedtls_cipher_setkey( &operation->cipher, key_buffer, + (int) key_bits, cipher_operation ); + } + if( ret != 0 ) + goto exit; + +#if defined(BUILTIN_ALG_CBC_NO_PADDING) || \ + defined(BUILTIN_ALG_CBC_PKCS7) + switch( alg ) + { + case PSA_ALG_CBC_NO_PADDING: + ret = mbedtls_cipher_set_padding_mode( &operation->cipher, + MBEDTLS_PADDING_NONE ); + break; + case PSA_ALG_CBC_PKCS7: + ret = mbedtls_cipher_set_padding_mode( &operation->cipher, + MBEDTLS_PADDING_PKCS7 ); + break; + default: + /* The algorithm doesn't involve padding. */ + ret = 0; + break; + } + if( ret != 0 ) + goto exit; +#endif /* BUILTIN_ALG_CBC_NO_PADDING || 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(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 cipher_encrypt_setup( + mbedtls_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 ) ); +} + +static psa_status_t cipher_decrypt_setup( + mbedtls_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 ) ); +} + +static psa_status_t cipher_set_iv( mbedtls_psa_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length ) +{ + if( iv_length != operation->iv_size ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + return( mbedtls_to_psa_error( + mbedtls_cipher_set_iv( &operation->cipher, + iv, iv_length ) ) ); +} + +static psa_status_t cipher_generate_iv( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length ) +{ + int status = PSA_ERROR_CORRUPTION_DETECTED; + + if( iv_size < operation->iv_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + status = psa_generate_random( iv, operation->iv_size ); + if( status != PSA_SUCCESS ) + return( status ); + + *iv_length = operation->iv_size; + + return( cipher_set_iv( operation, iv, *iv_length ) ); +} + +/* Process input for which the algorithm is set to ECB mode. This requires + * manual processing, since the PSA API is defined as being able to process + * arbitrary-length calls to psa_cipher_update() with ECB mode, but the + * underlying mbedtls_cipher_update only takes full blocks. */ +static psa_status_t psa_cipher_update_ecb( + mbedtls_cipher_context_t *ctx, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t block_size = ctx->cipher_info->block_size; + size_t internal_output_length = 0; + *output_length = 0; + + if( input_length == 0 ) + { + status = PSA_SUCCESS; + goto exit; + } + + if( ctx->unprocessed_len > 0 ) + { + /* Fill up to block size, and run the block if there's a full one. */ + size_t bytes_to_copy = block_size - ctx->unprocessed_len; + + if( input_length < bytes_to_copy ) + bytes_to_copy = input_length; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), + input, bytes_to_copy ); + input_length -= bytes_to_copy; + input += bytes_to_copy; + ctx->unprocessed_len += bytes_to_copy; + + if( ctx->unprocessed_len == block_size ) + { + status = mbedtls_to_psa_error( + mbedtls_cipher_update( ctx, + ctx->unprocessed_data, + block_size, + output, &internal_output_length ) ); + + if( status != PSA_SUCCESS ) + goto exit; + + output += internal_output_length; + output_size -= internal_output_length; + *output_length += internal_output_length; + ctx->unprocessed_len = 0; + } + } + + while( input_length >= block_size ) + { + /* Run all full blocks we have, one by one */ + status = mbedtls_to_psa_error( + mbedtls_cipher_update( ctx, input, + block_size, + output, &internal_output_length ) ); + + if( status != PSA_SUCCESS ) + goto exit; + + input_length -= block_size; + input += block_size; + + output += internal_output_length; + output_size -= internal_output_length; + *output_length += internal_output_length; + } + + if( input_length > 0 ) + { + /* Save unprocessed bytes for later processing */ + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), + input, input_length ); + ctx->unprocessed_len += input_length; + } + + status = PSA_SUCCESS; + +exit: + return( status ); +} + +static psa_status_t cipher_update( mbedtls_psa_cipher_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t expected_output_size; + + if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) ) + { + /* Take the unprocessed partial block left over from previous + * update calls, if any, plus the input to this call. Remove + * the last partial block, if any. You get the data that will be + * output in this call. */ + expected_output_size = + ( operation->cipher.unprocessed_len + input_length ) + / operation->block_size * operation->block_size; + } + else + { + expected_output_size = input_length; + } + + if( output_size < expected_output_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + if( operation->alg == PSA_ALG_ECB_NO_PADDING ) + { + /* mbedtls_cipher_update has an API inconsistency: it will only + * process a single block at a time in ECB mode. Abstract away that + * inconsistency here to match the PSA API behaviour. */ + status = psa_cipher_update_ecb( &operation->cipher, + input, + input_length, + output, + output_size, + output_length ); + } + else + { + status = mbedtls_to_psa_error( + mbedtls_cipher_update( &operation->cipher, input, + input_length, output, output_length ) ); + } + + return( status ); +} + +static psa_status_t cipher_finish( mbedtls_psa_cipher_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; + + if( operation->cipher.unprocessed_len != 0 ) + { + if( operation->alg == PSA_ALG_ECB_NO_PADDING || + operation->alg == PSA_ALG_CBC_NO_PADDING ) + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + } + + status = mbedtls_to_psa_error( + mbedtls_cipher_finish( &operation->cipher, + temp_output_buffer, + output_length ) ); + if( status != PSA_SUCCESS ) + goto exit; + + if( *output_length == 0 ) + ; /* Nothing to copy. Note that output may be NULL in this case. */ + else if( output_size >= *output_length ) + memcpy( output, temp_output_buffer, *output_length ); + else + status = PSA_ERROR_BUFFER_TOO_SMALL; + +exit: + mbedtls_platform_zeroize( temp_output_buffer, + sizeof( temp_output_buffer ) ); + + return( status ); +} + +static psa_status_t cipher_abort( mbedtls_psa_cipher_operation_t *operation ) +{ + /* Sanity check (shouldn't happen: operation->alg should + * always have been initialized to a valid value). */ + if( ! PSA_ALG_IS_CIPHER( operation->alg ) ) + return( PSA_ERROR_BAD_STATE ); + + mbedtls_cipher_free( &operation->cipher ); + + return( PSA_SUCCESS ); +} +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER || PSA_CRYPTO_DRIVER_TEST */ + +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) +psa_status_t mbedtls_psa_cipher_encrypt_setup( + mbedtls_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_encrypt_setup( + operation, attributes, key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_psa_cipher_decrypt_setup( + mbedtls_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_decrypt_setup( + operation, attributes, key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_psa_cipher_generate_iv( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length ) +{ + return( cipher_generate_iv( operation, iv, iv_size, iv_length ) ); +} + +psa_status_t mbedtls_psa_cipher_set_iv( mbedtls_psa_cipher_operation_t *operation, + const uint8_t *iv, + size_t iv_length ) +{ + return( cipher_set_iv( operation, iv, iv_length ) ); +} + +psa_status_t mbedtls_psa_cipher_update( mbedtls_psa_cipher_operation_t *operation, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + return( cipher_update( operation, input, input_length, + output, output_size, output_length ) ); +} + +psa_status_t mbedtls_psa_cipher_finish( mbedtls_psa_cipher_operation_t *operation, + uint8_t *output, + size_t output_size, + size_t *output_length ) +{ + return( cipher_finish( operation, output, output_size, output_length ) ); +} + +psa_status_t mbedtls_psa_cipher_abort( mbedtls_psa_cipher_operation_t *operation ) +{ + return( cipher_abort( operation ) ); +} +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ + +/* + * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. + */ + +#if defined(PSA_CRYPTO_DRIVER_TEST) +psa_status_t mbedtls_transparent_test_driver_cipher_encrypt_setup( + mbedtls_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_encrypt_setup( + operation, attributes, key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_decrypt_setup( + mbedtls_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_decrypt_setup( + operation, attributes, key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_generate_iv( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length ) +{ + return( cipher_generate_iv( operation, iv, iv_size, iv_length ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_set_iv( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length ) +{ + return( cipher_set_iv( operation, iv, iv_length ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_update( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length ) +{ + return( cipher_update( operation, input, input_length, + output, output_size, output_length ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_finish( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *output, size_t output_size, size_t *output_length ) +{ + return( cipher_finish( operation, output, output_size, output_length ) ); +} + +psa_status_t mbedtls_transparent_test_driver_cipher_abort( + mbedtls_psa_cipher_operation_t *operation ) +{ + return( cipher_abort( operation ) ); +} +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h new file mode 100644 index 000000000..3130e8b18 --- /dev/null +++ b/library/psa_crypto_cipher.h @@ -0,0 +1,264 @@ +/* + * PSA cipher driver entry points + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_CIPHER_H +#define PSA_CRYPTO_CIPHER_H + +#include +#include + +/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier + * as well as the PSA type and size of the key to be used with the cipher + * algorithm. + * + * \param alg PSA cipher algorithm identifier + * \param key_type PSA key type + * \param key_bits Size of the key in bits + * \param[out] cipher_id Mbed TLS cipher algorithm identifier + * + * \return The Mbed TLS cipher information of the cipher algorithm. + * \c NULL if the PSA cipher algorithm is not supported. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( + psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits, + mbedtls_cipher_id_t *cipher_id ); + +/** + * \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( + mbedtls_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( + mbedtls_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 ); + +/** Generate an IV for a symmetric encryption operation. + * + * This function generates a random IV (initialization vector), nonce + * or initial counter value for the encryption operation as appropriate + * for the chosen algorithm, key type and key size. + * + * \note The signature of this function is that of a PSA driver + * cipher_generate_iv entry point. This function behaves as a + * cipher_generate_iv entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in,out] operation Active cipher operation. + * \param[out] iv Buffer where the generated IV is to be written. + * \param[in] iv_size Size of the \p iv buffer in bytes. + * \param[out] iv_length On success, the number of bytes of the + * generated IV. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p iv buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t mbedtls_psa_cipher_generate_iv( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length ); + +/** Set the IV for a symmetric encryption or decryption operation. + * + * This function sets the IV (initialization vector), nonce + * or initial counter value for the encryption or decryption operation. + * + * \note The signature of this function is that of a PSA driver + * cipher_set_iv entry point. This function behaves as a + * cipher_set_iv entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in,out] operation Active cipher operation. + * \param[in] iv Buffer containing the IV to use. + * \param[in] iv_length Size of the IV in bytes. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The size of \p iv is not acceptable for the chosen algorithm, + * or the chosen algorithm does not use an IV. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t mbedtls_psa_cipher_set_iv( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length ); + +/** Encrypt or decrypt a message fragment in an active cipher operation. + * + * \note The signature of this function is that of a PSA driver + * cipher_update entry point. This function behaves as a + * cipher_update entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in,out] operation Active cipher operation. + * \param[in] input Buffer containing the message fragment to + * encrypt or decrypt. + * \param[in] input_length Size of the \p input buffer in bytes. + * \param[out] output Buffer where the output is to be written. + * \param[in] output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t mbedtls_psa_cipher_update( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length ); + +/** Finish encrypting or decrypting a message in a cipher operation. + * + * \note The signature of this function is that of a PSA driver + * cipher_finish entry point. This function behaves as a + * cipher_finish entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in,out] operation Active cipher operation. + * \param[out] output Buffer where the output is to be written. + * \param[in] output_size Size of the \p output buffer in bytes. + * \param[out] output_length On success, the number of bytes + * that make up the returned output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The total input size passed to this operation is not valid for + * this particular algorithm. For example, the algorithm is a based + * on block cipher and requires a whole number of blocks, but the + * total input size is not a multiple of the block size. + * \retval #PSA_ERROR_INVALID_PADDING + * This is a decryption operation for an algorithm that includes + * padding, and the ciphertext does not contain valid padding. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p output buffer is too small. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t mbedtls_psa_cipher_finish( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *output, size_t output_size, size_t *output_length ); + +/** Abort a cipher operation. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation. + * + * \note The signature of this function is that of a PSA driver + * cipher_abort entry point. This function behaves as a + * cipher_abort entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in,out] operation Initialized cipher operation. + * + * \retval #PSA_SUCCESS + */ +psa_status_t mbedtls_psa_cipher_abort( mbedtls_psa_cipher_operation_t *operation ); + +/* + * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. + */ + +#if defined(PSA_CRYPTO_DRIVER_TEST) +psa_status_t mbedtls_transparent_test_driver_cipher_encrypt_setup( + mbedtls_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 ); + +psa_status_t mbedtls_transparent_test_driver_cipher_decrypt_setup( + mbedtls_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 ); + +psa_status_t mbedtls_transparent_test_driver_cipher_generate_iv( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length ); + +psa_status_t mbedtls_transparent_test_driver_cipher_set_iv( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length ); + +psa_status_t mbedtls_transparent_test_driver_cipher_update( + mbedtls_psa_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length ); + +psa_status_t mbedtls_transparent_test_driver_cipher_finish( + mbedtls_psa_cipher_operation_t *operation, + uint8_t *output, size_t output_size, size_t *output_length ); + +psa_status_t mbedtls_transparent_test_driver_cipher_abort( + mbedtls_psa_cipher_operation_t *operation ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* PSA_CRYPTO_CIPHER_H */ diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 6c94472f8..32c957eff 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -19,6 +19,7 @@ * limitations under the License. */ +#include "psa_crypto_cipher.h" #include "psa_crypto_core.h" #include "psa_crypto_driver_wrappers.h" #include "psa_crypto_hash.h" @@ -710,365 +711,342 @@ psa_status_t psa_driver_wrapper_cipher_decrypt( } psa_status_t psa_driver_wrapper_cipher_encrypt_setup( - psa_operation_driver_context_t *operation, - psa_key_slot_t *slot, + 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 ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); - psa_key_attributes_t attributes = { - .core = slot->attr - }; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); switch( location ) { case PSA_KEY_LOCATION_LOCAL_STORAGE: /* Key is stored in the slot in export representation, so * cycle through all known transparent accelerators */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) - operation->ctx = mbedtls_calloc( 1, sizeof(test_transparent_cipher_operation_t) ); - if( operation->ctx == NULL ) - return PSA_ERROR_INSUFFICIENT_MEMORY; - - status = test_transparent_cipher_encrypt_setup( operation->ctx, - &attributes, - slot->key.data, - slot->key.bytes, - alg ); + status = test_transparent_cipher_encrypt_setup( + &operation->ctx.transparent_test_driver_ctx, + attributes, + key_buffer, + key_buffer_size, + alg ); /* Declared with fallback == true */ if( status == PSA_SUCCESS ) operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; - else - { - mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_transparent_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - } - return( status ); + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) /* Fell through, meaning no accelerator supports this operation */ - return( PSA_ERROR_NOT_SUPPORTED ); - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LIFETIME: - operation->ctx = mbedtls_calloc( 1, sizeof(test_opaque_cipher_operation_t) ); - if( operation->ctx == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - - status = test_opaque_cipher_encrypt_setup( operation->ctx, - &attributes, - slot->key.data, - slot->key.bytes, + status = mbedtls_psa_cipher_encrypt_setup( &operation->ctx.mbedtls_ctx, + attributes, + key_buffer, + key_buffer_size, alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ + return( PSA_ERROR_NOT_SUPPORTED ); + + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + status = test_opaque_cipher_encrypt_setup( + &operation->ctx.opaque_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + if( status == PSA_SUCCESS ) operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; - else - { - mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_opaque_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - } return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ default: /* Key is declared with a lifetime not known to us */ - return( PSA_ERROR_NOT_SUPPORTED ); + (void)status; + (void)key_buffer; + (void)key_buffer_size; + (void)alg; + return( PSA_ERROR_INVALID_ARGUMENT ); } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void)slot; - (void)alg; - (void)operation; - - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ } psa_status_t psa_driver_wrapper_cipher_decrypt_setup( - psa_operation_driver_context_t *operation, - psa_key_slot_t *slot, + 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 ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); - psa_key_attributes_t attributes = { - .core = slot->attr - }; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); switch( location ) { case PSA_KEY_LOCATION_LOCAL_STORAGE: /* Key is stored in the slot in export representation, so * cycle through all known transparent accelerators */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) - operation->ctx = mbedtls_calloc( 1, sizeof(test_transparent_cipher_operation_t) ); - if( operation->ctx == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - - status = test_transparent_cipher_decrypt_setup( operation->ctx, - &attributes, - slot->key.data, - slot->key.bytes, - alg ); + status = test_transparent_cipher_decrypt_setup( + &operation->ctx.transparent_test_driver_ctx, + attributes, + key_buffer, + key_buffer_size, + alg ); /* Declared with fallback == true */ if( status == PSA_SUCCESS ) operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; - else - { - mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_transparent_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - } - return( status ); + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) /* Fell through, meaning no accelerator supports this operation */ - return( PSA_ERROR_NOT_SUPPORTED ); - /* Add cases for opaque driver here */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LIFETIME: - operation->ctx = mbedtls_calloc( 1, sizeof(test_opaque_cipher_operation_t) ); - if( operation->ctx == NULL ) - return PSA_ERROR_INSUFFICIENT_MEMORY; - - status = test_opaque_cipher_decrypt_setup( operation->ctx, - &attributes, - slot->key.data, - slot->key.bytes, + status = mbedtls_psa_cipher_decrypt_setup( &operation->ctx.mbedtls_ctx, + attributes, + key_buffer, + key_buffer_size, alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + + return( status ); +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ + return( PSA_ERROR_NOT_SUPPORTED ); + + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + status = test_opaque_cipher_decrypt_setup( + &operation->ctx.opaque_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + if( status == PSA_SUCCESS ) operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; - else - { - mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_opaque_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - } return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ default: /* Key is declared with a lifetime not known to us */ - return( PSA_ERROR_NOT_SUPPORTED ); + (void)status; + (void)key_buffer; + (void)key_buffer_size; + (void)alg; + return( PSA_ERROR_INVALID_ARGUMENT ); } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void)slot; - (void)alg; - (void)operation; - - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ } psa_status_t psa_driver_wrapper_cipher_generate_iv( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, uint8_t *iv, size_t iv_size, size_t *iv_length ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) switch( operation->id ) { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( test_transparent_cipher_generate_iv( operation->ctx, - iv, - iv_size, - iv_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( test_opaque_cipher_generate_iv( operation->ctx, +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_cipher_generate_iv( &operation->ctx.mbedtls_ctx, iv, iv_size, iv_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - default: - /* Key is attached to a driver not known to us */ - return( PSA_ERROR_BAD_STATE ); - } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void) operation; - (void) iv; - (void) iv_size; - (void) iv_length; +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_generate_iv( + &operation->ctx.transparent_test_driver_ctx, + iv, iv_size, iv_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_generate_iv( + &operation->ctx.opaque_test_driver_ctx, + iv, + iv_size, + iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + (void)iv; + (void)iv_size; + (void)iv_length; + + return( PSA_ERROR_INVALID_ARGUMENT ); } psa_status_t psa_driver_wrapper_cipher_set_iv( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, const uint8_t *iv, size_t iv_length ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) switch( operation->id ) { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( test_transparent_cipher_set_iv( operation->ctx, - iv, - iv_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( test_opaque_cipher_set_iv( operation->ctx, +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_cipher_set_iv( &operation->ctx.mbedtls_ctx, iv, iv_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - default: - /* Key is attached to a driver not known to us */ - return( PSA_ERROR_BAD_STATE ); - } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void) operation; - (void) iv; - (void) iv_length; +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_set_iv( + &operation->ctx.transparent_test_driver_ctx, + iv, iv_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_set_iv( + &operation->ctx.opaque_test_driver_ctx, + iv, iv_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + (void)iv; + (void)iv_length; + + return( PSA_ERROR_INVALID_ARGUMENT ); } psa_status_t psa_driver_wrapper_cipher_update( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, const uint8_t *input, size_t input_length, uint8_t *output, size_t output_size, size_t *output_length ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) switch( operation->id ) { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( test_transparent_cipher_update( operation->ctx, - input, - input_length, - output, - output_size, - output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( test_opaque_cipher_update( operation->ctx, +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_cipher_update( &operation->ctx.mbedtls_ctx, input, input_length, output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - default: - /* Key is attached to a driver not known to us */ - return( PSA_ERROR_BAD_STATE ); - } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void) operation; - (void) input; - (void) input_length; - (void) output; - (void) output_length; - (void) output_size; +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_update( + &operation->ctx.transparent_test_driver_ctx, + input, input_length, + output, output_size, output_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_update( + &operation->ctx.opaque_test_driver_ctx, + input, input_length, + output, output_size, output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + (void)input; + (void)input_length; + (void)output; + (void)output_size; + (void)output_length; + + return( PSA_ERROR_INVALID_ARGUMENT ); } psa_status_t psa_driver_wrapper_cipher_finish( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, uint8_t *output, size_t output_size, size_t *output_length ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) switch( operation->id ) { -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( test_transparent_cipher_finish( operation->ctx, - output, - output_size, - output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( test_opaque_cipher_finish( operation->ctx, +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_cipher_finish( &operation->ctx.mbedtls_ctx, output, output_size, output_length ) ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ - default: - /* Key is attached to a driver not known to us */ - return( PSA_ERROR_BAD_STATE ); - } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void) operation; - (void) output; - (void) output_size; - (void) output_length; +#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( test_transparent_cipher_finish( + &operation->ctx.transparent_test_driver_ctx, + output, output_size, output_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( test_opaque_cipher_finish( + &operation->ctx.opaque_test_driver_ctx, + output, output_size, output_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + (void)output; + (void)output_size; + (void)output_length; + + return( PSA_ERROR_INVALID_ARGUMENT ); } psa_status_t psa_driver_wrapper_cipher_abort( - psa_operation_driver_context_t *operation ) + psa_cipher_operation_t *operation ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) && defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - - /* 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. */ - if( operation->ctx == NULL && operation->id == 0 ) - return( PSA_SUCCESS ); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; switch( operation->id ) { +#if defined(MBEDTLS_PSA_BUILTIN_CIPHER) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_cipher_abort( &operation->ctx.mbedtls_ctx ) ); +#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: - status = test_transparent_cipher_abort( operation->ctx ); + status = test_transparent_cipher_abort( + &operation->ctx.transparent_test_driver_ctx ); mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_transparent_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - operation->id = 0; - + &operation->ctx.transparent_test_driver_ctx, + sizeof( operation->ctx.transparent_test_driver_ctx ) ); return( status ); -#endif /* PSA_CRYPTO_DRIVER_TEST */ -#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - status = test_opaque_cipher_abort( operation->ctx ); + status = test_opaque_cipher_abort( + &operation->ctx.opaque_test_driver_ctx ); mbedtls_platform_zeroize( - operation->ctx, - sizeof( test_opaque_cipher_operation_t ) ); - mbedtls_free( operation->ctx ); - operation->ctx = NULL; - operation->id = 0; - + &operation->ctx.opaque_test_driver_ctx, + sizeof( operation->ctx.opaque_test_driver_ctx ) ); return( status ); #endif /* PSA_CRYPTO_DRIVER_TEST */ - default: - /* Operation is attached to a driver not known to us */ - return( PSA_ERROR_BAD_STATE ); +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ } -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void)operation; - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ + (void)status; + return( PSA_ERROR_INVALID_ARGUMENT ); } /* diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index dd7c6c7a1..d4ff91cde 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -90,28 +90,30 @@ psa_status_t psa_driver_wrapper_cipher_decrypt( size_t *output_length ); psa_status_t psa_driver_wrapper_cipher_encrypt_setup( - psa_operation_driver_context_t *operation, - psa_key_slot_t *slot, + 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 ); psa_status_t psa_driver_wrapper_cipher_decrypt_setup( - psa_operation_driver_context_t *operation, - psa_key_slot_t *slot, + 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 ); psa_status_t psa_driver_wrapper_cipher_generate_iv( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, uint8_t *iv, size_t iv_size, size_t *iv_length ); psa_status_t psa_driver_wrapper_cipher_set_iv( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, const uint8_t *iv, size_t iv_length ); psa_status_t psa_driver_wrapper_cipher_update( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, const uint8_t *input, size_t input_length, uint8_t *output, @@ -119,13 +121,13 @@ psa_status_t psa_driver_wrapper_cipher_update( size_t *output_length ); psa_status_t psa_driver_wrapper_cipher_finish( - psa_operation_driver_context_t *operation, + psa_cipher_operation_t *operation, uint8_t *output, size_t output_size, size_t *output_length ); psa_status_t psa_driver_wrapper_cipher_abort( - psa_operation_driver_context_t *operation ); + psa_cipher_operation_t *operation ); /* * Hashing functions diff --git a/tests/include/test/drivers/cipher.h b/tests/include/test/drivers/cipher.h index ef787f794..56b11591f 100644 --- a/tests/include/test/drivers/cipher.h +++ b/tests/include/test/drivers/cipher.h @@ -28,22 +28,9 @@ #if defined(PSA_CRYPTO_DRIVER_TEST) #include +#include #include "mbedtls/cipher.h" -typedef struct { - psa_algorithm_t alg; - unsigned int key_set : 1; - unsigned int iv_required : 1; - unsigned int iv_set : 1; - uint8_t iv_size; - uint8_t block_size; - mbedtls_cipher_context_t cipher; -} test_transparent_cipher_operation_t; - -typedef struct{ - unsigned int initialised : 1; - test_transparent_cipher_operation_t ctx; -} test_opaque_cipher_operation_t; typedef struct { /* If non-null, on success, copy this to the output. */ @@ -80,44 +67,36 @@ psa_status_t test_transparent_cipher_decrypt( uint8_t *output, size_t output_size, size_t *output_length); psa_status_t test_transparent_cipher_encrypt_setup( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg); psa_status_t test_transparent_cipher_decrypt_setup( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg); psa_status_t test_transparent_cipher_abort( - test_transparent_cipher_operation_t *operation); + mbedtls_transparent_test_driver_cipher_operation_t *operation ); psa_status_t test_transparent_cipher_generate_iv( - test_transparent_cipher_operation_t *operation, - uint8_t *iv, - size_t iv_size, - size_t *iv_length); + mbedtls_transparent_test_driver_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length); psa_status_t test_transparent_cipher_set_iv( - test_transparent_cipher_operation_t *operation, - const uint8_t *iv, - size_t iv_length); + mbedtls_transparent_test_driver_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length); psa_status_t test_transparent_cipher_update( - test_transparent_cipher_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); + mbedtls_transparent_test_driver_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length); psa_status_t test_transparent_cipher_finish( - test_transparent_cipher_operation_t *operation, - uint8_t *output, - size_t output_size, - size_t *output_length); + mbedtls_transparent_test_driver_cipher_operation_t *operation, + uint8_t *output, size_t output_size, size_t *output_length); /* * opaque versions @@ -137,44 +116,36 @@ psa_status_t test_opaque_cipher_decrypt( uint8_t *output, size_t output_size, size_t *output_length); psa_status_t test_opaque_cipher_encrypt_setup( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg); psa_status_t test_opaque_cipher_decrypt_setup( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg); psa_status_t test_opaque_cipher_abort( - test_opaque_cipher_operation_t *operation); + mbedtls_opaque_test_driver_cipher_operation_t *operation); psa_status_t test_opaque_cipher_generate_iv( - test_opaque_cipher_operation_t *operation, - uint8_t *iv, - size_t iv_size, - size_t *iv_length); + mbedtls_opaque_test_driver_cipher_operation_t *operation, + uint8_t *iv, size_t iv_size, size_t *iv_length); psa_status_t test_opaque_cipher_set_iv( - test_opaque_cipher_operation_t *operation, - const uint8_t *iv, - size_t iv_length); + mbedtls_opaque_test_driver_cipher_operation_t *operation, + const uint8_t *iv, size_t iv_length); psa_status_t test_opaque_cipher_update( - test_opaque_cipher_operation_t *operation, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); + mbedtls_opaque_test_driver_cipher_operation_t *operation, + const uint8_t *input, size_t input_length, + uint8_t *output, size_t output_size, size_t *output_length); psa_status_t test_opaque_cipher_finish( - test_opaque_cipher_operation_t *operation, - uint8_t *output, - size_t output_size, - size_t *output_length); + mbedtls_opaque_test_driver_cipher_operation_t *operation, + uint8_t *output, size_t output_size, size_t *output_length); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_TEST_DRIVERS_CIPHER_H */ diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 00e18ddd8..f768e1e5e 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1443,29 +1443,59 @@ component_test_no_use_psa_crypto_full_cmake_asan() { } component_test_psa_crypto_config_basic() { - # full plus MBEDTLS_PSA_CRYPTO_CONFIG - msg "build: full + MBEDTLS_PSA_CRYPTO_CONFIG" + # Test the library excluding all Mbed TLS cryptographic support for which + # we have an accelerator support. Acceleration is faked with the + # transparent test driver. + msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG + as much acceleration as supported" scripts/config.py full scripts/config.py set MBEDTLS_PSA_CRYPTO_CONFIG scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO + + # There is no intended accelerator support for ALG STREAM_CIPHER and + # ALG_ECB_NO_PADDING. Therefore, asking for them in the build implies the + # inclusion of the Mbed TLS cipher operations. As we want to test here with + # cipher operations solely supported by accelerators, disabled those + # PSA configuration options. + scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_STREAM_CIPHER + scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_ALG_ECB_NO_PADDING + + # Don't test DES encryption as: + # 1) It is not an issue if we don't test all cipher types here. + # 2) That way we don't have to modify in psa_crypto.c the compilation + # guards MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES for the code they guard to be + # available to the test driver. Modifications that we would need to + # revert when we move to compile the test driver separately. + # We also disable MBEDTLS_DES_C as the dependencies on DES in PSA test + # suites are still based on MBEDTLS_DES_C and not PSA_WANT_KEY_TYPE_DES. + scripts/config.py -f include/psa/crypto_config.h unset PSA_WANT_KEY_TYPE_DES + scripts/config.py unset MBEDTLS_DES_C + # Need to define the correct symbol and include the test driver header path in order to build with the test driver loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS" @@ -2239,21 +2269,29 @@ component_test_psa_crypto_drivers () { scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS # Need to define the correct symbol and include the test driver header path in order to build with the test driver loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_CAMELLIA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN" - loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CTR" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CFB" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_ECDSA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_DETERMINISTIC_ECDSA" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD2" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD4" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_MD5" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_OFB" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RIPEMD160" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PKCS1V15_SIGN" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_RSA_PSS" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_1" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_224" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_256" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" diff --git a/tests/src/drivers/cipher.c b/tests/src/drivers/cipher.c index fa7c6a9e7..295d47a69 100644 --- a/tests/src/drivers/cipher.c +++ b/tests/src/drivers/cipher.c @@ -26,6 +26,7 @@ #if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST) #include "psa/crypto.h" +#include "psa_crypto_cipher.h" #include "psa_crypto_core.h" #include "mbedtls/cipher.h" @@ -204,212 +205,100 @@ psa_status_t test_transparent_cipher_decrypt( output, output_size, output_length) ); } -static psa_status_t test_transparent_cipher_setup( - mbedtls_operation_t direction, - test_transparent_cipher_operation_t *operation, +psa_status_t test_transparent_cipher_encrypt_setup( + mbedtls_transparent_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg) { - const mbedtls_cipher_info_t *cipher_info = NULL; - int ret = 0; - test_driver_cipher_hooks.hits++; - if( operation->alg != 0 ) - return( PSA_ERROR_BAD_STATE ); - - /* Wiping the entire struct here, instead of member-by-member. This is useful - * for the test suite, since it gives a chance of catching memory corruption - * errors should the core not have allocated (enough) memory for our context - * struct. */ + /* Wiping the entire struct here, instead of member-by-member. This is + * useful for the test suite, since it gives a chance of catching memory + * corruption errors should the core not have allocated (enough) memory for + * our context struct. */ memset( operation, 0, sizeof( *operation ) ); - /* Allow overriding return value for testing purposes */ if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) return( test_driver_cipher_hooks.forced_status ); - /* Test driver supports AES-CTR only, to verify operation calls. */ - if( alg != PSA_ALG_CTR || - psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES ) - return( PSA_ERROR_NOT_SUPPORTED ); - - operation->alg = alg; - operation->iv_size = 16; - - cipher_info = mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES, - key_length * 8, - MBEDTLS_MODE_CTR ); - if( cipher_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - - mbedtls_cipher_init( &operation->cipher ); - ret = mbedtls_cipher_setup( &operation->cipher, cipher_info ); - if( ret != 0 ) { - mbedtls_cipher_free( &operation->cipher ); - return( mbedtls_to_psa_error( ret ) ); - } - - ret = mbedtls_cipher_setkey( &operation->cipher, - key, - key_length * 8, direction ); - if( ret != 0 ) { - mbedtls_cipher_free( &operation->cipher ); - return( mbedtls_to_psa_error( ret ) ); - } - - operation->iv_set = 0; - operation->iv_required = 1; - operation->key_set = 1; - - return( test_driver_cipher_hooks.forced_status ); -} - -psa_status_t test_transparent_cipher_encrypt_setup( - test_transparent_cipher_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key, size_t key_length, - psa_algorithm_t alg) -{ - return ( test_transparent_cipher_setup( MBEDTLS_ENCRYPT, - operation, - attributes, - key, - key_length, - alg ) ); + return ( mbedtls_transparent_test_driver_cipher_encrypt_setup( + operation, attributes, key, key_length, alg ) ); } psa_status_t test_transparent_cipher_decrypt_setup( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg) { - return ( test_transparent_cipher_setup( MBEDTLS_DECRYPT, - operation, - attributes, - key, - key_length, - alg ) ); + test_driver_cipher_hooks.hits++; + + if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_cipher_hooks.forced_status ); + + return ( mbedtls_transparent_test_driver_cipher_decrypt_setup( + operation, attributes, key, key_length, alg ) ); } psa_status_t test_transparent_cipher_abort( - test_transparent_cipher_operation_t *operation) + mbedtls_transparent_test_driver_cipher_operation_t *operation) { test_driver_cipher_hooks.hits++; if( operation->alg == 0 ) return( PSA_SUCCESS ); - if( operation->alg != PSA_ALG_CTR ) - return( PSA_ERROR_BAD_STATE ); - mbedtls_cipher_free( &operation->cipher ); + mbedtls_transparent_test_driver_cipher_abort( operation ); - /* Wiping the entire struct here, instead of member-by-member. This is useful - * for the test suite, since it gives a chance of catching memory corruption - * errors should the core not have allocated (enough) memory for our context - * struct. */ + /* Wiping the entire struct here, instead of member-by-member. This is + * useful for the test suite, since it gives a chance of catching memory + * corruption errors should the core not have allocated (enough) memory for + * our context struct. */ memset( operation, 0, sizeof( *operation ) ); - return( PSA_SUCCESS ); + return( test_driver_cipher_hooks.forced_status ); } psa_status_t test_transparent_cipher_generate_iv( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, uint8_t *iv, size_t iv_size, size_t *iv_length) { - psa_status_t status; - mbedtls_test_rnd_pseudo_info rnd_info; - memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) ); - test_driver_cipher_hooks.hits++; if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) return( test_driver_cipher_hooks.forced_status ); - if( operation->alg != PSA_ALG_CTR ) - return( PSA_ERROR_BAD_STATE ); - - if( operation->iv_set || ! operation->iv_required ) - return( PSA_ERROR_BAD_STATE ); - - if( iv_size < operation->iv_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - - status = mbedtls_to_psa_error( - mbedtls_test_rnd_pseudo_rand( &rnd_info, - iv, - operation->iv_size ) ); - if( status != PSA_SUCCESS ) - return( status ); - - *iv_length = operation->iv_size; - status = test_transparent_cipher_set_iv( operation, iv, *iv_length ); - - return( status ); + return( mbedtls_transparent_test_driver_cipher_generate_iv( + operation, iv, iv_size, iv_length ) ); } psa_status_t test_transparent_cipher_set_iv( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, const uint8_t *iv, size_t iv_length) { - psa_status_t status; - test_driver_cipher_hooks.hits++; if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) return( test_driver_cipher_hooks.forced_status ); - if( operation->alg != PSA_ALG_CTR ) - return( PSA_ERROR_BAD_STATE ); - - if( operation->iv_set || ! operation->iv_required ) - return( PSA_ERROR_BAD_STATE ); - - if( iv_length != operation->iv_size ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - status = mbedtls_to_psa_error( - mbedtls_cipher_set_iv( &operation->cipher, iv, iv_length ) ); - - if( status == PSA_SUCCESS ) - operation->iv_set = 1; - - return( status ); + return( mbedtls_transparent_test_driver_cipher_set_iv( + operation, iv, iv_length ) ); } psa_status_t test_transparent_cipher_update( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, const uint8_t *input, size_t input_length, uint8_t *output, size_t output_size, size_t *output_length) { - psa_status_t status; - test_driver_cipher_hooks.hits++; - if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) - return( test_driver_cipher_hooks.forced_status ); - - if( operation->alg != PSA_ALG_CTR ) - return( PSA_ERROR_BAD_STATE ); - - /* CTR is a stream cipher, so data in and out are always the same size */ - if( output_size < input_length ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - - status = mbedtls_to_psa_error( - mbedtls_cipher_update( &operation->cipher, input, - input_length, output, output_length ) ); - - if( status != PSA_SUCCESS ) - return status; - if( test_driver_cipher_hooks.forced_output != NULL ) { if( output_size < test_driver_cipher_hooks.forced_output_length ) @@ -419,52 +308,26 @@ psa_status_t test_transparent_cipher_update( test_driver_cipher_hooks.forced_output, test_driver_cipher_hooks.forced_output_length ); *output_length = test_driver_cipher_hooks.forced_output_length; + + return( test_driver_cipher_hooks.forced_status ); } - return( test_driver_cipher_hooks.forced_status ); + if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_cipher_hooks.forced_status ); + + return( mbedtls_transparent_test_driver_cipher_update( + operation, input, input_length, + output, output_size, output_length ) ); } psa_status_t test_transparent_cipher_finish( - test_transparent_cipher_operation_t *operation, + mbedtls_transparent_test_driver_cipher_operation_t *operation, uint8_t *output, size_t output_size, size_t *output_length) { - psa_status_t status = PSA_ERROR_GENERIC_ERROR; - uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH]; - test_driver_cipher_hooks.hits++; - if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) - return( test_driver_cipher_hooks.forced_status ); - - if( operation->alg != PSA_ALG_CTR ) - return( PSA_ERROR_BAD_STATE ); - - if( ! operation->key_set ) - return( PSA_ERROR_BAD_STATE ); - - if( operation->iv_required && ! operation->iv_set ) - return( PSA_ERROR_BAD_STATE ); - - status = mbedtls_to_psa_error( - mbedtls_cipher_finish( &operation->cipher, - temp_output_buffer, - output_length ) ); - - mbedtls_cipher_free( &operation->cipher ); - - if( status != PSA_SUCCESS ) - return( status ); - - if( *output_length == 0 ) - ; /* Nothing to copy. Note that output may be NULL in this case. */ - else if( output_size >= *output_length ) - memcpy( output, temp_output_buffer, *output_length ); - else - return( PSA_ERROR_BUFFER_TOO_SMALL ); - - if( test_driver_cipher_hooks.forced_output != NULL ) { if( output_size < test_driver_cipher_hooks.forced_output_length ) @@ -474,9 +337,15 @@ psa_status_t test_transparent_cipher_finish( test_driver_cipher_hooks.forced_output, test_driver_cipher_hooks.forced_output_length ); *output_length = test_driver_cipher_hooks.forced_output_length; + + return( test_driver_cipher_hooks.forced_status ); } - return( test_driver_cipher_hooks.forced_status ); + if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_cipher_hooks.forced_status ); + + return( mbedtls_transparent_test_driver_cipher_finish( + operation, output, output_size, output_length ) ); } /* @@ -521,7 +390,7 @@ psa_status_t test_opaque_cipher_decrypt( } psa_status_t test_opaque_cipher_encrypt_setup( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg) @@ -535,7 +404,7 @@ psa_status_t test_opaque_cipher_encrypt_setup( } psa_status_t test_opaque_cipher_decrypt_setup( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key, size_t key_length, psa_algorithm_t alg) @@ -549,14 +418,14 @@ psa_status_t test_opaque_cipher_decrypt_setup( } psa_status_t test_opaque_cipher_abort( - test_opaque_cipher_operation_t *operation) + mbedtls_opaque_test_driver_cipher_operation_t *operation ) { (void) operation; return( PSA_ERROR_NOT_SUPPORTED ); } psa_status_t test_opaque_cipher_generate_iv( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, uint8_t *iv, size_t iv_size, size_t *iv_length) @@ -569,7 +438,7 @@ psa_status_t test_opaque_cipher_generate_iv( } psa_status_t test_opaque_cipher_set_iv( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const uint8_t *iv, size_t iv_length) { @@ -580,7 +449,7 @@ psa_status_t test_opaque_cipher_set_iv( } psa_status_t test_opaque_cipher_update( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, const uint8_t *input, size_t input_length, uint8_t *output, @@ -597,7 +466,7 @@ psa_status_t test_opaque_cipher_update( } psa_status_t test_opaque_cipher_finish( - test_opaque_cipher_operation_t *operation, + mbedtls_opaque_test_driver_cipher_operation_t *operation, uint8_t *output, size_t output_size, size_t *output_length) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index b4ae8e56d..07311e47a 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -93,11 +93,11 @@ depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_SUCCESS:PSA_SUCCESS PSA symmetric encrypt: AES-CTR, 16 bytes, fallback -depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS PSA symmetric encrypt: AES-CTR, 15 bytes, fallback -depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"8f9408fe80a81d3e813da3c7b0b2bd":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS PSA symmetric encrypt: AES-CTR, 16 bytes, fake @@ -113,7 +113,7 @@ depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":0:PSA_SUCCESS:PSA_SUCCESS PSA symmetric decrypt: AES-CTR, 16 bytes, fallback -depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_CIPHER cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"dd3b5e5319b7591daab1e1a92687feb2":0:PSA_ERROR_NOT_SUPPORTED:PSA_SUCCESS PSA symmetric decrypt: AES-CTR, 16 bytes, fake diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 7a013443f..0fb1b5c7f 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -222,6 +222,7 @@ + @@ -250,6 +251,7 @@ + @@ -324,6 +326,7 @@ +