diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h new file mode 100644 index 000000000..1d11b003e --- /dev/null +++ b/include/psa/crypto_builtin_composites.h @@ -0,0 +1,92 @@ +/* + * 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_PSA_BUILTIN_ALG_CMAC) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) +#define MBEDTLS_PSA_BUILTIN_MAC +#endif + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) +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]; +} mbedtls_psa_hmac_operation_t; + +#define MBEDTLS_PSA_HMAC_OPERATION_INIT {0, PSA_HASH_OPERATION_INIT, {0}} +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ + +#include "mbedtls/cmac.h" + +typedef struct +{ + psa_algorithm_t alg; + union + { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_psa_hmac_operation_t hmac; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC) || defined(PSA_CRYPTO_DRIVER_TEST) + mbedtls_cipher_context_t cmac; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */ + } ctx; +} 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_builtin.h b/include/psa/crypto_builtin_primitives.h similarity index 94% rename from include/psa/crypto_builtin.h rename to include/psa/crypto_builtin_primitives.h index b3bc1408c..75801a178 100644 --- a/include/psa/crypto_builtin.h +++ b/include/psa/crypto_builtin_primitives.h @@ -1,6 +1,8 @@ /* * Context structure declaration of the Mbed TLS software-based PSA drivers * called through the PSA Crypto driver dispatch layer. + * This file contains the context structures of those algorithms which do not + * rely on other algorithms, i.e. are 'primitive' algorithms. * * \note This file may not be included directly. Applications must * include psa/crypto.h. @@ -28,8 +30,8 @@ * limitations under the License. */ -#ifndef PSA_CRYPTO_BUILTIN_H -#define PSA_CRYPTO_BUILTIN_H +#ifndef PSA_CRYPTO_BUILTIN_PRIMITIVES_H +#define PSA_CRYPTO_BUILTIN_PRIMITIVES_H #include @@ -141,4 +143,4 @@ typedef struct { #endif /* PSA_CRYPTO_DRIVER_TEST */ -#endif /* PSA_CRYPTO_BUILTIN_H */ +#endif /* PSA_CRYPTO_BUILTIN_PRIMITIVES_H */ diff --git a/include/psa/crypto_config.h b/include/psa/crypto_config.h index 736d9abe0..246e89427 100644 --- a/include/psa/crypto_config.h +++ b/include/psa/crypto_config.h @@ -57,6 +57,7 @@ #define PSA_WANT_ALG_CBC_NO_PADDING 1 #define PSA_WANT_ALG_CBC_PKCS7 1 #define PSA_WANT_ALG_CCM 1 +#define PSA_WANT_ALG_CMAC 1 #define PSA_WANT_ALG_CFB 1 #define PSA_WANT_ALG_CHACHA20_POLY1305 1 #define PSA_WANT_ALG_CMAC 1 diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h new file mode 100644 index 000000000..239fdcb33 --- /dev/null +++ b/include/psa/crypto_driver_contexts_composites.h @@ -0,0 +1,62 @@ +/* + * 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 */ + +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_driver_contexts.h b/include/psa/crypto_driver_contexts_primitives.h similarity index 88% rename from include/psa/crypto_driver_contexts.h rename to include/psa/crypto_driver_contexts_primitives.h index d725e8440..104d4bdb6 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,17 +30,16 @@ * 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" /* 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.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 +65,5 @@ typedef union { #endif } psa_driver_cipher_context_t; -#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_H */ +#endif /* PSA_CRYPTO_DRIVER_CONTEXTS_PRIMITIVES_H */ /* End of automatically generated file. */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 8ac7ce1ef..47012fdd0 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -76,8 +76,9 @@ extern "C" { #include "mbedtls/cmac.h" #include "mbedtls/gcm.h" -/* Include the context definition for the compiled-in drivers */ -#include "psa/crypto_driver_contexts.h" +/* 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,46 +99,6 @@ static inline struct psa_hash_operation_s psa_hash_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 */ - -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; - 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 - } ctx; -}; - -#define PSA_MAC_OPERATION_INIT {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; - return( v ); -} - struct psa_cipher_operation_s { /** Unique ID indicating which driver got assigned to do the @@ -163,6 +124,31 @@ static inline struct psa_cipher_operation_s psa_cipher_operation_init( void ) return( v ); } +/* 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 +{ + /** 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; + uint8_t mac_size; + unsigned int is_sign : 1; + psa_driver_mac_context_t ctx; +}; + +#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; + return( v ); +} + struct psa_aead_operation_s { psa_algorithm_t alg; @@ -184,12 +170,12 @@ 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; size_t info_length; - psa_hmac_internal_data 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 @@ -200,9 +186,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 */ @@ -227,17 +214,20 @@ 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; - psa_hmac_internal_data hmac; + uint8_t Ai[PSA_HASH_MAX_SIZE]; /* `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 { @@ -248,8 +238,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; diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 256feef53..22a172791 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -69,6 +69,7 @@ set(src_crypto psa_crypto_driver_wrappers.c psa_crypto_ecp.c psa_crypto_hash.c + psa_crypto_mac.c psa_crypto_rsa.c psa_crypto_se.c psa_crypto_slot_management.c diff --git a/library/Makefile b/library/Makefile index f089e0b58..dc101d28b 100644 --- a/library/Makefile +++ b/library/Makefile @@ -126,6 +126,7 @@ OBJS_CRYPTO= \ psa_crypto_driver_wrappers.o \ psa_crypto_ecp.o \ psa_crypto_hash.o \ + psa_crypto_mac.o \ psa_crypto_rsa.o \ psa_crypto_se.o \ psa_crypto_slot_management.o \ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f58df4aef..57970dafa 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) @@ -92,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 */ /****************************************************************/ @@ -2234,7 +2221,7 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation, return( status ); if( actual_hash_length != hash_length ) return( PSA_ERROR_INVALID_SIGNATURE ); - if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) + if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) return( PSA_ERROR_INVALID_SIGNATURE ); return( PSA_SUCCESS ); } @@ -2270,7 +2257,7 @@ psa_status_t psa_hash_compare( psa_algorithm_t alg, return( status ); if( actual_hash_length != hash_length ) return( PSA_ERROR_INVALID_SIGNATURE ); - if( safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) + if( mbedtls_psa_safer_memcmp( hash, actual_hash, actual_hash_length ) != 0 ) return( PSA_ERROR_INVALID_SIGNATURE ); return( PSA_SUCCESS ); } @@ -2297,222 +2284,19 @@ 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( 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(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 ); -} - -#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 *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. */ + /* Aborting a non-active operation is allowed */ + if( operation->id == 0 ) 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; + psa_status_t status = psa_driver_wrapper_mac_abort( operation ); + operation->mac_size = 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( 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 */ - -#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 ) ); + operation->id = 0; return( status ); } -#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, mbedtls_svc_key_id_t key, @@ -2522,35 +2306,38 @@ 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; /* 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( ! PSA_ALG_IS_MAC( alg ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + status = psa_get_and_lock_key_slot_with_policy( + key, + &slot, + is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, + alg ); if( status != PSA_SUCCESS ) return( status ); - if( is_sign ) - operation->is_sign = 1; - status = psa_get_and_lock_transparent_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 ); + operation->is_sign = is_sign; + + /* Get the output length for the algorithm and key combination */ + operation->mac_size = PSA_MAC_LENGTH( + psa_get_key_type( &attributes ), + psa_get_key_bits( &attributes ), + alg ); if( operation->mac_size < 4 ) { @@ -2562,8 +2349,9 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } - if( operation->mac_size > - PSA_MAC_LENGTH( slot->attr.type, 0, PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) + if( operation->mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), + psa_get_key_bits( &attributes ), + PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length * of the algorithm. */ @@ -2571,49 +2359,27 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *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( operation ); - } - else - { - operation->key_set = 1; - } unlock_status = psa_unlock_key_slot( slot ); @@ -2638,200 +2404,102 @@ psa_status_t psa_mac_update( psa_mac_operation_t *operation, const uint8_t *input, size_t input_length ) { - 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( 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( 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 *operation, uint8_t *mac, size_t mac_size, size_t *mac_length ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - if( operation->alg == 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. */ + /* 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 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->id == 0 ) + return( PSA_ERROR_BAD_STATE ); if( ! operation->is_sign ) - { return( PSA_ERROR_BAD_STATE ); - } - status = psa_mac_finish_internal( operation, mac, 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, + mac, operation->mac_size, + mac_length ); if( status == PSA_SUCCESS ) { - status = psa_mac_abort( operation ); - if( status == PSA_SUCCESS ) - *mac_length = operation->mac_size; - else - memset( mac, '!', mac_size ); + /* 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 - psa_mac_abort( operation ); - return( status ); + { + /* 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 ); + + return( status == PSA_SUCCESS ? abort_status : status ); } psa_status_t psa_mac_verify_finish( psa_mac_operation_t *operation, const uint8_t *mac, size_t mac_length ) { - uint8_t actual_mac[PSA_MAC_MAX_SIZE]; - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; - 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_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; + status = psa_driver_wrapper_mac_verify_finish( operation, + mac, mac_length ); cleanup: - if( status == PSA_SUCCESS ) - status = psa_mac_abort( operation ); - else - psa_mac_abort( operation ); + abort_status = psa_mac_abort( operation ); - mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); - - return( status ); + return( status == PSA_SUCCESS ? abort_status : status ); } @@ -3604,7 +3272,35 @@ 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 ); + + 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, + 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 */ @@ -3635,7 +3331,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 */ @@ -3645,6 +3341,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, @@ -3659,7 +3362,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. */ @@ -3702,11 +3405,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 ) @@ -3736,31 +3440,35 @@ 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 ); + + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + hkdf->prk, + hash_length ); if( status != PSA_SUCCESS ) return( status ); + if( hkdf->block_number != 1 ) { - status = psa_hash_update( &hkdf->hmac.hash_ctx, - hkdf->output_block, - hash_length ); + status = psa_mac_update( &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_mac_update( &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_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 ); } @@ -3777,7 +3485,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 ); - psa_hash_operation_t backup = PSA_HASH_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 @@ -3809,10 +3518,10 @@ 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_hash_clone( &tls12_prf->hmac.hash_ctx, &backup ); + status = psa_key_derivation_start_hmac( &hmac, + hash_alg, + tls12_prf->secret, + tls12_prf->secret_length ); if( status != PSA_SUCCESS ) goto cleanup; @@ -3822,57 +3531,58 @@ 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_mac_update( &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_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_hash_update( &tls12_prf->hmac.hash_ctx, - 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_hash_clone( &backup, &tls12_prf->hmac.hash_ctx ); + 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_hash_update( &tls12_prf->hmac.hash_ctx, - tls12_prf->Ai, hash_length ); + status = psa_key_derivation_start_hmac( &hmac, + hash_alg, + tls12_prf->secret, + tls12_prf->secret_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_mac_update( &hmac, tls12_prf->Ai, hash_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_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_hash_clone( &backup, &tls12_prf->hmac.hash_ctx ); + status = psa_mac_sign_finish( &hmac, + tls12_prf->output_block, hash_length, + &hmac_output_length ); if( status != PSA_SUCCESS ) goto cleanup; cleanup: - - cleanup_status = psa_hash_abort( &backup ); + cleanup_status = psa_mac_abort( &hmac ); if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS ) status = cleanup_status; @@ -3969,8 +3679,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 || @@ -4198,33 +3908,37 @@ 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 + { + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + data, data_length ); + 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 ); + status = psa_key_derivation_start_hmac( &hkdf->hmac, + hash_alg, + NULL, 0 ); if( status != PSA_SUCCESS ) return( status ); hkdf->state = HKDF_STATE_STARTED; } if( hkdf->state != HKDF_STATE_STARTED ) return( PSA_ERROR_BAD_STATE ); - status = psa_hash_update( &hkdf->hmac.hash_ctx, - 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 ); @@ -4277,17 +3991,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; @@ -4317,7 +4035,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 ) @@ -4327,7 +4044,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: @@ -4340,7 +4057,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 ) { @@ -4367,7 +4083,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 ); @@ -4375,18 +4091,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 */ @@ -4451,7 +4166,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 @@ -4460,7 +4174,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_core.h b/library/psa_crypto_core.h index 90f9d1863..b75e59a81 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -30,6 +30,26 @@ #include "psa/crypto.h" #include "psa/crypto_se_driver.h" +/** Constant-time buffer comparison + * + * \param[in] a Left-hand buffer for comparison. + * \param[in] b Right-hand buffer for comparison. + * \param n Amount of bytes to compare. + * + * \return 0 if the buffer contents are equal, non-zero otherwise + */ +static inline int mbedtls_psa_safer_memcmp( + const uint8_t *a, const uint8_t *b, size_t n ) +{ + size_t i; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= a[i] ^ b[i]; + + return( diff ); +} + /** The data structure representing a key slot, containing key material * and metadata for one key. */ diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 9bef02cd0..795e42489 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,344 @@ 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_test_transparent_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_test_opaque_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_test_transparent_mac_sign_setup( + &operation->ctx.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.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_test_opaque_mac_sign_setup( + &operation->ctx.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_test_transparent_mac_verify_setup( + &operation->ctx.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.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_test_opaque_mac_verify_setup( + &operation->ctx.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.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_test_transparent_mac_update( + &operation->ctx.transparent_test_driver_ctx, + input, input_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_test_opaque_mac_update( + &operation->ctx.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.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_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_test_opaque_mac_sign_finish( + &operation->ctx.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.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_test_transparent_mac_verify_finish( + &operation->ctx.transparent_test_driver_ctx, + mac, mac_length ) ); + + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_test_opaque_mac_verify_finish( + &operation->ctx.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 ) +{ + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_MAC) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + 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: + return( mbedtls_test_transparent_mac_abort( + &operation->ctx.transparent_test_driver_ctx ) ); + case PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID: + return( mbedtls_test_opaque_mac_abort( + &operation->ctx.opaque_test_driver_ctx ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} /* End of automatically generated file. */ diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index e82d0931b..37d5a9a1c 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -183,6 +183,53 @@ psa_status_t psa_driver_wrapper_aead_decrypt( const uint8_t *ciphertext, size_t ciphertext_length, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ); +/* + * MAC functions + */ +psa_status_t psa_driver_wrapper_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t psa_driver_wrapper_mac_sign_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_mac_verify_setup( + psa_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_mac_update( + psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t psa_driver_wrapper_mac_sign_finish( + psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t psa_driver_wrapper_mac_verify_finish( + psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t psa_driver_wrapper_mac_abort( + psa_mac_operation_t *operation ); + #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ /* End of automatically generated file. */ diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c new file mode 100644 index 000000000..20c56a021 --- /dev/null +++ b/library/psa_crypto_mac.c @@ -0,0 +1,787 @@ +/* + * 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 +#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 + +#if defined(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 ); + } +} + +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 ) ); +} + +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; + 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 ); +} + +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 ) ); +} + +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; + 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 /* BUILTIN_ALG_HMAC */ + +#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 ) +{ + 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, + psa_get_key_type( attributes ), + psa_get_key_bits( attributes ), + 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, + key_buffer, + psa_get_key_bits( attributes ) ); +exit: + return( mbedtls_to_psa_error( ret ) ); +} +#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( + mbedtls_psa_mac_operation_t *operation, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + operation->alg = alg; + +#if defined(BUILTIN_ALG_CMAC) + if( PSA_ALG_FULL_LENGTH_MAC( operation->alg ) == PSA_ALG_CMAC ) + { + 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 */ + { + status = PSA_ERROR_NOT_SUPPORTED; + } + + 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( PSA_ALG_FULL_LENGTH_MAC( 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; + + 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 ) +{ + 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 defined(BUILTIN_ALG_CMAC) + if( PSA_ALG_FULL_LENGTH_MAC( alg ) == PSA_ALG_CMAC ) + { + /* 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 */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( alg ) ) + { + status = psa_hmac_setup_internal( &operation->ctx.hmac, + key_buffer, + key_buffer_size, + PSA_ALG_HMAC_GET_HASH( alg ) ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + status = PSA_ERROR_NOT_SUPPORTED; + } + + if( status != PSA_SUCCESS ) + mac_abort( operation ); + + return( status ); +} + +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 ) +{ + /* One-shot MAC has not been implemented in this PSA implementation yet. */ + (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_update( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + if( operation->alg == 0 ) + return( PSA_ERROR_BAD_STATE ); + +#if defined(BUILTIN_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, + input, input_length ) ) ); + } + else +#endif /* BUILTIN_ALG_CMAC */ +#if defined(BUILTIN_ALG_HMAC) + if( PSA_ALG_IS_HMAC( operation->alg ) ) + { + return( psa_hmac_update_internal( &operation->ctx.hmac, + input, input_length ) ); + } + else +#endif /* BUILTIN_ALG_HMAC */ + { + /* This shouldn't happen if `operation` was initialized by + * a setup function. */ + (void) input; + (void) input_length; + return( PSA_ERROR_BAD_STATE ); + } +} + +static psa_status_t mac_finish_internal( mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size ) +{ +#if defined(BUILTIN_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, 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, 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 ); + } +} + +static psa_status_t mac_sign_finish( + mbedtls_psa_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if( operation->alg == 0 ) + return( PSA_ERROR_BAD_STATE ); + + status = mac_finish_internal( operation, mac, mac_size ); + + if( status == PSA_SUCCESS ) + *mac_length = mac_size; + + return( status ); +} + +static psa_status_t mac_verify_finish( + mbedtls_psa_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + uint8_t actual_mac[PSA_MAC_MAX_SIZE]; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + if( operation->alg == 0 ) + 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 ); + + status = mac_finish_internal( operation, actual_mac, mac_length ); + if( status != PSA_SUCCESS ) + goto cleanup; + + if( mbedtls_psa_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 /* BUILTIN_ALG_HMAC || BUILTIN_ALG_CMAC */ + +#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_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_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_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_setup( operation, attributes, + key_buffer, key_buffer_size, alg ) ); + else + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_update( operation, input, input_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_sign_finish( operation, mac, mac_size, mac_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + if( is_mac_accelerated( operation->alg ) ) + return( mac_verify_finish( operation, mac, mac_length ) ); + else + return( PSA_ERROR_BAD_STATE ); +} + +psa_status_t mbedtls_transparent_test_driver_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ) +{ + return( mac_abort( operation ) ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) input; + (void) input_length; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) attributes; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) input; + (void) input_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) mac; + (void) mac_size; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + (void) mac; + (void) mac_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t mbedtls_opaque_test_driver_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ) +{ + /* Opaque driver testing is not implemented yet through this mechanism. */ + (void) operation; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +#endif /* PSA_CRYPTO_DRIVER_TEST */ + +#endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h new file mode 100644 index 000000000..9b81e73e0 --- /dev/null +++ b/library/psa_crypto_mac.h @@ -0,0 +1,372 @@ +/* + * 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_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_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_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 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 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 + * 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 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(). + * + * 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. + * \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. + * \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 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. + * + * 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. + * \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. + * \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 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. + * + * 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/tests/include/test/drivers/mac.h b/tests/include/test/drivers/mac.h new file mode 100644 index 000000000..7733dd341 --- /dev/null +++ b/tests/include/test/drivers/mac.h @@ -0,0 +1,141 @@ +/* + * 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; +} mbedtls_test_driver_mac_hooks_t; + +#define MBEDTLS_TEST_DRIVER_MAC_INIT { 0, 0, 0 } +static inline mbedtls_test_driver_mac_hooks_t + mbedtls_test_driver_mac_hooks_init( void ) +{ + const mbedtls_test_driver_mac_hooks_t v = MBEDTLS_TEST_DRIVER_MAC_INIT; + return( v ); +} + +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, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_transparent_mac_sign_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_transparent_mac_verify_setup( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_transparent_mac_update( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_test_transparent_mac_sign_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_transparent_mac_verify_finish( + mbedtls_transparent_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_test_transparent_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ); + +psa_status_t mbedtls_test_opaque_mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_opaque_mac_sign_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_opaque_mac_verify_setup( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg ); + +psa_status_t mbedtls_test_opaque_mac_update( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t mbedtls_test_opaque_mac_sign_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ); + +psa_status_t mbedtls_test_opaque_mac_verify_finish( + mbedtls_opaque_test_driver_mac_operation_t *operation, + const uint8_t *mac, + size_t mac_length ); + +psa_status_t mbedtls_test_opaque_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ); + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_TEST_DRIVERS_MAC_H */ diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h index dc2136a6a..5b60932d3 100644 --- a/tests/include/test/drivers/test_driver.h +++ b/tests/include/test/drivers/test_driver.h @@ -25,6 +25,7 @@ #include "test/drivers/aead.h" #include "test/drivers/cipher.h" #include "test/drivers/hash.h" +#include "test/drivers/mac.h" #include "test/drivers/key_management.h" #include "test/drivers/signature.h" #include "test/drivers/size.h" diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index a85c7ce00..0713ed40f 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1496,6 +1496,8 @@ component_test_psa_crypto_config_basic() { loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="$loc_cflags" LDFLAGS="$ASAN_CFLAGS" @@ -2293,6 +2295,8 @@ component_test_psa_crypto_drivers () { loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_384" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_SHA_512" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_XTS" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_CMAC" + loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_ALG_HMAC" loc_cflags="${loc_cflags} -I../tests/include -O2" make CC=gcc CFLAGS="${loc_cflags}" LDFLAGS="$ASAN_CFLAGS" diff --git a/tests/src/drivers/test_driver_mac.c b/tests/src/drivers/test_driver_mac.c new file mode 100644 index 000000000..69af10780 --- /dev/null +++ b/tests/src/drivers/test_driver_mac.c @@ -0,0 +1,362 @@ +/* + * 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" + +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, + 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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + 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( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_sign_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_verify_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_update( + operation, input, input_length ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_sign_finish( + operation, mac, mac_size, mac_length ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_verify_finish( + operation, mac, mac_length ); + } + + return( mbedtls_test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_transparent_mac_abort( + mbedtls_transparent_test_driver_mac_operation_t *operation ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_transparent_test_driver_mac_abort( operation ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + 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( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_sign_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_verify_setup( + operation, attributes, key_buffer, key_buffer_size, alg ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_update( + operation, input, input_length ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_sign_finish( + operation, mac, mac_size, mac_length ); + } + + return( mbedtls_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 ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_verify_finish( + operation, mac, mac_length ); + } + + return( mbedtls_test_driver_mac_hooks.driver_status ); +} + +psa_status_t mbedtls_test_opaque_mac_abort( + mbedtls_opaque_test_driver_mac_operation_t *operation ) +{ + mbedtls_test_driver_mac_hooks.hits++; + + if( mbedtls_test_driver_mac_hooks.forced_status != PSA_SUCCESS ) + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_test_driver_mac_hooks.forced_status; + } + else + { + mbedtls_test_driver_mac_hooks.driver_status = + mbedtls_opaque_test_driver_mac_abort( operation ); + } + + 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.data b/tests/suites/test_suite_psa_crypto.data index 944ef2386..7b86185b9 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1294,6 +1294,22 @@ PSA MAC verify: HMAC-SHA-512, truncated to 4 bytes depends_on:PSA_WANT_ALG_HMAC:PSA_WANT_ALG_SHA_512:PSA_WANT_KEY_TYPE_HMAC mac_verify:PSA_KEY_TYPE_HMAC:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(PSA_ALG_SHA_512), 4):"4869205468657265":"87aa7cde" +PSA MAC sign: CMAC-3DES (CAVP vector #95) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_sign:PSA_KEY_TYPE_DES:"7c34e67a2a8fef581cc4f7dceaea130dad52c189739e401f":PSA_ALG_CMAC:"eb3365a0a9d141270334065547418fe64c47823c024082b94d54a66d149f2af1":"e1d7c3736739e726" + +PSA MAC verify: CMAC-3DES (CAVP vector #95) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_verify:PSA_KEY_TYPE_DES:"7c34e67a2a8fef581cc4f7dceaea130dad52c189739e401f":PSA_ALG_CMAC:"eb3365a0a9d141270334065547418fe64c47823c024082b94d54a66d149f2af1":"e1d7c3736739e726" + +PSA MAC: CMAC-3DES-2key (not supported in PSA) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_setup:PSA_KEY_TYPE_DES:"89fe91f1c1ef2f01efc4c18f5715894c":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED + +PSA MAC: CMAC-DES (not supported in PSA) +depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_DES +mac_setup:PSA_KEY_TYPE_DES:"89fe91f1c1ef2f01":PSA_ALG_CMAC:PSA_ERROR_NOT_SUPPORTED + PSA MAC sign: CMAC-AES-128 depends_on:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES mac_sign:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":PSA_ALG_CMAC:"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411":"dfa66747de9ae63030ca32611497c827" diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 5fbfac66a..95ab688be 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,31 +241,87 @@ 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 +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: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 +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: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: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 +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: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: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 +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: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: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 +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 diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index 503cdcdde..0055f9f0d 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; + 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. */ + 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 ); + mbedtls_test_driver_mac_hooks.forced_status = forced_status; + + /* Calculate the MAC. */ + status = psa_mac_sign_setup( &operation, key, alg ); + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 2 ); + else + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( mbedtls_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 ); + mbedtls_test_driver_mac_hooks = mbedtls_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; + mbedtls_test_driver_mac_hooks = mbedtls_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 ) ); + + mbedtls_test_driver_mac_hooks.forced_status = forced_status; + + /* Test the correct MAC. */ + status = psa_mac_verify_setup( &operation, key, alg ); + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 2 ); + else + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( mbedtls_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( mbedtls_test_driver_mac_hooks.hits, 4 ); + else + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); + +exit: + psa_mac_abort( &operation ); + psa_destroy_key( key ); + PSA_DONE( ); + mbedtls_test_driver_mac_hooks = mbedtls_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 a4385c90d..9cec716e3 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -222,11 +222,13 @@ - + + - + + @@ -247,6 +249,7 @@ + @@ -265,6 +268,7 @@ + @@ -341,6 +345,7 @@ + @@ -385,6 +390,7 @@ +