Change the way driver context structures are used

Apparently there's a goal to make the PSA Crypto core free from
dynamic memory allocations. Therefore, all driver context structures
need to be known at compile time in order for the core to know their
final size.

This change defines & implements for hashing operations how the context
structures get defined.

Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
Steven Cooreman 2021-03-04 13:01:18 +01:00
parent 8e9e407fed
commit dbf8ceda54
6 changed files with 119 additions and 123 deletions

View file

@ -68,14 +68,9 @@ extern "C" {
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/cmac.h" #include "mbedtls/cmac.h"
#include "mbedtls/gcm.h" #include "mbedtls/gcm.h"
#include "mbedtls/md.h"
#include "mbedtls/md2.h" /* Include the context definition for the compiled-in drivers */
#include "mbedtls/md4.h" #include "../../library/psa_crypto_driver_wrappers_contexts.h"
#include "mbedtls/md5.h"
#include "mbedtls/ripemd160.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
typedef struct { typedef struct {
/** Unique ID indicating which driver got assigned to do the /** Unique ID indicating which driver got assigned to do the
@ -89,10 +84,17 @@ typedef struct {
struct psa_hash_operation_s struct psa_hash_operation_s
{ {
psa_operation_driver_context_t ctx; /** 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
* ID value zero means the context is not valid or not assigned to
* any driver (i.e. none of the driver contexts are active). */
unsigned int id;
union psa_driver_hash_context_u ctx;
}; };
#define PSA_HASH_OPERATION_INIT {{0, 0}} #define PSA_HASH_OPERATION_INIT {0, {0}}
static inline struct psa_hash_operation_s psa_hash_operation_init( void ) static inline struct psa_hash_operation_s psa_hash_operation_init( void )
{ {
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT; const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;

View file

@ -2196,30 +2196,42 @@ const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg )
psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) psa_status_t psa_hash_abort( psa_hash_operation_t *operation )
{ {
if( operation != NULL ) /* Aborting a non-active operation is allowed */
return( psa_driver_wrapper_hash_abort( &operation->ctx ) ); if( operation->id == 0 )
else return( PSA_SUCCESS );
return( PSA_ERROR_INVALID_ARGUMENT );
psa_status_t status = psa_driver_wrapper_hash_abort( operation );
operation->id = 0;
return( status );
} }
psa_status_t psa_hash_setup( psa_hash_operation_t *operation, psa_status_t psa_hash_setup( psa_hash_operation_t *operation,
psa_algorithm_t alg ) psa_algorithm_t alg )
{ {
if( operation == NULL || !PSA_ALG_IS_HASH( alg ) ) /* A context must be freshly initialized before it can be set up. */
if( operation->id != 0 )
return( PSA_ERROR_BAD_STATE );
if( !PSA_ALG_IS_HASH( alg ) )
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_INVALID_ARGUMENT );
return( psa_driver_wrapper_hash_setup( &operation->ctx, alg ) ); return( psa_driver_wrapper_hash_setup( operation, alg ) );
} }
psa_status_t psa_hash_update( psa_hash_operation_t *operation, psa_status_t psa_hash_update( psa_hash_operation_t *operation,
const uint8_t *input, const uint8_t *input,
size_t input_length ) size_t input_length )
{ {
if( operation == NULL ) if( operation->id == 0 )
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_BAD_STATE );
return( psa_driver_wrapper_hash_update( &operation->ctx, psa_status_t status = psa_driver_wrapper_hash_update( operation,
input, input_length ) ); input, input_length );
if( status != PSA_SUCCESS )
psa_hash_abort( operation );
return( status );
} }
psa_status_t psa_hash_finish( psa_hash_operation_t *operation, psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
@ -2227,12 +2239,11 @@ psa_status_t psa_hash_finish( psa_hash_operation_t *operation,
size_t hash_size, size_t hash_size,
size_t *hash_length ) size_t *hash_length )
{ {
if( operation == NULL ) if( operation->id == 0 )
return( PSA_ERROR_INVALID_ARGUMENT ); return( PSA_ERROR_BAD_STATE );
psa_status_t status = psa_driver_wrapper_hash_finish( psa_status_t status = psa_driver_wrapper_hash_finish(
&operation->ctx, operation, hash, hash_size, hash_length );
hash, hash_size, hash_length );
psa_hash_abort( operation ); psa_hash_abort( operation );
return( status ); return( status );
} }
@ -2241,13 +2252,10 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
const uint8_t *hash, const uint8_t *hash,
size_t hash_length ) size_t hash_length )
{ {
if( operation == NULL )
return( PSA_ERROR_INVALID_ARGUMENT );
uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE]; uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
size_t actual_hash_length; size_t actual_hash_length;
psa_status_t status = psa_driver_wrapper_hash_finish( psa_status_t status = psa_hash_finish(
&operation->ctx, operation,
actual_hash, sizeof( actual_hash ), actual_hash, sizeof( actual_hash ),
&actual_hash_length ); &actual_hash_length );
if( status != PSA_SUCCESS ) if( status != PSA_SUCCESS )
@ -2290,11 +2298,18 @@ psa_status_t psa_hash_compare( psa_algorithm_t alg,
psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation,
psa_hash_operation_t *target_operation ) psa_hash_operation_t *target_operation )
{ {
if( source_operation == NULL || target_operation == NULL ) if( source_operation->id == 0 ||
return( PSA_ERROR_INVALID_ARGUMENT ); target_operation->id != 0 )
{
return( PSA_ERROR_BAD_STATE );
}
return( psa_driver_wrapper_hash_clone( &source_operation->ctx, psa_status_t status = psa_driver_wrapper_hash_clone( source_operation,
&target_operation->ctx ) ); target_operation );
if( status != PSA_SUCCESS )
psa_hash_abort( target_operation );
return( status );
} }

