From 675501d9db6e658ba8a2cdc9994a982679209fdd 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 b3bc1408c7..75801a1789 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 d725e8440f..3e7fdee398 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 8ac7ce1efe..5665fa541a 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 c3e1d026a4..66e1bc8da1 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -208,11 +208,11 @@ - + - + From f4248f2e1b1cffa4c64ec3e74457aa681211458e 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 3e7fdee398..104d4bdb6d 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 61398ec5dc9972ad2ed823c5dcc243708082ddcc 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 5665fa541a..9ae5c9bfc7 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 3c8dd634ddef53b66edcd9443d20588031fa49c6 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 0000000000..a22a997c50 --- /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 0000000000..1c71c52066 --- /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 9ae5c9bfc7..58f2c67b78 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 66e1bc8da1..201751b9c4 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -208,10 +208,12 @@ + + From d13a70f2dc8eb0edb0c3b92a35c7f5279b2b7c7f 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 a22a997c50..16fa3db720 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 1c71c52066..239fdcb337 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 58f2c67b78..975e9f76ba 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 e7ba130d91..f31820a2f8 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -68,6 +68,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 17e42c2cae..d7fa4d9275 100644 --- a/library/Makefile +++ b/library/Makefile @@ -125,6 +125,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 9bef02cd00..09f6319199 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 e82d0931bf..37d5a9a1c0 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 0000000000..169be3a454 --- /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 0000000000..4da60bf408 --- /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 201751b9c4..46adbbec5f 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -262,6 +262,7 @@ + @@ -337,6 +338,7 @@ + From 77e2cc56618371f57c3db1f3e6cacca815cb3cdb 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 16fa3db720..fd7f6f91a9 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 975e9f76ba..04c0064634 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 c153217908..ed847b280a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2277,7 +2277,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; @@ -2325,8 +2325,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 @@ -2374,7 +2377,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; @@ -2463,7 +2466,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 ) @@ -2474,6 +2477,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 ) { @@ -2557,7 +2563,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 { @@ -2583,10 +2589,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 ); @@ -2618,7 +2627,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 ); } @@ -2662,7 +2671,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 ) { @@ -2701,11 +2710,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 ) @@ -2731,21 +2743,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; @@ -2774,9 +2789,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 09f6319199..32ea7f535d 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 82c66b6b8ba1cdd073e89ae89d0bd98eb80bddf4 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 ed847b280a..edfe9a7571 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) @@ -2246,35 +2247,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, @@ -2317,14 +2289,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 */ @@ -2400,72 +2364,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, @@ -2631,46 +2529,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 169be3a454..b09efea596 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 4da60bf408..d923511605 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 e680419791dd308ac87ce0123614d5e624e96406 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 edfe9a7571..19503f681b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2247,124 +2247,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 ) @@ -2374,38 +2269,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, @@ -2415,8 +2304,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. */ @@ -2424,49 +2313,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 32ea7f535d..5d78aede29 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 b09efea596..03618a5831 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 6e7f291bb503394616d46746bc0de89d9c627764 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 19503f681b..7d7d05317c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2354,45 +2354,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 03618a5831..252afca1f1 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 a5b860a5f85dc24004755632bcb0c997aafc312d 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 7d7d05317c..3ca8c9d8f6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2374,59 +2374,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), @@ -2437,68 +2394,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 252afca1f1..72386d873e 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 7515e7535d0bb25bb08398460ea031dfaf26e638 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 b3f1415315..f6b1a430cc 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1437,6 +1437,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" @@ -2233,6 +2235,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 4fdf060a81e230871af95499402ba3946faeb403 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 fd7f6f91a9..2fb0633ab4 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 3ca8c9d8f6..0ef73dff7a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3331,19 +3331,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, @@ -3365,7 +3365,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 @@ -3400,7 +3400,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; @@ -3410,20 +3410,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; } @@ -3432,35 +3434,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; @@ -3806,8 +3808,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 72386d873e..5a7bc2c86a 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 d923511605..6a5629618d 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 d1955af5df458f10ec0710da37085d033a968ef1 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 2fb0633ab4..e1acf3955b 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 04c0064634..23a090836e 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 0ef73dff7a..01ddb524dc 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3365,7 +3365,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 5a7bc2c86a..5ea2f1760c 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 6a5629618d..e63da5304f 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 939102e7a32c3e471696f36ae96457c45092c41c 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 736d9abe08..246e894278 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 c7f0a576b68aa42bb0f5aee4417ad2edf4030279 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 5d78aede29..795e424894 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 0000000000..e4c750bd61 --- /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 dc2136a6ab..5b60932d3a 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 0000000000..4e26e9f21e --- /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 5fbfac66a8..cab40d37f8 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 a0b719ef69..f523d3c881 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 46adbbec5f..9aa0b78df1 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -236,6 +236,7 @@ + @@ -384,6 +385,7 @@ + From 02fc62a6fa283593d717fa7a3c36abb8f7a32160 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 e1acf3955b..3b0f82ad24 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 5ea2f1760c..0189cded8a 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 ba9a5bf5e7825c836dd49ec9e512a2b20718d99e 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 01ddb524dc..293f40e656 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2267,18 +2267,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 0189cded8a..d8e229325d 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 a4638e708e5c883ee4532b7dadea7287c4764d67 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 3b0f82ad24..780a6c54e3 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 d8e229325d..7122ecdd36 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 36876a01a46fa9d067166121868f2fe81f0fbdc5 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 293f40e656..432b77a31a 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 */ /****************************************************************/ @@ -2184,7 +2170,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 ); } @@ -2220,7 +2206,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 90f9d18630..b75e59a819 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 7122ecdd36..854aee4f0b 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 dd1a915c0f0236c5b4c76247dd8383743c8f4d89 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 780a6c54e3..81a8ec7191 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 23a090836e..79c4285a52 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 432b77a31a..f0a43e3ad5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3355,7 +3355,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 854aee4f0b..ac026ff4c9 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 e63da5304f..b7f2a6c3b9 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 ac8d82a6f825ff937d36e0acb17de7b83832c49e 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 81a8ec7191..6979dec42a 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 79c4285a52..22b5fc2fb7 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 d1ed1d935f5938a767cd66a15f8e6526b164b466 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 22b5fc2fb7..6b4cda60a0 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 f0a43e3ad5..05af159a26 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3213,7 +3213,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 */ @@ -3280,11 +3280,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 ) @@ -3314,31 +3315,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 ); } @@ -3778,33 +3790,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 a6df6040eec06b4defb5dadb8f0be774d3fb34ec 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 6b4cda60a0..fc7e7785cc 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 05af159a26..04a0637286 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3223,6 +3223,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, @@ -3237,7 +3244,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. */ @@ -3367,7 +3374,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 @@ -3399,10 +3407,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; @@ -3412,59 +3427,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; @@ -3561,8 +3578,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 || @@ -3891,17 +3908,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; @@ -3931,7 +3952,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 ) @@ -3941,7 +3961,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: @@ -3954,7 +3974,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 ) { @@ -3981,7 +4000,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 ); @@ -3989,18 +4008,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 */ @@ -4065,7 +4083,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 @@ -4074,7 +4091,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 ac026ff4c9..ca40b03bf7 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 b7f2a6c3b9..4da60bf408 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 094a77e79c079bb8d8f1258013a8f2cf012eebc4 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 04a0637286..1d33f6b63b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3182,7 +3182,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 */ @@ -3323,17 +3348,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 ); @@ -3407,17 +3425,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; @@ -3455,11 +3466,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 ); @@ -3479,8 +3489,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; @@ -3809,19 +3817,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; @@ -3831,17 +3829,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 ca40b03bf7..8e64741e6e 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 dcd081150196f567fa8b4ef2de5df3e755ef3bab 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 8e64741e6e..a5ef9e57da 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 8f37004bd71f674d47c8d79594bfe0101af5ffee 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 6979dec42a..f968c169e8 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 a5ef9e57da..dc07d455ed 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 3409b02b27b618edf3c171947ab3081c03a6e646 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 dc07d455ed..3d7f70bacb 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 f45f071f017980ab7e4c3770b7cded5724ebe170 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 4da60bf408..4635fe1d7b 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 a2058a7832442484ff2d378c0d8ff00ee1d6e43e 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 cab40d37f8..bc6d64703e 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 c112315aebc20e39ad1affb91eb84f4d21100073 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 bc6d64703e..95ab688bea 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 72f736a1912cf85dab2c488a9433f84e300ce901 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 f968c169e8..1d11b003e4 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 fc7e7785cc..47012fdd00 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 1d33f6b63b..4b769e9f6f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2240,6 +2240,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 ); @@ -2253,7 +2255,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 ) @@ -2279,12 +2280,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, @@ -2294,8 +2298,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. */ @@ -2372,26 +2377,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 ); } @@ -2405,8 +2429,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 ); @@ -3199,6 +3234,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 3d7f70bacb..6753dedf54 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 4635fe1d7b..9b81e73e02 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 2f60f20884d9659d0bf687fc3e0eba34226b8b19 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 6753dedf54..32ab88535d 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 02865f5cbb1eb22b4d2deb75e3d0cbbe7bb602dc 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 32ab88535d..9c44c237f0 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 0c239659772634a01e9ebec8400e4ba4193e811b 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 9c44c237f0..69724727a6 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 944ef23861..7b86185b9b 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 b29902ac9f11fdaaa17317b654625a5d1e7e4e89 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 69724727a6..9db9a37e52 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 d1a68f10c0e01e9d601f961f899bab8ebe461404 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 4b769e9f6f..c0e0976e8a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2282,11 +2282,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 ) { @@ -2299,7 +2299,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 ae3ec52d8d2f9d0ea080be1540de2f7bf6291ad0 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 e4c750bd61..7733dd341c 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 4e26e9f21e..69af107809 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 f523d3c881..ac241f5ad4 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 8af5c5c7de815bea536a92c58c584fb88e567953 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 c0e0976e8a..5f57c38c65 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2388,8 +2388,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 9e15fb783c2919144db086fc5eac06be81dd382a 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 9db9a37e52..20c56a0214 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 ); }