Merge pull request #3644 from stevew817/feature/transparent_multipart_driver
Add multipart cipher accelerator support and test driver
This commit is contained in:
commit
7107e661b8
11 changed files with 2154 additions and 71 deletions
4
ChangeLog.d/add_cipher_transparent_driver.txt
Normal file
4
ChangeLog.d/add_cipher_transparent_driver.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Features
|
||||||
|
* Partial implementation of the new PSA Crypto accelerator APIs for
|
||||||
|
enabling symmetric cipher acceleration through crypto accelerators.
|
||||||
|
Contributed by Steven Cooreman in #3644.
|
|
@ -77,6 +77,16 @@ extern "C" {
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#include "mbedtls/sha512.h"
|
#include "mbedtls/sha512.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
|
struct psa_hash_operation_s
|
||||||
{
|
{
|
||||||
psa_algorithm_t alg;
|
psa_algorithm_t alg;
|
||||||
|
@ -158,16 +168,18 @@ struct psa_cipher_operation_s
|
||||||
unsigned int key_set : 1;
|
unsigned int key_set : 1;
|
||||||
unsigned int iv_required : 1;
|
unsigned int iv_required : 1;
|
||||||
unsigned int iv_set : 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 iv_size;
|
||||||
uint8_t block_size;
|
uint8_t block_size;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
unsigned dummy; /* Enable easier initializing of the union. */
|
unsigned dummy; /* Enable easier initializing of the union. */
|
||||||
mbedtls_cipher_context_t cipher;
|
mbedtls_cipher_context_t cipher;
|
||||||
|
psa_operation_driver_context_t driver;
|
||||||
} ctx;
|
} ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, {0}}
|
#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}}
|
||||||
static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
|
static inline struct psa_cipher_operation_s psa_cipher_operation_init( void )
|
||||||
{
|
{
|
||||||
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
|
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
|
|
@ -4037,34 +4037,6 @@ rsa_exit:
|
||||||
/* Symmetric cryptography */
|
/* Symmetric cryptography */
|
||||||
/****************************************************************/
|
/****************************************************************/
|
||||||
|
|
||||||
/* Initialize the cipher operation structure. Once this function has been
|
|
||||||
* called, psa_cipher_abort can run and will do the right thing. */
|
|
||||||
static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation,
|
|
||||||
psa_algorithm_t alg )
|
|
||||||
{
|
|
||||||
if( ! PSA_ALG_IS_CIPHER( alg ) )
|
|
||||||
{
|
|
||||||
memset( operation, 0, sizeof( *operation ) );
|
|
||||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
|
||||||
}
|
|
||||||
|
|
||||||
operation->alg = alg;
|
|
||||||
operation->key_set = 0;
|
|
||||||
operation->iv_set = 0;
|
|
||||||
if( alg == PSA_ALG_ECB_NO_PADDING )
|
|
||||||
{
|
|
||||||
operation->iv_required = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
operation->iv_required = 1;
|
|
||||||
}
|
|
||||||
operation->iv_size = 0;
|
|
||||||
operation->block_size = 0;
|
|
||||||
mbedtls_cipher_init( &operation->ctx.cipher );
|
|
||||||
return( PSA_SUCCESS );
|
|
||||||
}
|
|
||||||
|
|
||||||
static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
||||||
psa_key_handle_t handle,
|
psa_key_handle_t handle,
|
||||||
psa_algorithm_t alg,
|
psa_algorithm_t alg,
|
||||||
|
@ -4081,19 +4053,63 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
||||||
|
|
||||||
/* A context must be freshly initialized before it can be set up. */
|
/* A context must be freshly initialized before it can be set up. */
|
||||||
if( operation->alg != 0 )
|
if( operation->alg != 0 )
|
||||||
{
|
|
||||||
return( PSA_ERROR_BAD_STATE );
|
return( PSA_ERROR_BAD_STATE );
|
||||||
}
|
|
||||||
|
|
||||||
status = psa_cipher_init( operation, alg );
|
/* The requested algorithm must be one that can be processed by cipher. */
|
||||||
if( status != PSA_SUCCESS )
|
if( ! PSA_ALG_IS_CIPHER( alg ) )
|
||||||
return( status );
|
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||||
|
|
||||||
status = psa_get_transparent_key( handle, &slot, usage, alg);
|
/* Fetch key material from key storage. */
|
||||||
|
status = psa_get_key_from_slot( handle, &slot, usage, alg );
|
||||||
if( status != PSA_SUCCESS )
|
if( status != PSA_SUCCESS )
|
||||||
goto exit;
|
goto exit;
|
||||||
key_bits = psa_get_key_slot_bits( slot );
|
|
||||||
|
|
||||||
|
/* Initialize the operation struct members, except for alg. The alg 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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
alg );
|
||||||
|
else
|
||||||
|
status = psa_driver_wrapper_cipher_decrypt_setup( &operation->ctx.driver,
|
||||||
|
slot,
|
||||||
|
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 );
|
cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL );
|
||||||
if( cipher_info == NULL )
|
if( cipher_info == NULL )
|
||||||
{
|
{
|
||||||
|
@ -4146,7 +4162,6 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
||||||
goto exit;
|
goto exit;
|
||||||
#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
|
#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
|
||||||
|
|
||||||
operation->key_set = 1;
|
|
||||||
operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
|
operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
|
||||||
PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
|
PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) );
|
||||||
if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
|
if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 &&
|
||||||
|
@ -4160,10 +4175,17 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
||||||
operation->iv_size = 12;
|
operation->iv_size = 12;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
status = PSA_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if( status == 0 )
|
if( ret != 0 )
|
||||||
status = mbedtls_to_psa_error( ret );
|
status = mbedtls_to_psa_error( ret );
|
||||||
if( status != 0 )
|
if( status == PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
/* Update operation flags for both driver and software implementations */
|
||||||
|
operation->key_set = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
psa_cipher_abort( operation );
|
psa_cipher_abort( operation );
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
@ -4193,6 +4215,16 @@ psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
|
||||||
{
|
{
|
||||||
return( PSA_ERROR_BAD_STATE );
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if( iv_size < operation->iv_size )
|
if( iv_size < operation->iv_size )
|
||||||
{
|
{
|
||||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||||
|
@ -4210,7 +4242,9 @@ psa_status_t psa_cipher_generate_iv( psa_cipher_operation_t *operation,
|
||||||
status = psa_cipher_set_iv( operation, iv, *iv_length );
|
status = psa_cipher_set_iv( operation, iv, *iv_length );
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if( status != PSA_SUCCESS )
|
if( status == PSA_SUCCESS )
|
||||||
|
operation->iv_set = 1;
|
||||||
|
else
|
||||||
psa_cipher_abort( operation );
|
psa_cipher_abort( operation );
|
||||||
return( status );
|
return( status );
|
||||||
}
|
}
|
||||||
|
@ -4225,6 +4259,15 @@ psa_status_t psa_cipher_set_iv( psa_cipher_operation_t *operation,
|
||||||
{
|
{
|
||||||
return( PSA_ERROR_BAD_STATE );
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if( iv_length != operation->iv_size )
|
if( iv_length != operation->iv_size )
|
||||||
{
|
{
|
||||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||||
|
@ -4337,11 +4380,25 @@ psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
|
||||||
{
|
{
|
||||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
size_t expected_output_size;
|
size_t expected_output_size;
|
||||||
|
|
||||||
if( operation->alg == 0 )
|
if( operation->alg == 0 )
|
||||||
{
|
{
|
||||||
return( PSA_ERROR_BAD_STATE );
|
return( PSA_ERROR_BAD_STATE );
|
||||||
}
|
}
|
||||||
|
if( operation->iv_required && ! operation->iv_set )
|
||||||
|
{
|
||||||
|
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 ) )
|
if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
|
||||||
{
|
{
|
||||||
|
@ -4394,10 +4451,8 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
|
||||||
size_t *output_length )
|
size_t *output_length )
|
||||||
{
|
{
|
||||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||||
int cipher_ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
|
||||||
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
|
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
|
||||||
|
if( operation->alg == 0 )
|
||||||
if( ! operation->key_set )
|
|
||||||
{
|
{
|
||||||
return( PSA_ERROR_BAD_STATE );
|
return( PSA_ERROR_BAD_STATE );
|
||||||
}
|
}
|
||||||
|
@ -4406,6 +4461,15 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
|
||||||
return( PSA_ERROR_BAD_STATE );
|
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->ctx.cipher.unprocessed_len != 0 )
|
||||||
{
|
{
|
||||||
if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
|
if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
|
||||||
|
@ -4413,49 +4477,44 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
|
||||||
operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) )
|
operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) )
|
||||||
{
|
{
|
||||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||||
goto error;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cipher_ret = mbedtls_cipher_finish( &operation->ctx.cipher,
|
status = mbedtls_to_psa_error(
|
||||||
temp_output_buffer,
|
mbedtls_cipher_finish( &operation->ctx.cipher,
|
||||||
output_length );
|
temp_output_buffer,
|
||||||
if( cipher_ret != 0 )
|
output_length ) );
|
||||||
{
|
if( status != PSA_SUCCESS )
|
||||||
status = mbedtls_to_psa_error( cipher_ret );
|
goto exit;
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *output_length == 0 )
|
if( *output_length == 0 )
|
||||||
; /* Nothing to copy. Note that output may be NULL in this case. */
|
; /* Nothing to copy. Note that output may be NULL in this case. */
|
||||||
else if( output_size >= *output_length )
|
else if( output_size >= *output_length )
|
||||||
memcpy( output, temp_output_buffer, *output_length );
|
memcpy( output, temp_output_buffer, *output_length );
|
||||||
else
|
else
|
||||||
{
|
|
||||||
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
status = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||||
goto error;
|
|
||||||
|
exit:
|
||||||
|
if( operation->mbedtls_in_use == 1 )
|
||||||
|
mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
|
||||||
|
|
||||||
|
if( status == PSA_SUCCESS )
|
||||||
|
return( psa_cipher_abort( operation ) );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*output_length = 0;
|
||||||
|
(void) psa_cipher_abort( operation );
|
||||||
|
|
||||||
|
return( status );
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
|
|
||||||
status = psa_cipher_abort( operation );
|
|
||||||
|
|
||||||
return( status );
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
*output_length = 0;
|
|
||||||
|
|
||||||
mbedtls_platform_zeroize( temp_output_buffer, sizeof( temp_output_buffer ) );
|
|
||||||
(void) psa_cipher_abort( operation );
|
|
||||||
|
|
||||||
return( status );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
|
psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
|
||||||
{
|
{
|
||||||
if( operation->alg == 0 )
|
if( operation->alg == 0 )
|
||||||
{
|
{
|
||||||
/* The object has (apparently) been initialized but it is not
|
/* 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
|
* in use. It's ok to call abort on such an object, and there's
|
||||||
* nothing to do. */
|
* nothing to do. */
|
||||||
return( PSA_SUCCESS );
|
return( PSA_SUCCESS );
|
||||||
|
@ -4466,11 +4525,15 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
|
||||||
if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
|
if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
|
||||||
return( PSA_ERROR_BAD_STATE );
|
return( PSA_ERROR_BAD_STATE );
|
||||||
|
|
||||||
mbedtls_cipher_free( &operation->ctx.cipher );
|
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->alg = 0;
|
||||||
operation->key_set = 0;
|
operation->key_set = 0;
|
||||||
operation->iv_set = 0;
|
operation->iv_set = 0;
|
||||||
|
operation->mbedtls_in_use = 0;
|
||||||
operation->iv_size = 0;
|
operation->iv_size = 0;
|
||||||
operation->block_size = 0;
|
operation->block_size = 0;
|
||||||
operation->iv_required = 0;
|
operation->iv_required = 0;
|
||||||
|
|
|
@ -38,6 +38,12 @@
|
||||||
|
|
||||||
/* Repeat above block for each JSON-declared driver during autogeneration */
|
/* Repeat above block for each JSON-declared driver during autogeneration */
|
||||||
|
|
||||||
|
/* Auto-generated values depending on which drivers are registered. ID 0 is
|
||||||
|
* reserved for unallocated operations. */
|
||||||
|
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||||
|
#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (1)
|
||||||
|
#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (2)
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
|
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
|
||||||
|
|
||||||
/* Support the 'old' SE interface when asked to */
|
/* Support the 'old' SE interface when asked to */
|
||||||
|
@ -370,4 +376,503 @@ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attrib
|
||||||
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cipher functions
|
||||||
|
*/
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_encrypt(
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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_DRIVER_TEST)
|
||||||
|
status = test_transparent_cipher_encrypt( &attributes,
|
||||||
|
slot->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
alg,
|
||||||
|
input,
|
||||||
|
input_length,
|
||||||
|
output,
|
||||||
|
output_size,
|
||||||
|
output_length );
|
||||||
|
/* Declared with fallback == true */
|
||||||
|
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||||
|
return( status );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
/* 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:
|
||||||
|
return( test_opaque_cipher_encrypt( &attributes,
|
||||||
|
slot->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
alg,
|
||||||
|
input,
|
||||||
|
input_length,
|
||||||
|
output,
|
||||||
|
output_size,
|
||||||
|
output_length ) );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
default:
|
||||||
|
/* Key is declared with a lifetime not known to us */
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
#else /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
(void) slot;
|
||||||
|
(void) alg;
|
||||||
|
(void) input;
|
||||||
|
(void) input_length;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_decrypt(
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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_DRIVER_TEST)
|
||||||
|
status = test_transparent_cipher_decrypt( &attributes,
|
||||||
|
slot->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
alg,
|
||||||
|
input,
|
||||||
|
input_length,
|
||||||
|
output,
|
||||||
|
output_size,
|
||||||
|
output_length );
|
||||||
|
/* Declared with fallback == true */
|
||||||
|
if( status != PSA_ERROR_NOT_SUPPORTED )
|
||||||
|
return( status );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
/* 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:
|
||||||
|
return( test_opaque_cipher_decrypt( &attributes,
|
||||||
|
slot->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
alg,
|
||||||
|
input,
|
||||||
|
input_length,
|
||||||
|
output,
|
||||||
|
output_size,
|
||||||
|
output_length ) );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
default:
|
||||||
|
/* Key is declared with a lifetime not known to us */
|
||||||
|
return( status );
|
||||||
|
}
|
||||||
|
#else /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
(void) slot;
|
||||||
|
(void) alg;
|
||||||
|
(void) input;
|
||||||
|
(void) input_length;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_encrypt_setup(
|
||||||
|
psa_operation_driver_context_t *operation,
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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_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->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
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 );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
/* 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->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
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 */
|
||||||
|
default:
|
||||||
|
/* Key is declared with a lifetime not known to us */
|
||||||
|
return( PSA_ERROR_BAD_STATE );
|
||||||
|
}
|
||||||
|
#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_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
|
||||||
|
};
|
||||||
|
|
||||||
|
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_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->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
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 );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
/* 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->data.key.data,
|
||||||
|
slot->data.key.bytes,
|
||||||
|
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 */
|
||||||
|
default:
|
||||||
|
/* Key is declared with a lifetime not known to us */
|
||||||
|
return( PSA_ERROR_BAD_STATE );
|
||||||
|
}
|
||||||
|
#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,
|
||||||
|
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,
|
||||||
|
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;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_set_iv(
|
||||||
|
psa_operation_driver_context_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,
|
||||||
|
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;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_update(
|
||||||
|
psa_operation_driver_context_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,
|
||||||
|
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;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_finish(
|
||||||
|
psa_operation_driver_context_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,
|
||||||
|
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;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_abort(
|
||||||
|
psa_operation_driver_context_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 );
|
||||||
|
|
||||||
|
switch( operation->id )
|
||||||
|
{
|
||||||
|
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||||
|
case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID:
|
||||||
|
status = test_transparent_cipher_abort( operation->ctx );
|
||||||
|
mbedtls_platform_zeroize(
|
||||||
|
operation->ctx,
|
||||||
|
sizeof( test_transparent_cipher_operation_t ) );
|
||||||
|
mbedtls_free( operation->ctx );
|
||||||
|
operation->ctx = NULL;
|
||||||
|
operation->id = 0;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
mbedtls_platform_zeroize(
|
||||||
|
operation->ctx,
|
||||||
|
sizeof( test_opaque_cipher_operation_t ) );
|
||||||
|
mbedtls_free( operation->ctx );
|
||||||
|
operation->ctx = NULL;
|
||||||
|
operation->id = 0;
|
||||||
|
|
||||||
|
return( status );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_TEST */
|
||||||
|
default:
|
||||||
|
/* Operation is attached to a driver not known to us */
|
||||||
|
return( PSA_ERROR_BAD_STATE );
|
||||||
|
}
|
||||||
|
#else /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
(void)operation;
|
||||||
|
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
#endif /* PSA_CRYPTO_DRIVER_PRESENT */
|
||||||
|
}
|
||||||
|
|
||||||
/* End of automatically generated file. */
|
/* End of automatically generated file. */
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#include "psa/crypto.h"
|
#include "psa/crypto.h"
|
||||||
#include "psa/crypto_driver_common.h"
|
#include "psa/crypto_driver_common.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Signature functions
|
||||||
|
*/
|
||||||
psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
|
psa_status_t psa_driver_wrapper_sign_hash( psa_key_slot_t *slot,
|
||||||
psa_algorithm_t alg,
|
psa_algorithm_t alg,
|
||||||
const uint8_t *hash,
|
const uint8_t *hash,
|
||||||
|
@ -43,6 +46,65 @@ psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot,
|
||||||
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
|
psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes,
|
||||||
psa_key_slot_t *slot );
|
psa_key_slot_t *slot );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cipher functions
|
||||||
|
*/
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_encrypt(
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input,
|
||||||
|
size_t input_length,
|
||||||
|
uint8_t *output,
|
||||||
|
size_t output_size,
|
||||||
|
size_t *output_length );
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_decrypt(
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input,
|
||||||
|
size_t input_length,
|
||||||
|
uint8_t *output,
|
||||||
|
size_t output_size,
|
||||||
|
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_algorithm_t alg );
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_decrypt_setup(
|
||||||
|
psa_operation_driver_context_t *operation,
|
||||||
|
psa_key_slot_t *slot,
|
||||||
|
psa_algorithm_t alg );
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_generate_iv(
|
||||||
|
psa_operation_driver_context_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,
|
||||||
|
const uint8_t *iv,
|
||||||
|
size_t iv_length );
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_update(
|
||||||
|
psa_operation_driver_context_t *operation,
|
||||||
|
const uint8_t *input,
|
||||||
|
size_t input_length,
|
||||||
|
uint8_t *output,
|
||||||
|
size_t output_size,
|
||||||
|
size_t *output_length );
|
||||||
|
|
||||||
|
psa_status_t psa_driver_wrapper_cipher_finish(
|
||||||
|
psa_operation_driver_context_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 );
|
||||||
|
|
||||||
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
|
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */
|
||||||
|
|
||||||
/* End of automatically generated file. */
|
/* End of automatically generated file. */
|
||||||
|
|
180
tests/include/test/drivers/cipher.h
Normal file
180
tests/include/test/drivers/cipher.h
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Test driver for cipher functions
|
||||||
|
*/
|
||||||
|
/* 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_TEST_DRIVERS_CIPHER_H
|
||||||
|
#define PSA_CRYPTO_TEST_DRIVERS_CIPHER_H
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PSA_CRYPTO_DRIVER_TEST)
|
||||||
|
#include <psa/crypto_driver_common.h>
|
||||||
|
|
||||||
|
#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. */
|
||||||
|
void *forced_output;
|
||||||
|
size_t forced_output_length;
|
||||||
|
/* If not PSA_SUCCESS, return this error code instead of processing the
|
||||||
|
* function call. */
|
||||||
|
psa_status_t forced_status;
|
||||||
|
/* Count the amount of times one of the cipher driver functions is called. */
|
||||||
|
unsigned long hits;
|
||||||
|
} test_driver_cipher_hooks_t;
|
||||||
|
|
||||||
|
#define TEST_DRIVER_CIPHER_INIT { NULL, 0, PSA_SUCCESS, 0 }
|
||||||
|
static inline test_driver_cipher_hooks_t test_driver_cipher_hooks_init( void )
|
||||||
|
{
|
||||||
|
const test_driver_cipher_hooks_t v = TEST_DRIVER_CIPHER_INIT;
|
||||||
|
return( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern test_driver_cipher_hooks_t test_driver_cipher_hooks;
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_encrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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_decrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_decrypt_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);
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_abort(
|
||||||
|
test_transparent_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);
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_set_iv(
|
||||||
|
test_transparent_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);
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_finish(
|
||||||
|
test_transparent_cipher_operation_t *operation,
|
||||||
|
uint8_t *output,
|
||||||
|
size_t output_size,
|
||||||
|
size_t *output_length);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* opaque versions
|
||||||
|
*/
|
||||||
|
psa_status_t test_opaque_cipher_encrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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_decrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
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_encrypt_setup(
|
||||||
|
test_opaque_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,
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_set_iv(
|
||||||
|
test_opaque_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);
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_finish(
|
||||||
|
test_opaque_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 */
|
|
@ -24,5 +24,6 @@
|
||||||
|
|
||||||
#include "test/drivers/signature.h"
|
#include "test/drivers/signature.h"
|
||||||
#include "test/drivers/keygen.h"
|
#include "test/drivers/keygen.h"
|
||||||
|
#include "test/drivers/cipher.h"
|
||||||
|
|
||||||
#endif /* PSA_CRYPTO_TEST_DRIVER_H */
|
#endif /* PSA_CRYPTO_TEST_DRIVER_H */
|
||||||
|
|
611
tests/src/drivers/cipher.c
Normal file
611
tests/src/drivers/cipher.c
Normal file
|
@ -0,0 +1,611 @@
|
||||||
|
/*
|
||||||
|
* Test driver for cipher functions.
|
||||||
|
* Currently only supports multi-part operations using AES-CTR.
|
||||||
|
*/
|
||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
|
#include "mbedtls/config.h"
|
||||||
|
#else
|
||||||
|
#include MBEDTLS_CONFIG_FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST)
|
||||||
|
#include "psa/crypto.h"
|
||||||
|
#include "psa_crypto_core.h"
|
||||||
|
#include "mbedtls/cipher.h"
|
||||||
|
|
||||||
|
#include "test/drivers/cipher.h"
|
||||||
|
|
||||||
|
#include "test/random.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Test driver implements AES-CTR only. Its default behaviour (when its return
|
||||||
|
* status is not overridden through the hooks) is to take care of all AES-CTR
|
||||||
|
* operations, and return PSA_ERROR_NOT_SUPPORTED for all others.
|
||||||
|
* Set test_driver_cipher_hooks.forced_status to PSA_ERROR_NOT_SUPPORTED to use
|
||||||
|
* fallback even for AES-CTR. */
|
||||||
|
test_driver_cipher_hooks_t test_driver_cipher_hooks = TEST_DRIVER_CIPHER_INIT;
|
||||||
|
|
||||||
|
static psa_status_t test_transparent_cipher_oneshot(
|
||||||
|
mbedtls_operation_t direction,
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output, size_t output_size, size_t *output_length)
|
||||||
|
{
|
||||||
|
test_driver_cipher_hooks.hits++;
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
|
||||||
|
/* If test driver response code is not SUCCESS, we can return early */
|
||||||
|
if( test_driver_cipher_hooks.forced_status != PSA_SUCCESS )
|
||||||
|
return( test_driver_cipher_hooks.forced_status );
|
||||||
|
|
||||||
|
/* If test driver output is overridden, we don't need to do actual crypto */
|
||||||
|
if( test_driver_cipher_hooks.forced_output != NULL )
|
||||||
|
{
|
||||||
|
if( output_size < test_driver_cipher_hooks.forced_output_length )
|
||||||
|
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||||
|
|
||||||
|
memcpy( output,
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run AES-CTR using the cipher module */
|
||||||
|
{
|
||||||
|
mbedtls_test_rnd_pseudo_info rnd_info;
|
||||||
|
memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
|
||||||
|
|
||||||
|
const mbedtls_cipher_info_t *cipher_info =
|
||||||
|
mbedtls_cipher_info_from_values( MBEDTLS_CIPHER_ID_AES,
|
||||||
|
key_length * 8,
|
||||||
|
MBEDTLS_MODE_CTR );
|
||||||
|
mbedtls_cipher_context_t cipher;
|
||||||
|
int ret = 0;
|
||||||
|
uint8_t temp_output_buffer[16] = {0};
|
||||||
|
size_t temp_output_length = 0;
|
||||||
|
|
||||||
|
if( direction == MBEDTLS_ENCRYPT )
|
||||||
|
{
|
||||||
|
/* Oneshot encrypt needs to prepend the IV to the output */
|
||||||
|
if( output_size < ( input_length + 16 ) )
|
||||||
|
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Oneshot decrypt has the IV prepended to the input */
|
||||||
|
if( output_size < ( input_length - 16 ) )
|
||||||
|
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cipher_info == NULL )
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
|
||||||
|
mbedtls_cipher_init( &cipher );
|
||||||
|
ret = mbedtls_cipher_setup( &cipher, cipher_info );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
ret = mbedtls_cipher_setkey( &cipher,
|
||||||
|
key,
|
||||||
|
key_length * 8, direction );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if( direction == MBEDTLS_ENCRYPT )
|
||||||
|
{
|
||||||
|
mbedtls_test_rnd_pseudo_info rnd_info;
|
||||||
|
memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) );
|
||||||
|
|
||||||
|
ret = mbedtls_test_rnd_pseudo_rand( &rnd_info,
|
||||||
|
temp_output_buffer,
|
||||||
|
16 );
|
||||||
|
if( ret != 0 )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
ret = mbedtls_cipher_set_iv( &cipher, temp_output_buffer, 16 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = mbedtls_cipher_set_iv( &cipher, input, 16 );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if( direction == MBEDTLS_ENCRYPT )
|
||||||
|
{
|
||||||
|
ret = mbedtls_cipher_update( &cipher,
|
||||||
|
input, input_length,
|
||||||
|
&output[16], output_length );
|
||||||
|
if( ret == 0 )
|
||||||
|
{
|
||||||
|
memcpy( output, temp_output_buffer, 16 );
|
||||||
|
*output_length += 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = mbedtls_cipher_update( &cipher,
|
||||||
|
&input[16], input_length - 16,
|
||||||
|
output, output_length );
|
||||||
|
|
||||||
|
if( ret != 0 )
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
ret = mbedtls_cipher_finish( &cipher,
|
||||||
|
temp_output_buffer,
|
||||||
|
&temp_output_length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
*output_length = 0;
|
||||||
|
memset(output, 0, output_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_cipher_free( &cipher );
|
||||||
|
return( mbedtls_to_psa_error( ret ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_encrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output, size_t output_size, size_t *output_length)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
test_transparent_cipher_oneshot(
|
||||||
|
MBEDTLS_ENCRYPT,
|
||||||
|
attributes,
|
||||||
|
key, key_length,
|
||||||
|
alg,
|
||||||
|
input, input_length,
|
||||||
|
output, output_size, output_length) );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_decrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output, size_t output_size, size_t *output_length)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
test_transparent_cipher_oneshot(
|
||||||
|
MBEDTLS_DECRYPT,
|
||||||
|
attributes,
|
||||||
|
key, key_length,
|
||||||
|
alg,
|
||||||
|
input, input_length,
|
||||||
|
output, output_size, output_length) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static psa_status_t test_transparent_cipher_setup(
|
||||||
|
mbedtls_operation_t direction,
|
||||||
|
test_transparent_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. */
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_decrypt_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_DECRYPT,
|
||||||
|
operation,
|
||||||
|
attributes,
|
||||||
|
key,
|
||||||
|
key_length,
|
||||||
|
alg ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_abort(
|
||||||
|
test_transparent_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 );
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_set_iv(
|
||||||
|
test_transparent_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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 )
|
||||||
|
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
memcpy( output,
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_transparent_cipher_finish(
|
||||||
|
test_transparent_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 )
|
||||||
|
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
memcpy( output,
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* opaque versions, to do
|
||||||
|
*/
|
||||||
|
psa_status_t test_opaque_cipher_encrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output, size_t output_size, size_t *output_length)
|
||||||
|
{
|
||||||
|
(void) attributes;
|
||||||
|
(void) key;
|
||||||
|
(void) key_length;
|
||||||
|
(void) alg;
|
||||||
|
(void) input;
|
||||||
|
(void) input_length;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_decrypt(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg,
|
||||||
|
const uint8_t *input, size_t input_length,
|
||||||
|
uint8_t *output, size_t output_size, size_t *output_length)
|
||||||
|
{
|
||||||
|
(void) attributes;
|
||||||
|
(void) key;
|
||||||
|
(void) key_length;
|
||||||
|
(void) alg;
|
||||||
|
(void) input;
|
||||||
|
(void) input_length;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_encrypt_setup(
|
||||||
|
test_opaque_cipher_operation_t *operation,
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) attributes;
|
||||||
|
(void) key;
|
||||||
|
(void) key_length;
|
||||||
|
(void) alg;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_decrypt_setup(
|
||||||
|
test_opaque_cipher_operation_t *operation,
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key, size_t key_length,
|
||||||
|
psa_algorithm_t alg)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) attributes;
|
||||||
|
(void) key;
|
||||||
|
(void) key_length;
|
||||||
|
(void) alg;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_abort(
|
||||||
|
test_opaque_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,
|
||||||
|
uint8_t *iv,
|
||||||
|
size_t iv_size,
|
||||||
|
size_t *iv_length)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) iv;
|
||||||
|
(void) iv_size;
|
||||||
|
(void) iv_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_set_iv(
|
||||||
|
test_opaque_cipher_operation_t *operation,
|
||||||
|
const uint8_t *iv,
|
||||||
|
size_t iv_length)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) iv;
|
||||||
|
(void) iv_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) input;
|
||||||
|
(void) input_length;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t test_opaque_cipher_finish(
|
||||||
|
test_opaque_cipher_operation_t *operation,
|
||||||
|
uint8_t *output,
|
||||||
|
size_t output_size,
|
||||||
|
size_t *output_length)
|
||||||
|
{
|
||||||
|
(void) operation;
|
||||||
|
(void) output;
|
||||||
|
(void) output_size;
|
||||||
|
(void) output_length;
|
||||||
|
return( PSA_ERROR_NOT_SUPPORTED );
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */
|
|
@ -39,3 +39,114 @@ generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_SUCCESS
|
||||||
|
|
||||||
generate_key through transparent driver: error
|
generate_key through transparent driver: error
|
||||||
generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR
|
generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR
|
||||||
|
|
||||||
|
PSA symmetric encrypt: AES-CTR, 16 bytes, good
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"8f9408fe80a81d3e813da3c7b0b2bd32":0:PSA_SUCCESS:PSA_SUCCESS
|
||||||
|
|
||||||
|
PSA symmetric encrypt: AES-CTR, 15 bytes, good
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
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:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
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:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
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
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
|
||||||
|
|
||||||
|
PSA symmetric encrypt: AES-CTR, 15 bytes, fake
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
|
||||||
|
|
||||||
|
PSA symmetric decrypt: AES-CTR, 16 bytes, good
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
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:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
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
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"396ee84fb75fdbb5c2b13c7fe5a654aa":"d07a6a6e2687feb2":1:PSA_SUCCESS:PSA_SUCCESS
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 11+5 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 16+16 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 12+20 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 20+12 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 12+10 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 0+15 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 15+0 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 0+16 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
PSA symmetric encryption multipart: AES-CTR, 16+0 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_encrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 11+5 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":11:11:5:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 16+16 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":16:16:16:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 12+20 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":12:12:20:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 20+12 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597bcef1389318c7fc865ef":20:20:12:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7baf71025f6ef6393ca587"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 12+10 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a5434f378a597":12:12:10:"8f9408fe80a81d3e813da3c7b0b2bd321c965bb1de7b"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 0+15 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":0:0:15:"8f9408fe80a81d3e813da3c7b0b2bd"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 15+0 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e11739317":15:15:0:"8f9408fe80a81d3e813da3c7b0b2bd"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 0+16 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":0:0:16:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
PSA symmetric decryption multipart: AES-CTR, 16+0 bytes
|
||||||
|
depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR
|
||||||
|
cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a":16:16:0:"8f9408fe80a81d3e813da3c7b0b2bd32"
|
||||||
|
|
||||||
|
Cipher driver: negative testing on all entry points
|
||||||
|
cipher_entry_points:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a"
|
||||||
|
|
|
@ -183,3 +183,536 @@ exit:
|
||||||
test_driver_keygen_hooks = test_driver_keygen_hooks_init();
|
test_driver_keygen_hooks = test_driver_keygen_hooks_init();
|
||||||
}
|
}
|
||||||
/* END_CASE */
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void cipher_encrypt( int alg_arg, int key_type_arg,
|
||||||
|
data_t *key, data_t *iv,
|
||||||
|
data_t *input, data_t *expected_output,
|
||||||
|
int mock_output_arg,
|
||||||
|
int force_status_arg,
|
||||||
|
int expected_status_arg )
|
||||||
|
{
|
||||||
|
psa_key_handle_t handle = 0;
|
||||||
|
psa_status_t status;
|
||||||
|
psa_key_type_t key_type = key_type_arg;
|
||||||
|
psa_algorithm_t alg = alg_arg;
|
||||||
|
psa_status_t expected_status = expected_status_arg;
|
||||||
|
psa_status_t force_status = force_status_arg;
|
||||||
|
unsigned char *output = NULL;
|
||||||
|
size_t output_buffer_size = 0;
|
||||||
|
size_t function_output_length = 0;
|
||||||
|
size_t total_output_length = 0;
|
||||||
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
test_driver_cipher_hooks.forced_status = force_status;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
|
||||||
|
psa_set_key_algorithm( &attributes, alg );
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
output_buffer_size = ( (size_t) input->len +
|
||||||
|
PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
|
||||||
|
ASSERT_ALLOC( output, output_buffer_size );
|
||||||
|
|
||||||
|
if( mock_output_arg )
|
||||||
|
{
|
||||||
|
test_driver_cipher_hooks.forced_output = expected_output->x;
|
||||||
|
test_driver_cipher_hooks.forced_output_length = expected_output->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
if( mock_output_arg )
|
||||||
|
{
|
||||||
|
test_driver_cipher_hooks.forced_output = NULL;
|
||||||
|
test_driver_cipher_hooks.forced_output_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
status = psa_cipher_finish( &operation,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length );
|
||||||
|
/* Finish will have called abort as well, so expecting two hits here */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 2 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
|
||||||
|
TEST_EQUAL( status, expected_status );
|
||||||
|
if( expected_status == PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
PSA_ASSERT( psa_cipher_abort( &operation ) );
|
||||||
|
// driver function should've been called as part of the finish() core routine
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
ASSERT_COMPARE( expected_output->x, expected_output->len,
|
||||||
|
output, total_output_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
mbedtls_free( output );
|
||||||
|
psa_destroy_key( handle );
|
||||||
|
PSA_DONE( );
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void cipher_encrypt_multipart( int alg_arg, int key_type_arg,
|
||||||
|
data_t *key, data_t *iv,
|
||||||
|
data_t *input,
|
||||||
|
int first_part_size_arg,
|
||||||
|
int output1_length_arg, int output2_length_arg,
|
||||||
|
data_t *expected_output )
|
||||||
|
{
|
||||||
|
psa_key_handle_t handle = 0;
|
||||||
|
psa_key_type_t key_type = key_type_arg;
|
||||||
|
psa_algorithm_t alg = alg_arg;
|
||||||
|
size_t first_part_size = first_part_size_arg;
|
||||||
|
size_t output1_length = output1_length_arg;
|
||||||
|
size_t output2_length = output2_length_arg;
|
||||||
|
unsigned char *output = NULL;
|
||||||
|
size_t output_buffer_size = 0;
|
||||||
|
size_t function_output_length = 0;
|
||||||
|
size_t total_output_length = 0;
|
||||||
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT );
|
||||||
|
psa_set_key_algorithm( &attributes, alg );
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
output_buffer_size = ( (size_t) input->len +
|
||||||
|
PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
|
||||||
|
ASSERT_ALLOC( output, output_buffer_size );
|
||||||
|
|
||||||
|
TEST_ASSERT( first_part_size <= input->len );
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation, input->x, first_part_size,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
TEST_ASSERT( function_output_length == output1_length );
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation,
|
||||||
|
input->x + first_part_size,
|
||||||
|
input->len - first_part_size,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
TEST_ASSERT( function_output_length == output2_length );
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_finish( &operation,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length ) );
|
||||||
|
/* Finish will have called abort as well, so expecting two hits here */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
test_driver_cipher_hooks.hits = 0 ;
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_abort( &operation ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( expected_output->x, expected_output->len,
|
||||||
|
output, total_output_length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
mbedtls_free( output );
|
||||||
|
psa_destroy_key( handle );
|
||||||
|
PSA_DONE( );
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void cipher_decrypt_multipart( int alg_arg, int key_type_arg,
|
||||||
|
data_t *key, data_t *iv,
|
||||||
|
data_t *input,
|
||||||
|
int first_part_size_arg,
|
||||||
|
int output1_length_arg, int output2_length_arg,
|
||||||
|
data_t *expected_output )
|
||||||
|
{
|
||||||
|
psa_key_handle_t handle = 0;
|
||||||
|
|
||||||
|
psa_key_type_t key_type = key_type_arg;
|
||||||
|
psa_algorithm_t alg = alg_arg;
|
||||||
|
size_t first_part_size = first_part_size_arg;
|
||||||
|
size_t output1_length = output1_length_arg;
|
||||||
|
size_t output2_length = output2_length_arg;
|
||||||
|
unsigned char *output = NULL;
|
||||||
|
size_t output_buffer_size = 0;
|
||||||
|
size_t function_output_length = 0;
|
||||||
|
size_t total_output_length = 0;
|
||||||
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
|
||||||
|
psa_set_key_algorithm( &attributes, alg );
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
|
||||||
|
handle, alg ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
output_buffer_size = ( (size_t) input->len +
|
||||||
|
PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
|
||||||
|
ASSERT_ALLOC( output, output_buffer_size );
|
||||||
|
|
||||||
|
TEST_ASSERT( first_part_size <= input->len );
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation,
|
||||||
|
input->x, first_part_size,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
TEST_ASSERT( function_output_length == output1_length );
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation,
|
||||||
|
input->x + first_part_size,
|
||||||
|
input->len - first_part_size,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
TEST_ASSERT( function_output_length == output2_length );
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_finish( &operation,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length ) );
|
||||||
|
/* Finish will have called abort as well, so expecting two hits here */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
PSA_ASSERT( psa_cipher_abort( &operation ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
|
||||||
|
ASSERT_COMPARE( expected_output->x, expected_output->len,
|
||||||
|
output, total_output_length );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
mbedtls_free( output );
|
||||||
|
psa_destroy_key( handle );
|
||||||
|
PSA_DONE( );
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void cipher_decrypt( int alg_arg, int key_type_arg,
|
||||||
|
data_t *key, data_t *iv,
|
||||||
|
data_t *input, data_t *expected_output,
|
||||||
|
int mock_output_arg,
|
||||||
|
int force_status_arg,
|
||||||
|
int expected_status_arg )
|
||||||
|
{
|
||||||
|
psa_key_handle_t handle = 0;
|
||||||
|
psa_status_t status;
|
||||||
|
psa_key_type_t key_type = key_type_arg;
|
||||||
|
psa_algorithm_t alg = alg_arg;
|
||||||
|
psa_status_t expected_status = expected_status_arg;
|
||||||
|
psa_status_t force_status = force_status_arg;
|
||||||
|
unsigned char *output = NULL;
|
||||||
|
size_t output_buffer_size = 0;
|
||||||
|
size_t function_output_length = 0;
|
||||||
|
size_t total_output_length = 0;
|
||||||
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
test_driver_cipher_hooks.forced_status = force_status;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT );
|
||||||
|
psa_set_key_algorithm( &attributes, alg );
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_decrypt_setup( &operation,
|
||||||
|
handle, alg ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
output_buffer_size = ( (size_t) input->len +
|
||||||
|
PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) );
|
||||||
|
ASSERT_ALLOC( output, output_buffer_size );
|
||||||
|
|
||||||
|
if( mock_output_arg )
|
||||||
|
{
|
||||||
|
test_driver_cipher_hooks.forced_output = expected_output->x;
|
||||||
|
test_driver_cipher_hooks.forced_output_length = expected_output->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 1 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
if( mock_output_arg )
|
||||||
|
{
|
||||||
|
test_driver_cipher_hooks.forced_output = NULL;
|
||||||
|
test_driver_cipher_hooks.forced_output_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
status = psa_cipher_finish( &operation,
|
||||||
|
output + total_output_length,
|
||||||
|
output_buffer_size - total_output_length,
|
||||||
|
&function_output_length );
|
||||||
|
/* Finish will have called abort as well, so expecting two hits here */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, ( force_status == PSA_SUCCESS ? 2 : 0 ) );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
total_output_length += function_output_length;
|
||||||
|
TEST_EQUAL( status, expected_status );
|
||||||
|
|
||||||
|
if( expected_status == PSA_SUCCESS )
|
||||||
|
{
|
||||||
|
PSA_ASSERT( psa_cipher_abort( &operation ) );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
ASSERT_COMPARE( expected_output->x, expected_output->len,
|
||||||
|
output, total_output_length );
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
mbedtls_free( output );
|
||||||
|
psa_destroy_key( handle );
|
||||||
|
PSA_DONE( );
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
||||||
|
/* BEGIN_CASE */
|
||||||
|
void cipher_entry_points( int alg_arg, int key_type_arg,
|
||||||
|
data_t *key, data_t *iv,
|
||||||
|
data_t *input )
|
||||||
|
{
|
||||||
|
psa_key_handle_t handle = 0;
|
||||||
|
psa_status_t status;
|
||||||
|
psa_key_type_t key_type = key_type_arg;
|
||||||
|
psa_algorithm_t alg = alg_arg;
|
||||||
|
unsigned char *output = NULL;
|
||||||
|
size_t output_buffer_size = 0;
|
||||||
|
size_t function_output_length = 0;
|
||||||
|
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
|
||||||
|
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
|
||||||
|
ASSERT_ALLOC( output, input->len + 16 );
|
||||||
|
output_buffer_size = input->len + 16;
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_crypto_init( ) );
|
||||||
|
|
||||||
|
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
|
||||||
|
psa_set_key_algorithm( &attributes, alg );
|
||||||
|
psa_set_key_type( &attributes, key_type );
|
||||||
|
|
||||||
|
PSA_ASSERT( psa_import_key( &attributes, key->x, key->len, &handle ) );
|
||||||
|
|
||||||
|
/* Test setup call, encrypt */
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR;
|
||||||
|
status = psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
/* When setup fails, it shouldn't call any further entry points */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_set_iv( &operation, iv->x, iv->len );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
|
||||||
|
/* Test setup call failure, decrypt */
|
||||||
|
status = psa_cipher_decrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
/* When setup fails, it shouldn't call any further entry points */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_set_iv( &operation, iv->x, iv->len );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
|
||||||
|
/* Test IV setting failure */
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_SUCCESS;
|
||||||
|
status = psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR;
|
||||||
|
status = psa_cipher_set_iv( &operation, iv->x, iv->len );
|
||||||
|
/* When setting the IV fails, it should call abort too */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
/* Failure should prevent further operations from executing on the driver */
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
|
||||||
|
/* Test IV generation failure */
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_SUCCESS;
|
||||||
|
status = psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR;
|
||||||
|
status = psa_cipher_generate_iv( &operation, output, 16, &function_output_length );
|
||||||
|
/* When generating the IV fails, it should call abort too */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
/* Failure should prevent further operations from executing on the driver */
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
|
||||||
|
/* Test update failure */
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_SUCCESS;
|
||||||
|
status = psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
status = psa_cipher_set_iv( &operation, iv->x, iv->len );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR;
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
/* When the update call fails, it should call abort too */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
/* Failure should prevent further operations from executing on the driver */
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
|
||||||
|
/* Test finish failure */
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_SUCCESS;
|
||||||
|
status = psa_cipher_encrypt_setup( &operation,
|
||||||
|
handle, alg );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
status = psa_cipher_set_iv( &operation, iv->x, iv->len );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 1 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
|
||||||
|
test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR;
|
||||||
|
status = psa_cipher_finish( &operation,
|
||||||
|
output + function_output_length,
|
||||||
|
output_buffer_size - function_output_length,
|
||||||
|
&function_output_length );
|
||||||
|
/* When the finish call fails, it should call abort too */
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 2 );
|
||||||
|
TEST_EQUAL( status, test_driver_cipher_hooks.forced_status );
|
||||||
|
/* Failure should prevent further operations from executing on the driver */
|
||||||
|
test_driver_cipher_hooks.hits = 0;
|
||||||
|
status = psa_cipher_update( &operation,
|
||||||
|
input->x, input->len,
|
||||||
|
output, output_buffer_size,
|
||||||
|
&function_output_length );
|
||||||
|
TEST_EQUAL( status, PSA_ERROR_BAD_STATE );
|
||||||
|
TEST_EQUAL( test_driver_cipher_hooks.hits, 0 );
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
|
||||||
|
exit:
|
||||||
|
psa_cipher_abort( &operation );
|
||||||
|
mbedtls_free( output );
|
||||||
|
psa_destroy_key( handle );
|
||||||
|
PSA_DONE( );
|
||||||
|
test_driver_cipher_hooks = test_driver_cipher_hooks_init();
|
||||||
|
}
|
||||||
|
/* END_CASE */
|
||||||
|
|
|
@ -238,6 +238,7 @@
|
||||||
<ClInclude Include="..\..\tests\include\test\psa_crypto_helpers.h" />
|
<ClInclude Include="..\..\tests\include\test\psa_crypto_helpers.h" />
|
||||||
<ClInclude Include="..\..\tests\include\test\psa_helpers.h" />
|
<ClInclude Include="..\..\tests\include\test\psa_helpers.h" />
|
||||||
<ClInclude Include="..\..\tests\include\test\random.h" />
|
<ClInclude Include="..\..\tests\include\test\random.h" />
|
||||||
|
<ClInclude Include="..\..\tests\include\test\drivers\cipher.h" />
|
||||||
<ClInclude Include="..\..\tests\include\test\drivers\keygen.h" />
|
<ClInclude Include="..\..\tests\include\test\drivers\keygen.h" />
|
||||||
<ClInclude Include="..\..\tests\include\test\drivers\signature.h" />
|
<ClInclude Include="..\..\tests\include\test\drivers\signature.h" />
|
||||||
<ClInclude Include="..\..\tests\include\test\drivers\test_driver.h" />
|
<ClInclude Include="..\..\tests\include\test\drivers\test_driver.h" />
|
||||||
|
|
Loading…
Reference in a new issue