View file

@ -59,9 +59,6 @@
#include "psa_crypto_se.h" #include "psa_crypto_se.h"
#endif #endif
/* Include software fallback when present */
#include "psa_crypto_hash.h"
/* Start delegation functions */ /* Start delegation functions */
psa_status_t psa_driver_wrapper_sign_hash( psa_status_t psa_driver_wrapper_sign_hash(
const psa_key_attributes_t *attributes, const psa_key_attributes_t *attributes,
@ -1109,31 +1106,18 @@ psa_status_t psa_driver_wrapper_hash_compute(
} }
psa_status_t psa_driver_wrapper_hash_setup( psa_status_t psa_driver_wrapper_hash_setup(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
psa_algorithm_t alg ) psa_algorithm_t alg )
{ {
psa_status_t status = PSA_ERROR_NOT_SUPPORTED; psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
/* A context must be freshly initialized before it can be set up. */
if( operation->id != 0 || operation->ctx != NULL )
return( PSA_ERROR_BAD_STATE );
/* Try setup on accelerators first */ /* Try setup on accelerators first */
/* If software fallback is compiled in, try fallback */ /* If software fallback is compiled in, try fallback */
#if defined(MBEDTLS_PSA_BUILTIN_HASH) #if defined(MBEDTLS_PSA_BUILTIN_HASH)
operation->ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) ); status = mbedtls_psa_hash_setup( &operation->ctx.mbedtls_ctx, alg );
status = mbedtls_psa_hash_setup( operation->ctx, alg );
if( status == PSA_SUCCESS ) if( status == PSA_SUCCESS )
{
operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
}
else
{
mbedtls_free( operation->ctx );
operation->ctx = NULL;
operation->id = 0;
}
if( status != PSA_ERROR_NOT_SUPPORTED ) if( status != PSA_ERROR_NOT_SUPPORTED )
return( status ); return( status );
@ -1146,131 +1130,77 @@ psa_status_t psa_driver_wrapper_hash_setup(
} }
psa_status_t psa_driver_wrapper_hash_clone( psa_status_t psa_driver_wrapper_hash_clone(
const psa_operation_driver_context_t *source_operation, const psa_hash_operation_t *source_operation,
psa_operation_driver_context_t *target_operation ) psa_hash_operation_t *target_operation )
{ {
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if( source_operation->ctx == NULL || source_operation->id == 0 )
return( PSA_ERROR_BAD_STATE );
if( target_operation->ctx != NULL || target_operation->id != 0 )
return( PSA_ERROR_BAD_STATE );
switch( source_operation->id ) switch( source_operation->id )
{ {
#if defined(MBEDTLS_PSA_BUILTIN_HASH) #if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID: case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
target_operation->ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) );
if( target_operation->ctx == NULL )
{
status = PSA_ERROR_INSUFFICIENT_MEMORY;
break;
}
target_operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; target_operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID;
status = mbedtls_psa_hash_clone( source_operation->ctx, return( mbedtls_psa_hash_clone( &source_operation->ctx.mbedtls_ctx,
target_operation->ctx ); &target_operation->ctx.mbedtls_ctx ) );
break;
#endif #endif
default: default:
(void) status;
(void) source_operation; (void) source_operation;
(void) target_operation; (void) target_operation;
return( PSA_ERROR_BAD_STATE ); return( PSA_ERROR_BAD_STATE );
} }
if( status != PSA_SUCCESS )
psa_driver_wrapper_hash_abort( target_operation );
return( status );
} }
psa_status_t psa_driver_wrapper_hash_update( psa_status_t psa_driver_wrapper_hash_update(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
const uint8_t *input, const uint8_t *input,
size_t input_length ) size_t input_length )
{ {
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if( operation->ctx == NULL || operation->id == 0 )
return( PSA_ERROR_BAD_STATE );
switch( operation->id ) switch( operation->id )
{ {
#if defined(MBEDTLS_PSA_BUILTIN_HASH) #if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID: case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
status = mbedtls_psa_hash_update( operation->ctx, return( mbedtls_psa_hash_update( &operation->ctx.mbedtls_ctx,
input, input_length ); input, input_length ) );
break;
#endif #endif
default: default:
(void) status;
(void) operation; (void) operation;
(void) input; (void) input;
(void) input_length; (void) input_length;
return( PSA_ERROR_BAD_STATE ); return( PSA_ERROR_BAD_STATE );
} }
if( status != PSA_SUCCESS )
psa_driver_wrapper_hash_abort( operation );
return( status );
} }
psa_status_t psa_driver_wrapper_hash_finish( psa_status_t psa_driver_wrapper_hash_finish(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
uint8_t *hash, uint8_t *hash,
size_t hash_size, size_t hash_size,
size_t *hash_length ) size_t *hash_length )
{ {
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
if( operation->ctx == NULL || operation->id == 0 )
return( PSA_ERROR_BAD_STATE );
switch( operation->id ) switch( operation->id )
{ {
#if defined(MBEDTLS_PSA_BUILTIN_HASH) #if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID: case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
status = mbedtls_psa_hash_finish( operation->ctx, return( mbedtls_psa_hash_finish( &operation->ctx.mbedtls_ctx,
hash, hash_size, hash_length ); hash, hash_size, hash_length ) );
break; break;
#endif #endif
default: default:
(void) status;
(void) operation; (void) operation;
(void) hash; (void) hash;
(void) hash_size; (void) hash_size;
(void) hash_length; (void) hash_length;
return( PSA_ERROR_BAD_STATE ); return( PSA_ERROR_BAD_STATE );
} }
psa_driver_wrapper_hash_abort( operation );
return( status );
} }
psa_status_t psa_driver_wrapper_hash_abort( psa_status_t psa_driver_wrapper_hash_abort(
psa_operation_driver_context_t *operation ) psa_hash_operation_t *operation )
{ {
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
switch( operation->id ) switch( operation->id )
{ {
case 0:
if( operation->ctx == NULL )
return( PSA_SUCCESS );
else
return( PSA_ERROR_BAD_STATE );
#if defined(MBEDTLS_PSA_BUILTIN_HASH) #if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID: case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
if( operation->ctx != NULL ) return( mbedtls_psa_hash_abort( &operation->ctx.mbedtls_ctx ) );
{
status = mbedtls_psa_hash_abort( operation->ctx );
mbedtls_free( operation->ctx );
operation->ctx = NULL;
}
operation->id = 0;
return( PSA_SUCCESS );
#endif #endif
default: default:
(void) status;
return( PSA_ERROR_BAD_STATE ); return( PSA_ERROR_BAD_STATE );
} }
} }

View file

@ -139,26 +139,26 @@ psa_status_t psa_driver_wrapper_hash_compute(
size_t *hash_length); size_t *hash_length);
psa_status_t psa_driver_wrapper_hash_setup( psa_status_t psa_driver_wrapper_hash_setup(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
psa_algorithm_t alg ); psa_algorithm_t alg );
psa_status_t psa_driver_wrapper_hash_clone( psa_status_t psa_driver_wrapper_hash_clone(
const psa_operation_driver_context_t *source_operation, const psa_hash_operation_t *source_operation,
psa_operation_driver_context_t *target_operation ); psa_hash_operation_t *target_operation );
psa_status_t psa_driver_wrapper_hash_update( psa_status_t psa_driver_wrapper_hash_update(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
const uint8_t *input, const uint8_t *input,
size_t input_length ); size_t input_length );
psa_status_t psa_driver_wrapper_hash_finish( psa_status_t psa_driver_wrapper_hash_finish(
psa_operation_driver_context_t *operation, psa_hash_operation_t *operation,
uint8_t *hash, uint8_t *hash,
size_t hash_size, size_t hash_size,
size_t *hash_length ); size_t *hash_length );
psa_status_t psa_driver_wrapper_hash_abort( psa_status_t psa_driver_wrapper_hash_abort(
psa_operation_driver_context_t *operation ); psa_hash_operation_t *operation );
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */

View file

@ -0,0 +1,48 @@
/*
* Declaration of context structures for use with the PSA driver wrapper
* interface.
*
* Warning: This file will be auto-generated in the future.
*/
/* 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_DRIVER_WRAPPERS_CONTEXTS_H
#define PSA_CRYPTO_DRIVER_WRAPPERS_CONTEXTS_H
#include "psa/crypto.h"
#include "psa/crypto_driver_common.h"
/* Include all structure definitions for the drivers that have been included
* during the auto-generation of this file (autogeneration not yet in place) */
/* Include the structure definitions for the mbed TLS software drivers */
#include "psa_crypto_hash.h"
/* Define the context to be used for an operation that is executed through the
* PSA Driver wrapper layer as the union of all possible driver's contexts.
*
* The union members are the driver's context structures, and the member names
* are formatted as `'drivername'_ctx`. This allows for procedural generation
* of both this file and the content of psa_crypto_driver_wrappers.c */
union psa_driver_hash_context_u {
unsigned dummy; /* Make sure this structure is always non-empty */
mbedtls_psa_hash_operation_t mbedtls_ctx;
};
#endif /* PSA_CRYPTO_DRIVER_WRAPPERS_CONTEXTS_H */
/* End of automatically generated file. */

View file

@ -250,6 +250,7 @@
<ClInclude Include="..\..\library\common.h" /> <ClInclude Include="..\..\library\common.h" />
<ClInclude Include="..\..\library\psa_crypto_core.h" /> <ClInclude Include="..\..\library\psa_crypto_core.h" />
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" /> <ClInclude Include="..\..\library\psa_crypto_driver_wrappers.h" />
<ClInclude Include="..\..\library\psa_crypto_driver_wrappers_contexts.h" />
<ClInclude Include="..\..\library\psa_crypto_ecp.h" /> <ClInclude Include="..\..\library\psa_crypto_ecp.h" />
<ClInclude Include="..\..\library\psa_crypto_hash.h" /> <ClInclude Include="..\..\library\psa_crypto_hash.h" />
<ClInclude Include="..\..\library\psa_crypto_invasive.h" /> <ClInclude Include="..\..\library\psa_crypto_invasive.h" />