mbedtls/library/md.c

731 lines
18 KiB
C
Raw Normal View History

/**
* \file mbedtls_md.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
2015-07-27 09:11:48 +00:00
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
2015-09-04 12:21:07 +00:00
* SPDX-License-Identifier: Apache-2.0
*
2015-09-04 12:21:07 +00:00
* 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
*
2015-09-04 12:21:07 +00:00
* http://www.apache.org/licenses/LICENSE-2.0
*
2015-09-04 12:21:07 +00:00
* 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.
*
2015-09-04 12:21:07 +00:00
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
2015-03-09 17:05:11 +00:00
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_MD_C)
2015-03-09 17:05:11 +00:00
#include "mbedtls/md.h"
#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_PLATFORM_C)
2015-03-25 10:49:07 +00:00
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
2015-03-25 10:49:07 +00:00
#endif
#include <string.h>
2015-05-28 12:44:00 +00:00
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
2019-07-26 13:38:44 +00:00
/*
*
* Definitions of MD information structures for various digests.
*
*/
/*
* MD-2
*/
#if defined(MBEDTLS_MD2_C)
static const mbedtls_md_info_t mbedtls_md2_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_MD2,
"MD2",
16,
16,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md2_starts_wrap,
mbedtls_md2_update_wrap,
mbedtls_md2_finish_wrap,
2019-07-26 13:38:44 +00:00
mbedtls_md2_ret,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md2_ctx_alloc,
mbedtls_md2_ctx_free,
mbedtls_md2_clone_wrap,
mbedtls_md2_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_MD2_C */
/*
* MD-4
*/
#if defined(MBEDTLS_MD4_C)
static const mbedtls_md_info_t mbedtls_md4_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_MD4,
"MD4",
16,
64,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md4_starts_wrap,
mbedtls_md4_update_wrap,
mbedtls_md4_finish_wrap,
2019-07-26 13:38:44 +00:00
mbedtls_md4_ret,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md4_ctx_alloc,
mbedtls_md4_ctx_free,
mbedtls_md4_clone_wrap,
mbedtls_md4_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_MD4_C */
/*
* MD-5
*/
#if defined(MBEDTLS_MD5_C)
static const mbedtls_md_info_t mbedtls_md5_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_MD5,
"MD5",
16,
64,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md5_starts_wrap,
mbedtls_md5_update_wrap,
mbedtls_md5_finish_wrap,
2019-07-26 13:38:44 +00:00
mbedtls_md5_ret,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_md5_ctx_alloc,
mbedtls_md5_ctx_free,
mbedtls_md5_clone_wrap,
mbedtls_md5_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_MD5_C */
/*
* RIPEMD-160
*/
#if defined(MBEDTLS_RIPEMD160_C)
static const mbedtls_md_info_t mbedtls_ripemd160_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_RIPEMD160,
"RIPEMD160",
20,
64,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_ripemd160_starts_wrap,
mbedtls_ripemd160_update_wrap,
mbedtls_ripemd160_finish_wrap,
2019-07-26 13:38:44 +00:00
mbedtls_ripemd160_ret,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_ripemd160_ctx_alloc,
mbedtls_ripemd160_ctx_free,
mbedtls_ripemd160_clone_wrap,
mbedtls_ripemd160_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_RIPEMD160_C */
/*
* SHA-1
*/
#if defined(MBEDTLS_SHA1_C)
static const mbedtls_md_info_t mbedtls_sha1_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_SHA1,
"SHA1",
20,
64,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_sha1_starts_wrap,
mbedtls_sha1_update_wrap,
mbedtls_sha1_finish_wrap,
2019-07-26 13:38:44 +00:00
mbedtls_sha1_ret,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_sha1_ctx_alloc,
mbedtls_sha1_ctx_free,
mbedtls_sha1_clone_wrap,
mbedtls_sha1_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_SHA1_C */
/*
* SHA-224 and SHA-256
*/
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
static const mbedtls_md_info_t mbedtls_sha224_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_SHA224,
"SHA224",
28,
64,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_sha224_starts_wrap,
mbedtls_sha224_update_wrap,
mbedtls_sha224_finish_wrap,
mbedtls_sha224_wrap,
mbedtls_sha224_ctx_alloc,
mbedtls_sha224_ctx_free,
mbedtls_sha224_clone_wrap,
mbedtls_sha224_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* !MBEDTLS_SHA256_NO_SHA224 */
static const mbedtls_md_info_t mbedtls_sha256_info =
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_INFO( MBEDTLS_MD_INFO_SHA256 );
#endif /* MBEDTLS_SHA256_C */
/*
* SHA-384 and SHA-512
*/
#if defined(MBEDTLS_SHA512_C)
static const mbedtls_md_info_t mbedtls_sha384_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_SHA384,
"SHA384",
48,
128,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_sha384_starts_wrap,
mbedtls_sha384_update_wrap,
mbedtls_sha384_finish_wrap,
mbedtls_sha384_wrap,
mbedtls_sha384_ctx_alloc,
mbedtls_sha384_ctx_free,
mbedtls_sha384_clone_wrap,
mbedtls_sha384_process_wrap,
2019-07-26 13:38:44 +00:00
};
static const mbedtls_md_info_t mbedtls_sha512_info = {
2019-07-26 13:38:44 +00:00
MBEDTLS_MD_SHA512,
"SHA512",
64,
128,
Introduce md_internal.h Recall that in the default configuration, Mbed TLS provides access digest implementations through two layers of indirection: 1) Call of MD API (e.g. mbedtls_md_update()) 2) Call of function pointer from MD info structure 3) Actual digest implementation (e.g. mbedtls_sha256_update()). Ideally, if only a single digest is enabled - say SHA-256 - then calling mbedtls_md_update() should _directly_ jump to mbedtls_sha256_update(), with both layers of indirection removed. So far, however, setting MBEDTLS_MD_SINGLE_HASH will only remove the second - function pointer - layer of indirection, while keeping the non-inlined stub implementations of e.g. mbedtls_md_update() around. This commit is a step towards allowing to define implementations of the MD API as `static inline` in case we know that they are so small that they should be defined in md.h and not in md.c. In a nutshell, the approach is as follows: For an MD API function mbedtls_md_xxx() that should be inlin-able, introduce its implementation as a `static inline` wrapper `mbedtls_md_xxx_internal()` in md.h, and then define mbedtls_md_xxx() either in md.h or in md.c, by just calling mbedtls_md_xxx_internal(). Moving the implementations of those MD API functions that should be inlinable to md.h requires the presence of both the MD info struct and all specific digest wrapper functions in md.h, and this is what this commit ensures, by moving them from md.c into a new internal header file md_internal.h. Implementing the aforementioned wrappers for those MD API that should be inlinable is left for subsequent commits.
2019-09-04 11:43:22 +00:00
mbedtls_sha512_starts_wrap,
mbedtls_sha384_update_wrap,
mbedtls_sha384_finish_wrap,
mbedtls_sha512_wrap,
mbedtls_sha384_ctx_alloc,
mbedtls_sha384_ctx_free,
mbedtls_sha384_clone_wrap,
mbedtls_sha384_process_wrap,
2019-07-26 13:38:44 +00:00
};
#endif /* MBEDTLS_SHA512_C */
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
*/
static const int supported_digests[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
MBEDTLS_MD_SHA384,
#endif
#if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256,
#if !defined(MBEDTLS_SHA256_NO_SHA224)
MBEDTLS_MD_SHA224,
#endif
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA1_C)
MBEDTLS_MD_SHA1,
#endif
#if defined(MBEDTLS_RIPEMD160_C)
MBEDTLS_MD_RIPEMD160,
2014-01-17 19:41:32 +00:00
#endif
#if defined(MBEDTLS_MD5_C)
MBEDTLS_MD_MD5,
#endif
#if defined(MBEDTLS_MD4_C)
MBEDTLS_MD_MD4,
#endif
#if defined(MBEDTLS_MD2_C)
MBEDTLS_MD_MD2,
#endif
MBEDTLS_MD_NONE
};
const int *mbedtls_md_list( void )
{
2014-06-17 12:06:49 +00:00
return( supported_digests );
}
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
{
if( NULL == md_name )
2014-06-17 12:06:49 +00:00
return( NULL );
/* Get the appropriate digest information */
#if defined(MBEDTLS_MD2_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "MD2", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
#endif
#if defined(MBEDTLS_MD4_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "MD4", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
#endif
#if defined(MBEDTLS_MD5_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "MD5", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
#endif
#if defined(MBEDTLS_RIPEMD160_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "RIPEMD160", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
2014-01-17 19:41:32 +00:00
#endif
#if defined(MBEDTLS_SHA1_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
#endif
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
2015-05-28 15:06:07 +00:00
if( !strcmp( "SHA224", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
#endif
2015-05-28 15:06:07 +00:00
if( !strcmp( "SHA256", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
2015-05-28 15:06:07 +00:00
if( !strcmp( "SHA384", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
2015-05-28 15:06:07 +00:00
if( !strcmp( "SHA512", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
#endif
2014-06-17 12:06:49 +00:00
return( NULL );
}
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{
switch( md_type )
{
#if defined(MBEDTLS_MD2_C)
case MBEDTLS_MD_MD2:
return( &mbedtls_md2_info );
#endif
#if defined(MBEDTLS_MD4_C)
case MBEDTLS_MD_MD4:
return( &mbedtls_md4_info );
#endif
#if defined(MBEDTLS_MD5_C)
case MBEDTLS_MD_MD5:
return( &mbedtls_md5_info );
#endif
#if defined(MBEDTLS_RIPEMD160_C)
case MBEDTLS_MD_RIPEMD160:
return( &mbedtls_ripemd160_info );
2014-01-17 19:41:32 +00:00
#endif
#if defined(MBEDTLS_SHA1_C)
case MBEDTLS_MD_SHA1:
return( &mbedtls_sha1_info );
#endif
#if defined(MBEDTLS_SHA256_C)
#if !defined(MBEDTLS_SHA256_NO_SHA224)
case MBEDTLS_MD_SHA224:
return( &mbedtls_sha224_info );
#endif
case MBEDTLS_MD_SHA256:
return( &mbedtls_sha256_info );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA384:
return( &mbedtls_sha384_info );
case MBEDTLS_MD_SHA512:
return( &mbedtls_sha512_info );
#endif
default:
2014-06-17 12:06:49 +00:00
return( NULL );
}
}
#else /* MBEDTLS_MD_SINGLE_HASH */
const int *mbedtls_md_list( void )
{
static int single_hash[2] =
{ MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH ),
MBEDTLS_MD_INVALID_HANDLE };
return( single_hash );
}
mbedtls_md_handle_t mbedtls_md_info_from_string( const char *md_name )
{
static const char * const hash_name =
MBEDTLS_MD_INFO_NAME( MBEDTLS_MD_SINGLE_HASH );
if( md_name != NULL && strcmp( hash_name, md_name ) == 0 )
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
return( MBEDTLS_MD_INVALID_HANDLE );
}
mbedtls_md_handle_t mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
{
static const mbedtls_md_type_t hash_type =
MBEDTLS_MD_INFO_TYPE( MBEDTLS_MD_SINGLE_HASH );
if( hash_type == md_type )
return( MBEDTLS_MD_UNIQUE_VALID_HANDLE );
return( MBEDTLS_MD_INVALID_HANDLE );
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
void mbedtls_md_init( mbedtls_md_context_t *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
#if defined(MBEDTLS_MD_SINGLE_HASH)
mbedtls_md_info_init( mbedtls_md_get_handle( ctx ),
ctx->md_ctx );
#endif
}
void mbedtls_md_free( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || mbedtls_md_get_handle( ctx ) == MBEDTLS_MD_INVALID_HANDLE )
return;
#if !defined(MBEDTLS_MD_SINGLE_HASH)
2015-03-25 10:49:07 +00:00
if( ctx->md_ctx != NULL )
{
mbedtls_md_info_ctx_free( mbedtls_md_get_handle( ctx ), ctx->md_ctx );
}
2015-03-25 10:49:07 +00:00
if( ctx->hmac_ctx != NULL )
{
mbedtls_platform_zeroize( ctx->hmac_ctx,
2 * mbedtls_md_info_block_size( mbedtls_md_get_handle( ctx ) ) );
mbedtls_free( ctx->hmac_ctx );
2015-03-25 10:49:07 +00:00
}
#endif /* MBEDTLS_MD_SINGLE_HASH */
2015-03-25 10:49:07 +00:00
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
}
2015-07-06 14:06:02 +00:00
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src )
{
if( dst == NULL || mbedtls_md_get_handle( dst ) == MBEDTLS_MD_INVALID_HANDLE ||
src == NULL || mbedtls_md_get_handle( src ) == MBEDTLS_MD_INVALID_HANDLE ||
mbedtls_md_get_handle( dst ) != mbedtls_md_get_handle( src ) )
2015-07-06 14:06:02 +00:00
{
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
mbedtls_md_info_clone( mbedtls_md_get_handle( dst ),
dst->md_ctx, src->md_ctx );
2015-07-06 14:06:02 +00:00
return( 0 );
}
#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info )
{
return mbedtls_md_setup( ctx, md_info, 1 );
}
#endif
#if !defined(MBEDTLS_MD_SINGLE_HASH)
int mbedtls_md_setup( mbedtls_md_context_t *ctx, mbedtls_md_handle_t md_info, int hmac )
{
return( mbedtls_md_setup_internal( ctx, md_info, hmac ) );
}
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
return( mbedtls_md_starts_internal( ctx ) );
}
int mbedtls_md_update( mbedtls_md_context_t *ctx,
const unsigned char *input,
size_t ilen )
{
return( mbedtls_md_update_internal( ctx, input, ilen ) );
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
return( mbedtls_md_finish_internal( ctx, output ) );
}
int mbedtls_md( mbedtls_md_handle_t md_info, const unsigned char *input, size_t ilen,
unsigned char *output )
{
return( mbedtls_md_internal( md_info, input, ilen, output ) );
}
#endif /* !MBEDTLS_MD_SINGLE_HASH */
2015-05-28 12:44:00 +00:00
#if defined(MBEDTLS_FS_IO)
int mbedtls_md_file( mbedtls_md_handle_t md_info, const char *path, unsigned char *output )
{
int ret;
2015-05-28 12:44:00 +00:00
FILE *f;
size_t n;
mbedtls_md_context_t ctx;
unsigned char buf[1024];
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
2015-05-28 12:44:00 +00:00
if( ( f = fopen( path, "rb" ) ) == NULL )
return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
mbedtls_md_init( &ctx );
2015-05-28 12:44:00 +00:00
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
ret = mbedtls_md_info_starts( md_info, ctx.md_ctx );
if( ret != 0 )
goto cleanup;
2015-05-28 12:44:00 +00:00
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
{
ret = mbedtls_md_info_update( md_info, ctx.md_ctx,
buf, n );
if( ret != 0 )
goto cleanup;
}
2015-05-28 12:44:00 +00:00
if( ferror( f ) != 0 )
{
2015-05-28 12:44:00 +00:00
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
}
else
{
ret = mbedtls_md_info_finish( md_info, ctx.md_ctx,
output );
}
2015-05-28 12:44:00 +00:00
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
2015-05-28 12:44:00 +00:00
fclose( f );
mbedtls_md_free( &ctx );
return( ret );
}
2015-05-28 12:44:00 +00:00
#endif /* MBEDTLS_FS_IO */
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{
int ret;
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
2015-03-25 10:49:07 +00:00
unsigned char *ipad, *opad;
2015-03-24 15:48:22 +00:00
size_t i;
mbedtls_md_handle_t md_info;
if( ctx == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
if( keylen > (size_t) mbedtls_md_info_block_size( md_info ) )
2015-03-24 15:48:22 +00:00
{
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx,
key, keylen ) ) != 0 )
{
goto cleanup;
}
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, sum ) ) != 0 )
goto cleanup;
2015-03-24 15:48:22 +00:00
keylen = mbedtls_md_info_size( md_info );
2015-03-24 15:48:22 +00:00
key = sum;
}
2015-03-25 10:49:07 +00:00
ipad = (unsigned char *) ctx->hmac_ctx;
opad = (unsigned char *) ctx->hmac_ctx +
mbedtls_md_info_block_size( md_info );
2015-03-25 10:49:07 +00:00
memset( ipad, 0x36, mbedtls_md_info_block_size( md_info ) );
memset( opad, 0x5C, mbedtls_md_info_block_size( md_info ) );
2015-03-24 15:48:22 +00:00
for( i = 0; i < keylen; i++ )
{
2015-03-25 10:49:07 +00:00
ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
opad[i] = (unsigned char)( opad[i] ^ key[i] );
2015-03-24 15:48:22 +00:00
}
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, ipad,
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
{
2017-07-20 15:27:03 +00:00
goto cleanup;
}
2015-03-24 15:48:22 +00:00
cleanup:
mbedtls_platform_zeroize( sum, sizeof( sum ) );
return( ret );
}
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx,
const unsigned char *input, size_t ilen )
{
mbedtls_md_handle_t md_info;
if( ctx == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
return( mbedtls_md_info_update( md_info,
ctx->md_ctx, input,
ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
int ret;
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
2015-03-25 10:49:07 +00:00
unsigned char *opad;
2015-03-24 15:48:22 +00:00
mbedtls_md_handle_t md_info;
if( ctx == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
opad = (unsigned char *) ctx->hmac_ctx +
mbedtls_md_info_block_size( md_info );
2015-03-25 10:49:07 +00:00
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, tmp ) ) != 0 )
return( ret );
if( ( ret = mbedtls_md_info_starts( md_info, ctx->md_ctx ) ) != 0 )
return( ret );
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, opad,
mbedtls_md_info_block_size( md_info ) ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_md_info_update( md_info, ctx->md_ctx, tmp,
mbedtls_md_info_size( md_info ) ) ) != 0 )
{
return( ret );
}
if( ( ret = mbedtls_md_info_finish( md_info, ctx->md_ctx, output ) ) != 0 )
return( ret );
return( 0 );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{
int ret;
2015-03-25 10:49:07 +00:00
unsigned char *ipad;
mbedtls_md_handle_t md_info;
if( ctx == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
md_info = mbedtls_md_get_handle( ctx );
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
2015-03-25 10:49:07 +00:00
ipad = (unsigned char *) ctx->hmac_ctx;
ret = mbedtls_md_info_starts( md_info, ctx->md_ctx );
if( ret != 0 )
return( ret );
ret = mbedtls_md_info_update( md_info,
ctx->md_ctx, ipad,
mbedtls_md_info_block_size( md_info ) );
return( ret );
}
int mbedtls_md_hmac( mbedtls_md_handle_t md_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output )
{
mbedtls_md_context_t ctx;
2015-03-24 15:48:22 +00:00
int ret;
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
mbedtls_md_init( &ctx );
2015-03-24 15:48:22 +00:00
if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
goto cleanup;
2015-03-24 15:48:22 +00:00
if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
goto cleanup;
2015-03-24 15:48:22 +00:00
cleanup:
mbedtls_md_free( &ctx );
return( ret );
}
#if !defined(MBEDTLS_MD_SINGLE_HASH)
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
{
return( mbedtls_md_process_internal( ctx, data ) );
}
#endif /* !MBEDTLS_MD_SINGLE_HASH */
unsigned char mbedtls_md_get_size( mbedtls_md_handle_t md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( 0 );
return mbedtls_md_info_size( md_info );
}
mbedtls_md_type_t mbedtls_md_get_type( mbedtls_md_handle_t md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( MBEDTLS_MD_NONE );
return mbedtls_md_info_type( md_info );
}
const char *mbedtls_md_get_name( mbedtls_md_handle_t md_info )
{
if( md_info == MBEDTLS_MD_INVALID_HANDLE )
return( NULL );
return mbedtls_md_info_name( md_info );
}
#endif /* MBEDTLS_MD_C */