From 47728841336816a1b4bbd5b111e2071b984b3234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 18 Jul 2022 13:00:40 +0200 Subject: [PATCH] New internal module for managing hash information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using static inline functions is bad for code size; the function from md_internal.h was already used from 3 different C files, so already was copied at least 3 times in the library, and this would only get worse over time. Use actual functions, and also share the actual data between them. Provide a consistent set of operations. Conversion to/from human-readable string was omitted for now but could be added later if needed. In the future, this can be used to replace other similar (inline) functions that are currently scattered, including (but perhaps not limited to): - mbedtls_psa_translate_md() from psa_util.h - mbedtls_md_info_from_psa() (indirectly) from psa_crypto_hash.h - get_md_alg_from_psa() from psa_crypto_rsa.c Signed-off-by: Manuel Pégourié-Gonnard --- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/hash_info.c | 109 ++++++++++++++++++++++++++++ library/hash_info.h | 77 ++++++++++++++++++++ library/md_internal.h | 70 ------------------ library/pk.c | 4 +- library/psa_crypto_rsa.c | 4 +- library/rsa.c | 4 +- tests/suites/test_suite_pk.function | 4 +- 9 files changed, 196 insertions(+), 78 deletions(-) create mode 100644 library/hash_info.c create mode 100644 library/hash_info.h delete mode 100644 library/md_internal.h diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index d65215717..be6aecf8c 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -38,6 +38,7 @@ set(src_crypto entropy_poll.c error.c gcm.c + hash_info.c hkdf.c hmac_drbg.c md.c diff --git a/library/Makefile b/library/Makefile index f5ff474ec..3c4c7ea5e 100644 --- a/library/Makefile +++ b/library/Makefile @@ -103,6 +103,7 @@ OBJS_CRYPTO= \ entropy_poll.o \ error.o \ gcm.o \ + hash_info.o \ hkdf.o \ hmac_drbg.o \ md.o \ diff --git a/library/hash_info.c b/library/hash_info.c new file mode 100644 index 000000000..b45d1d297 --- /dev/null +++ b/library/hash_info.c @@ -0,0 +1,109 @@ +/* + * Hash information that's independent from the crypto implementation. + * + * (See the corresponding header file for usage notes.) + */ +/* + * 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 "hash_info.h" +#include "or_psa_helpers.h" + +typedef struct +{ + psa_algorithm_t psa_alg; + mbedtls_md_type_t md_type; + unsigned char size; + unsigned char block_size; +} hash_entry; + +static const hash_entry hash_table[] = { +#if defined(MBEDTLS_OR_PSA_WANT_ALG_MD5) + { PSA_ALG_MD5, MBEDTLS_MD_MD5, 16, 64 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_RIPEMD160) + { PSA_ALG_RIPEMD160, MBEDTLS_MD_RIPEMD160, 20, 64 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_1) + { PSA_ALG_SHA_1, MBEDTLS_MD_SHA1, 20, 64 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_224) + { PSA_ALG_SHA_224, MBEDTLS_MD_SHA224, 28, 64 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_256) + { PSA_ALG_SHA_256, MBEDTLS_MD_SHA256, 32, 64 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_384) + { PSA_ALG_SHA_384, MBEDTLS_MD_SHA384, 48, 128 }, +#endif +#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_512) + { PSA_ALG_SHA_512, MBEDTLS_MD_SHA512, 64, 128 }, +#endif + { PSA_ALG_NONE, MBEDTLS_MD_NONE, 0, 0 }, +}; + +/* Get size from MD type */ +unsigned char mbedtls_hash_info_get_size( mbedtls_md_type_t md_type ) +{ + const hash_entry *entry = hash_table; + while( entry->md_type != MBEDTLS_MD_NONE && + entry->md_type != md_type ) + { + entry++; + } + + return entry->size; +} + +/* Get block size from MD type */ +unsigned char mbedtls_hash_info_get_block_size( mbedtls_md_type_t md_type ) +{ + const hash_entry *entry = hash_table; + while( entry->md_type != MBEDTLS_MD_NONE && + entry->md_type != md_type ) + { + entry++; + } + + return entry->block_size; +} + +/* Get PSA from MD */ +psa_algorithm_t mbedtls_hash_info_psa_from_md( mbedtls_md_type_t md_type ) +{ + const hash_entry *entry = hash_table; + while( entry->md_type != MBEDTLS_MD_NONE && + entry->md_type != md_type ) + { + entry++; + } + + return entry->psa_alg; +} + +/* Get PSA from MD */ +mbedtls_md_type_t mbedtls_hash_info_md_from_psa( psa_algorithm_t psa_alg ) +{ + const hash_entry *entry = hash_table; + while( entry->md_type != MBEDTLS_MD_NONE && + entry->psa_alg != psa_alg ) + { + entry++; + } + + return entry->md_type; +} diff --git a/library/hash_info.h b/library/hash_info.h new file mode 100644 index 000000000..e0f47a414 --- /dev/null +++ b/library/hash_info.h @@ -0,0 +1,77 @@ +/** + * Hash information that's independent from the crypto implementation. + * + * This can be used by: + * - code based on PSA + * - code based on the legacy API + * - code based on either of them depending on MBEDTLS_USE_PSA_CRYPTO + * - code based on either of them depending on what's available + * + * Note: this internal module will go away when everything become based on + * PSA Crypto; it is a helper for the transition while hash algorithms are + * wtill represented using mbedtls_md_type_t in most places even when PSA is + * used for the actual crypto computations. + * + * 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 MBEDTLS_HASH_INFO_H +#define MBEDTLS_HASH_INFO_H + +#include "common.h" + +#include "mbedtls/md.h" +#include "psa/crypto.h" + +/** Get the output length of the given hash type from its MD type. + * + * \note To get the output length from the PSA alg, use \c PSA_HASH_LENGTH(). + * + * \param md_type The hash MD type. + * + * \return The output length in bytes, or 0 if not known. + */ +unsigned char mbedtls_hash_info_get_size( mbedtls_md_type_t md_type ); + +/** Get the block size of the given hash type from its MD type. + * + * \note To get the output length from the PSA alg, use + * \c PSA_HASH_BLOCK_LENGTH(). + * + * \param md_type The hash MD type. + * + * \return The block size in bytes, or 0 if not known. + */ +unsigned char mbedtls_hash_info_get_block_size( mbedtls_md_type_t md_type ); + +/** Get the PSA alg from the MD type. + * + * \param md_type The hash MD type. + * + * \return The corresponding PSA algorithm identifier, + * or PSA_ALG_NONE if not known. + */ +psa_algorithm_t mbedtls_hash_info_psa_from_md( mbedtls_md_type_t md_type ); + +/** Get the MD type alg from the PSA algorithm identifier. + * + * \param psa_alg The PSA hash algorithm. + * + * \return The corresponding MD type, + * or MBEDTLS_MD_NONE if not known. + */ +mbedtls_md_type_t mbedtls_hash_info_md_from_psa( psa_algorithm_t psa_alg ); + +#endif /* MBEDTLS_HASH_INFO_H */ diff --git a/library/md_internal.h b/library/md_internal.h deleted file mode 100644 index 1f216437c..000000000 --- a/library/md_internal.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Internal MD/hash functions - no crypto, just data. - * This is used to avoid depending on MD_C just to query a length. - * - * 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 MBEDTLS_MD_INTERNAL_H -#define MBEDTLS_MD_INTERNAL_H - -#include "common.h" - -#include "mbedtls/md.h" -#include "or_psa_helpers.h" - -/** Get the output length of the given hash type - * - * \param md_type The hash type. - * - * \return The output length in bytes, or 0 if not known - */ -static inline unsigned char mbedtls_md_internal_get_size( mbedtls_md_type_t md_type ) -{ - switch( md_type ) - { -#if defined(MBEDTLS_OR_PSA_WANT_ALG_MD5) - case MBEDTLS_MD_MD5: - return( 16 ); -#endif -#if defined(MBEDTLS_OR_PSA_WANT_ALG_RIPEMD160) || \ - defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_1) - case MBEDTLS_MD_RIPEMD160: - case MBEDTLS_MD_SHA1: - return( 20 ); -#endif -#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_224) - case MBEDTLS_MD_SHA224: - return( 28 ); -#endif -#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_256) - case MBEDTLS_MD_SHA256: - return( 32 ); -#endif -#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_384) - case MBEDTLS_MD_SHA384: - return( 48 ); -#endif -#if defined(MBEDTLS_OR_PSA_WANT_ALG_SHA_512) - case MBEDTLS_MD_SHA512: - return( 64 ); -#endif - default: - return( 0 ); - } -} - -#endif /* MBEDTLS_MD_INTERNAL_H */ diff --git a/library/pk.c b/library/pk.c index 462807c82..f2c1ad551 100644 --- a/library/pk.c +++ b/library/pk.c @@ -24,7 +24,7 @@ #include "pk_wrap.h" #include "pkwrite.h" -#include "md_internal.h" +#include "hash_info.h" #include "mbedtls/platform_util.h" #include "mbedtls/error.h" @@ -363,7 +363,7 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len if( *hash_len != 0 ) return( 0 ); - *hash_len = mbedtls_md_internal_get_size( md_alg ); + *hash_len = mbedtls_hash_info_get_size( md_alg ); if( *hash_len == 0 ) return( -1 ); diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index f4d3f9c92..4a3944e18 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -41,7 +41,7 @@ #include #include #include "pk_wrap.h" -#include "md_internal.h" +#include "hash_info.h" #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \ defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \ @@ -366,7 +366,7 @@ static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg, { if( *md_alg == MBEDTLS_MD_NONE ) return( PSA_ERROR_NOT_SUPPORTED ); - if( mbedtls_md_internal_get_size( *md_alg ) != hash_length ) + if( mbedtls_hash_info_get_size( *md_alg ) != hash_length ) return( PSA_ERROR_INVALID_ARGUMENT ); } diff --git a/library/rsa.c b/library/rsa.c index 462cff6ee..17a7d9e7c 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -46,7 +46,7 @@ #include "mbedtls/error.h" #include "constant_time_internal.h" #include "mbedtls/constant_time.h" -#include "md_internal.h" +#include "hash_info.h" #include @@ -1736,7 +1736,7 @@ static int rsa_rsassa_pkcs1_v15_encode( mbedtls_md_type_t md_alg, /* Are we signing hashed or raw data? */ if( md_alg != MBEDTLS_MD_NONE ) { - unsigned char md_size = mbedtls_md_internal_get_size( md_alg ); + unsigned char md_size = mbedtls_hash_info_get_size( md_alg ); if( md_size == 0 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index 1899b269c..ca471f103 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -7,7 +7,7 @@ #include "mbedtls/ecp.h" #include "mbedtls/rsa.h" -#include "md_internal.h" +#include "hash_info.h" #include "use_psa_helpers.h" #include @@ -1277,7 +1277,7 @@ void pk_psa_sign_ext( int pk_type, int parameter, int key_pk_type, int md_alg ) size_t sig_len; unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; unsigned char hash[PSA_HASH_MAX_SIZE]; - size_t hash_len = mbedtls_md_internal_get_size( md_alg ); + size_t hash_len = mbedtls_hash_info_get_size( md_alg ); void const *options = NULL; mbedtls_pk_rsassa_pss_options rsassa_pss_options; memset( hash, 0x2a, sizeof( hash ) );