From 040d1cea155eb3504635b1ec5c6ea76ccbf017dc Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 26 Apr 2021 11:54:58 +0200 Subject: [PATCH 01/39] Rename the PSA driver context structure headers to _primitives This is a preparatory step in order to be able to organize the include chain from crypto_struct in such a way that the MAC operation structure for the PSA 'software' driver can make use of the hash operation structure. Conceptually: * Primitives: * Hash * Cipher * Composites: * AEAD (can use cipher) * MAC (can use cipher and/or hash) Signed-off-by: Steven Cooreman --- .../{crypto_builtin.h => crypto_builtin_primitives.h} | 8 +++++--- ...contexts.h => crypto_driver_contexts_primitives.h} | 11 ++++++----- include/psa/crypto_struct.h | 2 +- visualc/VS2010/mbedTLS.vcxproj | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) rename include/psa/{crypto_builtin.h => crypto_builtin_primitives.h} (94%) rename include/psa/{crypto_driver_contexts.h => crypto_driver_contexts_primitives.h} (88%) diff --git a/include/psa/crypto_builtin.h b/include/psa/crypto_builtin_primitives.h similarity index 94% rename from include/psa/crypto_builtin.h rename to include/psa/crypto_builtin_primitives.h index b3bc1408c..75801a178 100644 --- a/include/psa/crypto_builtin.h +++ b/include/psa/crypto_builtin_primitives.h @@ -1,6 +1,8 @@ /* * Context structure declaration of the Mbed TLS software-based PSA drivers * called through the PSA Crypto driver dispatch layer. + * This file contains the context structures of those algorithms which do not + * rely on other algorithms, i.e. are 'primitive' algorithms. * * \note This file may not be included directly. Applications must * include psa/crypto.h. @@ -28,8 +30,8 @@ * limitations under the License. */ -#ifndef PSA_CRYPTO_BUILTIN_H -#define PSA_CRYPTO_BUILTIN_H +#ifndef PSA_CRYPTO_BUILTIN_PRIMITIVES_H +#define PSA_CRYPTO_BUILTIN_PRIMITIVES_H #include @@ -141,4 +143,4 @@ typedef struct { #endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_BUILTIN_H */ +#endif /* PSA_CRYPTO_BUILTIN_PRIMITIVES_H */ diff --git a/include/psa/crypto_driver_contexts.h b/include/psa/crypto_driver_contexts_primitives.h similarity index 88% rename from include/psa/crypto_driver_contexts.h rename to include/psa/crypto_driver_contexts_primitives.h index d725e8440..3e7fdee39 100644 --- a/include/psa/crypto_driver_contexts.h +++ b/include/psa/crypto_driver_contexts_primitives.h @@ -1,6 +1,7 @@ /* * Declaration of context structures for use with the PSA driver wrapper - * interface. + * interface. This file contains the context structures for 'primitive' + * operations, i.e. those operations which do not rely on other contexts. * * Warning: This file will be auto-generated in the future. * @@ -29,8 +30,8 @@ * limitations under the License. */ -#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_H -#define PSA_CRYPTO_DRIVER_CONTEXTS_H +#ifndef PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H +#define PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H #include "psa/crypto.h" #include "psa/crypto_driver_common.h" @@ -39,7 +40,7 @@ * declared during the autogeneration process. */ /* Include the context structure definitions for the Mbed TLS software drivers */ -#include "psa/crypto_builtin.h" +#include "psa/crypto_builtin_primitives.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. @@ -65,5 +66,5 @@ typedef union { #endif } psa_driver_cipher_context_t; -#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_H */ +#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H */ /* End of automatically generated file. */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 8ac7ce1ef..5665fa541 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -77,7 +77,7 @@ extern "C" { #include "mbedtls/gcm.h" /* Include the context definition for the compiled-in drivers */ -#include "psa/crypto_driver_contexts.h" +#include "psa/crypto_driver_contexts_primitives.h" struct psa_hash_operation_s { diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index a4385c90d..efe090b21 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -222,11 +222,11 @@ - + - + From 7c3213921a73dd7f8b5c861ff22f38c20b6044a2 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 26 Apr 2021 11:56:33 +0200 Subject: [PATCH 02/39] Remove inclusion of top-level crypto.h from the driver context header This was probably included by mistake, because the file itself is part of the inclusion chain starting with crypto.h. Signed-off-by: Steven Cooreman --- include/psa/crypto_driver_contexts_primitives.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/psa/crypto_driver_contexts_primitives.h b/include/psa/crypto_driver_contexts_primitives.h index 3e7fdee39..104d4bdb6 100644 --- a/include/psa/crypto_driver_contexts_primitives.h +++ b/include/psa/crypto_driver_contexts_primitives.h @@ -33,7 +33,6 @@ #ifndef PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H #define PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H -#include "psa/crypto.h" #include "psa/crypto_driver_common.h" /* Include the context structure definitions for those drivers that were From 14d09f42236c5c235ec3d850a35853e6a49e8364 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 26 Apr 2021 12:04:53 +0200 Subject: [PATCH 03/39] Move the cipher operation structure declaration for grouping Cipher and Hash are grouped, since they are 'primitive' operations. Signed-off-by: Steven Cooreman --- include/psa/crypto_struct.h | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 5665fa541..9ae5c9bfc 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -76,7 +76,8 @@ extern "C" { #include "mbedtls/cmac.h" #include "mbedtls/gcm.h" -/* Include the context definition for the compiled-in drivers */ +/* Include the context definition for the compiled-in drivers for the primitive + * algorithms. */ #include "psa/crypto_driver_contexts_primitives.h" struct psa_hash_operation_s @@ -98,6 +99,31 @@ static inline struct psa_hash_operation_s psa_hash_operation_init( void ) return( v ); } +struct psa_cipher_operation_s +{ + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_crypto_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int id; + + unsigned int iv_required : 1; + unsigned int iv_set : 1; + + uint8_t default_iv_length; + + psa_driver_cipher_context_t ctx; +}; + +#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, {0}} +static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) +{ + const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; + return( v ); +} + #if defined(MBEDTLS_MD_C) typedef struct { @@ -138,31 +164,6 @@ static inline struct psa_mac_operation_s psa_mac_operation_init( void ) return( v ); } -struct psa_cipher_operation_s -{ - /** Unique ID indicating which driver got assigned to do the - * operation. Since driver contexts are driver-specific, swapping - * drivers halfway through the operation is not supported. - * ID values are auto-generated in psa_crypto_driver_wrappers.h - * ID value zero means the context is not valid or not assigned to - * any driver (i.e. none of the driver contexts are active). */ - unsigned int id; - - unsigned int iv_required : 1; - unsigned int iv_set : 1; - - uint8_t default_iv_length; - - psa_driver_cipher_context_t ctx; -}; - -#define PSA_CIPHER_OPERATION_INIT {0, 0, 0, 0, {0}} -static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) -{ - const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT; - return( v ); -} - struct psa_aead_operation_s { psa_algorithm_t alg; From aecf0d3e704d64771976a0e5d60dd73c17cf0847 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 26 Apr 2021 12:16:27 +0200 Subject: [PATCH 04/39] Add include headers for composite operation contexts and move hmac Modeled after the include chain of the primitive operation contexts. Also moved the HMAC context structure to the builtin composites file, since that is where it conceptually belongs. This is a preparatory step for implementing driver dispatch of MAC multipart operations. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 54 +++++++++++++++++++ .../psa/crypto_driver_contexts_composites.h | 53 ++++++++++++++++++ include/psa/crypto_struct.h | 14 ++--- visualc/VS2010/mbedTLS.vcxproj | 2 + 4 files changed, 112 insertions(+), 11 deletions(-) create mode 100644 include/psa/crypto_builtin_composites.h create mode 100644 include/psa/crypto_driver_contexts_composites.h diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h new file mode 100644 index 000000000..a22a997c5 --- /dev/null +++ b/include/psa/crypto_builtin_composites.h @@ -0,0 +1,54 @@ +/* + * Context structure declaration of the Mbed TLS software-based PSA drivers + * called through the PSA Crypto driver dispatch layer. + * This file contains the context structures of those algorithms which need to + * rely on other algorithms, i.e. are 'composite' algorithms. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the Mbed TLS software-based PSA drivers. The + * definition of these objects are then used by crypto_struct.h to define the + * implementation-defined types of PSA multi-part state objects. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_BUILTIN_COMPOSITES_H +#define PSA_CRYPTO_BUILTIN_COMPOSITES_H + +#include + +/* + * MAC multi-part operation definitions. + */ + +#if defined(MBEDTLS_MD_C) +typedef struct +{ + /** The HMAC algorithm in use */ + psa_algorithm_t alg; + /** The hash context. */ + struct psa_hash_operation_s hash_ctx; + /** The HMAC part of the context. */ + uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; +} psa_hmac_internal_data; +#endif /* MBEDTLS_MD_C */ + +#endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h new file mode 100644 index 000000000..1c71c5206 --- /dev/null +++ b/include/psa/crypto_driver_contexts_composites.h @@ -0,0 +1,53 @@ +/* + * Declaration of context structures for use with the PSA driver wrapper + * interface. This file contains the context structures for 'composite' + * operations, i.e. those operations which need to make use of other operations + * from the primitives (crypto_driver_contexts_primitives.h) + * + * Warning: This file will be auto-generated in the future. + * + * \note This file may not be included directly. Applications must + * include psa/crypto.h. + * + * \note This header and its content is not part of the Mbed TLS API and + * applications must not depend on it. Its main purpose is to define the + * multi-part state objects of the PSA drivers included in the cryptographic + * library. The definition of these objects are then used by crypto_struct.h + * to define the implementation-defined types of PSA multi-part state objects. + */ +/* 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_CONTEXTS_COMPOSITES_H +#define PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H + +#include "psa/crypto_driver_common.h" + +/* Include the context structure definitions for those drivers that were + * declared during the autogeneration process. */ + +/* Include the context structure definitions for the Mbed TLS software drivers */ +#include "psa/crypto_builtin_composites.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 */ + +#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ +/* End of automatically generated file. */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 9ae5c9bfc..58f2c67b7 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -124,17 +124,9 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) return( v ); } -#if defined(MBEDTLS_MD_C) -typedef struct -{ - /** The HMAC algorithm in use */ - psa_algorithm_t alg; - /** The hash context. */ - struct psa_hash_operation_s hash_ctx; - /** The HMAC part of the context. */ - uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; -} psa_hmac_internal_data; -#endif /* MBEDTLS_MD_C */ +/* Include the context definition for the compiled-in drivers for the composite + * algorithms. */ +#include "psa/crypto_driver_contexts_composites.h" struct psa_mac_operation_s { diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index efe090b21..f34720089 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -222,10 +222,12 @@ + + From 896d51e5846cf8241de5ac6324c85b81d6dc2324 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 15:24:23 +0100 Subject: [PATCH 05/39] Add boilerplate for dispatching MAC operations Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 28 ++ .../psa/crypto_driver_contexts_composites.h | 9 + include/psa/crypto_struct.h | 4 +- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/psa_crypto_driver_wrappers.c | 349 ++++++++++++++ library/psa_crypto_driver_wrappers.h | 47 ++ library/psa_crypto_mac.c | 434 ++++++++++++++++++ library/psa_crypto_mac.h | 375 +++++++++++++++ visualc/VS2010/mbedTLS.vcxproj | 2 + 10 files changed, 1249 insertions(+), 1 deletion(-) create mode 100644 library/psa_crypto_mac.c create mode 100644 library/psa_crypto_mac.h diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index a22a997c5..16fa3db72 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -51,4 +51,32 @@ typedef struct } psa_hmac_internal_data; #endif /* MBEDTLS_MD_C */ +#include "mbedtls/cmac.h" + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_MAC +#endif + +typedef struct +{ + psa_algorithm_t alg; + /* To be fleshed out in a later commit. */ +} mbedtls_psa_mac_operation_t; + +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, {0}} + +/* + * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. + */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + +typedef mbedtls_psa_mac_operation_t mbedtls_transparent_test_driver_mac_operation_t; +typedef mbedtls_psa_mac_operation_t mbedtls_opaque_test_driver_mac_operation_t; + +#define MBEDTLS_TRANSPARENT_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT +#define MBEDTLS_OPAQUE_TEST_DRIVER_MAC_OPERATION_INIT MBEDTLS_PSA_MAC_OPERATION_INIT + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h index 1c71c5206..239fdcb33 100644 --- a/include/psa/crypto_driver_contexts_composites.h +++ b/include/psa/crypto_driver_contexts_composites.h @@ -49,5 +49,14 @@ * are formatted as `'drivername'_ctx`. This allows for procedural generation * of both this file and the content of psa_crypto_driver_wrappers.c */ +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_mac_operation_t mbedtls_ctx; +#if defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_transparent_test_driver_mac_operation_t transparent_test_driver_ctx; + mbedtls_opaque_test_driver_mac_operation_t opaque_test_driver_ctx; +#endif +} psa_driver_mac_context_t; + #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ /* End of automatically generated file. */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 58f2c67b7..975e9f76b 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -137,6 +137,7 @@ struct psa_mac_operation_s unsigned int has_input : 1; unsigned int is_sign : 1; uint8_t mac_size; + unsigned int id; union { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ @@ -146,10 +147,11 @@ struct psa_mac_operation_s #if defined(MBEDTLS_CMAC_C) mbedtls_cipher_context_t cmac; #endif + psa_driver_mac_context_t driver; } ctx; }; -#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, {0}} +#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, 0, {0}} static inline struct psa_mac_operation_s psa_mac_operation_init( void ) { const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 256feef53..22a172791 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -69,6 +69,7 @@ set(src_crypto psa_crypto_driver_wrappers.c psa_crypto_ecp.c psa_crypto_hash.c + psa_crypto_mac.c psa_crypto_rsa.c psa_crypto_se.c psa_crypto_slot_management.c diff --git a/library/Makefile b/library/Makefile index f089e0b58..dc101d28b 100644 --- a/library/Makefile +++ b/library/Makefile @@ -126,6 +126,7 @@ OBJS_CRYPTO= \ psa_crypto_driver_wrappers.o \ psa_crypto_ecp.o \ psa_crypto_hash.o \ + psa_crypto_mac.o \ psa_crypto_rsa.o \ psa_crypto_se.o \ psa_crypto_slot_management.o \ diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 9bef02cd0..09f631919 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -24,6 +24,7 @@ #include "psa_crypto_core.h" #include "psa_crypto_driver_wrappers.h" #include "psa_crypto_hash.h" +#include "psa_crypto_mac.h" #include "mbedtls/platform.h" @@ -1290,4 +1291,352 @@ psa_status_t psa_driver_wrapper_aead_decrypt( return( PSA_ERROR_INVALID_ARGUMENT ); } } + + +/* + * MAC functions + */ +psa_status_t psa_driver_wrapper_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = mbedtls_transparent_test_driver_mac_compute( + attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + /* Fell through, meaning no accelerator supports this operation */ + status = mbedtls_psa_mac_compute( + attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ); + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + return( PSA_ERROR_NOT_SUPPORTED ); + + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LOCATION: + status = mbedtls_opaque_test_driver_mac_compute( + attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ); + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + /* Key is declared with a lifetime not known to us */ + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) input; + (void) input_length; + (void) mac; + (void) mac_size; + (void) mac_length; + (void) status; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_sign_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = mbedtls_transparent_test_driver_mac_sign_setup( + &operation->ctx.driver.transparent_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + /* Declared with fallback == true */ + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + /* Fell through, meaning no accelerator supports this operation */ + status = mbedtls_psa_mac_sign_setup( &operation->ctx.driver.mbedtls_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + return( PSA_ERROR_NOT_SUPPORTED ); + + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LOCATION: + status = mbedtls_opaque_test_driver_mac_sign_setup( + &operation->ctx.driver.opaque_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + /* Key is declared with a lifetime not known to us */ + (void) status; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_verify_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = mbedtls_transparent_test_driver_mac_verify_setup( + &operation->ctx.driver.transparent_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + /* Declared with fallback == true */ + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID; + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + /* Fell through, meaning no accelerator supports this operation */ + status = mbedtls_psa_mac_verify_setup( &operation->ctx.driver.mbedtls_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + return( PSA_ERROR_NOT_SUPPORTED ); + + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LOCATION: + status = mbedtls_opaque_test_driver_mac_sign_setup( + &operation->ctx.driver.opaque_test_driver_ctx, + attributes, + key_buffer, key_buffer_size, + alg ); + + if( status == PSA_SUCCESS ) + operation->id = PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID; + + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + /* Key is declared with a lifetime not known to us */ + (void) status; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_update( + psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_mac_update( &operation->ctx.driver.mbedtls_ctx, + input, input_length ) ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( mbedtls_transparent_test_driver_mac_update( + &operation->ctx.driver.transparent_test_driver_ctx, + input, input_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_opaque_test_driver_mac_update( + &operation->ctx.driver.opaque_test_driver_ctx, + input, input_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + (void) input; + (void) input_length; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_sign_finish( + psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_mac_sign_finish( &operation->ctx.driver.mbedtls_ctx, + mac, mac_size, mac_length ) ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( mbedtls_transparent_test_driver_mac_sign_finish( + &operation->ctx.driver.transparent_test_driver_ctx, + mac, mac_size, mac_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_opaque_test_driver_mac_sign_finish( + &operation->ctx.driver.opaque_test_driver_ctx, + mac, mac_size, mac_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_verify_finish( + psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_mac_verify_finish( &operation->ctx.driver.mbedtls_ctx, + mac, mac_length ) ); +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + return( mbedtls_transparent_test_driver_mac_verify_finish( + &operation->ctx.driver.transparent_test_driver_ctx, + mac, mac_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_opaque_test_driver_mac_verify_finish( + &operation->ctx.driver.opaque_test_driver_ctx, + mac, mac_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + (void) mac; + (void) mac_length; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_mac_abort( + psa_mac_operation_t *operation ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + status = mbedtls_psa_mac_abort( &operation->ctx.driver.mbedtls_ctx ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: + status = mbedtls_transparent_test_driver_mac_abort( + &operation->ctx.driver.transparent_test_driver_ctx ); + break; + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + status = mbedtls_opaque_test_driver_mac_abort( + &operation->ctx.driver.opaque_test_driver_ctx ); + break; +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + status = PSA_ERROR_INVALID_ARGUMENT; + break; + } + + operation->id = 0; + return( status ); +} /* End of automatically generated file. */ diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index e82d0931b..37d5a9a1c 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -183,6 +183,53 @@ psa_status_t psa_driver_wrapper_aead_decrypt( const uint8_t *ciphertext, size_t ciphertext_length, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ); +/* + * MAC functions + */ +psa_status_t psa_driver_wrapper_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t psa_driver_wrapper_mac_sign_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_mac_verify_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_mac_update( + psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t psa_driver_wrapper_mac_sign_finish( + psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t psa_driver_wrapper_mac_verify_finish( + psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t psa_driver_wrapper_mac_abort( + psa_mac_operation_t *operation ); + #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ /* End of automatically generated file. */ diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c new file mode 100644 index 000000000..169be3a45 --- /dev/null +++ b/library/psa_crypto_mac.c @@ -0,0 +1,434 @@ +/* + * PSA MAC layer on top of Mbed TLS software crypto + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#include +#include "psa_crypto_core.h" +#include "psa_crypto_mac.h" + +#include +#include + +/* Use builtin defines specific to this compilation unit, since the test driver + * relies on the software driver. */ +#if( defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) ) ) +#define BUILTIN_ALG_CMAC 1 +#endif +#if( defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \ + ( defined(PSA_CRYPTO_DRIVER_TEST) && defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) ) ) +#define BUILTIN_ALG_HMAC 1 +#endif + +/* Implement the PSA driver MAC interface on top of mbed TLS if either the + * software driver or the test driver requires it. */ +#if defined(MBEDTLS_PSA_BUILTIN_MAC) || defined(PSA_CRYPTO_DRIVER_TEST) +static psa_status_t mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* To be fleshed out in a subsequent commit */ + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) input; + (void) input_length; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_sign_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_verify_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_update( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + (void) input; + (void) input_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_sign_finish( + mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_verify_finish( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + (void) mac; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +static psa_status_t mac_abort( + mbedtls_psa_mac_operation_t *operation ) +{ + /* To be fleshed out in a subsequent commit */ + (void) operation; + return( PSA_ERROR_NOT_SUPPORTED ); +} +#endif /* MBEDTLS_PSA_BUILTIN_MAC || PSA_CRYPTO_DRIVER_TEST */ + +#if defined(MBEDTLS_PSA_BUILTIN_MAC) +psa_status_t mbedtls_psa_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + return( mac_compute( attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ) ); +} + +psa_status_t mbedtls_psa_mac_sign_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + return( mac_sign_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_psa_mac_verify_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + return( mac_verify_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); +} + +psa_status_t mbedtls_psa_mac_update( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + return( mac_update( operation, input, input_length ) ); +} + +psa_status_t mbedtls_psa_mac_sign_finish( + mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + return( mac_sign_finish( operation, mac, mac_size, mac_length ) ); +} + +psa_status_t mbedtls_psa_mac_verify_finish( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + return( mac_verify_finish( operation, mac, mac_length ) ); +} + +psa_status_t mbedtls_psa_mac_abort( + mbedtls_psa_mac_operation_t *operation ) +{ + return( mac_abort( operation ) ); +} +#endif /* MBEDTLS_PSA_BUILTIN_MAC */ + + /* + * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. + */ +#if defined(PSA_CRYPTO_DRIVER_TEST) + +static int is_mac_accelerated( psa_algorithm_t alg ) +{ +#if defined(MBEDTLS_PSA_ACCEL_ALG_HMAC) + if( PSA_ALG_IS_HMAC( alg ) ) + return( 1 ); +#endif + + switch( PSA_ALG_FULL_LENGTH_MAC( alg ) ) + { +#if defined(MBEDTLS_PSA_ACCEL_ALG_CMAC) + case PSA_ALG_CMAC: + return( 1 ); +#endif + default: + return( 0 ); + } +} + +psa_status_t mbedtls_transparent_test_driver_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + if( is_mac_accelerated( alg ) ) + return( mac_compute( attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ) ); + else + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_sign_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + if( is_mac_accelerated( alg ) ) + return( mac_sign_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); + else + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_verify_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + if( is_mac_accelerated( alg ) ) + return( mac_verify_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); + else + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_update( operation, input, input_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_sign_finish( operation, mac, mac_size, mac_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_verify_finish( operation, mac, mac_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ) +{ + return( mac_abort( operation ) ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) input; + (void) input_length; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) input; + (void) input_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) mac; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h new file mode 100644 index 000000000..4da60bf40 --- /dev/null +++ b/library/psa_crypto_mac.h @@ -0,0 +1,375 @@ +/* + * PSA MAC layer on top of Mbed TLS software crypto + */ +/* + * 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_MAC_H +#define PSA_CRYPTO_MAC_H + +#include + +/** Calculate the MAC (message authentication code) of a message using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver mac_compute + * entry point. This function behaves as a mac_compute entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key to use for + * computing the MAC. This buffer contains the key + * in export representation as defined by + * psa_export_key() (i.e. the raw key bytes). + * \param key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * \param[in] input Buffer containing the input message. + * \param input_length Size of the \p input buffer in bytes. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \p mac_size is too small + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length); + +/** Set up a multipart MAC calculation operation using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver mac_sign_setup + * entry point. This function behaves as a mac_sign_setup entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized and not yet in use. + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key to use for + * computing the MAC. This buffer contains the key + * in export representation as defined by + * psa_export_key() (i.e. the raw key bytes). + * \param key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + */ +psa_status_t mbedtls_psa_mac_sign_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg); + +/** Set up a multipart MAC verification operation using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver mac_verify_setup + * entry point. This function behaves as a mac_verify_setup entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized and not yet in use. + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key to use for + * computing the MAC. This buffer contains the key + * in export representation as defined by + * psa_export_key() (i.e. the raw key bytes). + * \param key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param alg The MAC algorithm to use (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_MAC(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is not compatible with \p alg. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be inactive). + */ +psa_status_t mbedtls_psa_mac_verify_setup( + mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg); + +/** Add a message fragment to a multipart MAC operation using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver mac_update + * entry point. This function behaves as a mac_update entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * The core must call mbedtls_psa_mac_sign_setup() or + * mbedtls_psa_mac_verify_setup() before calling this function. + * + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling psa_mac_abort(). + * + * \param[in,out] operation Active MAC operation. + * \param[in] input Buffer containing the message fragment to add to + * the MAC calculation. + * \param input_length Size of the \p input buffer in bytes. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_mac_update( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +/** Finish the calculation of the MAC of a message using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver mac_sign_finish + * entry point. This function behaves as a mac_sign_finish entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * The core must call mbedtls_psa_mac_sign_setup() before calling this function. + * This function calculates the MAC of the message formed by concatenating + * the inputs passed to preceding calls to mbedtls_psa_mac_update(). + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling mbedtls_psa_mac_abort(). + * + * \param[in,out] operation Active MAC operation. + * \param[out] mac Buffer where the MAC value is to be written. + * \param mac_size Size of the \p mac buffer in bytes. + * \param[out] mac_length On success, the number of bytes + * that make up the MAC value. This is always + * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) + * where \c key_type and \c key_bits are the type and + * bit-size respectively of the key and \c alg is the + * MAC algorithm that is calculated. + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac sign + * operation). + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p mac buffer is too small. A sufficient buffer size + * can be determined by calling PSA_MAC_LENGTH(). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_mac_sign_finish( + mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +/** Finish the calculation of the MAC of a message and compare it with + * an expected value using Mbed TLS. + * + * \note The signature of this function is that of a PSA driver + * mac_verify_finish entry point. This function behaves as a + * mac_verify_finish entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * The core must call mbedtls_psa_mac_verify_setup() before calling this + * function. This function calculates the MAC of the message formed by + * concatenating the inputs passed to preceding calls to + * mbedtls_psa_mac_update(). It then compares the calculated MAC with the + * expected MAC passed as a parameter to this function. + * + * When this function returns successfully, the operation becomes inactive. + * If this function returns an error status, the operation enters an error + * state and must be aborted by calling mbedtls_psa_mac_abort(). + * + * \param[in,out] operation Active MAC operation. + * \param[in] mac Buffer containing the expected MAC value. + * \param mac_length Size of the \p mac buffer in bytes. + * + * \retval #PSA_SUCCESS + * The expected MAC is identical to the actual MAC of the message. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The MAC of the message was calculated successfully, but it + * differs from the expected MAC. + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be an active mac verify + * operation). + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_mac_verify_finish( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +/** Abort a MAC operation using Mbed TLS. + * + * Aborting an operation frees all associated resources except for the + * \p operation structure itself. Once aborted, the operation object + * can be reused for another operation by calling + * mbedtls_psa_mac_sign_setup() or mbedtls_psa_mac_verify_setup() again. + * + * The core may call this function any time after the operation object has + * been initialized by one of the methods described in + * #mbedtls_psa_mac_operation_t. + * + * In particular, calling mbedtls_psa_mac_abort() after the operation has been + * terminated by a call to mbedtls_psa_mac_abort(), + * mbedtls_psa_mac_sign_finish() or mbedtls_psa_mac_verify_finish() is safe and + * has no effect. + * + * \param[in,out] operation Initialized MAC operation. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_mac_abort( + mbedtls_psa_mac_operation_t *operation ); + +/* + * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. + */ + +#if defined(PSA_CRYPTO_DRIVER_TEST) + +psa_status_t mbedtls_transparent_test_driver_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_transparent_test_driver_mac_sign_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_transparent_test_driver_mac_verify_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_transparent_test_driver_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_transparent_test_driver_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_transparent_test_driver_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_transparent_test_driver_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ); + +psa_status_t mbedtls_opaque_test_driver_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_opaque_test_driver_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_opaque_test_driver_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_opaque_test_driver_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_opaque_test_driver_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_opaque_test_driver_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_opaque_test_driver_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ); + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* PSA_CRYPTO_MAC_H */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index f34720089..dc6ee248b 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -267,6 +267,7 @@ + @@ -343,6 +344,7 @@ + From 6e3c2cbb52d807bd94e5232c64208a5d454af537 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 17:05:52 +0100 Subject: [PATCH 06/39] Move the MAC operation structure into the driver headers Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 33 +++++++++++++------ include/psa/crypto_struct.h | 27 +++++----------- library/psa_crypto.c | 43 +++++++++++++++++-------- library/psa_crypto_driver_wrappers.c | 36 ++++++++++----------- 4 files changed, 79 insertions(+), 60 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 16fa3db72..fd7f6f91a 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -38,8 +38,12 @@ /* * MAC multi-part operation definitions. */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_MAC +#endif -#if defined(MBEDTLS_MD_C) +#if defined(PSA_WANT_ALG_HMAC) typedef struct { /** The HMAC algorithm in use */ @@ -49,22 +53,33 @@ typedef struct /** The HMAC part of the context. */ uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; } psa_hmac_internal_data; -#endif /* MBEDTLS_MD_C */ +#endif /* PSA_WANT_ALG_HMAC */ #include "mbedtls/cmac.h" -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || \ - defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -#define MBEDTLS_PSA_BUILTIN_MAC -#endif - typedef struct { psa_algorithm_t alg; - /* To be fleshed out in a later commit. */ + unsigned int key_set : 1; + unsigned int iv_required : 1; + unsigned int iv_set : 1; + unsigned int has_input : 1; + unsigned int is_sign : 1; + uint8_t mac_size; + unsigned int id; + union + { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(PSA_WANT_ALG_HMAC) + psa_hmac_internal_data hmac; +#endif +#if defined(MBEDTLS_CMAC_C) + mbedtls_cipher_context_t cmac; +#endif + } ctx; } mbedtls_psa_mac_operation_t; -#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, {0}} +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, 0, {0}} /* * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 975e9f76b..04c006463 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -130,28 +130,17 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) struct psa_mac_operation_s { - psa_algorithm_t alg; - unsigned int key_set : 1; - unsigned int iv_required : 1; - unsigned int iv_set : 1; - unsigned int has_input : 1; - unsigned int is_sign : 1; - uint8_t mac_size; + /** 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 - { - unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ -#if defined(MBEDTLS_MD_C) - psa_hmac_internal_data hmac; -#endif -#if defined(MBEDTLS_CMAC_C) - mbedtls_cipher_context_t cmac; -#endif - psa_driver_mac_context_t driver; - } ctx; + psa_driver_mac_context_t ctx; }; -#define PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, 0, {0}} +#define PSA_MAC_OPERATION_INIT {0, {0}} static inline struct psa_mac_operation_s psa_mac_operation_init( void ) { const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f58df4aef..f91e5c322 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2328,7 +2328,7 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg ) /* Initialize the MAC operation structure. Once this function has been * called, psa_mac_abort can run and will do the right thing. */ -static psa_status_t psa_mac_init( psa_mac_operation_t *operation, +static psa_status_t psa_mac_init( mbedtls_psa_mac_operation_t *operation, psa_algorithm_t alg ) { psa_status_t status = PSA_ERROR_NOT_SUPPORTED; @@ -2376,8 +2376,11 @@ static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) } #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ -psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) +psa_status_t psa_mac_abort( psa_mac_operation_t *psa_operation ) { + /* Temporary recast to avoid changing a lot of lines */ + mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + if( operation->alg == 0 ) { /* The object has (apparently) been initialized but it is not @@ -2425,7 +2428,7 @@ bad_state: } #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) -static psa_status_t psa_cmac_setup( psa_mac_operation_t *operation, +static psa_status_t psa_cmac_setup( mbedtls_psa_mac_operation_t *operation, psa_key_slot_t *slot ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -2514,7 +2517,7 @@ cleanup: } #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ -static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, +static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, mbedtls_svc_key_id_t key, psa_algorithm_t alg, int is_sign ) @@ -2525,6 +2528,9 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, psa_key_usage_t usage = is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH; + /* Temporary recast to avoid changing a lot of lines */ + mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + /* A context must be freshly initialized before it can be set up. */ if( operation->alg != 0 ) { @@ -2608,7 +2614,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, exit: if( status != PSA_SUCCESS ) { - psa_mac_abort( operation ); + psa_mac_abort( psa_operation ); } else { @@ -2634,10 +2640,13 @@ psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation, return( psa_mac_setup( operation, key, alg, 0 ) ); } -psa_status_t psa_mac_update( psa_mac_operation_t *operation, +psa_status_t psa_mac_update( psa_mac_operation_t *psa_operation, const uint8_t *input, size_t input_length ) { + /* Temporary recast to avoid changing a lot of lines */ + mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + psa_status_t status = PSA_ERROR_BAD_STATE; if( ! operation->key_set ) return( PSA_ERROR_BAD_STATE ); @@ -2669,7 +2678,7 @@ psa_status_t psa_mac_update( psa_mac_operation_t *operation, } if( status != PSA_SUCCESS ) - psa_mac_abort( operation ); + psa_mac_abort( psa_operation ); return( status ); } @@ -2713,7 +2722,7 @@ exit: } #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ -static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation, +static psa_status_t psa_mac_finish_internal( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size ) { @@ -2752,11 +2761,14 @@ static psa_status_t psa_mac_finish_internal( psa_mac_operation_t *operation, } } -psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, +psa_status_t psa_mac_sign_finish( psa_mac_operation_t *psa_operation, uint8_t *mac, size_t mac_size, size_t *mac_length ) { + /* Temporary recast to avoid changing a lot of lines */ + mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + psa_status_t status; if( operation->alg == 0 ) @@ -2782,21 +2794,24 @@ psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, if( status == PSA_SUCCESS ) { - status = psa_mac_abort( operation ); + status = psa_mac_abort( psa_operation ); if( status == PSA_SUCCESS ) *mac_length = operation->mac_size; else memset( mac, '!', mac_size ); } else - psa_mac_abort( operation ); + psa_mac_abort( psa_operation ); return( status ); } -psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, +psa_status_t psa_mac_verify_finish( psa_mac_operation_t *psa_operation, const uint8_t *mac, size_t mac_length ) { + /* Temporary recast to avoid changing a lot of lines */ + mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + uint8_t actual_mac[PSA_MAC_MAX_SIZE]; psa_status_t status; @@ -2825,9 +2840,9 @@ psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, cleanup: if( status == PSA_SUCCESS ) - status = psa_mac_abort( operation ); + status = psa_mac_abort( psa_operation ); else - psa_mac_abort( operation ); + psa_mac_abort( psa_operation ); mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 09f631919..32ea7f535 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -1383,7 +1383,7 @@ psa_status_t psa_driver_wrapper_mac_sign_setup( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) status = mbedtls_transparent_test_driver_mac_sign_setup( - &operation->ctx.driver.transparent_test_driver_ctx, + &operation->ctx.transparent_test_driver_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1397,7 +1397,7 @@ psa_status_t psa_driver_wrapper_mac_sign_setup( #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_mac_sign_setup( &operation->ctx.driver.mbedtls_ctx, + status = mbedtls_psa_mac_sign_setup( &operation->ctx.mbedtls_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1414,7 +1414,7 @@ psa_status_t psa_driver_wrapper_mac_sign_setup( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LOCATION: status = mbedtls_opaque_test_driver_mac_sign_setup( - &operation->ctx.driver.opaque_test_driver_ctx, + &operation->ctx.opaque_test_driver_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1454,7 +1454,7 @@ psa_status_t psa_driver_wrapper_mac_verify_setup( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) status = mbedtls_transparent_test_driver_mac_verify_setup( - &operation->ctx.driver.transparent_test_driver_ctx, + &operation->ctx.transparent_test_driver_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1468,7 +1468,7 @@ psa_status_t psa_driver_wrapper_mac_verify_setup( #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) /* Fell through, meaning no accelerator supports this operation */ - status = mbedtls_psa_mac_verify_setup( &operation->ctx.driver.mbedtls_ctx, + status = mbedtls_psa_mac_verify_setup( &operation->ctx.mbedtls_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1485,7 +1485,7 @@ psa_status_t psa_driver_wrapper_mac_verify_setup( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LOCATION: status = mbedtls_opaque_test_driver_mac_sign_setup( - &operation->ctx.driver.opaque_test_driver_ctx, + &operation->ctx.opaque_test_driver_ctx, attributes, key_buffer, key_buffer_size, alg ); @@ -1515,7 +1515,7 @@ psa_status_t psa_driver_wrapper_mac_update( { #if defined(MBEDTLS_PSA_BUILTIN_MAC) case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_update( &operation->ctx.driver.mbedtls_ctx, + return( mbedtls_psa_mac_update( &operation->ctx.mbedtls_ctx, input, input_length ) ); #endif /* MBEDTLS_PSA_BUILTIN_MAC */ @@ -1523,12 +1523,12 @@ psa_status_t psa_driver_wrapper_mac_update( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: return( mbedtls_transparent_test_driver_mac_update( - &operation->ctx.driver.transparent_test_driver_ctx, + &operation->ctx.transparent_test_driver_ctx, input, input_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: return( mbedtls_opaque_test_driver_mac_update( - &operation->ctx.driver.opaque_test_driver_ctx, + &operation->ctx.opaque_test_driver_ctx, input, input_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -1549,7 +1549,7 @@ psa_status_t psa_driver_wrapper_mac_sign_finish( { #if defined(MBEDTLS_PSA_BUILTIN_MAC) case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_sign_finish( &operation->ctx.driver.mbedtls_ctx, + return( mbedtls_psa_mac_sign_finish( &operation->ctx.mbedtls_ctx, mac, mac_size, mac_length ) ); #endif /* MBEDTLS_PSA_BUILTIN_MAC */ @@ -1557,12 +1557,12 @@ psa_status_t psa_driver_wrapper_mac_sign_finish( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: return( mbedtls_transparent_test_driver_mac_sign_finish( - &operation->ctx.driver.transparent_test_driver_ctx, + &operation->ctx.transparent_test_driver_ctx, mac, mac_size, mac_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: return( mbedtls_opaque_test_driver_mac_sign_finish( - &operation->ctx.driver.opaque_test_driver_ctx, + &operation->ctx.opaque_test_driver_ctx, mac, mac_size, mac_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -1583,7 +1583,7 @@ psa_status_t psa_driver_wrapper_mac_verify_finish( { #if defined(MBEDTLS_PSA_BUILTIN_MAC) case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - return( mbedtls_psa_mac_verify_finish( &operation->ctx.driver.mbedtls_ctx, + return( mbedtls_psa_mac_verify_finish( &operation->ctx.mbedtls_ctx, mac, mac_length ) ); #endif /* MBEDTLS_PSA_BUILTIN_MAC */ @@ -1591,12 +1591,12 @@ psa_status_t psa_driver_wrapper_mac_verify_finish( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: return( mbedtls_transparent_test_driver_mac_verify_finish( - &operation->ctx.driver.transparent_test_driver_ctx, + &operation->ctx.transparent_test_driver_ctx, mac, mac_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: return( mbedtls_opaque_test_driver_mac_verify_finish( - &operation->ctx.driver.opaque_test_driver_ctx, + &operation->ctx.opaque_test_driver_ctx, mac, mac_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -1615,7 +1615,7 @@ psa_status_t psa_driver_wrapper_mac_abort( { #if defined(MBEDTLS_PSA_BUILTIN_MAC) case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - status = mbedtls_psa_mac_abort( &operation->ctx.driver.mbedtls_ctx ); + status = mbedtls_psa_mac_abort( &operation->ctx.mbedtls_ctx ); break; #endif /* MBEDTLS_PSA_BUILTIN_MAC */ @@ -1623,11 +1623,11 @@ psa_status_t psa_driver_wrapper_mac_abort( #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: status = mbedtls_transparent_test_driver_mac_abort( - &operation->ctx.driver.transparent_test_driver_ctx ); + &operation->ctx.transparent_test_driver_ctx ); break; case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: status = mbedtls_opaque_test_driver_mac_abort( - &operation->ctx.driver.opaque_test_driver_ctx ); + &operation->ctx.opaque_test_driver_ctx ); break; #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ From 32d569449b63fe7d3af874904323e7e25be43b02 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 17:39:17 +0100 Subject: [PATCH 07/39] Move internal HMAC implementation into internal MAC driver This is a temporary measure. Other operations in the PSA Core which rely on this internal HMAC API should be rewritten to use the MAC API instead, since they can then leverage accelerated HMAC should a platform provide such acceleration support. Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 144 +-------------------------------------- library/psa_crypto_mac.c | 140 ++++++++++++++++++++++++++++++++++++- library/psa_crypto_mac.h | 11 +++ 3 files changed, 151 insertions(+), 144 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f91e5c322..fc055011a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -35,6 +35,7 @@ #include "psa_crypto_driver_wrappers.h" #include "psa_crypto_ecp.h" #include "psa_crypto_hash.h" +#include "psa_crypto_mac.h" #include "psa_crypto_rsa.h" #include "psa_crypto_ecp.h" #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -2297,35 +2298,6 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, /* MAC */ /****************************************************************/ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -static size_t psa_get_hash_block_size( psa_algorithm_t alg ) -{ - switch( alg ) - { - case PSA_ALG_MD2: - return( 16 ); - case PSA_ALG_MD4: - return( 64 ); - case PSA_ALG_MD5: - return( 64 ); - case PSA_ALG_RIPEMD160: - return( 64 ); - case PSA_ALG_SHA_1: - return( 64 ); - case PSA_ALG_SHA_224: - return( 64 ); - case PSA_ALG_SHA_256: - return( 64 ); - case PSA_ALG_SHA_384: - return( 128 ); - case PSA_ALG_SHA_512: - return( 128 ); - default: - return( 0 ); - } -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) */ - /* Initialize the MAC operation structure. Once this function has been * called, psa_mac_abort can run and will do the right thing. */ static psa_status_t psa_mac_init( mbedtls_psa_mac_operation_t *operation, @@ -2368,14 +2340,6 @@ static psa_status_t psa_mac_init( mbedtls_psa_mac_operation_t *operation, return( status ); } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -static psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) -{ - mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); - return( psa_hash_abort( &hmac->hash_ctx ) ); -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - psa_status_t psa_mac_abort( psa_mac_operation_t *psa_operation ) { /* Temporary recast to avoid changing a lot of lines */ @@ -2451,72 +2415,6 @@ exit: } #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -static psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, - const uint8_t *key, - size_t key_length, - psa_algorithm_t hash_alg ) -{ - uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; - size_t i; - size_t hash_size = PSA_HASH_LENGTH( hash_alg ); - size_t block_size = psa_get_hash_block_size( hash_alg ); - psa_status_t status; - - hmac->alg = hash_alg; - - /* Sanity checks on block_size, to guarantee that there won't be a buffer - * overflow below. This should never trigger if the hash algorithm - * is implemented correctly. */ - /* The size checks against the ipad and opad buffers cannot be written - * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )` - * because that triggers -Wlogical-op on GCC 7.3. */ - if( block_size > sizeof( ipad ) ) - return( PSA_ERROR_NOT_SUPPORTED ); - if( block_size > sizeof( hmac->opad ) ) - return( PSA_ERROR_NOT_SUPPORTED ); - if( block_size < hash_size ) - return( PSA_ERROR_NOT_SUPPORTED ); - - if( key_length > block_size ) - { - status = psa_hash_compute( hash_alg, key, key_length, - ipad, sizeof( ipad ), &key_length ); - if( status != PSA_SUCCESS ) - goto cleanup; - } - /* A 0-length key is not commonly used in HMAC when used as a MAC, - * but it is permitted. It is common when HMAC is used in HKDF, for - * example. Don't call `memcpy` in the 0-length because `key` could be - * an invalid pointer which would make the behavior undefined. */ - else if( key_length != 0 ) - memcpy( ipad, key, key_length ); - - /* ipad contains the key followed by garbage. Xor and fill with 0x36 - * to create the ipad value. */ - for( i = 0; i < key_length; i++ ) - ipad[i] ^= 0x36; - memset( ipad + key_length, 0x36, block_size - key_length ); - - /* Copy the key material from ipad to opad, flipping the requisite bits, - * and filling the rest of opad with the requisite constant. */ - for( i = 0; i < key_length; i++ ) - hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C; - memset( hmac->opad + key_length, 0x5C, block_size - key_length ); - - status = psa_hash_setup( &hmac->hash_ctx, hash_alg ); - if( status != PSA_SUCCESS ) - goto cleanup; - - status = psa_hash_update( &hmac->hash_ctx, ipad, block_size ); - -cleanup: - mbedtls_platform_zeroize( ipad, sizeof( ipad ) ); - - return( status ); -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, mbedtls_svc_key_id_t key, psa_algorithm_t alg, @@ -2682,46 +2580,6 @@ psa_status_t psa_mac_update( psa_mac_operation_t *psa_operation, return( status ); } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) -static psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, - uint8_t *mac, - size_t mac_size ) -{ - uint8_t tmp[MBEDTLS_MD_MAX_SIZE]; - psa_algorithm_t hash_alg = hmac->alg; - size_t hash_size = 0; - size_t block_size = psa_get_hash_block_size( hash_alg ); - psa_status_t status; - - status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size ); - if( status != PSA_SUCCESS ) - return( status ); - /* From here on, tmp needs to be wiped. */ - - status = psa_hash_setup( &hmac->hash_ctx, hash_alg ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size ); - if( status != PSA_SUCCESS ) - goto exit; - - memcpy( mac, tmp, mac_size ); - -exit: - mbedtls_platform_zeroize( tmp, hash_size ); - return( status ); -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - static psa_status_t psa_mac_finish_internal( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size ) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 169be3a45..b09efea59 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -25,6 +25,7 @@ #include #include "psa_crypto_core.h" #include "psa_crypto_mac.h" +#include #include #include @@ -40,6 +41,143 @@ #define BUILTIN_ALG_HMAC 1 #endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) +static size_t psa_get_hash_block_size( psa_algorithm_t alg ) +{ + switch( alg ) + { + case PSA_ALG_MD2: + return( 16 ); + case PSA_ALG_MD4: + return( 64 ); + case PSA_ALG_MD5: + return( 64 ); + case PSA_ALG_RIPEMD160: + return( 64 ); + case PSA_ALG_SHA_1: + return( 64 ); + case PSA_ALG_SHA_224: + return( 64 ); + case PSA_ALG_SHA_256: + return( 64 ); + case PSA_ALG_SHA_384: + return( 128 ); + case PSA_ALG_SHA_512: + return( 128 ); + default: + return( 0 ); + } +} + +psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) +{ + mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); + return( psa_hash_abort( &hmac->hash_ctx ) ); +} + +psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, + const uint8_t *key, + size_t key_length, + psa_algorithm_t hash_alg ) +{ + uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; + size_t i; + size_t hash_size = PSA_HASH_LENGTH( hash_alg ); + size_t block_size = psa_get_hash_block_size( hash_alg ); + psa_status_t status; + + hmac->alg = hash_alg; + + /* Sanity checks on block_size, to guarantee that there won't be a buffer + * overflow below. This should never trigger if the hash algorithm + * is implemented correctly. */ + /* The size checks against the ipad and opad buffers cannot be written + * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )` + * because that triggers -Wlogical-op on GCC 7.3. */ + if( block_size > sizeof( ipad ) ) + return( PSA_ERROR_NOT_SUPPORTED ); + if( block_size > sizeof( hmac->opad ) ) + return( PSA_ERROR_NOT_SUPPORTED ); + if( block_size < hash_size ) + return( PSA_ERROR_NOT_SUPPORTED ); + + if( key_length > block_size ) + { + status = psa_hash_compute( hash_alg, key, key_length, + ipad, sizeof( ipad ), &key_length ); + if( status != PSA_SUCCESS ) + goto cleanup; + } + /* A 0-length key is not commonly used in HMAC when used as a MAC, + * but it is permitted. It is common when HMAC is used in HKDF, for + * example. Don't call `memcpy` in the 0-length because `key` could be + * an invalid pointer which would make the behavior undefined. */ + else if( key_length != 0 ) + memcpy( ipad, key, key_length ); + + /* ipad contains the key followed by garbage. Xor and fill with 0x36 + * to create the ipad value. */ + for( i = 0; i < key_length; i++ ) + ipad[i] ^= 0x36; + memset( ipad + key_length, 0x36, block_size - key_length ); + + /* Copy the key material from ipad to opad, flipping the requisite bits, + * and filling the rest of opad with the requisite constant. */ + for( i = 0; i < key_length; i++ ) + hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C; + memset( hmac->opad + key_length, 0x5C, block_size - key_length ); + + status = psa_hash_setup( &hmac->hash_ctx, hash_alg ); + if( status != PSA_SUCCESS ) + goto cleanup; + + status = psa_hash_update( &hmac->hash_ctx, ipad, block_size ); + +cleanup: + mbedtls_platform_zeroize( ipad, sizeof( ipad ) ); + + return( status ); +} + +psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, + uint8_t *mac, + size_t mac_size ) +{ + uint8_t tmp[MBEDTLS_MD_MAX_SIZE]; + psa_algorithm_t hash_alg = hmac->alg; + size_t hash_size = 0; + size_t block_size = psa_get_hash_block_size( hash_alg ); + psa_status_t status; + + status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size ); + if( status != PSA_SUCCESS ) + return( status ); + /* From here on, tmp needs to be wiped. */ + + status = psa_hash_setup( &hmac->hash_ctx, hash_alg ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_hash_update( &hmac->hash_ctx, hmac->opad, block_size ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_hash_update( &hmac->hash_ctx, tmp, hash_size ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_hash_finish( &hmac->hash_ctx, tmp, sizeof( tmp ), &hash_size ); + if( status != PSA_SUCCESS ) + goto exit; + + memcpy( mac, tmp, mac_size ); + +exit: + mbedtls_platform_zeroize( tmp, hash_size ); + return( status ); +} +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */ + /* Implement the PSA driver MAC interface on top of mbed TLS if either the * software driver or the test driver requires it. */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) || defined(PSA_CRYPTO_DRIVER_TEST) @@ -54,7 +192,7 @@ static psa_status_t mac_compute( size_t mac_size, size_t *mac_length ) { - /* To be fleshed out in a subsequent commit */ + /* One-shot MAC has not been implemented in this PSA implementation yet. */ (void) attributes; (void) key_buffer; (void) key_buffer_size; diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index 4da60bf40..d92351160 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -23,6 +23,17 @@ #include +psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, + const uint8_t *key, + size_t key_length, + psa_algorithm_t hash_alg ); + +psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, + uint8_t *mac, + size_t mac_size ); + +psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ); + /** Calculate the MAC (message authentication code) of a message using Mbed TLS. * * \note The signature of this function is that of a PSA driver mac_compute From 0789783c17abd761ec92038c6231389fed031704 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 18:28:56 +0100 Subject: [PATCH 08/39] Migrate MAC setup/abort calls into the software driver Step 1/x in moving the driver. Separate commits should make for easier review. Additional changes on top of just moving code: * Added a sanity check on the key buffer size for CMAC. * Transfered responsibility for resetting the core members of the PSA MAC operation structure back to the core (from the driver wrapper layer) Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 197 ++++-------------------- library/psa_crypto_driver_wrappers.c | 20 +-- library/psa_crypto_mac.c | 221 ++++++++++++++++++++++++--- 3 files changed, 237 insertions(+), 201 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index fc055011a..075f8ded1 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2298,124 +2298,19 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, /* MAC */ /****************************************************************/ -/* Initialize the MAC operation structure. Once this function has been - * called, psa_mac_abort can run and will do the right thing. */ -static psa_status_t psa_mac_init( mbedtls_psa_mac_operation_t *operation, - psa_algorithm_t alg ) +psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) { - psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + /* Aborting a non-active operation is allowed */ + if( operation->id == 0 ) + return( PSA_SUCCESS ); - operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); - operation->key_set = 0; - operation->iv_set = 0; - operation->iv_required = 0; - operation->has_input = 0; - operation->is_sign = 0; + psa_status_t status = psa_driver_wrapper_mac_abort( operation ); + operation->id = 0; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) - { - operation->iv_required = 0; - mbedtls_cipher_init( &operation->ctx.cmac ); - status = PSA_SUCCESS; - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if( PSA_ALG_IS_HMAC( operation->alg ) ) - { - /* We'll set up the hash operation later in psa_hmac_setup_internal. */ - operation->ctx.hmac.alg = 0; - status = PSA_SUCCESS; - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - if( ! PSA_ALG_IS_MAC( alg ) ) - status = PSA_ERROR_INVALID_ARGUMENT; - } - - if( status != PSA_SUCCESS ) - memset( operation, 0, sizeof( *operation ) ); return( status ); } -psa_status_t psa_mac_abort( psa_mac_operation_t *psa_operation ) -{ - /* Temporary recast to avoid changing a lot of lines */ - mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; - - if( operation->alg == 0 ) - { - /* 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. */ - return( PSA_SUCCESS ); - } - else -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) - { - mbedtls_cipher_free( &operation->ctx.cmac ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if( PSA_ALG_IS_HMAC( operation->alg ) ) - { - psa_hmac_abort_internal( &operation->ctx.hmac ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* Sanity check (shouldn't happen: operation->alg should - * always have been initialized to a valid value). */ - goto bad_state; - } - - operation->alg = 0; - operation->key_set = 0; - operation->iv_set = 0; - operation->iv_required = 0; - operation->has_input = 0; - operation->is_sign = 0; - - return( PSA_SUCCESS ); - -bad_state: - /* If abort is called on an uninitialized object, we can't trust - * anything. Wipe the object in case it contains confidential data. - * This may result in a memory leak if a pointer gets overwritten, - * but it's too late to do anything about this. */ - memset( operation, 0, sizeof( *operation ) ); - return( PSA_ERROR_BAD_STATE ); -} - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) -static psa_status_t psa_cmac_setup( mbedtls_psa_mac_operation_t *operation, - psa_key_slot_t *slot ) -{ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_cipher_info_t *cipher_info = - mbedtls_cipher_info_from_psa( PSA_ALG_CMAC, - slot->attr.type, slot->attr.bits, - NULL ); - if( cipher_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - - ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info ); - if( ret != 0 ) - goto exit; - - ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac, - slot->key.data, - slot->attr.bits ); -exit: - return( mbedtls_to_psa_error( ret ) ); -} -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ - -static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, +static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, mbedtls_svc_key_id_t key, psa_algorithm_t alg, int is_sign ) @@ -2425,38 +2320,32 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, psa_key_slot_t *slot; psa_key_usage_t usage = is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH; - - /* Temporary recast to avoid changing a lot of lines */ - mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + size_t mac_size = 0; /* A context must be freshly initialized before it can be set up. */ - if( operation->alg != 0 ) - { + if( operation->id != 0 ) return( PSA_ERROR_BAD_STATE ); - } - status = psa_mac_init( operation, alg ); - if( status != PSA_SUCCESS ) - return( status ); - if( is_sign ) - operation->is_sign = 1; - - status = psa_get_and_lock_transparent_key_slot_with_policy( + status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; + psa_key_attributes_t attributes = { + .core = slot->attr + }; + /* Validate the combination of key type and algorithm */ - status = psa_mac_key_can_do( alg, slot->attr.type ); + status = psa_mac_key_can_do( alg, psa_get_key_type( &attributes ) ); if( status != PSA_SUCCESS ) goto exit; /* Get the output length for the algorithm and key combination. None of the * currently supported algorithms have an output length dependent on actual * key size, so setting it to a bogus value is currently OK. */ - operation->mac_size = PSA_MAC_LENGTH( slot->attr.type, 0, alg ); + mac_size = PSA_MAC_LENGTH( psa_get_key_type( &attributes ), 0, alg ); - if( operation->mac_size < 4 ) + if( mac_size < 4 ) { /* A very short MAC is too short for security since it can be * brute-forced. Ancient protocols with 32-bit MACs do exist, @@ -2466,8 +2355,8 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, goto exit; } - if( operation->mac_size > - PSA_MAC_LENGTH( slot->attr.type, 0, PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) + if( mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), 0, + PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length * of the algorithm. */ @@ -2475,49 +2364,27 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *psa_operation, goto exit; } -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC ) + /* Dispatch the MAC setup call with validated input */ + if( is_sign ) { - status = psa_cmac_setup( operation, slot ); + status = psa_driver_wrapper_mac_sign_setup( operation, + &attributes, + slot->key.data, + slot->key.bytes, + alg ); } else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if( PSA_ALG_IS_HMAC( alg ) ) { - /* Sanity check. This shouldn't fail on a valid configuration. */ - if( operation->mac_size > sizeof( operation->ctx.hmac.opad ) ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - if( slot->attr.type != PSA_KEY_TYPE_HMAC ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - - status = psa_hmac_setup_internal( &operation->ctx.hmac, - slot->key.data, - slot->key.bytes, - PSA_ALG_HMAC_GET_HASH( alg ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - status = PSA_ERROR_NOT_SUPPORTED; + status = psa_driver_wrapper_mac_verify_setup( operation, + &attributes, + slot->key.data, + slot->key.bytes, + alg ); } exit: if( status != PSA_SUCCESS ) - { - psa_mac_abort( psa_operation ); - } - else - { - operation->key_set = 1; - } + psa_mac_abort( operation ); unlock_status = psa_unlock_key_slot( slot ); diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 32ea7f535..5d78aede2 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -1610,33 +1610,25 @@ psa_status_t psa_driver_wrapper_mac_verify_finish( psa_status_t psa_driver_wrapper_mac_abort( psa_mac_operation_t *operation ) { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; switch( operation->id ) { #if defined(MBEDTLS_PSA_BUILTIN_MAC) case PSA_CRYPTO_MBED_TLS_DRIVER_ID: - status = mbedtls_psa_mac_abort( &operation->ctx.mbedtls_ctx ); - break; + return( mbedtls_psa_mac_abort( &operation->ctx.mbedtls_ctx ) ); #endif /* MBEDTLS_PSA_BUILTIN_MAC */ #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - status = mbedtls_transparent_test_driver_mac_abort( - &operation->ctx.transparent_test_driver_ctx ); - break; + return( mbedtls_transparent_test_driver_mac_abort( + &operation->ctx.transparent_test_driver_ctx ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - status = mbedtls_opaque_test_driver_mac_abort( - &operation->ctx.opaque_test_driver_ctx ); - break; + return( mbedtls_opaque_test_driver_mac_abort( + &operation->ctx.opaque_test_driver_ctx ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ default: - status = PSA_ERROR_INVALID_ARGUMENT; - break; + return( PSA_ERROR_INVALID_ARGUMENT ); } - - operation->id = 0; - return( status ); } /* End of automatically generated file. */ diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index b09efea59..03618a583 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -181,6 +181,201 @@ exit: /* Implement the PSA driver MAC interface on top of mbed TLS if either the * software driver or the test driver requires it. */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) || defined(PSA_CRYPTO_DRIVER_TEST) + +#if defined(BUILTIN_ALG_CMAC) +static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size ) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const mbedtls_cipher_info_t * cipher_info_tmp = + mbedtls_cipher_info_from_psa( + PSA_ALG_CMAC, + psa_get_key_type( attributes ), + psa_get_key_bits( attributes ), + NULL ); + + if( cipher_info_tmp == NULL ) + return( PSA_ERROR_NOT_SUPPORTED ); + + if( key_buffer_size < PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info_tmp ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_starts( &operation->ctx.cmac, + key_buffer, + psa_get_key_bits( attributes ) ); +exit: + return( mbedtls_to_psa_error( ret ) ); +} +#endif /* BUILTIN_ALG_CMAC */ + +/* Initialize this driver's MAC operation structure. Once this function has been + * called, mbedtls_psa_mac_abort can run and will do the right thing. */ +static psa_status_t mac_init( + mbedtls_psa_mac_operation_t *operation, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); + operation->key_set = 0; + operation->iv_set = 0; + operation->iv_required = 0; + operation->has_input = 0; + operation->is_sign = 0; + +#if defined(BUILTIN_ALG_CMAC) + if( operation->alg == PSA_ALG_CMAC ) + { + operation->iv_required = 0; + mbedtls_cipher_init( &operation->ctx.cmac ); + status = PSA_SUCCESS; + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( operation->alg ) ) + { + /* We'll set up the hash operation later in psa_hmac_setup_internal. */ + operation->ctx.hmac.alg = 0; + status = PSA_SUCCESS; + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + if( ! PSA_ALG_IS_MAC( alg ) ) + status = PSA_ERROR_INVALID_ARGUMENT; + } + + if( status != PSA_SUCCESS ) + memset( operation, 0, sizeof( *operation ) ); + return( status ); +} + +static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) +{ + if( operation->alg == 0 ) + { + /* 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. */ + return( PSA_SUCCESS ); + } + else +#if defined(BUILTIN_ALG_CMAC) + if( operation->alg == PSA_ALG_CMAC ) + { + mbedtls_cipher_free( &operation->ctx.cmac ); + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( operation->alg ) ) + { + psa_hmac_abort_internal( &operation->ctx.hmac ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + /* Sanity check (shouldn't happen: operation->alg should + * always have been initialized to a valid value). */ + goto bad_state; + } + + operation->alg = 0; + operation->key_set = 0; + operation->iv_set = 0; + operation->iv_required = 0; + operation->has_input = 0; + operation->is_sign = 0; + + return( PSA_SUCCESS ); + +bad_state: + /* If abort is called on an uninitialized object, we can't trust + * anything. Wipe the object in case it contains confidential data. + * This may result in a memory leak if a pointer gets overwritten, + * but it's too late to do anything about this. */ + memset( operation, 0, sizeof( *operation ) ); + return( PSA_ERROR_BAD_STATE ); +} + +static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + int is_sign ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + /* A context must be freshly initialized before it can be set up. */ + if( operation->alg != 0 ) + { + return( PSA_ERROR_BAD_STATE ); + } + + status = mac_init( operation, alg ); + if( status != PSA_SUCCESS ) + return( status ); + if( is_sign ) + operation->is_sign = 1; + + /* Get the output length for the algorithm and key combination. None of the + * currently supported algorithms have an output length dependent on actual + * key size, so setting it to a bogus value is currently OK. */ + operation->mac_size = + PSA_MAC_LENGTH( psa_get_key_type( attributes ), 0, alg ); + +#if defined(BUILTIN_ALG_CMAC) + if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC ) + { + status = cmac_setup( operation, attributes, + key_buffer, key_buffer_size ); + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( alg ) ) + { + /* Sanity check. This shouldn't fail on a valid configuration. */ + if( operation->mac_size > sizeof( operation->ctx.hmac.opad ) ) + { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + + if( psa_get_key_type( attributes ) != PSA_KEY_TYPE_HMAC ) + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + + status = psa_hmac_setup_internal( &operation->ctx.hmac, + key_buffer, + key_buffer_size, + PSA_ALG_HMAC_GET_HASH( alg ) ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + status = PSA_ERROR_NOT_SUPPORTED; + } + +exit: + if( status == PSA_SUCCESS ) + operation->key_set = 1; + else + mac_abort( operation ); + + return( status ); +} + static psa_status_t mac_compute( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, @@ -212,13 +407,8 @@ static psa_status_t mac_sign_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - /* To be fleshed out in a subsequent commit */ - (void) operation; - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - return( PSA_ERROR_NOT_SUPPORTED ); + return( mac_setup( operation, attributes, key_buffer, key_buffer_size, alg, + 1 ) ); } static psa_status_t mac_verify_setup( @@ -228,13 +418,8 @@ static psa_status_t mac_verify_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - /* To be fleshed out in a subsequent commit */ - (void) operation; - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - return( PSA_ERROR_NOT_SUPPORTED ); + return( mac_setup( operation, attributes, key_buffer, key_buffer_size, alg, + 0 ) ); } static psa_status_t mac_update( @@ -274,14 +459,6 @@ static psa_status_t mac_verify_finish( (void) mac_length; return( PSA_ERROR_NOT_SUPPORTED ); } - -static psa_status_t mac_abort( - mbedtls_psa_mac_operation_t *operation ) -{ - /* To be fleshed out in a subsequent commit */ - (void) operation; - return( PSA_ERROR_NOT_SUPPORTED ); -} #endif /* MBEDTLS_PSA_BUILTIN_MAC || PSA_CRYPTO_DRIVER_TEST */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) From 11743f91de58569006d6333980f54c1cf9219101 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 18:38:46 +0100 Subject: [PATCH 09/39] Migrate MAC update call into the software driver Step 2/x in moving the driver. Separate commits should make for easier review. Additional changes on top of code movement: * Early-return success on input with zero-length to mac_update, to avoid NULL pointers getting passed into the driver dispatch Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 42 ++++++++++------------------------------ library/psa_crypto_mac.c | 33 ++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 075f8ded1..ac772bce3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2405,45 +2405,23 @@ psa_status_t psa_mac_verify_setup( psa_mac_operation_t *operation, return( psa_mac_setup( operation, key, alg, 0 ) ); } -psa_status_t psa_mac_update( psa_mac_operation_t *psa_operation, +psa_status_t psa_mac_update( psa_mac_operation_t *operation, const uint8_t *input, size_t input_length ) { - /* Temporary recast to avoid changing a lot of lines */ - mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; - - psa_status_t status = PSA_ERROR_BAD_STATE; - if( ! operation->key_set ) + if( operation->id == 0 ) return( PSA_ERROR_BAD_STATE ); - if( operation->iv_required && ! operation->iv_set ) - return( PSA_ERROR_BAD_STATE ); - operation->has_input = 1; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) - { - int ret = mbedtls_cipher_cmac_update( &operation->ctx.cmac, - input, input_length ); - status = mbedtls_to_psa_error( ret ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if( PSA_ALG_IS_HMAC( operation->alg ) ) - { - status = psa_hash_update( &operation->ctx.hmac.hash_ctx, input, - input_length ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* This shouldn't happen if `operation` was initialized by - * a setup function. */ - return( PSA_ERROR_BAD_STATE ); - } + /* Don't require hash implementations to behave correctly on a + * zero-length input, which may have an invalid pointer. */ + if( input_length == 0 ) + return( PSA_SUCCESS ); + psa_status_t status = psa_driver_wrapper_mac_update( operation, + input, input_length ); if( status != PSA_SUCCESS ) - psa_mac_abort( psa_operation ); + psa_mac_abort( operation ); + return( status ); } diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 03618a583..252afca1f 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -427,11 +427,34 @@ static psa_status_t mac_update( const uint8_t *input, size_t input_length ) { - /* To be fleshed out in a subsequent commit */ - (void) operation; - (void) input; - (void) input_length; - return( PSA_ERROR_NOT_SUPPORTED ); + if( ! operation->key_set ) + return( PSA_ERROR_BAD_STATE ); + if( operation->iv_required && ! operation->iv_set ) + return( PSA_ERROR_BAD_STATE ); + operation->has_input = 1; + +#if defined(BUILTIN_ALG_CMAC) + if( operation->alg == PSA_ALG_CMAC ) + { + return( mbedtls_to_psa_error( + mbedtls_cipher_cmac_update( &operation->ctx.cmac, + input, input_length ) ) ); + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( operation->alg ) ) + { + return( psa_hash_update( &operation->ctx.hmac.hash_ctx, input, + input_length ) ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + /* This shouldn't happen if `operation` was initialized by + * a setup function. */ + return( PSA_ERROR_BAD_STATE ); + } } static psa_status_t mac_sign_finish( From 87885df795193a9ddd91f36855380bef2051e74c Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 19:04:39 +0100 Subject: [PATCH 10/39] Migrate MAC finish calls into the software driver Step 3/x in moving the driver. Separate commits should make for easier review. Additional changes on top of code movement: * Copied the implementation of safer_memcmp from psa_crypto into psa_cipher_mac since the mac_verify driver implementation depends on it, and it isn't available through external linkage Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 117 +++++++-------------------------------- library/psa_crypto_mac.c | 102 ++++++++++++++++++++++++++++++---- 2 files changed, 110 insertions(+), 109 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ac772bce3..4f9cf8f25 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2425,59 +2425,16 @@ psa_status_t psa_mac_update( psa_mac_operation_t *operation, return( status ); } -static psa_status_t psa_mac_finish_internal( mbedtls_psa_mac_operation_t *operation, - uint8_t *mac, - size_t mac_size ) -{ - if( ! operation->key_set ) - return( PSA_ERROR_BAD_STATE ); - if( operation->iv_required && ! operation->iv_set ) - return( PSA_ERROR_BAD_STATE ); - - if( mac_size < operation->mac_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) - { - uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE]; - int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp ); - if( ret == 0 ) - memcpy( mac, tmp, operation->mac_size ); - mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); - return( mbedtls_to_psa_error( ret ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) - if( PSA_ALG_IS_HMAC( operation->alg ) ) - { - return( psa_hmac_finish_internal( &operation->ctx.hmac, - mac, operation->mac_size ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ - { - /* This shouldn't happen if `operation` was initialized by - * a setup function. */ - return( PSA_ERROR_BAD_STATE ); - } -} - -psa_status_t psa_mac_sign_finish( psa_mac_operation_t *psa_operation, +psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size, size_t *mac_length ) { - /* Temporary recast to avoid changing a lot of lines */ - mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t status; - - if( operation->alg == 0 ) - { + if( operation->id == 0 ) return( PSA_ERROR_BAD_STATE ); - } /* Fill the output buffer with something that isn't a valid mac * (barring an attack on the mac and deliberately-crafted input), @@ -2488,68 +2445,32 @@ psa_status_t psa_mac_sign_finish( psa_mac_operation_t *psa_operation, if( mac_size != 0 ) memset( mac, '!', mac_size ); - if( ! operation->is_sign ) - { - return( PSA_ERROR_BAD_STATE ); - } + status = psa_driver_wrapper_mac_sign_finish( operation, + mac, mac_size, mac_length ); - status = psa_mac_finish_internal( operation, mac, mac_size ); + abort_status = psa_mac_abort( operation ); - if( status == PSA_SUCCESS ) - { - status = psa_mac_abort( psa_operation ); - if( status == PSA_SUCCESS ) - *mac_length = operation->mac_size; - else - memset( mac, '!', mac_size ); - } - else - psa_mac_abort( psa_operation ); - return( status ); + if( status != PSA_SUCCESS && mac_size > 0 ) + memset( mac, '!', mac_size ); + + return( status == PSA_SUCCESS ? abort_status : status ); } -psa_status_t psa_mac_verify_finish( psa_mac_operation_t *psa_operation, +psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, const uint8_t *mac, size_t mac_length ) { - /* Temporary recast to avoid changing a lot of lines */ - mbedtls_psa_mac_operation_t* operation = &psa_operation->ctx.mbedtls_ctx; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t actual_mac[PSA_MAC_MAX_SIZE]; - psa_status_t status; - - if( operation->alg == 0 ) - { + if( operation->id == 0 ) return( PSA_ERROR_BAD_STATE ); - } - if( operation->is_sign ) - { - return( PSA_ERROR_BAD_STATE ); - } - if( operation->mac_size != mac_length ) - { - status = PSA_ERROR_INVALID_SIGNATURE; - goto cleanup; - } + status = psa_driver_wrapper_mac_verify_finish( operation, + mac, mac_length ); + abort_status = psa_mac_abort( operation ); - status = psa_mac_finish_internal( operation, - actual_mac, sizeof( actual_mac ) ); - if( status != PSA_SUCCESS ) - goto cleanup; - - if( safer_memcmp( mac, actual_mac, mac_length ) != 0 ) - status = PSA_ERROR_INVALID_SIGNATURE; - -cleanup: - if( status == PSA_SUCCESS ) - status = psa_mac_abort( psa_operation ); - else - psa_mac_abort( psa_operation ); - - mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); - - return( status ); + return( status == PSA_SUCCESS ? abort_status : status ); } diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 252afca1f..72386d873 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -457,18 +457,77 @@ static psa_status_t mac_update( } } +static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size ) +{ + if( ! operation->key_set ) + return( PSA_ERROR_BAD_STATE ); + if( operation->iv_required && ! operation->iv_set ) + return( PSA_ERROR_BAD_STATE ); + + if( mac_size < operation->mac_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + +#if defined(BUILTIN_ALG_CMAC) + if( operation->alg == PSA_ALG_CMAC ) + { + uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE]; + int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp ); + if( ret == 0 ) + memcpy( mac, tmp, operation->mac_size ); + mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); + return( mbedtls_to_psa_error( ret ) ); + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( operation->alg ) ) + { + return( psa_hmac_finish_internal( &operation->ctx.hmac, + mac, operation->mac_size ) ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + /* This shouldn't happen if `operation` was initialized by + * a setup function. */ + return( PSA_ERROR_BAD_STATE ); + } +} + static psa_status_t mac_sign_finish( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size, size_t *mac_length ) { - /* To be fleshed out in a subsequent commit */ - (void) operation; - (void) mac; - (void) mac_size; - (void) mac_length; - return( PSA_ERROR_NOT_SUPPORTED ); + psa_status_t status; + + if( operation->alg == 0 ) + return( PSA_ERROR_BAD_STATE ); + + if( ! operation->is_sign ) + return( PSA_ERROR_BAD_STATE ); + + status = mac_finish_internal( operation, mac, mac_size ); + + if( status == PSA_SUCCESS ) + *mac_length = operation->mac_size; + + return( status ); +} + +/* constant-time buffer comparison */ +static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n ) +{ + size_t i; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= a[i] ^ b[i]; + + return( diff ); } static psa_status_t mac_verify_finish( @@ -476,11 +535,32 @@ static psa_status_t mac_verify_finish( const uint8_t *mac, size_t mac_length ) { - /* To be fleshed out in a subsequent commit */ - (void) operation; - (void) mac; - (void) mac_length; - return( PSA_ERROR_NOT_SUPPORTED ); + uint8_t actual_mac[PSA_MAC_MAX_SIZE]; + psa_status_t status; + + if( operation->alg == 0 ) + return( PSA_ERROR_BAD_STATE ); + + if( operation->is_sign ) + return( PSA_ERROR_BAD_STATE ); + + if( operation->mac_size != mac_length ) + { + status = PSA_ERROR_INVALID_SIGNATURE; + goto cleanup; + } + + status = mac_finish_internal( operation, actual_mac, sizeof( actual_mac ) ); + if( status != PSA_SUCCESS ) + goto cleanup; + + if( safer_memcmp( mac, actual_mac, mac_length ) != 0 ) + status = PSA_ERROR_INVALID_SIGNATURE; + +cleanup: + mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); + + return( status ); } #endif /* MBEDTLS_PSA_BUILTIN_MAC || PSA_CRYPTO_DRIVER_TEST */ From 6f32bcacfa4a86748b1d3db6f792fd56e2a54077 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 19 Mar 2021 19:36:38 +0100 Subject: [PATCH 11/39] Add CMAC and HMAC driver testing to all.sh Signed-off-by: Steven Cooreman --- tests/scripts/all.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a85c7ce00..0713ed40f 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1496,6 +1496,8 @@ component_test_psa_crypto_config_basic() { loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS" @@ -2293,6 +2295,8 @@ component_test_psa_crypto_drivers () { loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" From 76720f63891850d4b634eecb9a058cc2addee42a Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 22 Mar 2021 12:21:10 +0100 Subject: [PATCH 12/39] Complete, document and fully use internal HMAC API Since HMAC moved into its own compilation unit, the internal API needed to be documented and finalized. This means no more reaching deep into the operation structure from within the PSA Crypto core. This will make future refactoring work easier, since internal HMAC is now opaque to the core. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 2 + library/psa_crypto.c | 56 +++++++++--------- library/psa_crypto_mac.c | 23 ++++++++ library/psa_crypto_mac.h | 78 +++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 27 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index fd7f6f91a..2fb0633ab 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -53,6 +53,8 @@ typedef struct /** The HMAC part of the context. */ uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; } psa_hmac_internal_data; + +#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, {0}, {0}} #endif /* PSA_WANT_ALG_HMAC */ #include "mbedtls/cmac.h" diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4f9cf8f25..83088f541 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3382,19 +3382,19 @@ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkd return( status ); if( hkdf->block_number != 1 ) { - status = psa_hash_update( &hkdf->hmac.hash_ctx, - hkdf->output_block, - hash_length ); + status = psa_hmac_update_internal( &hkdf->hmac, + hkdf->output_block, + hash_length ); if( status != PSA_SUCCESS ) return( status ); } - status = psa_hash_update( &hkdf->hmac.hash_ctx, - hkdf->info, - hkdf->info_length ); + status = psa_hmac_update_internal( &hkdf->hmac, + hkdf->info, + hkdf->info_length ); if( status != PSA_SUCCESS ) return( status ); - status = psa_hash_update( &hkdf->hmac.hash_ctx, - &hkdf->block_number, 1 ); + status = psa_hmac_update_internal( &hkdf->hmac, + &hkdf->block_number, 1 ); if( status != PSA_SUCCESS ) return( status ); status = psa_hmac_finish_internal( &hkdf->hmac, @@ -3416,7 +3416,7 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg ); uint8_t hash_length = PSA_HASH_LENGTH( hash_alg ); - psa_hash_operation_t backup = PSA_HASH_OPERATION_INIT; + psa_hmac_internal_data backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; psa_status_t status, cleanup_status; /* We can't be wanting more output after block 0xff, otherwise @@ -3451,7 +3451,7 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( /* Save the hash context before using it, to preserve the hash state with * only the inner padding in it. We need this, because inner padding depends * on the key (secret in the RFC's terminology). */ - status = psa_hash_clone( &tls12_prf->hmac.hash_ctx, &backup ); + status = psa_hmac_clone_internal( &tls12_prf->hmac, &backup ); if( status != PSA_SUCCESS ) goto cleanup; @@ -3461,20 +3461,22 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads * the variable seed and in this instance means it in the context of the * P_hash function, where seed = label + seed.) */ - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->label, tls12_prf->label_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->label, + tls12_prf->label_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->seed, tls12_prf->seed_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->seed, + tls12_prf->seed_length ); if( status != PSA_SUCCESS ) goto cleanup; } else { /* A(i) = HMAC_hash(secret, A(i-1)) */ - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->Ai, hash_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->Ai, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; } @@ -3483,35 +3485,35 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( tls12_prf->Ai, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx ); + status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac ); if( status != PSA_SUCCESS ) goto cleanup; /* Calculate HMAC_hash(secret, A(i) + label + seed). */ - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->Ai, hash_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->Ai, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->label, tls12_prf->label_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->label, tls12_prf->label_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->seed, tls12_prf->seed_length ); + status = psa_hmac_update_internal( &tls12_prf->hmac, + tls12_prf->seed, tls12_prf->seed_length ); if( status != PSA_SUCCESS ) goto cleanup; status = psa_hmac_finish_internal( &tls12_prf->hmac, tls12_prf->output_block, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hash_clone( &backup, &tls12_prf->hmac.hash_ctx ); + status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac ); if( status != PSA_SUCCESS ) goto cleanup; cleanup: - cleanup_status = psa_hash_abort( &backup ); + cleanup_status = psa_hmac_abort_internal( &backup ); if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS ) status = cleanup_status; @@ -3857,8 +3859,8 @@ static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, } if( hkdf->state != HKDF_STATE_STARTED ) return( PSA_ERROR_BAD_STATE ); - status = psa_hash_update( &hkdf->hmac.hash_ctx, - data, data_length ); + status = psa_hmac_update_internal( &hkdf->hmac, + data, data_length ); if( status != PSA_SUCCESS ) return( status ); status = psa_hmac_finish_internal( &hkdf->hmac, diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 72386d873..5a7bc2c86 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -139,6 +139,13 @@ cleanup: return( status ); } +psa_status_t psa_hmac_update_internal( psa_hmac_internal_data *hmac, + const uint8_t *data, + size_t data_length ) +{ + return( psa_hash_update( &hmac->hash_ctx, data, data_length ) ); +} + psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, uint8_t *mac, size_t mac_size ) @@ -176,6 +183,22 @@ exit: mbedtls_platform_zeroize( tmp, hash_size ); return( status ); } + +psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data *source, + psa_hmac_internal_data *destination ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + destination->alg = source->alg; + destination->hash_ctx = psa_hash_operation_init(); + status = psa_hash_clone( &source->hash_ctx, &destination->hash_ctx ); + memcpy( destination->opad, source->opad, sizeof( destination->opad ) ); + + if( status != PSA_SUCCESS ) + memset( destination, 0, sizeof( *destination ) ); + + return( status ); +} #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */ /* Implement the PSA driver MAC interface on top of mbed TLS if either the diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index d92351160..6a5629618 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -23,15 +23,93 @@ #include +/** Internal API for starting an HMAC operation, using PSA hash primitives. + * + * \note This API is not meant for application use. Applications should always + * use the top-level psa_mac_xxx APIs for doing HMAC operations. + * + * \param[in] hmac Context structure for this HMAC operation. Needs to have + * been zero-initialized prior to calling this function. + * \param[in] key Key to initialize the HMAC operation with. + * \param key_length Length (in bytes) of key \p key. + * \param hash_alg Hash algorithm to use for calculating the HMAC. + * + * \retval #PSA_SUCCESS + * Success. + * \return Any error code reported by psa_hash_compute(), psa_hash_setup() or + * psa_hash_update(). + */ psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, const uint8_t *key, size_t key_length, psa_algorithm_t hash_alg ); +/** Internal API for adding data to an HMAC operation, using PSA hash primitives. + * + * \note This API is not meant for application use. Applications should always + * use the top-level psa_mac_xxx APIs for doing HMAC operations. + * + * \param[in] hmac Context structure for this HMAC operation. Needs to have + * been initialized with psa_hmac_setup_internal(). + * \param[in] data Buffer containing the data to add to the current HMAC + * calculation. + * \param data_length Length (in bytes) of the input buffer \p data. + * + * \retval #PSA_SUCCESS + * Success. + * \return Any error code reported by psa_hash_update(). + */ +psa_status_t psa_hmac_update_internal( psa_hmac_internal_data *hmac, + const uint8_t *data, + size_t data_length ); + +/** Internal API for finalizing an HMAC operation, using PSA hash primitives. + * + * \note This API is not meant for application use. Applications should always + * use the top-level psa_mac_xxx APIs for doing HMAC operations. + * + * \param[in] hmac Context structure for this HMAC operation. Needs to have + * been initialized with psa_hmac_setup_internal(). + * \param[out] mac Buffer to output the calculated HMAC into. + * \param mac_size Size (in bytes) of the output buffer \p mac. + * + * \retval #PSA_SUCCESS + * Success. + * \return Any error code reported by psa_hash_setup(), psa_hash_update() or + * psa_hash_finish(). + */ psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, uint8_t *mac, size_t mac_size ); +/** Internal API for cloning an HMAC operation, using PSA hash primitives. + * + * \note This API is not meant for application use. Applications should always + * use the top-level psa_mac_xxx APIs for doing HMAC operations. + * + * \param[in] source Context structure to clone from. Needs to have been + * initialized with psa_hmac_setup_internal(). + * \param[out] destination Context structure to clone to. Needs to have been + * zero-initialized. + * + * \retval #PSA_SUCCESS + * Success. + * \return Any error code reported by psa_hash_clone(). + */ +psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data *source, + psa_hmac_internal_data *destination ); + +/** Internal API for aborting an HMAC operation, using PSA hash primitives. + * + * \note This API is not meant for application use. Applications should always + * use the top-level psa_mac_xxx APIs for doing HMAC operations. + * + * \param[in] hmac Context structure for the HMAC operation to abort. + * + * \retval #PSA_SUCCESS + * Success. + * \return Any error code reported by psa_hash_abort(). + */ psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ); /** Calculate the MAC (message authentication code) of a message using Mbed TLS. From f64b25e2057e69ca0f88cbec0a03309cfc786b27 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 22 Mar 2021 14:49:06 +0100 Subject: [PATCH 13/39] Rename internal HMAC structure type to match convention Typedef'ed structures are suffixed _t Also updated the initialiser macro with content that actually matches the structure's content. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 18 +++++++++--------- include/psa/crypto_struct.h | 4 ++-- library/psa_crypto.c | 2 +- library/psa_crypto_mac.c | 12 ++++++------ library/psa_crypto_mac.h | 12 ++++++------ 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 2fb0633ab..e1acf3955 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -46,15 +46,15 @@ #if defined(PSA_WANT_ALG_HMAC) typedef struct { - /** The HMAC algorithm in use */ - psa_algorithm_t alg; - /** The hash context. */ - struct psa_hash_operation_s hash_ctx; - /** The HMAC part of the context. */ - uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; -} psa_hmac_internal_data; + /** The HMAC algorithm in use */ + psa_algorithm_t alg; + /** The hash context. */ + struct psa_hash_operation_s hash_ctx; + /** The HMAC part of the context. */ + uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; +} psa_hmac_internal_data_t; -#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, {0}, {0}} +#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, PSA_HASH_OPERATION_INIT, {0}} #endif /* PSA_WANT_ALG_HMAC */ #include "mbedtls/cmac.h" @@ -73,7 +73,7 @@ typedef struct { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ #if defined(PSA_WANT_ALG_HMAC) - psa_hmac_internal_data hmac; + psa_hmac_internal_data_t hmac; #endif #if defined(MBEDTLS_CMAC_C) mbedtls_cipher_context_t cmac; diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 04c006463..23a090836 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -173,7 +173,7 @@ typedef struct { uint8_t *info; size_t info_length; - psa_hmac_internal_data hmac; + psa_hmac_internal_data_t hmac; uint8_t prk[PSA_HASH_MAX_SIZE]; uint8_t output_block[PSA_HASH_MAX_SIZE]; #if PSA_HASH_MAX_SIZE > 0xff @@ -215,7 +215,7 @@ typedef struct psa_tls12_prf_key_derivation_s size_t seed_length; uint8_t *label; size_t label_length; - psa_hmac_internal_data hmac; + psa_hmac_internal_data_t hmac; uint8_t Ai[PSA_HASH_MAX_SIZE]; /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 83088f541..a4a112064 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3416,7 +3416,7 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg ); uint8_t hash_length = PSA_HASH_LENGTH( hash_alg ); - psa_hmac_internal_data backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; + psa_hmac_internal_data_t backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; psa_status_t status, cleanup_status; /* We can't be wanting more output after block 0xff, otherwise diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 5a7bc2c86..5ea2f1760 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -69,13 +69,13 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg ) } } -psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ) +psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data_t *hmac ) { mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); return( psa_hash_abort( &hmac->hash_ctx ) ); } -psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data_t *hmac, const uint8_t *key, size_t key_length, psa_algorithm_t hash_alg ) @@ -139,14 +139,14 @@ cleanup: return( status ); } -psa_status_t psa_hmac_update_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_update_internal( psa_hmac_internal_data_t *hmac, const uint8_t *data, size_t data_length ) { return( psa_hash_update( &hmac->hash_ctx, data, data_length ) ); } -psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data_t *hmac, uint8_t *mac, size_t mac_size ) { @@ -184,8 +184,8 @@ exit: return( status ); } -psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data *source, - psa_hmac_internal_data *destination ) +psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data_t *source, + psa_hmac_internal_data_t *destination ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index 6a5629618..e63da5304 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -39,7 +39,7 @@ * \return Any error code reported by psa_hash_compute(), psa_hash_setup() or * psa_hash_update(). */ -psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data_t *hmac, const uint8_t *key, size_t key_length, psa_algorithm_t hash_alg ); @@ -59,7 +59,7 @@ psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data *hmac, * Success. * \return Any error code reported by psa_hash_update(). */ -psa_status_t psa_hmac_update_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_update_internal( psa_hmac_internal_data_t *hmac, const uint8_t *data, size_t data_length ); @@ -78,7 +78,7 @@ psa_status_t psa_hmac_update_internal( psa_hmac_internal_data *hmac, * \return Any error code reported by psa_hash_setup(), psa_hash_update() or * psa_hash_finish(). */ -psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, +psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data_t *hmac, uint8_t *mac, size_t mac_size ); @@ -96,8 +96,8 @@ psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data *hmac, * Success. * \return Any error code reported by psa_hash_clone(). */ -psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data *source, - psa_hmac_internal_data *destination ); +psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data_t *source, + psa_hmac_internal_data_t *destination ); /** Internal API for aborting an HMAC operation, using PSA hash primitives. * @@ -110,7 +110,7 @@ psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data *source, * Success. * \return Any error code reported by psa_hash_abort(). */ -psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data *hmac ); +psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data_t *hmac ); /** Calculate the MAC (message authentication code) of a message using Mbed TLS. * From 09832b126e0917bf9410dcee01c265b4c0709d80 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 22 Mar 2021 15:09:44 +0100 Subject: [PATCH 14/39] Add CMAC to standard PSA config Signed-off-by: Steven Cooreman --- include/psa/crypto_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h index 736d9abe0..246e89427 100644 --- a/include/psa/crypto_config.h +++ b/include/psa/crypto_config.h @@ -57,6 +57,7 @@ #define PSA_WANT_ALG_CBC_NO_PADDING 1 #define PSA_WANT_ALG_CBC_PKCS7 1 #define PSA_WANT_ALG_CCM 1 +#define PSA_WANT_ALG_CMAC 1 #define PSA_WANT_ALG_CFB 1 #define PSA_WANT_ALG_CHACHA20_POLY1305 1 #define PSA_WANT_ALG_CMAC 1 From 2d9a3f946e80a11db7f54c61a32b6181437230a0 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 21:10:11 +0200 Subject: [PATCH 15/39] Add testing of the MAC driver entry points Signed-off-by: Steven Cooreman --- library/psa_crypto_driver_wrappers.c | 28 +- tests/include/test/drivers/mac.h | 140 +++++++ tests/include/test/drivers/test_driver.h | 1 + tests/src/drivers/test_driver_mac.c | 361 ++++++++++++++++++ ...test_suite_psa_crypto_driver_wrappers.data | 48 +++ ..._suite_psa_crypto_driver_wrappers.function | 191 +++++++++ visualc/VS2010/mbedTLS.vcxproj | 2 + 7 files changed, 757 insertions(+), 14 deletions(-) create mode 100644 tests/include/test/drivers/mac.h create mode 100644 tests/src/drivers/test_driver_mac.c diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 5d78aede2..795e42489 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -1318,7 +1318,7 @@ psa_status_t psa_driver_wrapper_mac_compute( * cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_transparent_test_driver_mac_compute( + status = mbedtls_test_transparent_mac_compute( attributes, key_buffer, key_buffer_size, alg, input, input_length, mac, mac_size, mac_length ); @@ -1342,7 +1342,7 @@ psa_status_t psa_driver_wrapper_mac_compute( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_opaque_test_driver_mac_compute( + status = mbedtls_test_opaque_mac_compute( attributes, key_buffer, key_buffer_size, alg, input, input_length, mac, mac_size, mac_length ); @@ -1382,7 +1382,7 @@ psa_status_t psa_driver_wrapper_mac_sign_setup( * cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_transparent_test_driver_mac_sign_setup( + status = mbedtls_test_transparent_mac_sign_setup( &operation->ctx.transparent_test_driver_ctx, attributes, key_buffer, key_buffer_size, @@ -1413,7 +1413,7 @@ psa_status_t psa_driver_wrapper_mac_sign_setup( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_opaque_test_driver_mac_sign_setup( + status = mbedtls_test_opaque_mac_sign_setup( &operation->ctx.opaque_test_driver_ctx, attributes, key_buffer, key_buffer_size, @@ -1453,7 +1453,7 @@ psa_status_t psa_driver_wrapper_mac_verify_setup( * cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) - status = mbedtls_transparent_test_driver_mac_verify_setup( + status = mbedtls_test_transparent_mac_verify_setup( &operation->ctx.transparent_test_driver_ctx, attributes, key_buffer, key_buffer_size, @@ -1484,7 +1484,7 @@ psa_status_t psa_driver_wrapper_mac_verify_setup( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LOCATION: - status = mbedtls_opaque_test_driver_mac_sign_setup( + status = mbedtls_test_opaque_mac_verify_setup( &operation->ctx.opaque_test_driver_ctx, attributes, key_buffer, key_buffer_size, @@ -1522,12 +1522,12 @@ psa_status_t psa_driver_wrapper_mac_update( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( mbedtls_transparent_test_driver_mac_update( + return( mbedtls_test_transparent_mac_update( &operation->ctx.transparent_test_driver_ctx, input, input_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( mbedtls_opaque_test_driver_mac_update( + return( mbedtls_test_opaque_mac_update( &operation->ctx.opaque_test_driver_ctx, input, input_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ @@ -1556,12 +1556,12 @@ psa_status_t psa_driver_wrapper_mac_sign_finish( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( mbedtls_transparent_test_driver_mac_sign_finish( + return( mbedtls_test_transparent_mac_sign_finish( &operation->ctx.transparent_test_driver_ctx, mac, mac_size, mac_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( mbedtls_opaque_test_driver_mac_sign_finish( + return( mbedtls_test_opaque_mac_sign_finish( &operation->ctx.opaque_test_driver_ctx, mac, mac_size, mac_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ @@ -1590,12 +1590,12 @@ psa_status_t psa_driver_wrapper_mac_verify_finish( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( mbedtls_transparent_test_driver_mac_verify_finish( + return( mbedtls_test_transparent_mac_verify_finish( &operation->ctx.transparent_test_driver_ctx, mac, mac_length ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( mbedtls_opaque_test_driver_mac_verify_finish( + return( mbedtls_test_opaque_mac_verify_finish( &operation->ctx.opaque_test_driver_ctx, mac, mac_length ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ @@ -1620,10 +1620,10 @@ psa_status_t psa_driver_wrapper_mac_abort( #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID: - return( mbedtls_transparent_test_driver_mac_abort( + return( mbedtls_test_transparent_mac_abort( &operation->ctx.transparent_test_driver_ctx ) ); case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: - return( mbedtls_opaque_test_driver_mac_abort( + return( mbedtls_test_opaque_mac_abort( &operation->ctx.opaque_test_driver_ctx ) ); #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ diff --git a/tests/include/test/drivers/mac.h b/tests/include/test/drivers/mac.h new file mode 100644 index 000000000..e4c750bd6 --- /dev/null +++ b/tests/include/test/drivers/mac.h @@ -0,0 +1,140 @@ +/* + * Test driver for MAC driver entry points. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_TEST_DRIVERS_MAC_H +#define PSA_CRYPTO_TEST_DRIVERS_MAC_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(PSA_CRYPTO_DRIVER_TEST) +#include + +typedef struct { + /* If not PSA_SUCCESS, return this error code instead of processing the + * function call. */ + psa_status_t forced_status; + /* Count the amount of times MAC driver functions are called. */ + unsigned long hits; + /* Status returned by the last MAC driver function call. */ + psa_status_t driver_status; +} test_driver_mac_hooks_t; + +#define MBEDTLS_TEST_DRIVER_MAC_INIT { 0, 0, 0 } +static inline test_driver_mac_hooks_t test_driver_mac_hooks_init( void ) +{ + const test_driver_mac_hooks_t v = MBEDTLS_TEST_DRIVER_MAC_INIT; + return( v ); +} + +extern test_driver_mac_hooks_t test_driver_mac_hooks; + +psa_status_t mbedtls_test_transparent_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_transparent_mac_sign_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_transparent_mac_verify_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_transparent_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_test_transparent_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_transparent_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_test_transparent_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ); + +psa_status_t mbedtls_test_opaque_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_opaque_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_opaque_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_opaque_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_test_opaque_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_opaque_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_test_opaque_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ); + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_TEST_DRIVERS_MAC_H */ diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h index dc2136a6a..5b60932d3 100644 --- a/tests/include/test/drivers/test_driver.h +++ b/tests/include/test/drivers/test_driver.h @@ -25,6 +25,7 @@ #include "test/drivers/aead.h" #include "test/drivers/cipher.h" #include "test/drivers/hash.h" +#include "test/drivers/mac.h" #include "test/drivers/key_management.h" #include "test/drivers/signature.h" #include "test/drivers/size.h" diff --git a/tests/src/drivers/test_driver_mac.c b/tests/src/drivers/test_driver_mac.c new file mode 100644 index 000000000..4e26e9f21 --- /dev/null +++ b/tests/src/drivers/test_driver_mac.c @@ -0,0 +1,361 @@ +/* + * Test driver for MAC entry points. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#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_mac.h" + +#include "test/drivers/mac.h" + +test_driver_mac_hooks_t test_driver_mac_hooks = MBEDTLS_TEST_DRIVER_MAC_INIT; + +psa_status_t mbedtls_test_transparent_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_compute( + attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_sign_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_sign_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_verify_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_verify_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_update( + operation, input, input_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_sign_finish( + operation, mac, mac_size, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_verify_finish( + operation, mac, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_abort( operation ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_compute( + attributes, key_buffer, key_buffer_size, alg, + input, input_length, + mac, mac_size, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_sign_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_verify_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_update( + operation, input, input_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_sign_finish( + operation, mac, mac_size, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_verify_finish( + operation, mac, mac_length ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ) +{ + test_driver_mac_hooks.hits++; + + if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_mac_hooks.driver_status = + test_driver_mac_hooks.forced_status; + } + else + { + test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_abort( operation ); + } + + return( test_driver_mac_hooks.driver_status ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 5fbfac66a..cab40d37f 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -244,6 +244,54 @@ PSA AEAD decrypt, AES-GCM, 144 bytes #1, INSUFFICIENT_MEMORY depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY +PSA MAC sign, through driver: HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS + +PSA MAC sign, fallback: HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_NOT_SUPPORTED + +PSA MAC sign, driver reports error: RFC4231 Test case 1 - HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_GENERIC_ERROR + +PSA MAC sign, through driver: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_SUCCESS + +PSA MAC sign, fallback: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_NOT_SUPPORTED + +PSA MAC sign, driver reports error: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_GENERIC_ERROR + +PSA MAC verify, through driver: HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS + +PSA MAC verify, fallback: HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_NOT_SUPPORTED + +PSA MAC verify, driver reports error: RFC4231 Test case 1 - HMAC-SHA-224 +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_GENERIC_ERROR + +PSA MAC verify, through driver: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_SUCCESS + +PSA MAC verify, fallback: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_NOT_SUPPORTED + +PSA MAC verify, driver reports error: CMAC-AES-128 +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_GENERIC_ERROR + PSA opaque driver builtin key export: AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index 503cdcdde..3247b95a0 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -963,6 +963,197 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mac_sign( int key_type_arg, + data_t *key_data, + int alg_arg, + data_t *input, + data_t *expected_mac, + int forced_status_arg ) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint8_t *actual_mac = NULL; + size_t mac_buffer_size = + PSA_MAC_LENGTH( key_type, PSA_BYTES_TO_BITS( key_data->len ), alg ); + size_t mac_length = 0; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t forced_status = forced_status_arg; + test_driver_mac_hooks = test_driver_mac_hooks_init(); + + TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE ); + /* We expect PSA_MAC_LENGTH to be exact. */ + TEST_ASSERT( expected_mac->len == mac_buffer_size ); + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, key_type ); + + PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, + &key ) ); + + ASSERT_ALLOC( actual_mac, mac_buffer_size ); + test_driver_mac_hooks.forced_status = forced_status; + + /* Calculate the MAC. */ + status = psa_mac_sign_setup( &operation, key, alg ); + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( forced_status, status ); + + status = psa_mac_update( &operation, + input->x, input->len ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 2 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( PSA_ERROR_BAD_STATE, status ); + + status = psa_mac_sign_finish( &operation, + actual_mac, mac_buffer_size, + &mac_length ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( PSA_ERROR_BAD_STATE, status ); + + PSA_ASSERT( psa_mac_abort( &operation ) ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS ) + { + ASSERT_COMPARE( expected_mac->x, expected_mac->len, + actual_mac, mac_length ); + } + + mbedtls_free( actual_mac ); + actual_mac = NULL; + +exit: + psa_mac_abort( &operation ); + psa_destroy_key( key ); + PSA_DONE( ); + mbedtls_free( actual_mac ); + test_driver_mac_hooks = test_driver_mac_hooks_init(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void mac_verify( int key_type_arg, + data_t *key_data, + int alg_arg, + data_t *input, + data_t *expected_mac, + int forced_status_arg ) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + psa_status_t forced_status = forced_status_arg; + test_driver_mac_hooks = test_driver_mac_hooks_init(); + + TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE ); + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, key_type ); + + PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, + &key ) ); + + test_driver_mac_hooks.forced_status = forced_status; + + /* Test the correct MAC. */ + status = psa_mac_verify_setup( &operation, key, alg ); + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( forced_status, status ); + + status = psa_mac_update( &operation, + input->x, input->len ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 2 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( PSA_ERROR_BAD_STATE, status ); + + status = psa_mac_verify_finish( &operation, + expected_mac->x, + expected_mac->len ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( PSA_ERROR_BAD_STATE, status ); + + + PSA_ASSERT( psa_mac_abort( &operation ) ); + if( forced_status == PSA_SUCCESS ) + TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + +exit: + psa_mac_abort( &operation ); + psa_destroy_key( key ); + PSA_DONE( ); + test_driver_mac_hooks = test_driver_mac_hooks_init(); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:PSA_CRYPTO_DRIVER_TEST:MBEDTLS_PSA_CRYPTO_DRIVERS:MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ void builtin_key_export( int builtin_key_id_arg, int builtin_key_type_arg, diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index dc6ee248b..9cec716e3 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -249,6 +249,7 @@ + @@ -389,6 +390,7 @@ + From 5c85ef0a564f6f9b52adc8e2f1ef0a49a31d1a08 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 15:32:42 +0200 Subject: [PATCH 16/39] Remove unused items from MAC operation context structure Apparently it was at some point assumed that there would be support for MAC algorithms with IV, but that hasn't been implemented yet. Until that time, these context structure members are superfluous and can be removed. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 5 +---- library/psa_crypto_mac.c | 9 --------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index e1acf3955..3b0f82ad2 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -63,12 +63,9 @@ typedef struct { psa_algorithm_t alg; unsigned int key_set : 1; - unsigned int iv_required : 1; - unsigned int iv_set : 1; unsigned int has_input : 1; unsigned int is_sign : 1; uint8_t mac_size; - unsigned int id; union { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ @@ -81,7 +78,7 @@ typedef struct } ctx; } mbedtls_psa_mac_operation_t; -#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, 0, 0, 0, {0}} +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, {0}} /* * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 5ea2f1760..0189cded8 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -247,15 +247,12 @@ static psa_status_t mac_init( operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); operation->key_set = 0; - operation->iv_set = 0; - operation->iv_required = 0; operation->has_input = 0; operation->is_sign = 0; #if defined(BUILTIN_ALG_CMAC) if( operation->alg == PSA_ALG_CMAC ) { - operation->iv_required = 0; mbedtls_cipher_init( &operation->ctx.cmac ); status = PSA_SUCCESS; } @@ -312,8 +309,6 @@ static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) operation->alg = 0; operation->key_set = 0; - operation->iv_set = 0; - operation->iv_required = 0; operation->has_input = 0; operation->is_sign = 0; @@ -452,8 +447,6 @@ static psa_status_t mac_update( { if( ! operation->key_set ) return( PSA_ERROR_BAD_STATE ); - if( operation->iv_required && ! operation->iv_set ) - return( PSA_ERROR_BAD_STATE ); operation->has_input = 1; #if defined(BUILTIN_ALG_CMAC) @@ -486,8 +479,6 @@ static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, { if( ! operation->key_set ) return( PSA_ERROR_BAD_STATE ); - if( operation->iv_required && ! operation->iv_set ) - return( PSA_ERROR_BAD_STATE ); if( mac_size < operation->mac_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); From 6e6451ec015947de7dd2875e137513aa3b985ebf Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 16:21:24 +0200 Subject: [PATCH 17/39] Code flow/readability improvements after review * Early return since there's nothing to clean up * Get rid of unnecessary local variable * Check algorithm validity for MAC in the PSA core instead of in the driver Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 14 +++++++++----- library/psa_crypto_mac.c | 5 ++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a4a112064..81770bff9 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2318,18 +2318,22 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - psa_key_usage_t usage = - is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH; - size_t mac_size = 0; + size_t mac_size; /* 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_MAC( alg ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); + status = psa_get_and_lock_key_slot_with_policy( - key, &slot, usage, alg ); + key, + &slot, + is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, + alg ); if( status != PSA_SUCCESS ) - goto exit; + return( status ); psa_key_attributes_t attributes = { .core = slot->attr diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 0189cded8..d8e229325 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -243,7 +243,7 @@ static psa_status_t mac_init( mbedtls_psa_mac_operation_t *operation, psa_algorithm_t alg ) { - psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); operation->key_set = 0; @@ -268,8 +268,7 @@ static psa_status_t mac_init( else #endif /* BUILTIN_ALG_HMAC */ { - if( ! PSA_ALG_IS_MAC( alg ) ) - status = PSA_ERROR_INVALID_ARGUMENT; + status = PSA_ERROR_NOT_SUPPORTED; } if( status != PSA_SUCCESS ) From b4b9b2879c565a686d797514b0e853d161c6de92 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 16:24:36 +0200 Subject: [PATCH 18/39] Remove redundant key_set from MAC operation structure The purpose of key_set was to guard the operation structure from being used for update/finish before a key was set. Now that the implementation fully adheres to the PSA API, that function is covered by the `alg` variable instead. It's set to the algorithm in use when a key is set, and is zero when the operation is reset/invalid. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 3 +-- library/psa_crypto_mac.c | 11 +++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 3b0f82ad2..780a6c54e 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -62,7 +62,6 @@ typedef struct typedef struct { psa_algorithm_t alg; - unsigned int key_set : 1; unsigned int has_input : 1; unsigned int is_sign : 1; uint8_t mac_size; @@ -78,7 +77,7 @@ typedef struct } ctx; } mbedtls_psa_mac_operation_t; -#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, 0, {0}} +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, {0}} /* * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index d8e229325..7122ecdd3 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -246,7 +246,6 @@ static psa_status_t mac_init( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); - operation->key_set = 0; operation->has_input = 0; operation->is_sign = 0; @@ -307,7 +306,6 @@ static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) } operation->alg = 0; - operation->key_set = 0; operation->has_input = 0; operation->is_sign = 0; @@ -385,9 +383,7 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, } exit: - if( status == PSA_SUCCESS ) - operation->key_set = 1; - else + if( status != PSA_SUCCESS ) mac_abort( operation ); return( status ); @@ -444,7 +440,7 @@ static psa_status_t mac_update( const uint8_t *input, size_t input_length ) { - if( ! operation->key_set ) + if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); operation->has_input = 1; @@ -476,9 +472,8 @@ static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size ) { - if( ! operation->key_set ) + if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); - if( mac_size < operation->mac_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); From a2a1b803da77e6a1fe3f059f2059280a97a95ca2 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 16:37:59 +0200 Subject: [PATCH 19/39] Make safer_memcmp available to all compile units under PSA Now renamed to mbedtls_psa_safer_memcmp, it provides a single location for buffer comparison. Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 18 ++---------------- library/psa_crypto_core.h | 20 ++++++++++++++++++++ library/psa_crypto_mac.c | 14 +------------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 81770bff9..dbf05b9ec 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -93,20 +93,6 @@ #define ARRAY_LENGTH( array ) ( sizeof( array ) / sizeof( *( array ) ) ) -/* constant-time buffer comparison */ -static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n ) -{ - size_t i; - unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - diff |= a[i] ^ b[i]; - - return( diff ); -} - - - /****************************************************************/ /* Global data, support functions and library management */ /****************************************************************/ @@ -2235,7 +2221,7 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation, return( status ); if( actual_hash_length != hash_length ) return( PSA_ERROR_INVALID_SIGNATURE ); - if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) + if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) return( PSA_ERROR_INVALID_SIGNATURE ); return( PSA_SUCCESS ); } @@ -2271,7 +2257,7 @@ psa_status_t psa_hash_compare( psa_algorithm_t alg, return( status ); if( actual_hash_length != hash_length ) return( PSA_ERROR_INVALID_SIGNATURE ); - if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) + if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) return( PSA_ERROR_INVALID_SIGNATURE ); return( PSA_SUCCESS ); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 90f9d1863..b75e59a81 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -30,6 +30,26 @@ #include "psa/crypto.h" #include "psa/crypto_se_driver.h" +/** Constant-time buffer comparison + * + * \param[in] a Left-hand buffer for comparison. + * \param[in] b Right-hand buffer for comparison. + * \param n Amount of bytes to compare. + * + * \return 0 if the buffer contents are equal, non-zero otherwise + */ +static inline int mbedtls_psa_safer_memcmp( + const uint8_t *a, const uint8_t *b, size_t n ) +{ + size_t i; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= a[i] ^ b[i]; + + return( diff ); +} + /** The data structure representing a key slot, containing key material * and metadata for one key. */ diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 7122ecdd3..854aee4f0 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -526,18 +526,6 @@ static psa_status_t mac_sign_finish( return( status ); } -/* constant-time buffer comparison */ -static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n ) -{ - size_t i; - unsigned char diff = 0; - - for( i = 0; i < n; i++ ) - diff |= a[i] ^ b[i]; - - return( diff ); -} - static psa_status_t mac_verify_finish( mbedtls_psa_mac_operation_t *operation, const uint8_t *mac, @@ -562,7 +550,7 @@ static psa_status_t mac_verify_finish( if( status != PSA_SUCCESS ) goto cleanup; - if( safer_memcmp( mac, actual_mac, mac_length ) != 0 ) + if( mbedtls_psa_safer_memcmp( mac, actual_mac, mac_length ) != 0 ) status = PSA_ERROR_INVALID_SIGNATURE; cleanup: From 4f7cae6cbefa68559a798b14b35e6e002c38d5d4 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 17:49:11 +0200 Subject: [PATCH 20/39] Rename HMAC operation structure Prefix with 'mbedtls_psa' as per the other types which implement some sort of algorithm in software. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 4 ++-- include/psa/crypto_struct.h | 4 ++-- library/psa_crypto.c | 2 +- library/psa_crypto_mac.c | 13 +++++++------ library/psa_crypto_mac.h | 13 +++++++------ 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 780a6c54e..81a8ec719 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -52,7 +52,7 @@ typedef struct struct psa_hash_operation_s hash_ctx; /** The HMAC part of the context. */ uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; -} psa_hmac_internal_data_t; +} mbedtls_psa_hmac_operation_t; #define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, PSA_HASH_OPERATION_INIT, {0}} #endif /* PSA_WANT_ALG_HMAC */ @@ -69,7 +69,7 @@ typedef struct { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ #if defined(PSA_WANT_ALG_HMAC) - psa_hmac_internal_data_t hmac; + mbedtls_psa_hmac_operation_t hmac; #endif #if defined(MBEDTLS_CMAC_C) mbedtls_cipher_context_t cmac; diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 23a090836..79c4285a5 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -173,7 +173,7 @@ typedef struct { uint8_t *info; size_t info_length; - psa_hmac_internal_data_t hmac; + mbedtls_psa_hmac_operation_t hmac; uint8_t prk[PSA_HASH_MAX_SIZE]; uint8_t output_block[PSA_HASH_MAX_SIZE]; #if PSA_HASH_MAX_SIZE > 0xff @@ -215,7 +215,7 @@ typedef struct psa_tls12_prf_key_derivation_s size_t seed_length; uint8_t *label; size_t label_length; - psa_hmac_internal_data_t hmac; + mbedtls_psa_hmac_operation_t hmac; uint8_t Ai[PSA_HASH_MAX_SIZE]; /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index dbf05b9ec..1b77d6938 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3406,7 +3406,7 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg ); uint8_t hash_length = PSA_HASH_LENGTH( hash_alg ); - psa_hmac_internal_data_t backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; + mbedtls_psa_hmac_operation_t backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; psa_status_t status, cleanup_status; /* We can't be wanting more output after block 0xff, otherwise diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 854aee4f0..ac026ff4c 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -69,13 +69,13 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg ) } } -psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data_t *hmac ) +psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac ) { mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); return( psa_hash_abort( &hmac->hash_ctx ) ); } -psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac, const uint8_t *key, size_t key_length, psa_algorithm_t hash_alg ) @@ -139,14 +139,14 @@ cleanup: return( status ); } -psa_status_t psa_hmac_update_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac, const uint8_t *data, size_t data_length ) { return( psa_hash_update( &hmac->hash_ctx, data, data_length ) ); } -psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac, uint8_t *mac, size_t mac_size ) { @@ -184,8 +184,9 @@ exit: return( status ); } -psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data_t *source, - psa_hmac_internal_data_t *destination ) +psa_status_t psa_hmac_clone_internal( + const mbedtls_psa_hmac_operation_t *source, + mbedtls_psa_hmac_operation_t *destination ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index e63da5304..b7f2a6c3b 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -39,7 +39,7 @@ * \return Any error code reported by psa_hash_compute(), psa_hash_setup() or * psa_hash_update(). */ -psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac, const uint8_t *key, size_t key_length, psa_algorithm_t hash_alg ); @@ -59,7 +59,7 @@ psa_status_t psa_hmac_setup_internal( psa_hmac_internal_data_t *hmac, * Success. * \return Any error code reported by psa_hash_update(). */ -psa_status_t psa_hmac_update_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac, const uint8_t *data, size_t data_length ); @@ -78,7 +78,7 @@ psa_status_t psa_hmac_update_internal( psa_hmac_internal_data_t *hmac, * \return Any error code reported by psa_hash_setup(), psa_hash_update() or * psa_hash_finish(). */ -psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data_t *hmac, +psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac, uint8_t *mac, size_t mac_size ); @@ -96,8 +96,9 @@ psa_status_t psa_hmac_finish_internal( psa_hmac_internal_data_t *hmac, * Success. * \return Any error code reported by psa_hash_clone(). */ -psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data_t *source, - psa_hmac_internal_data_t *destination ); +psa_status_t psa_hmac_clone_internal( + const mbedtls_psa_hmac_operation_t *source, + mbedtls_psa_hmac_operation_t *destination ); /** Internal API for aborting an HMAC operation, using PSA hash primitives. * @@ -110,7 +111,7 @@ psa_status_t psa_hmac_clone_internal( const psa_hmac_internal_data_t *source, * Success. * \return Any error code reported by psa_hash_abort(). */ -psa_status_t psa_hmac_abort_internal( psa_hmac_internal_data_t *hmac ); +psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac ); /** Calculate the MAC (message authentication code) of a message using Mbed TLS. * From c2cbac017f7947e1e70057f25ee9ac35b0fc596d Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 18:01:53 +0200 Subject: [PATCH 21/39] Use the correct guards on the context structures for MAC/HKDF/PRF Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 12 ++++++------ include/psa/crypto_struct.h | 15 ++++++++++----- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 81a8ec719..6979dec42 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -43,7 +43,7 @@ #define MBEDTLS_PSA_BUILTIN_MAC #endif -#if defined(PSA_WANT_ALG_HMAC) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) typedef struct { /** The HMAC algorithm in use */ @@ -55,7 +55,7 @@ typedef struct } mbedtls_psa_hmac_operation_t; #define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, PSA_HASH_OPERATION_INIT, {0}} -#endif /* PSA_WANT_ALG_HMAC */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ #include "mbedtls/cmac.h" @@ -68,12 +68,12 @@ typedef struct union { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ -#if defined(PSA_WANT_ALG_HMAC) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) mbedtls_psa_hmac_operation_t hmac; -#endif -#if defined(MBEDTLS_CMAC_C) +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || defined(PSA_CRYPTO_DRIVER_TEST) mbedtls_cipher_context_t cmac; -#endif +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ } ctx; } mbedtls_psa_mac_operation_t; diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 79c4285a5..22b5fc2fb 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -168,7 +168,7 @@ static inline struct psa_aead_operation_s psa_aead_operation_init( void ) return( v ); } -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) typedef struct { uint8_t *info; @@ -184,9 +184,10 @@ typedef struct unsigned int state : 2; unsigned int info_set : 1; } psa_hkdf_key_derivation_t; -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HKDF */ -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) typedef enum { PSA_TLS12_PRF_STATE_INIT, /* no input provided */ @@ -221,7 +222,8 @@ typedef struct psa_tls12_prf_key_derivation_s /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */ uint8_t output_block[PSA_HASH_MAX_SIZE]; } psa_tls12_prf_key_derivation_t; -#endif /* MBEDTLS_MD_C */ +#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || + * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ struct psa_key_derivation_s { @@ -232,8 +234,11 @@ struct psa_key_derivation_s { /* Make the union non-empty even with no supported algorithms. */ uint8_t dummy; -#if defined(MBEDTLS_MD_C) +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) psa_hkdf_key_derivation_t hkdf; +#endif +#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) psa_tls12_prf_key_derivation_t tls12_prf; #endif } ctx; From b27e3506fe6c67f4b2d7dd15224e35c438aa43d4 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 19:11:25 +0200 Subject: [PATCH 22/39] Make HKDF use the generic MAC API Such that the underlying HMAC can be accelerated if such a driver is present Signed-off-by: Steven Cooreman --- include/psa/crypto_struct.h | 2 +- library/psa_crypto.c | 100 ++++++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 22b5fc2fb..6b4cda60a 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -173,7 +173,7 @@ typedef struct { uint8_t *info; size_t info_length; - mbedtls_psa_hmac_operation_t hmac; + psa_mac_operation_t hmac; uint8_t prk[PSA_HASH_MAX_SIZE]; uint8_t output_block[PSA_HASH_MAX_SIZE]; #if PSA_HASH_MAX_SIZE > 0xff diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1b77d6938..03792fc39 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3264,7 +3264,7 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation if( PSA_ALG_IS_HKDF( kdf_alg ) ) { mbedtls_free( operation->ctx.hkdf.info ); - status = psa_hmac_abort_internal( &operation->ctx.hkdf.hmac ); + status = psa_mac_abort( &operation->ctx.hkdf.hmac ); } else #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF */ @@ -3331,11 +3331,12 @@ psa_status_t psa_key_derivation_set_capacity( psa_key_derivation_operation_t *op /* Read some bytes from an HKDF-based operation. This performs a chunk * of the expand phase of the HKDF algorithm. */ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkdf, - psa_algorithm_t hash_alg, - uint8_t *output, - size_t output_length ) + psa_algorithm_t hash_alg, + uint8_t *output, + size_t output_length ) { uint8_t hash_length = PSA_HASH_LENGTH( hash_alg ); + size_t hmac_output_length; psa_status_t status; if( hkdf->state < HKDF_STATE_KEYED || ! hkdf->info_set ) @@ -3365,31 +3366,42 @@ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkd /* We need a new block */ ++hkdf->block_number; hkdf->offset_in_block = 0; - status = psa_hmac_setup_internal( &hkdf->hmac, - hkdf->prk, hash_length, - hash_alg ); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, + PSA_BYTES_TO_BITS( hash_length ) ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + + status = psa_driver_wrapper_mac_sign_setup( &hkdf->hmac, + &attributes, + hkdf->prk, hash_length, + PSA_ALG_HMAC( hash_alg ) ); + psa_reset_key_attributes( &attributes ); if( status != PSA_SUCCESS ) return( status ); + if( hkdf->block_number != 1 ) { - status = psa_hmac_update_internal( &hkdf->hmac, - hkdf->output_block, - hash_length ); + status = psa_mac_update( &hkdf->hmac, + hkdf->output_block, + hash_length ); if( status != PSA_SUCCESS ) return( status ); } - status = psa_hmac_update_internal( &hkdf->hmac, - hkdf->info, - hkdf->info_length ); + status = psa_mac_update( &hkdf->hmac, + hkdf->info, + hkdf->info_length ); if( status != PSA_SUCCESS ) return( status ); - status = psa_hmac_update_internal( &hkdf->hmac, - &hkdf->block_number, 1 ); + status = psa_mac_update( &hkdf->hmac, + &hkdf->block_number, 1 ); if( status != PSA_SUCCESS ) return( status ); - status = psa_hmac_finish_internal( &hkdf->hmac, - hkdf->output_block, - sizeof( hkdf->output_block ) ); + status = psa_mac_sign_finish( &hkdf->hmac, + hkdf->output_block, + sizeof( hkdf->output_block ), + &hmac_output_length ); if( status != PSA_SUCCESS ) return( status ); } @@ -3829,33 +3841,55 @@ static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, case PSA_KEY_DERIVATION_INPUT_SALT: if( hkdf->state != HKDF_STATE_INIT ) return( PSA_ERROR_BAD_STATE ); - status = psa_hmac_setup_internal( &hkdf->hmac, - data, data_length, - hash_alg ); - if( status != PSA_SUCCESS ) - return( status ); - hkdf->state = HKDF_STATE_STARTED; - return( PSA_SUCCESS ); + else + { + /* In a scope block due to scope-local attributes variable */ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, + PSA_BYTES_TO_BITS( data_length ) ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + + status = psa_driver_wrapper_mac_sign_setup( + &hkdf->hmac, + &attributes, + data, data_length, + PSA_ALG_HMAC( hash_alg ) ); + psa_reset_key_attributes( &attributes ); + if( status != PSA_SUCCESS ) + return( status ); + hkdf->state = HKDF_STATE_STARTED; + return( PSA_SUCCESS ); + } case PSA_KEY_DERIVATION_INPUT_SECRET: /* If no salt was provided, use an empty salt. */ if( hkdf->state == HKDF_STATE_INIT ) { - status = psa_hmac_setup_internal( &hkdf->hmac, - NULL, 0, - hash_alg ); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, 0 ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + + status = psa_driver_wrapper_mac_sign_setup( + &hkdf->hmac, + &attributes, + NULL, 0, + PSA_ALG_HMAC( hash_alg ) ); + psa_reset_key_attributes( &attributes ); if( status != PSA_SUCCESS ) return( status ); hkdf->state = HKDF_STATE_STARTED; } if( hkdf->state != HKDF_STATE_STARTED ) return( PSA_ERROR_BAD_STATE ); - status = psa_hmac_update_internal( &hkdf->hmac, - data, data_length ); + status = psa_mac_update( &hkdf->hmac, + data, data_length ); if( status != PSA_SUCCESS ) return( status ); - status = psa_hmac_finish_internal( &hkdf->hmac, - hkdf->prk, - sizeof( hkdf->prk ) ); + status = psa_mac_sign_finish( &hkdf->hmac, + hkdf->prk, + sizeof( hkdf->prk ), + &data_length ); if( status != PSA_SUCCESS ) return( status ); hkdf->offset_in_block = PSA_HASH_LENGTH( hash_alg ); From 22dea1d52752d7c36a44e77c2b9d1adf71955653 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 29 Apr 2021 19:32:25 +0200 Subject: [PATCH 23/39] Base the PSA implementation of TLS 1.2 PRF on the MAC API This means there is no longer a need to have an internal HMAC API, so it is being removed in this commit as well. Signed-off-by: Steven Cooreman --- include/psa/crypto_struct.h | 4 +- library/psa_crypto.c | 106 +++++++++++++++++++++--------------- library/psa_crypto_mac.c | 47 ++++++---------- library/psa_crypto_mac.h | 90 ------------------------------ 4 files changed, 81 insertions(+), 166 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 6b4cda60a..fc7e7785c 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -212,11 +212,13 @@ typedef struct psa_tls12_prf_key_derivation_s psa_tls12_prf_key_derivation_state_t state; + uint8_t *secret; + size_t secret_length; uint8_t *seed; size_t seed_length; uint8_t *label; size_t label_length; - mbedtls_psa_hmac_operation_t hmac; + uint8_t Ai[PSA_HASH_MAX_SIZE]; /* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 03792fc39..959549785 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3274,6 +3274,13 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation /* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */ PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { + if( operation->ctx.tls12_prf.secret != NULL ) + { + mbedtls_platform_zeroize( operation->ctx.tls12_prf.secret, + operation->ctx.tls12_prf.secret_length ); + mbedtls_free( operation->ctx.tls12_prf.secret ); + } + if( operation->ctx.tls12_prf.seed != NULL ) { mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed, @@ -3288,7 +3295,7 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation mbedtls_free( operation->ctx.tls12_prf.label ); } - status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac ); + status = PSA_SUCCESS; /* We leave the fields Ai and output_block to be erased safely by the * mbedtls_platform_zeroize() in the end of this function. */ @@ -3418,7 +3425,8 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( { psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg ); uint8_t hash_length = PSA_HASH_LENGTH( hash_alg ); - mbedtls_psa_hmac_operation_t backup = MBEDTLS_PSA_HMAC_OPERATION_INIT; + psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT; + size_t hmac_output_length; psa_status_t status, cleanup_status; /* We can't be wanting more output after block 0xff, otherwise @@ -3450,10 +3458,17 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( * `block_number`. */ - /* Save the hash context before using it, to preserve the hash state with - * only the inner padding in it. We need this, because inner padding depends - * on the key (secret in the RFC's terminology). */ - status = psa_hmac_clone_internal( &tls12_prf->hmac, &backup ); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, + PSA_BYTES_TO_BITS( tls12_prf->secret_length ) ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + + status = psa_driver_wrapper_mac_sign_setup( &hmac, + &attributes, + tls12_prf->secret, + tls12_prf->secret_length, + PSA_ALG_HMAC( hash_alg ) ); if( status != PSA_SUCCESS ) goto cleanup; @@ -3463,59 +3478,61 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( /* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads * the variable seed and in this instance means it in the context of the * P_hash function, where seed = label + seed.) */ - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->label, - tls12_prf->label_length ); + status = psa_mac_update( &hmac, + tls12_prf->label, + tls12_prf->label_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->seed, - tls12_prf->seed_length ); + status = psa_mac_update( &hmac, + tls12_prf->seed, + tls12_prf->seed_length ); if( status != PSA_SUCCESS ) goto cleanup; } else { /* A(i) = HMAC_hash(secret, A(i-1)) */ - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->Ai, hash_length ); + status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; } - status = psa_hmac_finish_internal( &tls12_prf->hmac, - tls12_prf->Ai, hash_length ); - if( status != PSA_SUCCESS ) - goto cleanup; - status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac ); + status = psa_mac_sign_finish( &hmac, + tls12_prf->Ai, hash_length, + &hmac_output_length ); + if( hmac_output_length != hash_length ) + status = PSA_ERROR_CORRUPTION_DETECTED; if( status != PSA_SUCCESS ) goto cleanup; /* Calculate HMAC_hash(secret, A(i) + label + seed). */ - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->Ai, hash_length ); + status = psa_driver_wrapper_mac_sign_setup( &hmac, + &attributes, + tls12_prf->secret, + tls12_prf->secret_length, + PSA_ALG_HMAC( hash_alg ) ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->label, tls12_prf->label_length ); + status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hmac_update_internal( &tls12_prf->hmac, - tls12_prf->seed, tls12_prf->seed_length ); + status = psa_mac_update( &hmac, tls12_prf->label, tls12_prf->label_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hmac_finish_internal( &tls12_prf->hmac, - tls12_prf->output_block, hash_length ); + status = psa_mac_update( &hmac, tls12_prf->seed, tls12_prf->seed_length ); if( status != PSA_SUCCESS ) goto cleanup; - status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac ); + status = psa_mac_sign_finish( &hmac, + tls12_prf->output_block, hash_length, + &hmac_output_length ); if( status != PSA_SUCCESS ) goto cleanup; cleanup: + psa_reset_key_attributes( &attributes ); - cleanup_status = psa_hmac_abort_internal( &backup ); + cleanup_status = psa_mac_abort( &hmac ); if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS ) status = cleanup_status; @@ -3612,8 +3629,8 @@ psa_status_t psa_key_derivation_output_bytes( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf, - kdf_alg, output, - output_length ); + kdf_alg, output, + output_length ); } else #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF || @@ -3942,17 +3959,21 @@ static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf, } static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf, - psa_algorithm_t hash_alg, const uint8_t *data, size_t data_length ) { - psa_status_t status; if( prf->state != PSA_TLS12_PRF_STATE_SEED_SET ) return( PSA_ERROR_BAD_STATE ); - status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg ); - if( status != PSA_SUCCESS ) - return( status ); + if( data_length != 0 ) + { + prf->secret = mbedtls_calloc( 1, data_length ); + if( prf->secret == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + + memcpy( prf->secret, data, data_length ); + prf->secret_length = data_length; + } prf->state = PSA_TLS12_PRF_STATE_KEY_SET; @@ -3982,7 +4003,6 @@ static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf } static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf, - psa_algorithm_t hash_alg, psa_key_derivation_step_t step, const uint8_t *data, size_t data_length ) @@ -3992,7 +4012,7 @@ static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf, case PSA_KEY_DERIVATION_INPUT_SEED: return( psa_tls12_prf_set_seed( prf, data, data_length ) ); case PSA_KEY_DERIVATION_INPUT_SECRET: - return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) ); + return( psa_tls12_prf_set_key( prf, data, data_length ) ); case PSA_KEY_DERIVATION_INPUT_LABEL: return( psa_tls12_prf_set_label( prf, data, data_length ) ); default: @@ -4005,7 +4025,6 @@ static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf, #if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) static psa_status_t psa_tls12_prf_psk_to_ms_set_key( psa_tls12_prf_key_derivation_t *prf, - psa_algorithm_t hash_alg, const uint8_t *data, size_t data_length ) { @@ -4032,7 +4051,7 @@ static psa_status_t psa_tls12_prf_psk_to_ms_set_key( memcpy( cur, data, data_length ); cur += data_length; - status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms ); + status = psa_tls12_prf_set_key( prf, pms, cur - pms ); mbedtls_platform_zeroize( pms, sizeof( pms ) ); return( status ); @@ -4040,18 +4059,17 @@ static psa_status_t psa_tls12_prf_psk_to_ms_set_key( static psa_status_t psa_tls12_prf_psk_to_ms_input( psa_tls12_prf_key_derivation_t *prf, - psa_algorithm_t hash_alg, psa_key_derivation_step_t step, const uint8_t *data, size_t data_length ) { if( step == PSA_KEY_DERIVATION_INPUT_SECRET ) { - return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg, + return( psa_tls12_prf_psk_to_ms_set_key( prf, data, data_length ) ); } - return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) ); + return( psa_tls12_prf_input( prf, step, data, data_length ) ); } #endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ @@ -4116,7 +4134,6 @@ static psa_status_t psa_key_derivation_input_internal( if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) ) { status = psa_tls12_prf_input( &operation->ctx.tls12_prf, - PSA_ALG_HKDF_GET_HASH( kdf_alg ), step, data, data_length ); } else @@ -4125,7 +4142,6 @@ static psa_status_t psa_key_derivation_input_internal( if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) ) { status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf, - PSA_ALG_HKDF_GET_HASH( kdf_alg ), step, data, data_length ); } else diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index ac026ff4c..ca40b03bf 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -69,16 +69,18 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg ) } } -psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac ) +static psa_status_t psa_hmac_abort_internal( + mbedtls_psa_hmac_operation_t *hmac ) { mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) ); return( psa_hash_abort( &hmac->hash_ctx ) ); } -psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *key, - size_t key_length, - psa_algorithm_t hash_alg ) +static psa_status_t psa_hmac_setup_internal( + mbedtls_psa_hmac_operation_t *hmac, + const uint8_t *key, + size_t key_length, + psa_algorithm_t hash_alg ) { uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE]; size_t i; @@ -139,16 +141,18 @@ cleanup: return( status ); } -psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *data, - size_t data_length ) +static psa_status_t psa_hmac_update_internal( + mbedtls_psa_hmac_operation_t *hmac, + const uint8_t *data, + size_t data_length ) { return( psa_hash_update( &hmac->hash_ctx, data, data_length ) ); } -psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac, - uint8_t *mac, - size_t mac_size ) +static psa_status_t psa_hmac_finish_internal( + mbedtls_psa_hmac_operation_t *hmac, + uint8_t *mac, + size_t mac_size ) { uint8_t tmp[MBEDTLS_MD_MAX_SIZE]; psa_algorithm_t hash_alg = hmac->alg; @@ -183,23 +187,6 @@ exit: mbedtls_platform_zeroize( tmp, hash_size ); return( status ); } - -psa_status_t psa_hmac_clone_internal( - const mbedtls_psa_hmac_operation_t *source, - mbedtls_psa_hmac_operation_t *destination ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - - destination->alg = source->alg; - destination->hash_ctx = psa_hash_operation_init(); - status = psa_hash_clone( &source->hash_ctx, &destination->hash_ctx ); - memcpy( destination->opad, source->opad, sizeof( destination->opad ) ); - - if( status != PSA_SUCCESS ) - memset( destination, 0, sizeof( *destination ) ); - - return( status ); -} #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */ /* Implement the PSA driver MAC interface on top of mbed TLS if either the @@ -457,8 +444,8 @@ static psa_status_t mac_update( #if defined(BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( operation->alg ) ) { - return( psa_hash_update( &operation->ctx.hmac.hash_ctx, input, - input_length ) ); + return( psa_hmac_update_internal( &operation->ctx.hmac, + input, input_length ) ); } else #endif /* BUILTIN_ALG_HMAC */ diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index b7f2a6c3b..4da60bf40 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -23,96 +23,6 @@ #include -/** Internal API for starting an HMAC operation, using PSA hash primitives. - * - * \note This API is not meant for application use. Applications should always - * use the top-level psa_mac_xxx APIs for doing HMAC operations. - * - * \param[in] hmac Context structure for this HMAC operation. Needs to have - * been zero-initialized prior to calling this function. - * \param[in] key Key to initialize the HMAC operation with. - * \param key_length Length (in bytes) of key \p key. - * \param hash_alg Hash algorithm to use for calculating the HMAC. - * - * \retval #PSA_SUCCESS - * Success. - * \return Any error code reported by psa_hash_compute(), psa_hash_setup() or - * psa_hash_update(). - */ -psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *key, - size_t key_length, - psa_algorithm_t hash_alg ); - -/** Internal API for adding data to an HMAC operation, using PSA hash primitives. - * - * \note This API is not meant for application use. Applications should always - * use the top-level psa_mac_xxx APIs for doing HMAC operations. - * - * \param[in] hmac Context structure for this HMAC operation. Needs to have - * been initialized with psa_hmac_setup_internal(). - * \param[in] data Buffer containing the data to add to the current HMAC - * calculation. - * \param data_length Length (in bytes) of the input buffer \p data. - * - * \retval #PSA_SUCCESS - * Success. - * \return Any error code reported by psa_hash_update(). - */ -psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac, - const uint8_t *data, - size_t data_length ); - -/** Internal API for finalizing an HMAC operation, using PSA hash primitives. - * - * \note This API is not meant for application use. Applications should always - * use the top-level psa_mac_xxx APIs for doing HMAC operations. - * - * \param[in] hmac Context structure for this HMAC operation. Needs to have - * been initialized with psa_hmac_setup_internal(). - * \param[out] mac Buffer to output the calculated HMAC into. - * \param mac_size Size (in bytes) of the output buffer \p mac. - * - * \retval #PSA_SUCCESS - * Success. - * \return Any error code reported by psa_hash_setup(), psa_hash_update() or - * psa_hash_finish(). - */ -psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac, - uint8_t *mac, - size_t mac_size ); - -/** Internal API for cloning an HMAC operation, using PSA hash primitives. - * - * \note This API is not meant for application use. Applications should always - * use the top-level psa_mac_xxx APIs for doing HMAC operations. - * - * \param[in] source Context structure to clone from. Needs to have been - * initialized with psa_hmac_setup_internal(). - * \param[out] destination Context structure to clone to. Needs to have been - * zero-initialized. - * - * \retval #PSA_SUCCESS - * Success. - * \return Any error code reported by psa_hash_clone(). - */ -psa_status_t psa_hmac_clone_internal( - const mbedtls_psa_hmac_operation_t *source, - mbedtls_psa_hmac_operation_t *destination ); - -/** Internal API for aborting an HMAC operation, using PSA hash primitives. - * - * \note This API is not meant for application use. Applications should always - * use the top-level psa_mac_xxx APIs for doing HMAC operations. - * - * \param[in] hmac Context structure for the HMAC operation to abort. - * - * \retval #PSA_SUCCESS - * Success. - * \return Any error code reported by psa_hash_abort(). - */ -psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac ); - /** Calculate the MAC (message authentication code) of a message using Mbed TLS. * * \note The signature of this function is that of a PSA driver mac_compute From 9878a160c69a4e77a586abb5d9673a7484476cb7 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 17:58:36 +0200 Subject: [PATCH 24/39] Code flow and style improvements Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 98 ++++++++++++++++++---------------------- library/psa_crypto_mac.c | 15 +++--- 2 files changed, 50 insertions(+), 63 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 959549785..44b3680b5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3233,7 +3233,32 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) #define AT_LEAST_ONE_BUILTIN_KDF -#endif +#endif /* At least one builtin KDF */ + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS) +static psa_status_t psa_key_derivation_start_hmac( + psa_mac_operation_t *operation, + psa_algorithm_t hash_alg, + const uint8_t *hmac_key, + size_t hmac_key_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); + psa_set_key_bits( &attributes, PSA_BYTES_TO_BITS( hmac_key_length ) ); + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + + status = psa_driver_wrapper_mac_sign_setup( operation, + &attributes, + hmac_key, hmac_key_length, + PSA_ALG_HMAC( hash_alg ) ); + + psa_reset_key_attributes( &attributes ); + return( status ); +} +#endif /* KDF algorithms reliant on HMAC */ #define HKDF_STATE_INIT 0 /* no input yet */ #define HKDF_STATE_STARTED 1 /* got salt */ @@ -3374,17 +3399,10 @@ static psa_status_t psa_key_derivation_hkdf_read( psa_hkdf_key_derivation_t *hkd ++hkdf->block_number; hkdf->offset_in_block = 0; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); - psa_set_key_bits( &attributes, - PSA_BYTES_TO_BITS( hash_length ) ); - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); - - status = psa_driver_wrapper_mac_sign_setup( &hkdf->hmac, - &attributes, - hkdf->prk, hash_length, - PSA_ALG_HMAC( hash_alg ) ); - psa_reset_key_attributes( &attributes ); + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + hkdf->prk, + hash_length ); if( status != PSA_SUCCESS ) return( status ); @@ -3458,17 +3476,10 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( * `block_number`. */ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); - psa_set_key_bits( &attributes, - PSA_BYTES_TO_BITS( tls12_prf->secret_length ) ); - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); - - status = psa_driver_wrapper_mac_sign_setup( &hmac, - &attributes, - tls12_prf->secret, - tls12_prf->secret_length, - PSA_ALG_HMAC( hash_alg ) ); + status = psa_key_derivation_start_hmac( &hmac, + hash_alg, + tls12_prf->secret, + tls12_prf->secret_length ); if( status != PSA_SUCCESS ) goto cleanup; @@ -3506,11 +3517,10 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( goto cleanup; /* Calculate HMAC_hash(secret, A(i) + label + seed). */ - status = psa_driver_wrapper_mac_sign_setup( &hmac, - &attributes, - tls12_prf->secret, - tls12_prf->secret_length, - PSA_ALG_HMAC( hash_alg ) ); + status = psa_key_derivation_start_hmac( &hmac, + hash_alg, + tls12_prf->secret, + tls12_prf->secret_length ); if( status != PSA_SUCCESS ) goto cleanup; status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length ); @@ -3530,8 +3540,6 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block( cleanup: - psa_reset_key_attributes( &attributes ); - cleanup_status = psa_mac_abort( &hmac ); if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS ) status = cleanup_status; @@ -3860,19 +3868,9 @@ static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, return( PSA_ERROR_BAD_STATE ); else { - /* In a scope block due to scope-local attributes variable */ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); - psa_set_key_bits( &attributes, - PSA_BYTES_TO_BITS( data_length ) ); - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); - - status = psa_driver_wrapper_mac_sign_setup( - &hkdf->hmac, - &attributes, - data, data_length, - PSA_ALG_HMAC( hash_alg ) ); - psa_reset_key_attributes( &attributes ); + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + data, data_length ); if( status != PSA_SUCCESS ) return( status ); hkdf->state = HKDF_STATE_STARTED; @@ -3882,17 +3880,9 @@ static psa_status_t psa_hkdf_input( psa_hkdf_key_derivation_t *hkdf, /* If no salt was provided, use an empty salt. */ if( hkdf->state == HKDF_STATE_INIT ) { - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC ); - psa_set_key_bits( &attributes, 0 ); - psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); - - status = psa_driver_wrapper_mac_sign_setup( - &hkdf->hmac, - &attributes, - NULL, 0, - PSA_ALG_HMAC( hash_alg ) ); - psa_reset_key_attributes( &attributes ); + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + NULL, 0 ); if( status != PSA_SUCCESS ) return( status ); hkdf->state = HKDF_STATE_STARTED; diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index ca40b03bf..8e64741e6 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -200,20 +200,20 @@ static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, size_t key_buffer_size ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - const mbedtls_cipher_info_t * cipher_info_tmp = + const mbedtls_cipher_info_t * cipher_info = mbedtls_cipher_info_from_psa( PSA_ALG_CMAC, psa_get_key_type( attributes ), psa_get_key_bits( attributes ), NULL ); - if( cipher_info_tmp == NULL ) + if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); if( key_buffer_size < PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info_tmp ); + ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info ); if( ret != 0 ) goto exit; @@ -319,15 +319,12 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, /* A context must be freshly initialized before it can be set up. */ if( operation->alg != 0 ) - { return( PSA_ERROR_BAD_STATE ); - } status = mac_init( operation, alg ); if( status != PSA_SUCCESS ) return( status ); - if( is_sign ) - operation->is_sign = 1; + operation->is_sign = is_sign; /* Get the output length for the algorithm and key combination. None of the * currently supported algorithms have an output length dependent on actual @@ -498,7 +495,7 @@ static psa_status_t mac_sign_finish( size_t mac_size, size_t *mac_length ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); @@ -520,7 +517,7 @@ static psa_status_t mac_verify_finish( size_t mac_length ) { uint8_t actual_mac[PSA_MAC_MAX_SIZE]; - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); From af81a71b8b4b56938a553e9af24192b322452bf3 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 18:00:37 +0200 Subject: [PATCH 25/39] Remove superfluous length check The key passed to the driver has been imported by the PSA Core, meaning its length has already been verified, and the driver can rely on the buffer length and key attributes being consistent. Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 8e64741e6..a5ef9e57d 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -196,8 +196,7 @@ exit: #if defined(BUILTIN_ALG_CMAC) static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size ) + const uint8_t *key_buffer ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const mbedtls_cipher_info_t * cipher_info = @@ -210,9 +209,6 @@ static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); - if( key_buffer_size < PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - ret = mbedtls_cipher_setup( &operation->ctx.cmac, cipher_info ); if( ret != 0 ) goto exit; @@ -335,8 +331,10 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, #if defined(BUILTIN_ALG_CMAC) if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC ) { - status = cmac_setup( operation, attributes, - key_buffer, key_buffer_size ); + /* Key buffer size for CMAC is dictated by the key bits set on the + * attributes, and previously validated by the core on key import. */ + (void) key_buffer_size; + status = cmac_setup( operation, attributes, key_buffer ); } else #endif /* BUILTIN_ALG_CMAC */ From e68bb52afd3f11782c53f552486709d01afc8cbd Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 18:02:39 +0200 Subject: [PATCH 26/39] Remove unused variable from MAC driver structure Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 1 - library/psa_crypto_mac.c | 3 --- 2 files changed, 4 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index 6979dec42..f968c169e 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -62,7 +62,6 @@ typedef struct typedef struct { psa_algorithm_t alg; - unsigned int has_input : 1; unsigned int is_sign : 1; uint8_t mac_size; union diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index a5ef9e57d..dc07d455e 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -230,7 +230,6 @@ static psa_status_t mac_init( psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); - operation->has_input = 0; operation->is_sign = 0; #if defined(BUILTIN_ALG_CMAC) @@ -290,7 +289,6 @@ static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) } operation->alg = 0; - operation->has_input = 0; operation->is_sign = 0; return( PSA_SUCCESS ); @@ -425,7 +423,6 @@ static psa_status_t mac_update( { if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); - operation->has_input = 1; #if defined(BUILTIN_ALG_CMAC) if( operation->alg == PSA_ALG_CMAC ) From dba0644818dde3167e0960336add3c0bd3cba867 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 18:08:30 +0200 Subject: [PATCH 27/39] Remove superfluous check As psa_mac_sign_finish / psa_mac_verify_finish already checks that the operation structure is valid (id is non-zero), the driver itself doesn't have to check for that anymore. If the operation has a driver ID assigned, it means that driver has returned success from its setup function, so the algorithm value will be set correctly. Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index dc07d455e..3d7f70bac 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -452,8 +452,6 @@ static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size ) { - if( operation->alg == 0 ) - return( PSA_ERROR_BAD_STATE ); if( mac_size < operation->mac_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); From bd1f60868a0d77785c4d6cc1bbf62ce496127a40 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 19:23:00 +0200 Subject: [PATCH 28/39] Minor documentation and language fixes Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.h | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index 4da60bf40..4635fe1d7 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -48,8 +48,6 @@ * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. * \retval #PSA_ERROR_BUFFER_TOO_SMALL @@ -89,8 +87,6 @@ psa_status_t mbedtls_psa_mac_compute( * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -126,8 +122,6 @@ psa_status_t mbedtls_psa_mac_sign_setup( * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. * \retval #PSA_ERROR_INSUFFICIENT_MEMORY @@ -149,11 +143,11 @@ psa_status_t mbedtls_psa_mac_verify_setup( * defined in the PSA driver interface specification for transparent * drivers. * - * The core must call mbedtls_psa_mac_sign_setup() or + * The PSA core calls mbedtls_psa_mac_sign_setup() or * mbedtls_psa_mac_verify_setup() before calling this function. * - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling psa_mac_abort(). + * If this function returns an error status, the PSA core aborts the + * operation by calling mbedtls_psa_mac_abort(). * * \param[in,out] operation Active MAC operation. * \param[in] input Buffer containing the message fragment to add to @@ -179,13 +173,12 @@ psa_status_t mbedtls_psa_mac_update( * defined in the PSA driver interface specification for transparent * drivers. * - * The core must call mbedtls_psa_mac_sign_setup() before calling this function. + * The PSA core calls mbedtls_psa_mac_sign_setup() before calling this function. * This function calculates the MAC of the message formed by concatenating * the inputs passed to preceding calls to mbedtls_psa_mac_update(). * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling mbedtls_psa_mac_abort(). + * Whether this function returns successfully or not, the PSA core subsequently + * aborts the operation by calling mbedtls_psa_mac_abort(). * * \param[in,out] operation Active MAC operation. * \param[out] mac Buffer where the MAC value is to be written. @@ -222,15 +215,14 @@ psa_status_t mbedtls_psa_mac_sign_finish( * mac_verify_finish entry point as defined in the PSA driver interface * specification for transparent drivers. * - * The core must call mbedtls_psa_mac_verify_setup() before calling this + * The PSA core calls mbedtls_psa_mac_verify_setup() before calling this * function. This function calculates the MAC of the message formed by * concatenating the inputs passed to preceding calls to * mbedtls_psa_mac_update(). It then compares the calculated MAC with the * expected MAC passed as a parameter to this function. * - * When this function returns successfully, the operation becomes inactive. - * If this function returns an error status, the operation enters an error - * state and must be aborted by calling mbedtls_psa_mac_abort(). + * Whether this function returns successfully or not, the PSA core subsequently + * aborts the operation by calling mbedtls_psa_mac_abort(). * * \param[in,out] operation Active MAC operation. * \param[in] mac Buffer containing the expected MAC value. @@ -259,7 +251,7 @@ psa_status_t mbedtls_psa_mac_verify_finish( * can be reused for another operation by calling * mbedtls_psa_mac_sign_setup() or mbedtls_psa_mac_verify_setup() again. * - * The core may call this function any time after the operation object has + * The PSA core may call this function any time after the operation object has * been initialized by one of the methods described in * #mbedtls_psa_mac_operation_t. * From dabac4283b22bd876d688b4d3ca301c34cb70d9f Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 19:38:42 +0200 Subject: [PATCH 29/39] Convert mbedTLS to PSA dependencies for the driver wrapper tests Signed-off-by: Steven Cooreman --- ...test_suite_psa_crypto_driver_wrappers.data | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index cab40d37f..bc6d64703 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -197,7 +197,7 @@ depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES cipher_entry_points:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a" PSA AEAD encrypt: AES-CCM, 24 bytes -depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_SUCCESS PSA AEAD encrypt: AES-CCM, 24 bytes, fallback @@ -205,11 +205,11 @@ depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_ERROR_NOT_SUPPORTED PSA AEAD encrypt: AES-CCM, 24 bytes, INSUFFICIENT_MEMORY -depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_ERROR_INSUFFICIENT_MEMORY PSA AEAD encrypt, AES-GCM, 128 bytes #1 -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_SUCCESS PSA AEAD encrypt, AES-GCM, 128 bytes #1, fallback @@ -217,11 +217,11 @@ depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_ERROR_NOT_SUPPORTED PSA AEAD encrypt, AES-GCM, 128 bytes #1, INSUFFICIENT_MEMORY -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_ERROR_INSUFFICIENT_MEMORY PSA AEAD decrypt: AES-CCM, 39 bytes -depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_SUCCESS PSA AEAD decrypt: AES-CCM, 39 bytes, fallback @@ -229,11 +229,11 @@ depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_ERROR_NOT_SUPPORTED PSA AEAD decrypt: AES-CCM, 39 bytes, INSUFFICIENT_MEMORY -depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_ERROR_INSUFFICIENT_MEMORY PSA AEAD decrypt, AES-GCM, 144 bytes #1 -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS PSA AEAD decrypt, AES-GCM, 144 bytes #1, fallback @@ -241,7 +241,7 @@ depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_NOT_SUPPORTED PSA AEAD decrypt, AES-GCM, 144 bytes #1, INSUFFICIENT_MEMORY -depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY PSA MAC sign, through driver: HMAC-SHA-224 @@ -293,27 +293,35 @@ depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_GENERIC_ERROR PSA opaque driver builtin key export: AES +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS PSA opaque driver builtin key export: AES (registered to ID_MAX-1) +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX - 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS PSA opaque driver builtin key export: AES (registered to ID_MAX) +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS PSA opaque driver builtin key export: key ID out of range (ID_MIN - 1) +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_ERROR_INVALID_HANDLE PSA opaque driver builtin key export: key ID out of range (ID_MAX + 1) +depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX + 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_ERROR_INVALID_HANDLE PSA opaque driver builtin key export: secp256r1 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"dc7d9d26d67a4f632c34c2dc0b6986183882c206df04cdb7d69aabe28be4f81a":PSA_SUCCESS PSA opaque driver builtin pubkey export: secp256r1 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR builtin_pubkey_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"0485f64d89f00be66c88dd937efd6d7c445648dcb701150b8a9509295850f41c1931e571fb8f8c78317a20b380e866584bbc2516c3d2702d792f131a922095fd6c":PSA_SUCCESS PSA opaque driver builtin pubkey export: not a public key +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR builtin_pubkey_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"0485f64d89f00be66c88dd937efd6d7c445648dcb701150b8a9509295850f41c1931e571fb8f8c78317a20b380e866584bbc2516c3d2702d792f131a922095fd6c":PSA_ERROR_INVALID_ARGUMENT Hash compute: SHA-256, computed by the driver From 7dccfce5fb2c320430313260efa3a6f2aacf8070 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Thu, 6 May 2021 19:41:15 +0200 Subject: [PATCH 30/39] Add PSA_ACCEL test dependencies in MAC driver wrappers tests To avoid the MAC tests from being run when only part of the driver wrappers (not including MAC) are being configured for test. Signed-off-by: Steven Cooreman --- .../test_suite_psa_crypto_driver_wrappers.data | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index bc6d64703..95ab688be 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -245,11 +245,11 @@ depends_on:PSA_WANT_ALG_GCM:PSA_WANT_KEY_TYPE_AES aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY PSA MAC sign, through driver: HMAC-SHA-224 -depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS PSA MAC sign, fallback: HMAC-SHA-224 -depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_BUILTIN_ALG_HMAC mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_NOT_SUPPORTED PSA MAC sign, driver reports error: RFC4231 Test case 1 - HMAC-SHA-224 @@ -257,11 +257,11 @@ depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC mac_sign:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_GENERIC_ERROR PSA MAC sign, through driver: CMAC-AES-128 -depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_ACCEL_ALG_CMAC mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_SUCCESS PSA MAC sign, fallback: CMAC-AES-128 -depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_ALG_CMAC mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_NOT_SUPPORTED PSA MAC sign, driver reports error: CMAC-AES-128 @@ -269,11 +269,11 @@ depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_GENERIC_ERROR PSA MAC verify, through driver: HMAC-SHA-224 -depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_ACCEL_ALG_HMAC mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_SUCCESS PSA MAC verify, fallback: HMAC-SHA-224 -depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC +depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC:MBEDTLS_PSA_BUILTIN_ALG_HMAC mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_NOT_SUPPORTED PSA MAC verify, driver reports error: RFC4231 Test case 1 - HMAC-SHA-224 @@ -281,11 +281,11 @@ depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_224:PSA_WANT_KEY_TYPE_HMAC mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_HMAC(PSA_ALG_SHA_224):"4869205468657265":"896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22":PSA_ERROR_GENERIC_ERROR PSA MAC verify, through driver: CMAC-AES-128 -depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_ACCEL_ALG_CMAC mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_SUCCESS PSA MAC verify, fallback: CMAC-AES-128 -depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:MBEDTLS_PSA_BUILTIN_ALG_CMAC mac_verify:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827":PSA_ERROR_NOT_SUPPORTED PSA MAC verify, driver reports error: CMAC-AES-128 From 15f0d92a48f983d45fe8ee070aec5a1145425884 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 7 May 2021 14:14:37 +0200 Subject: [PATCH 31/39] Move is_sign and mac_size checking back to PSA core scope It makes sense to do the length checking in the core rather than expect each driver to deal with it themselves. This puts the onus on the core to dictate which algorithm/key combinations are valid before calling a driver. Additionally, this commit also updates the psa_mac_sign_finish function to better deal with output buffer sanitation, as per the review comments on #4247. Signed-off-by: Steven Cooreman --- include/psa/crypto_builtin_composites.h | 4 +- include/psa/crypto_struct.h | 4 +- library/psa_crypto.c | 72 +++++++++++++++++++------ library/psa_crypto_mac.c | 62 ++++++++------------- library/psa_crypto_mac.h | 21 +++++--- 5 files changed, 94 insertions(+), 69 deletions(-) diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index f968c169e..1d11b003e 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -62,8 +62,6 @@ typedef struct typedef struct { psa_algorithm_t alg; - unsigned int is_sign : 1; - uint8_t mac_size; union { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ @@ -76,7 +74,7 @@ typedef struct } ctx; } mbedtls_psa_mac_operation_t; -#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, 0, 0, 0, {0}} +#define MBEDTLS_PSA_MAC_OPERATION_INIT {0, {0}} /* * BEYOND THIS POINT, TEST DRIVER DECLARATIONS ONLY. diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index fc7e7785c..47012fdd0 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -137,10 +137,12 @@ struct psa_mac_operation_s * 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; + uint8_t mac_size; + unsigned int is_sign : 1; psa_driver_mac_context_t ctx; }; -#define PSA_MAC_OPERATION_INIT {0, {0}} +#define PSA_MAC_OPERATION_INIT {0, 0, 0, {0}} static inline struct psa_mac_operation_s psa_mac_operation_init( void ) { const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT; diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 44b3680b5..3385229e8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2291,6 +2291,8 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) return( PSA_SUCCESS ); psa_status_t status = psa_driver_wrapper_mac_abort( operation ); + operation->mac_size = 0; + operation->is_sign = 0; operation->id = 0; return( status ); @@ -2304,7 +2306,6 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - size_t mac_size; /* A context must be freshly initialized before it can be set up. */ if( operation->id != 0 ) @@ -2330,12 +2331,15 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, if( status != PSA_SUCCESS ) goto exit; + operation->is_sign = is_sign; + /* Get the output length for the algorithm and key combination. None of the * currently supported algorithms have an output length dependent on actual * key size, so setting it to a bogus value is currently OK. */ - mac_size = PSA_MAC_LENGTH( psa_get_key_type( &attributes ), 0, alg ); + operation->mac_size = PSA_MAC_LENGTH( + psa_get_key_type( &attributes ), 0, alg ); - if( mac_size < 4 ) + if( operation->mac_size < 4 ) { /* A very short MAC is too short for security since it can be * brute-forced. Ancient protocols with 32-bit MACs do exist, @@ -2345,8 +2349,9 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } - if( mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), 0, - PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) + if( operation->mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), + 0, + PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length * of the algorithm. */ @@ -2423,26 +2428,45 @@ psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; + /* Set the output length and content to a safe default, such that in + * case the caller misses an error check, the output would be an + * unachievable MAC. */ + *mac_length = mac_size; + if( operation->id == 0 ) return( PSA_ERROR_BAD_STATE ); - /* Fill the output buffer with something that isn't a valid mac - * (barring an attack on the mac and deliberately-crafted input), - * in case the caller doesn't check the return status properly. */ - *mac_length = mac_size; - /* If mac_size is 0 then mac may be NULL and then the - * call to memset would have undefined behavior. */ - if( mac_size != 0 ) - memset( mac, '!', mac_size ); + if( ! operation->is_sign ) + return( PSA_ERROR_BAD_STATE ); + + /* Sanity checks on output buffer length. */ + if( mac_size == 0 || mac_size < operation->mac_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); status = psa_driver_wrapper_mac_sign_finish( operation, - mac, mac_size, mac_length ); + mac, operation->mac_size, + mac_length ); + + if( status == PSA_SUCCESS ) + { + /* Set the excess room in the output buffer to an invalid value, to + * avoid potentially leaking a longer MAC. */ + if( mac_size > operation->mac_size ) + memset( &mac[operation->mac_size], + '!', + mac_size - operation->mac_size ); + } + else + { + /* Set the output length and content to a safe default, such that in + * case the caller misses an error check, the output would be an + * unachievable MAC. */ + *mac_length = mac_size; + memset( mac, '!', mac_size ); + } abort_status = psa_mac_abort( operation ); - if( status != PSA_SUCCESS && mac_size > 0 ) - memset( mac, '!', mac_size ); - return( status == PSA_SUCCESS ? abort_status : status ); } @@ -2456,8 +2480,19 @@ psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, if( operation->id == 0 ) return( PSA_ERROR_BAD_STATE ); + if( operation->is_sign ) + return( PSA_ERROR_BAD_STATE ); + + if( operation->mac_size != mac_length ) + { + status = PSA_ERROR_INVALID_SIGNATURE; + goto cleanup; + } + status = psa_driver_wrapper_mac_verify_finish( operation, mac, mac_length ); + +cleanup: abort_status = psa_mac_abort( operation ); return( status == PSA_SUCCESS ? abort_status : status ); @@ -3250,6 +3285,9 @@ static psa_status_t psa_key_derivation_start_hmac( psa_set_key_bits( &attributes, PSA_BYTES_TO_BITS( hmac_key_length ) ); psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH ); + operation->is_sign = 1; + operation->mac_size = PSA_HASH_LENGTH( hash_alg ); + status = psa_driver_wrapper_mac_sign_setup( operation, &attributes, hmac_key, hmac_key_length, diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 3d7f70bac..6753dedf5 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -229,11 +229,10 @@ static psa_status_t mac_init( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - operation->alg = PSA_ALG_FULL_LENGTH_MAC( alg ); - operation->is_sign = 0; + operation->alg = alg; #if defined(BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) + if( PSA_ALG_FULL_LENGTH_MAC( operation->alg ) == PSA_ALG_CMAC ) { mbedtls_cipher_init( &operation->ctx.cmac ); status = PSA_SUCCESS; @@ -269,7 +268,7 @@ static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) } else #if defined(BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) + if( PSA_ALG_FULL_LENGTH_MAC( operation->alg ) == PSA_ALG_CMAC ) { mbedtls_cipher_free( &operation->ctx.cmac ); } @@ -289,7 +288,6 @@ static psa_status_t mac_abort( mbedtls_psa_mac_operation_t *operation ) } operation->alg = 0; - operation->is_sign = 0; return( PSA_SUCCESS ); @@ -306,8 +304,7 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - int is_sign ) + psa_algorithm_t alg ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -318,13 +315,6 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, status = mac_init( operation, alg ); if( status != PSA_SUCCESS ) return( status ); - operation->is_sign = is_sign; - - /* Get the output length for the algorithm and key combination. None of the - * currently supported algorithms have an output length dependent on actual - * key size, so setting it to a bogus value is currently OK. */ - operation->mac_size = - PSA_MAC_LENGTH( psa_get_key_type( attributes ), 0, alg ); #if defined(BUILTIN_ALG_CMAC) if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC ) @@ -340,7 +330,8 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, if( PSA_ALG_IS_HMAC( alg ) ) { /* Sanity check. This shouldn't fail on a valid configuration. */ - if( operation->mac_size > sizeof( operation->ctx.hmac.opad ) ) + if( PSA_MAC_LENGTH( psa_get_key_type( attributes ), 0, alg ) > + sizeof( operation->ctx.hmac.opad ) ) { status = PSA_ERROR_NOT_SUPPORTED; goto exit; @@ -363,7 +354,6 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, status = PSA_ERROR_NOT_SUPPORTED; } -exit: if( status != PSA_SUCCESS ) mac_abort( operation ); @@ -401,8 +391,8 @@ static psa_status_t mac_sign_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - return( mac_setup( operation, attributes, key_buffer, key_buffer_size, alg, - 1 ) ); + return( mac_setup( operation, + attributes, key_buffer, key_buffer_size, alg ) ); } static psa_status_t mac_verify_setup( @@ -412,8 +402,8 @@ static psa_status_t mac_verify_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - return( mac_setup( operation, attributes, key_buffer, key_buffer_size, alg, - 0 ) ); + return( mac_setup( operation, + attributes, key_buffer, key_buffer_size, alg ) ); } static psa_status_t mac_update( @@ -425,7 +415,7 @@ static psa_status_t mac_update( return( PSA_ERROR_BAD_STATE ); #if defined(BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) + if( PSA_ALG_FULL_LENGTH_MAC( operation->alg ) == PSA_ALG_CMAC ) { return( mbedtls_to_psa_error( mbedtls_cipher_cmac_update( &operation->ctx.cmac, @@ -452,16 +442,13 @@ static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, uint8_t *mac, size_t mac_size ) { - if( mac_size < operation->mac_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - #if defined(BUILTIN_ALG_CMAC) - if( operation->alg == PSA_ALG_CMAC ) + if( PSA_ALG_FULL_LENGTH_MAC( operation->alg ) == PSA_ALG_CMAC ) { uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE]; int ret = mbedtls_cipher_cmac_finish( &operation->ctx.cmac, tmp ); if( ret == 0 ) - memcpy( mac, tmp, operation->mac_size ); + memcpy( mac, tmp, mac_size ); mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); return( mbedtls_to_psa_error( ret ) ); } @@ -471,13 +458,16 @@ static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, if( PSA_ALG_IS_HMAC( operation->alg ) ) { return( psa_hmac_finish_internal( &operation->ctx.hmac, - mac, operation->mac_size ) ); + mac, mac_size ) ); } else #endif /* BUILTIN_ALG_HMAC */ { /* This shouldn't happen if `operation` was initialized by * a setup function. */ + (void) operation; + (void) mac; + (void) mac_size; return( PSA_ERROR_BAD_STATE ); } } @@ -493,13 +483,10 @@ static psa_status_t mac_sign_finish( if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); - if( ! operation->is_sign ) - return( PSA_ERROR_BAD_STATE ); - status = mac_finish_internal( operation, mac, mac_size ); if( status == PSA_SUCCESS ) - *mac_length = operation->mac_size; + *mac_length = mac_size; return( status ); } @@ -515,16 +502,11 @@ static psa_status_t mac_verify_finish( if( operation->alg == 0 ) return( PSA_ERROR_BAD_STATE ); - if( operation->is_sign ) - return( PSA_ERROR_BAD_STATE ); + /* Consistency check: requested MAC length fits our local buffer */ + if( mac_length > sizeof( actual_mac ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); - if( operation->mac_size != mac_length ) - { - status = PSA_ERROR_INVALID_SIGNATURE; - goto cleanup; - } - - status = mac_finish_internal( operation, actual_mac, sizeof( actual_mac ) ); + status = mac_finish_internal( operation, actual_mac, mac_length ); if( status != PSA_SUCCESS ) goto cleanup; diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index 4635fe1d7..9b81e73e0 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -182,13 +182,15 @@ psa_status_t mbedtls_psa_mac_update( * * \param[in,out] operation Active MAC operation. * \param[out] mac Buffer where the MAC value is to be written. - * \param mac_size Size of the \p mac buffer in bytes. - * \param[out] mac_length On success, the number of bytes - * that make up the MAC value. This is always - * #PSA_MAC_LENGTH(\c key_type, \c key_bits, \c alg) - * where \c key_type and \c key_bits are the type and - * bit-size respectively of the key and \c alg is the - * MAC algorithm that is calculated. + * \param mac_size Output size requested for the MAC algorithm. The PSA + * core guarantees this is a valid MAC length for the + * algorithm and key combination passed to + * mbedtls_psa_mac_sign_setup(). It also guarantees the + * \p mac buffer is large enough to contain the + * requested output size. + * \param[out] mac_length On success, the number of bytes output to buffer + * \p mac, which will be equal to the requested length + * \p mac_size. * * \retval #PSA_SUCCESS * Success. @@ -226,7 +228,10 @@ psa_status_t mbedtls_psa_mac_sign_finish( * * \param[in,out] operation Active MAC operation. * \param[in] mac Buffer containing the expected MAC value. - * \param mac_length Size of the \p mac buffer in bytes. + * \param mac_length Length in bytes of the expected MAC value. The PSA + * core guarantees that this length is a valid MAC + * length for the algorithm and key combination passed + * to mbedtls_psa_mac_verify_setup(). * * \retval #PSA_SUCCESS * The expected MAC is identical to the actual MAC of the message. From 2a18f56b4ef20d763d4e0468186e9a832d53301a Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 7 May 2021 15:44:46 +0200 Subject: [PATCH 32/39] Remove superfluous checking from MAC driver The PSA core checks the key type and algorithm combination before calling the driver, so the driver doesn't have to do this once more. The PSA core will also not start an operation with a requested length which is larger than the full MAC output size, so the output length check in the driver isn't needed as long as the driver returns an error on mac_setup if it doesn't support the underlying hash algorithm. Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 6753dedf5..32ab88535 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -329,20 +329,6 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, #if defined(BUILTIN_ALG_HMAC) if( PSA_ALG_IS_HMAC( alg ) ) { - /* Sanity check. This shouldn't fail on a valid configuration. */ - if( PSA_MAC_LENGTH( psa_get_key_type( attributes ), 0, alg ) > - sizeof( operation->ctx.hmac.opad ) ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - - if( psa_get_key_type( attributes ) != PSA_KEY_TYPE_HMAC ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } - status = psa_hmac_setup_internal( &operation->ctx.hmac, key_buffer, key_buffer_size, From aaf9944db3e8ef0a82885cc3fcf8fecd7b79e5ac Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 7 May 2021 15:55:27 +0200 Subject: [PATCH 33/39] Use the proper define guards in the MAC driver Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 32ab88535..9c44c237f 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -41,7 +41,7 @@ #define BUILTIN_ALG_HMAC 1 #endif -#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) +#if defined(BUILTIN_ALG_HMAC) static size_t psa_get_hash_block_size( psa_algorithm_t alg ) { switch( alg ) @@ -187,11 +187,7 @@ exit: mbedtls_platform_zeroize( tmp, hash_size ); return( status ); } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */ - -/* Implement the PSA driver MAC interface on top of mbed TLS if either the - * software driver or the test driver requires it. */ -#if defined(MBEDTLS_PSA_BUILTIN_MAC) || defined(PSA_CRYPTO_DRIVER_TEST) +#endif /* BUILTIN_ALG_HMAC */ #if defined(BUILTIN_ALG_CMAC) static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, @@ -221,6 +217,10 @@ exit: } #endif /* BUILTIN_ALG_CMAC */ +/* Implement the PSA driver MAC interface on top of mbed TLS if either the + * software driver or the test driver requires it. */ +#if defined(BUILTIN_ALG_HMAC) || defined(BUILTIN_ALG_CMAC) + /* Initialize this driver's MAC operation structure. Once this function has been * called, mbedtls_psa_mac_abort can run and will do the right thing. */ static psa_status_t mac_init( @@ -504,7 +504,7 @@ cleanup: return( status ); } -#endif /* MBEDTLS_PSA_BUILTIN_MAC || PSA_CRYPTO_DRIVER_TEST */ +#endif /* BUILTIN_ALG_HMAC || BUILTIN_ALG_CMAC */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) psa_status_t mbedtls_psa_mac_compute( From 63fa40e593405cb872295b8c396ec335f6854801 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Fri, 7 May 2021 17:27:27 +0200 Subject: [PATCH 34/39] Add sanity tests for CMAC-(3)DES through PSA Crypto Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 10 ++++++++++ tests/suites/test_suite_psa_crypto.data | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 9c44c237f..69724727a 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -195,6 +195,16 @@ static psa_status_t cmac_setup( mbedtls_psa_mac_operation_t *operation, const uint8_t *key_buffer ) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + +#if defined(PSA_WANT_KEY_TYPE_DES) + /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept + * to do CMAC with pure DES, so return NOT_SUPPORTED here. */ + if( psa_get_key_type( attributes ) == PSA_KEY_TYPE_DES && + ( psa_get_key_bits( attributes ) == 64 || + psa_get_key_bits( attributes ) == 128 ) ) + return( PSA_ERROR_NOT_SUPPORTED ); +#endif + const mbedtls_cipher_info_t * cipher_info = mbedtls_cipher_info_from_psa( PSA_ALG_CMAC, diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 944ef2386..7b86185b9 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1294,6 +1294,22 @@ PSA MAC verify: HMAC-SHA-512, truncated to 4 bytes depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_HMAC mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 4):"4869205468657265":"87aa7cde" +PSA MAC sign: CMAC-3DES (CAVP vector #95) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_sign:PSA_KEY_TYPE_DES:"7c34e67a2a8fef581cc4f7dceaea130dad52c189739e401f":PSA_ALG_CMAC:"eb3365a0a9d141270334065547418fe64c47823c024082b94d54a66d149f2af1":"e1d7c3736739e726" + +PSA MAC verify: CMAC-3DES (CAVP vector #95) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_verify:PSA_KEY_TYPE_DES:"7c34e67a2a8fef581cc4f7dceaea130dad52c189739e401f":PSA_ALG_CMAC:"eb3365a0a9d141270334065547418fe64c47823c024082b94d54a66d149f2af1":"e1d7c3736739e726" + +PSA MAC: CMAC-3DES-2key (not supported in PSA) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_setup:PSA_KEY_TYPE_DES:"89fe91f1c1ef2f01efc4c18f5715894c":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED + +PSA MAC: CMAC-DES (not supported in PSA) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_setup:PSA_KEY_TYPE_DES:"89fe91f1c1ef2f01":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED + PSA MAC sign: CMAC-AES-128 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827" From 9621f444a71068fd5c7e60f905eea6ad222b42c1 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 10 May 2021 09:47:05 +0200 Subject: [PATCH 35/39] Correctly mark unused arguments when MAC algorithms are compiled out Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 69724727a..9db9a37e5 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -347,6 +347,9 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, else #endif /* BUILTIN_ALG_HMAC */ { + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; status = PSA_ERROR_NOT_SUPPORTED; } @@ -430,6 +433,8 @@ static psa_status_t mac_update( { /* This shouldn't happen if `operation` was initialized by * a setup function. */ + (void) input; + (void) input_length; return( PSA_ERROR_BAD_STATE ); } } From a6474de2ac8b5c4bc42c72e46c28c9a5a4d65a4d Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 10 May 2021 11:13:41 +0200 Subject: [PATCH 36/39] Supply actual key bits to PSA_MAC_LENGTH during MAC setup Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3385229e8..b48af39fb 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2333,11 +2333,11 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, operation->is_sign = is_sign; - /* Get the output length for the algorithm and key combination. None of the - * currently supported algorithms have an output length dependent on actual - * key size, so setting it to a bogus value is currently OK. */ + /* Get the output length for the algorithm and key combination */ operation->mac_size = PSA_MAC_LENGTH( - psa_get_key_type( &attributes ), 0, alg ); + psa_get_key_type( &attributes ), + psa_get_key_bits( &attributes ), + alg ); if( operation->mac_size < 4 ) { @@ -2350,7 +2350,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, } if( operation->mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), - 0, + psa_get_key_bits( &attributes ), PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length From be21dab0993a55559f27f42d7d6af6465bcdf704 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Mon, 10 May 2021 11:18:20 +0200 Subject: [PATCH 37/39] Apply mbedtls namespacing to MAC driver test hooks Signed-off-by: Steven Cooreman --- tests/include/test/drivers/mac.h | 9 +- tests/src/drivers/test_driver_mac.c | 171 +++++++++--------- ..._suite_psa_crypto_driver_wrappers.function | 40 ++-- 3 files changed, 111 insertions(+), 109 deletions(-) diff --git a/tests/include/test/drivers/mac.h b/tests/include/test/drivers/mac.h index e4c750bd6..7733dd341 100644 --- a/tests/include/test/drivers/mac.h +++ b/tests/include/test/drivers/mac.h @@ -37,16 +37,17 @@ typedef struct { unsigned long hits; /* Status returned by the last MAC driver function call. */ psa_status_t driver_status; -} test_driver_mac_hooks_t; +} mbedtls_test_driver_mac_hooks_t; #define MBEDTLS_TEST_DRIVER_MAC_INIT { 0, 0, 0 } -static inline test_driver_mac_hooks_t test_driver_mac_hooks_init( void ) +static inline mbedtls_test_driver_mac_hooks_t + mbedtls_test_driver_mac_hooks_init( void ) { - const test_driver_mac_hooks_t v = MBEDTLS_TEST_DRIVER_MAC_INIT; + const mbedtls_test_driver_mac_hooks_t v = MBEDTLS_TEST_DRIVER_MAC_INIT; return( v ); } -extern test_driver_mac_hooks_t test_driver_mac_hooks; +extern mbedtls_test_driver_mac_hooks_t mbedtls_test_driver_mac_hooks; psa_status_t mbedtls_test_transparent_mac_compute( const psa_key_attributes_t *attributes, diff --git a/tests/src/drivers/test_driver_mac.c b/tests/src/drivers/test_driver_mac.c index 4e26e9f21..69af10780 100644 --- a/tests/src/drivers/test_driver_mac.c +++ b/tests/src/drivers/test_driver_mac.c @@ -28,7 +28,8 @@ #include "test/drivers/mac.h" -test_driver_mac_hooks_t test_driver_mac_hooks = MBEDTLS_TEST_DRIVER_MAC_INIT; +mbedtls_test_driver_mac_hooks_t mbedtls_test_driver_mac_hooks = + MBEDTLS_TEST_DRIVER_MAC_INIT; psa_status_t mbedtls_test_transparent_mac_compute( const psa_key_attributes_t *attributes, @@ -41,23 +42,23 @@ psa_status_t mbedtls_test_transparent_mac_compute( size_t mac_size, size_t *mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_compute( attributes, key_buffer, key_buffer_size, alg, input, input_length, mac, mac_size, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_sign_setup( @@ -67,21 +68,21 @@ psa_status_t mbedtls_test_transparent_mac_sign_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_sign_setup( operation, attributes, key_buffer, key_buffer_size, alg ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_verify_setup( @@ -91,21 +92,21 @@ psa_status_t mbedtls_test_transparent_mac_verify_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_verify_setup( operation, attributes, key_buffer, key_buffer_size, alg ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_update( @@ -113,21 +114,21 @@ psa_status_t mbedtls_test_transparent_mac_update( const uint8_t *input, size_t input_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_update( operation, input, input_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_sign_finish( @@ -136,21 +137,21 @@ psa_status_t mbedtls_test_transparent_mac_sign_finish( size_t mac_size, size_t *mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_sign_finish( operation, mac, mac_size, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_verify_finish( @@ -158,40 +159,40 @@ psa_status_t mbedtls_test_transparent_mac_verify_finish( const uint8_t *mac, size_t mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_verify_finish( operation, mac, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_transparent_mac_abort( mbedtls_transparent_test_driver_mac_operation_t *operation ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_transparent_test_driver_mac_abort( operation ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_compute( @@ -205,23 +206,23 @@ psa_status_t mbedtls_test_opaque_mac_compute( size_t mac_size, size_t *mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_compute( attributes, key_buffer, key_buffer_size, alg, input, input_length, mac, mac_size, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_sign_setup( @@ -231,21 +232,21 @@ psa_status_t mbedtls_test_opaque_mac_sign_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_sign_setup( operation, attributes, key_buffer, key_buffer_size, alg ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_verify_setup( @@ -255,21 +256,21 @@ psa_status_t mbedtls_test_opaque_mac_verify_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_verify_setup( operation, attributes, key_buffer, key_buffer_size, alg ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_update( @@ -277,21 +278,21 @@ psa_status_t mbedtls_test_opaque_mac_update( const uint8_t *input, size_t input_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_update( operation, input, input_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_sign_finish( @@ -300,21 +301,21 @@ psa_status_t mbedtls_test_opaque_mac_sign_finish( size_t mac_size, size_t *mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_sign_finish( operation, mac, mac_size, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_verify_finish( @@ -322,40 +323,40 @@ psa_status_t mbedtls_test_opaque_mac_verify_finish( const uint8_t *mac, size_t mac_length ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_verify_finish( operation, mac, mac_length ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } psa_status_t mbedtls_test_opaque_mac_abort( mbedtls_opaque_test_driver_mac_operation_t *operation ) { - test_driver_mac_hooks.hits++; + mbedtls_test_driver_mac_hooks.hits++; - if( test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) { - test_driver_mac_hooks.driver_status = - test_driver_mac_hooks.forced_status; + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; } else { - test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.driver_status = mbedtls_opaque_test_driver_mac_abort( operation ); } - return( test_driver_mac_hooks.driver_status ); + return( mbedtls_test_driver_mac_hooks.driver_status ); } #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index 3247b95a0..0055f9f0d 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -982,7 +982,7 @@ void mac_sign( int key_type_arg, size_t mac_length = 0; psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t forced_status = forced_status_arg; - test_driver_mac_hooks = test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); TEST_ASSERT( mac_buffer_size <= PSA_MAC_MAX_SIZE ); /* We expect PSA_MAC_LENGTH to be exact. */ @@ -998,11 +998,11 @@ void mac_sign( int key_type_arg, &key ) ); ASSERT_ALLOC( actual_mac, mac_buffer_size ); - test_driver_mac_hooks.forced_status = forced_status; + mbedtls_test_driver_mac_hooks.forced_status = forced_status; /* Calculate the MAC. */ status = psa_mac_sign_setup( &operation, key, alg ); - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) @@ -1015,9 +1015,9 @@ void mac_sign( int key_type_arg, status = psa_mac_update( &operation, input->x, input->len ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 2 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) { @@ -1030,9 +1030,9 @@ void mac_sign( int key_type_arg, actual_mac, mac_buffer_size, &mac_length ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) @@ -1044,9 +1044,9 @@ void mac_sign( int key_type_arg, PSA_ASSERT( psa_mac_abort( &operation ) ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS ) { @@ -1062,7 +1062,7 @@ exit: psa_destroy_key( key ); PSA_DONE( ); mbedtls_free( actual_mac ); - test_driver_mac_hooks = test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); } /* END_CASE */ @@ -1081,7 +1081,7 @@ void mac_verify( int key_type_arg, psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status = PSA_ERROR_GENERIC_ERROR; psa_status_t forced_status = forced_status_arg; - test_driver_mac_hooks = test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); TEST_ASSERT( expected_mac->len <= PSA_MAC_MAX_SIZE ); @@ -1094,11 +1094,11 @@ void mac_verify( int key_type_arg, PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, &key ) ); - test_driver_mac_hooks.forced_status = forced_status; + mbedtls_test_driver_mac_hooks.forced_status = forced_status; /* Test the correct MAC. */ status = psa_mac_verify_setup( &operation, key, alg ); - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) @@ -1111,9 +1111,9 @@ void mac_verify( int key_type_arg, status = psa_mac_update( &operation, input->x, input->len ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 2 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 2 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) @@ -1127,9 +1127,9 @@ void mac_verify( int key_type_arg, expected_mac->x, expected_mac->len ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); if( forced_status == PSA_SUCCESS || forced_status == PSA_ERROR_NOT_SUPPORTED ) @@ -1142,15 +1142,15 @@ void mac_verify( int key_type_arg, PSA_ASSERT( psa_mac_abort( &operation ) ); if( forced_status == PSA_SUCCESS ) - TEST_EQUAL( test_driver_mac_hooks.hits, 4 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 4 ); else - TEST_EQUAL( test_driver_mac_hooks.hits, 1 ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); exit: psa_mac_abort( &operation ); psa_destroy_key( key ); PSA_DONE( ); - test_driver_mac_hooks = test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); } /* END_CASE */ From f8ad2123f92f53b6988d013fa58619204abfbcc0 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Tue, 11 May 2021 11:09:13 +0200 Subject: [PATCH 38/39] Be explicit about why the zero-length check is there Since a valid mac operation context would guarantee that the stored mac size is >= 4, it wasn't immediately obvious that the zero-length check is meant for static analyzers and a bit of robustness. Signed-off-by: Steven Cooreman --- library/psa_crypto.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b48af39fb..57970dafa 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2439,8 +2439,12 @@ psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, if( ! operation->is_sign ) return( PSA_ERROR_BAD_STATE ); - /* Sanity checks on output buffer length. */ - if( mac_size == 0 || mac_size < operation->mac_size ) + /* Sanity check. This will guarantee that mac_size != 0 (and so mac != NULL) + * once all the error checks are done. */ + if( operation->mac_size == 0 ) + return( PSA_ERROR_BAD_STATE ); + + if( mac_size < operation->mac_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); status = psa_driver_wrapper_mac_sign_finish( operation, From bbb19524147ae07ce02ae52ae4d6ee6f32ece5c8 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Tue, 11 May 2021 11:10:34 +0200 Subject: [PATCH 39/39] Refactor out mac_sign_setup and mac_verify_setup Since they became equivalent after moving the is_sign checking back to the PSA core, they're now redundant, and the generic mac_setup function can just be called directly. Signed-off-by: Steven Cooreman --- library/psa_crypto_mac.c | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 9db9a37e5..20c56a021 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -383,28 +383,6 @@ static psa_status_t mac_compute( return( PSA_ERROR_NOT_SUPPORTED ); } -static psa_status_t mac_sign_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg ) -{ - return( mac_setup( operation, - attributes, key_buffer, key_buffer_size, alg ) ); -} - -static psa_status_t mac_verify_setup( - mbedtls_psa_mac_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg ) -{ - return( mac_setup( operation, - attributes, key_buffer, key_buffer_size, alg ) ); -} - static psa_status_t mac_update( mbedtls_psa_mac_operation_t *operation, const uint8_t *input, @@ -545,8 +523,8 @@ psa_status_t mbedtls_psa_mac_sign_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - return( mac_sign_setup( operation, attributes, - key_buffer, key_buffer_size, alg ) ); + return( mac_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); } psa_status_t mbedtls_psa_mac_verify_setup( @@ -556,8 +534,8 @@ psa_status_t mbedtls_psa_mac_verify_setup( size_t key_buffer_size, psa_algorithm_t alg ) { - return( mac_verify_setup( operation, attributes, - key_buffer, key_buffer_size, alg ) ); + return( mac_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); } psa_status_t mbedtls_psa_mac_update( @@ -642,8 +620,8 @@ psa_status_t mbedtls_transparent_test_driver_mac_sign_setup( psa_algorithm_t alg ) { if( is_mac_accelerated( alg ) ) - return( mac_sign_setup( operation, attributes, - key_buffer, key_buffer_size, alg ) ); + return( mac_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); else return( PSA_ERROR_NOT_SUPPORTED ); } @@ -656,8 +634,8 @@ psa_status_t mbedtls_transparent_test_driver_mac_verify_setup( psa_algorithm_t alg ) { if( is_mac_accelerated( alg ) ) - return( mac_verify_setup( operation, attributes, - key_buffer, key_buffer_size, alg ) ); + return( mac_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); else return( PSA_ERROR_NOT_SUPPORTED ); }