diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 1defd9bd7..5d03d110d 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -68,14 +68,9 @@ extern "C" {
#include "mbedtls/cipher.h"
#include "mbedtls/cmac.h"
#include "mbedtls/gcm.h"
-#include "mbedtls/md.h"
-#include "mbedtls/md2.h"
-#include "mbedtls/md4.h"
-#include "mbedtls/md5.h"
-#include "mbedtls/ripemd160.h"
-#include "mbedtls/sha1.h"
-#include "mbedtls/sha256.h"
-#include "mbedtls/sha512.h"
+
+/* Include the context definition for the compiled-in drivers */
+#include "../../library/psa_crypto_driver_wrappers_contexts.h"
typedef struct {
/** Unique ID indicating which driver got assigned to do the
@@ -89,10 +84,17 @@ typedef struct {
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 )
{
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 4824b45a3..9c645efb6 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -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 )
{
- if( operation != NULL )
- return( psa_driver_wrapper_hash_abort( &operation->ctx ) );
- else
- return( PSA_ERROR_INVALID_ARGUMENT );
+ /* Aborting a non-active operation is allowed */
+ if( operation->id == 0 )
+ return( PSA_SUCCESS );
+
+ 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_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_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,
const uint8_t *input,
size_t input_length )
{
- if( operation == NULL )
- return( PSA_ERROR_INVALID_ARGUMENT );
+ if( operation->id == 0 )
+ return( PSA_ERROR_BAD_STATE );
- return( psa_driver_wrapper_hash_update( &operation->ctx,
- input, input_length ) );
+ psa_status_t status = psa_driver_wrapper_hash_update( operation,
+ input, input_length );
+ if( status != PSA_SUCCESS )
+ psa_hash_abort( operation );
+
+ return( status );
}
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_length )
{
- if( operation == NULL )
- return( PSA_ERROR_INVALID_ARGUMENT );
+ if( operation->id == 0 )
+ return( PSA_ERROR_BAD_STATE );
psa_status_t status = psa_driver_wrapper_hash_finish(
- &operation->ctx,
- hash, hash_size, hash_length );
+ operation, hash, hash_size, hash_length );
psa_hash_abort( operation );
return( status );
}
@@ -2241,13 +2252,10 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation,
const uint8_t *hash,
size_t hash_length )
{
- if( operation == NULL )
- return( PSA_ERROR_INVALID_ARGUMENT );
-
uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE];
size_t actual_hash_length;
- psa_status_t status = psa_driver_wrapper_hash_finish(
- &operation->ctx,
+ psa_status_t status = psa_hash_finish(
+ operation,
actual_hash, sizeof( actual_hash ),
&actual_hash_length );
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_hash_operation_t *target_operation )
{
- if( source_operation == NULL || target_operation == NULL )
- return( PSA_ERROR_INVALID_ARGUMENT );
+ if( source_operation->id == 0 ||
+ target_operation->id != 0 )
+ {
+ return( PSA_ERROR_BAD_STATE );
+ }
- return( psa_driver_wrapper_hash_clone( &source_operation->ctx,
- &target_operation->ctx ) );
+ psa_status_t status = psa_driver_wrapper_hash_clone( source_operation,
+ target_operation );
+ if( status != PSA_SUCCESS )
+ psa_hash_abort( target_operation );
+
+ return( status );
}
diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c
index 72077acd3..43aa180cb 100644
--- a/library/psa_crypto_driver_wrappers.c
+++ b/library/psa_crypto_driver_wrappers.c
@@ -59,9 +59,6 @@
#include "psa_crypto_se.h"
#endif
-/* Include software fallback when present */
-#include "psa_crypto_hash.h"
-
/* Start delegation functions */
psa_status_t psa_driver_wrapper_sign_hash(
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_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
psa_algorithm_t alg )
{
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 */
/* If software fallback is compiled in, try fallback */
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
- operation->ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) );
- status = mbedtls_psa_hash_setup( operation->ctx, alg );
+ status = mbedtls_psa_hash_setup( &operation->ctx.mbedtls_ctx, alg );
if( status == PSA_SUCCESS )
- {
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 )
return( status );
@@ -1146,131 +1130,77 @@ psa_status_t psa_driver_wrapper_hash_setup(
}
psa_status_t psa_driver_wrapper_hash_clone(
- const psa_operation_driver_context_t *source_operation,
- psa_operation_driver_context_t *target_operation )
+ const psa_hash_operation_t *source_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 )
{
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
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;
- status = mbedtls_psa_hash_clone( source_operation->ctx,
- target_operation->ctx );
- break;
+ return( mbedtls_psa_hash_clone( &source_operation->ctx.mbedtls_ctx,
+ &target_operation->ctx.mbedtls_ctx ) );
#endif
default:
- (void) status;
(void) source_operation;
(void) target_operation;
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_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
const uint8_t *input,
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 )
{
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
- status = mbedtls_psa_hash_update( operation->ctx,
- input, input_length );
- break;
+ return( mbedtls_psa_hash_update( &operation->ctx.mbedtls_ctx,
+ input, input_length ) );
#endif
default:
- (void) status;
(void) operation;
(void) input;
(void) input_length;
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_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
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 )
{
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
- status = mbedtls_psa_hash_finish( operation->ctx,
- hash, hash_size, hash_length );
+ return( mbedtls_psa_hash_finish( &operation->ctx.mbedtls_ctx,
+ hash, hash_size, hash_length ) );
break;
#endif
default:
- (void) status;
(void) operation;
(void) hash;
(void) hash_size;
(void) hash_length;
return( PSA_ERROR_BAD_STATE );
}
-
- psa_driver_wrapper_hash_abort( operation );
- return( status );
}
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 )
{
- case 0:
- if( operation->ctx == NULL )
- return( PSA_SUCCESS );
- else
- return( PSA_ERROR_BAD_STATE );
#if defined(MBEDTLS_PSA_BUILTIN_HASH)
case PSA_CRYPTO_MBED_TLS_DRIVER_ID:
- if( operation->ctx != NULL )
- {
- status = mbedtls_psa_hash_abort( operation->ctx );
- mbedtls_free( operation->ctx );
- operation->ctx = NULL;
- }
- operation->id = 0;
- return( PSA_SUCCESS );
+ return( mbedtls_psa_hash_abort( &operation->ctx.mbedtls_ctx ) );
#endif
default:
- (void) status;
return( PSA_ERROR_BAD_STATE );
}
}
diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h
index 1190a0e1b..dd7c6c7a1 100644
--- a/library/psa_crypto_driver_wrappers.h
+++ b/library/psa_crypto_driver_wrappers.h
@@ -139,26 +139,26 @@ psa_status_t psa_driver_wrapper_hash_compute(
size_t *hash_length);
psa_status_t psa_driver_wrapper_hash_setup(
- psa_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
psa_algorithm_t alg );
psa_status_t psa_driver_wrapper_hash_clone(
- const psa_operation_driver_context_t *source_operation,
- psa_operation_driver_context_t *target_operation );
+ const psa_hash_operation_t *source_operation,
+ psa_hash_operation_t *target_operation );
psa_status_t psa_driver_wrapper_hash_update(
- psa_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
const uint8_t *input,
size_t input_length );
psa_status_t psa_driver_wrapper_hash_finish(
- psa_operation_driver_context_t *operation,
+ psa_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length );
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 */
diff --git a/library/psa_crypto_driver_wrappers_contexts.h b/library/psa_crypto_driver_wrappers_contexts.h
new file mode 100644
index 000000000..9bb79664a
--- /dev/null
+++ b/library/psa_crypto_driver_wrappers_contexts.h
@@ -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. */
diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj
index a80671e11..c4ec8b674 100644
--- a/visualc/VS2010/mbedTLS.vcxproj
+++ b/visualc/VS2010/mbedTLS.vcxproj
@@ -250,6 +250,7 @@
+