Merge remote-tracking branch 'psa/psa-wrapper-apis-march-12' into feature-psa
This commit is contained in:
commit
3aa8efb230
5 changed files with 885 additions and 13 deletions
|
@ -301,8 +301,6 @@ static psa_status_t mbedtls_to_psa_error( int ret )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key management */
|
||||
/****************************************************************/
|
||||
|
@ -920,7 +918,9 @@ static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
|
|||
if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
|
||||
{
|
||||
if( PSA_ALG_IS_BLOCK_CIPHER( alg ) )
|
||||
alg &= ~PSA_ALG_BLOCK_CIPHER_MODE_MASK;
|
||||
{
|
||||
alg &= ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
|
||||
}
|
||||
switch( alg )
|
||||
{
|
||||
case PSA_ALG_STREAM_CIPHER:
|
||||
|
@ -996,11 +996,13 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation )
|
|||
#endif /* MBEDTLS_MD_C */
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
}
|
||||
|
||||
operation->alg = 0;
|
||||
operation->key_set = 0;
|
||||
operation->iv_set = 0;
|
||||
operation->iv_required = 0;
|
||||
operation->has_input = 0;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
|
@ -1378,6 +1380,269 @@ psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Symmetric cryptography */
|
||||
/****************************************************************/
|
||||
|
||||
static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation,
|
||||
psa_key_slot_t key,
|
||||
psa_algorithm_t alg,
|
||||
mbedtls_operation_t cipher_operation )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
psa_status_t status;
|
||||
key_slot_t *slot;
|
||||
psa_key_type_t key_type;
|
||||
size_t key_bits;
|
||||
const mbedtls_cipher_info_t *cipher_info = NULL;
|
||||
|
||||
operation->alg = alg;
|
||||
operation->key_set = 0;
|
||||
operation->iv_set = 0;
|
||||
operation->iv_required = 1;
|
||||
operation->iv_size = 0;
|
||||
operation->block_size = 0;
|
||||
|
||||
status = psa_get_key_information( key, &key_type, &key_bits );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
slot = &global_data.key_slots[key];
|
||||
|
||||
cipher_info = mbedtls_cipher_info_from_psa( alg, key_type, key_bits );
|
||||
if( cipher_info == NULL )
|
||||
return( PSA_ERROR_NOT_SUPPORTED );
|
||||
|
||||
mbedtls_cipher_init( &operation->ctx.cipher );
|
||||
ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_setkey( &operation->ctx.cipher, slot->data.raw.data,
|
||||
key_bits, cipher_operation );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING)
|
||||
if( ( alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK ) == PSA_ALG_CBC_BASE )
|
||||
{
|
||||
psa_algorithm_t padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
|
||||
mbedtls_cipher_padding_t mode;
|
||||
|
||||
switch ( padding_mode )
|
||||
{
|
||||
case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
|
||||
mode = MBEDTLS_PADDING_PKCS7;
|
||||
break;
|
||||
case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
|
||||
mode = MBEDTLS_PADDING_NONE;
|
||||
break;
|
||||
default:
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher, mode );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
}
|
||||
#endif //MBEDTLS_CIPHER_MODE_WITH_PADDING
|
||||
|
||||
operation->key_set = 1;
|
||||
operation->alg = alg;
|
||||
operation->block_size = ( PSA_ALG_IS_BLOCK_CIPHER( alg ) ?
|
||||
PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) :
|
||||
1 );
|
||||
if( PSA_ALG_IS_BLOCK_CIPHER( alg ) || ( alg == PSA_ALG_CTR ) )
|
||||
{
|
||||
operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type );
|
||||
}
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_encrypt_setup( psa_cipher_operation_t *operation,
|
||||
psa_key_slot_t key,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
return psa_cipher_setup( operation, key, alg, MBEDTLS_ENCRYPT );
|
||||
}
|
||||
|
||||
psa_status_t psa_decrypt_setup( psa_cipher_operation_t *operation,
|
||||
psa_key_slot_t key,
|
||||
psa_algorithm_t alg )
|
||||
{
|
||||
return psa_cipher_setup( operation, key, alg, MBEDTLS_DECRYPT );
|
||||
}
|
||||
|
||||
psa_status_t psa_encrypt_generate_iv( psa_cipher_operation_t *operation,
|
||||
unsigned char *iv,
|
||||
size_t iv_size,
|
||||
size_t *iv_length )
|
||||
{
|
||||
int ret = PSA_SUCCESS;
|
||||
if( operation->iv_set || !( operation->iv_required ) )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
if( iv_size < operation->iv_size )
|
||||
{
|
||||
ret = PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
goto exit;
|
||||
}
|
||||
ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg,
|
||||
iv, operation->iv_size );
|
||||
if( ret != 0 )
|
||||
{
|
||||
ret = mbedtls_to_psa_error( ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
*iv_length = operation->iv_size;
|
||||
ret = psa_encrypt_set_iv( operation, iv, *iv_length );
|
||||
|
||||
exit:
|
||||
if( ret != PSA_SUCCESS )
|
||||
psa_cipher_abort( operation );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
psa_status_t psa_encrypt_set_iv( psa_cipher_operation_t *operation,
|
||||
const unsigned char *iv,
|
||||
size_t iv_length )
|
||||
{
|
||||
int ret = PSA_SUCCESS;
|
||||
if( operation->iv_set || !( operation->iv_required ) )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
if( iv_length != operation->iv_size )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
ret = mbedtls_cipher_set_iv( &operation->ctx.cipher, iv, iv_length );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
operation->iv_set = 1;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_update( psa_cipher_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
unsigned char *output,
|
||||
size_t output_size,
|
||||
size_t *output_length )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
size_t expected_output_size;
|
||||
if( PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
|
||||
{
|
||||
/* Take the unprocessed partial block left over from previous
|
||||
* update calls, if any, plus the input to this call. Remove
|
||||
* the last partial block, if any. You get the data that will be
|
||||
* output in this call. */
|
||||
expected_output_size =
|
||||
( operation->ctx.cipher.unprocessed_len + input_length )
|
||||
/ operation->block_size * operation->block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
expected_output_size = input_length;
|
||||
}
|
||||
if( output_size < expected_output_size )
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
|
||||
ret = mbedtls_cipher_update( &operation->ctx.cipher, input,
|
||||
input_length, output, output_length );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length )
|
||||
{
|
||||
int ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
|
||||
uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
|
||||
|
||||
if( ! operation->key_set )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
if( operation->iv_required && ! operation->iv_set )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
}
|
||||
if( operation->ctx.cipher.operation == MBEDTLS_ENCRYPT &&
|
||||
PSA_ALG_IS_BLOCK_CIPHER( operation->alg ) )
|
||||
{
|
||||
psa_algorithm_t padding_mode =
|
||||
operation->alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
|
||||
if( operation->ctx.cipher.unprocessed_len >= operation->block_size )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_TAMPERING_DETECTED );
|
||||
}
|
||||
if( padding_mode == PSA_ALG_BLOCK_CIPHER_PAD_NONE )
|
||||
{
|
||||
if( operation->ctx.cipher.unprocessed_len != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_INVALID_ARGUMENT );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = mbedtls_cipher_finish( &operation->ctx.cipher, temp_output_buffer,
|
||||
output_length );
|
||||
if( ret != 0 )
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( mbedtls_to_psa_error( ret ) );
|
||||
}
|
||||
if( output_size >= *output_length )
|
||||
memcpy( output, temp_output_buffer, *output_length );
|
||||
else
|
||||
{
|
||||
psa_cipher_abort( operation );
|
||||
return( PSA_ERROR_BUFFER_TOO_SMALL );
|
||||
}
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation )
|
||||
{
|
||||
mbedtls_cipher_free( &operation->ctx.cipher );
|
||||
|
||||
operation->alg = 0;
|
||||
operation->key_set = 0;
|
||||
operation->iv_set = 0;
|
||||
operation->iv_size = 0;
|
||||
operation->block_size = 0;
|
||||
operation->iv_required = 0;
|
||||
|
||||
return( PSA_SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* Key Policy */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue