blob: a22878965383fdbdc4a02cb152d7a7858bddecbb [file] [log] [blame]
Paul Bakker17373852011-01-06 14:20:01 +00001/**
Gilles Peskine2091f3a2021-02-12 23:34:01 +01002 * \file md.c
Paul Bakker9af723c2014-05-01 13:03:14 +02003 *
Manuel Pégourié-Gonnardb4fe3cb2015-01-22 16:11:05 +00004 * \brief Generic message digest wrapper for mbed TLS
Paul Bakker17373852011-01-06 14:20:01 +00005 *
6 * \author Adriaan de Jong <dejong@fox-it.com>
7 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02008 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02009 * SPDX-License-Identifier: Apache-2.0
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
Paul Bakker17373852011-01-06 14:20:01 +000022 */
23
Gilles Peskinedb09ef62020-06-03 01:43:33 +020024#include "common.h"
Paul Bakker17373852011-01-06 14:20:01 +000025
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if defined(MBEDTLS_MD_C)
Paul Bakker17373852011-01-06 14:20:01 +000027
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/md.h"
Chris Jonesdaacb592021-03-09 17:03:29 +000029#include "md_wrap.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000031#include "mbedtls/error.h"
Paul Bakker17373852011-01-06 14:20:01 +000032
Gilles Peskine84867cf2019-07-19 15:46:03 +020033#include "mbedtls/md5.h"
34#include "mbedtls/ripemd160.h"
35#include "mbedtls/sha1.h"
36#include "mbedtls/sha256.h"
37#include "mbedtls/sha512.h"
38
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010040#include "mbedtls/platform.h"
41#else
Paul Bakker17373852011-01-06 14:20:01 +000042#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020043#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#define mbedtls_free free
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010045#endif
46
Rich Evans00ab4702015-02-06 13:43:58 +000047#include <string.h>
Paul Bakker17373852011-01-06 14:20:01 +000048
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +020049#if defined(MBEDTLS_FS_IO)
50#include <stdio.h>
Paul Bakkeraf5c85f2011-04-18 03:47:52 +000051#endif
52
Gilles Peskine84867cf2019-07-19 15:46:03 +020053#if defined(MBEDTLS_MD5_C)
54const mbedtls_md_info_t mbedtls_md5_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020055 "MD5",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020056 MBEDTLS_MD_MD5,
Gilles Peskine84867cf2019-07-19 15:46:03 +020057 16,
58 64,
59};
60#endif
61
62#if defined(MBEDTLS_RIPEMD160_C)
63const mbedtls_md_info_t mbedtls_ripemd160_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020064 "RIPEMD160",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020065 MBEDTLS_MD_RIPEMD160,
Gilles Peskine84867cf2019-07-19 15:46:03 +020066 20,
67 64,
68};
69#endif
70
71#if defined(MBEDTLS_SHA1_C)
72const mbedtls_md_info_t mbedtls_sha1_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020073 "SHA1",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020074 MBEDTLS_MD_SHA1,
Gilles Peskine84867cf2019-07-19 15:46:03 +020075 20,
76 64,
77};
78#endif
79
Mateusz Starzyke3c48b42021-04-19 16:46:28 +020080#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +020081const mbedtls_md_info_t mbedtls_sha224_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020082 "SHA224",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020083 MBEDTLS_MD_SHA224,
Gilles Peskine84867cf2019-07-19 15:46:03 +020084 28,
85 64,
86};
Mateusz Starzyke3c48b42021-04-19 16:46:28 +020087#endif
Gilles Peskine84867cf2019-07-19 15:46:03 +020088
Mateusz Starzyke3c48b42021-04-19 16:46:28 +020089#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +020090const mbedtls_md_info_t mbedtls_sha256_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020091 "SHA256",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020092 MBEDTLS_MD_SHA256,
Gilles Peskine84867cf2019-07-19 15:46:03 +020093 32,
94 64,
95};
96#endif
97
Mateusz Starzyk3352a532021-04-06 14:28:22 +020098#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +020099const mbedtls_md_info_t mbedtls_sha384_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200100 "SHA384",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200101 MBEDTLS_MD_SHA384,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200102 48,
103 128,
104};
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200105#endif
Gilles Peskine84867cf2019-07-19 15:46:03 +0200106
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200107#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200108const mbedtls_md_info_t mbedtls_sha512_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200109 "SHA512",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200110 MBEDTLS_MD_SHA512,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200111 64,
112 128,
113};
114#endif
115
Manuel Pégourié-Gonnard88db5da2015-06-15 14:34:59 +0200116/*
Gilles Peskine3a671502020-02-26 19:52:06 +0100117 * Reminder: update profiles in x509_crt.c when adding a new hash!
Manuel Pégourié-Gonnard88db5da2015-06-15 14:34:59 +0200118 */
Paul Bakker72f62662011-01-16 21:27:44 +0000119static const int supported_digests[] = {
120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121#if defined(MBEDTLS_SHA512_C)
122 MBEDTLS_MD_SHA512,
Paul Bakker72f62662011-01-16 21:27:44 +0000123#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200124
125#if defined(MBEDTLS_SHA384_C)
126 MBEDTLS_MD_SHA384,
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200127#endif
Paul Bakker72f62662011-01-16 21:27:44 +0000128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129#if defined(MBEDTLS_SHA256_C)
130 MBEDTLS_MD_SHA256,
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200131#endif
132#if defined(MBEDTLS_SHA224_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 MBEDTLS_MD_SHA224,
Paul Bakker72f62662011-01-16 21:27:44 +0000134#endif
135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136#if defined(MBEDTLS_SHA1_C)
137 MBEDTLS_MD_SHA1,
Paul Bakker72f62662011-01-16 21:27:44 +0000138#endif
139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140#if defined(MBEDTLS_RIPEMD160_C)
141 MBEDTLS_MD_RIPEMD160,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200142#endif
143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144#if defined(MBEDTLS_MD5_C)
145 MBEDTLS_MD_MD5,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200146#endif
147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 MBEDTLS_MD_NONE
Paul Bakker72f62662011-01-16 21:27:44 +0000149};
150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151const int *mbedtls_md_list( void )
Paul Bakker72f62662011-01-16 21:27:44 +0000152{
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200153 return( supported_digests );
Paul Bakker72f62662011-01-16 21:27:44 +0000154}
155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
Paul Bakker17373852011-01-06 14:20:01 +0000157{
158 if( NULL == md_name )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200159 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000160
161 /* Get the appropriate digest information */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162#if defined(MBEDTLS_MD5_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200163 if( !strcmp( "MD5", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
Paul Bakker17373852011-01-06 14:20:01 +0000165#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200167 if( !strcmp( "RIPEMD160", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100169#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170#if defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200171 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Paul Bakker17373852011-01-06 14:20:01 +0000173#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200174#if defined(MBEDTLS_SHA224_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200175 if( !strcmp( "SHA224", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200177#endif
178#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200179 if( !strcmp( "SHA256", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
Paul Bakker17373852011-01-06 14:20:01 +0000181#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200182#if defined(MBEDTLS_SHA384_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200183 if( !strcmp( "SHA384", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200185#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200186#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200187 if( !strcmp( "SHA512", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
Paul Bakker17373852011-01-06 14:20:01 +0000189#endif
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200190 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000191}
192
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
Paul Bakker17373852011-01-06 14:20:01 +0000194{
195 switch( md_type )
196 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197#if defined(MBEDTLS_MD5_C)
198 case MBEDTLS_MD_MD5:
199 return( &mbedtls_md5_info );
Paul Bakker17373852011-01-06 14:20:01 +0000200#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201#if defined(MBEDTLS_RIPEMD160_C)
202 case MBEDTLS_MD_RIPEMD160:
203 return( &mbedtls_ripemd160_info );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100204#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205#if defined(MBEDTLS_SHA1_C)
206 case MBEDTLS_MD_SHA1:
207 return( &mbedtls_sha1_info );
Paul Bakker17373852011-01-06 14:20:01 +0000208#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200209#if defined(MBEDTLS_SHA224_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 case MBEDTLS_MD_SHA224:
211 return( &mbedtls_sha224_info );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200212#endif
213#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 case MBEDTLS_MD_SHA256:
215 return( &mbedtls_sha256_info );
Paul Bakker17373852011-01-06 14:20:01 +0000216#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200217#if defined(MBEDTLS_SHA384_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218 case MBEDTLS_MD_SHA384:
219 return( &mbedtls_sha384_info );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200220#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200221#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222 case MBEDTLS_MD_SHA512:
223 return( &mbedtls_sha512_info );
Paul Bakker17373852011-01-06 14:20:01 +0000224#endif
225 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200226 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000227 }
228}
229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230void mbedtls_md_init( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200231{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200233}
234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235void mbedtls_md_free( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200236{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100237 if( ctx == NULL || ctx->md_info == NULL )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200238 return;
239
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100240 if( ctx->md_ctx != NULL )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200241 {
242 switch( ctx->md_info->type )
243 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200244#if defined(MBEDTLS_MD5_C)
245 case MBEDTLS_MD_MD5:
246 mbedtls_md5_free( ctx->md_ctx );
247 break;
248#endif
249#if defined(MBEDTLS_RIPEMD160_C)
250 case MBEDTLS_MD_RIPEMD160:
251 mbedtls_ripemd160_free( ctx->md_ctx );
252 break;
253#endif
254#if defined(MBEDTLS_SHA1_C)
255 case MBEDTLS_MD_SHA1:
256 mbedtls_sha1_free( ctx->md_ctx );
257 break;
258#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200259#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200260 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200261 mbedtls_sha256_free( ctx->md_ctx );
262 break;
263#endif
264#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200265 case MBEDTLS_MD_SHA256:
266 mbedtls_sha256_free( ctx->md_ctx );
267 break;
268#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200269#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200270 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200271 mbedtls_sha512_free( ctx->md_ctx );
272 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200273#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200274#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200275 case MBEDTLS_MD_SHA512:
276 mbedtls_sha512_free( ctx->md_ctx );
277 break;
278#endif
279 default:
280 /* Shouldn't happen */
281 break;
282 }
283 mbedtls_free( ctx->md_ctx );
284 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200285
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100286 if( ctx->hmac_ctx != NULL )
287 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500288 mbedtls_platform_zeroize( ctx->hmac_ctx,
289 2 * ctx->md_info->block_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290 mbedtls_free( ctx->hmac_ctx );
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100291 }
292
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500293 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200294}
295
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200296int mbedtls_md_clone( mbedtls_md_context_t *dst,
297 const mbedtls_md_context_t *src )
298{
299 if( dst == NULL || dst->md_info == NULL ||
300 src == NULL || src->md_info == NULL ||
301 dst->md_info != src->md_info )
302 {
303 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
304 }
305
Gilles Peskine84867cf2019-07-19 15:46:03 +0200306 switch( src->md_info->type )
307 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200308#if defined(MBEDTLS_MD5_C)
309 case MBEDTLS_MD_MD5:
310 mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
311 break;
312#endif
313#if defined(MBEDTLS_RIPEMD160_C)
314 case MBEDTLS_MD_RIPEMD160:
315 mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
316 break;
317#endif
318#if defined(MBEDTLS_SHA1_C)
319 case MBEDTLS_MD_SHA1:
320 mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
321 break;
322#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200323#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200324 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200325 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
326 break;
327#endif
328#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200329 case MBEDTLS_MD_SHA256:
330 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
331 break;
332#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200333#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200334 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200335 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
336 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200337#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200338#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200339 case MBEDTLS_MD_SHA512:
340 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
341 break;
342#endif
343 default:
344 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
345 }
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200346
347 return( 0 );
348}
349
Gilles Peskine84867cf2019-07-19 15:46:03 +0200350#define ALLOC( type ) \
351 do { \
352 ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
353 if( ctx->md_ctx == NULL ) \
354 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
355 mbedtls_##type##_init( ctx->md_ctx ); \
356 } \
357 while( 0 )
358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
Paul Bakker17373852011-01-06 14:20:01 +0000360{
Paul Bakker279432a2012-04-26 10:09:35 +0000361 if( md_info == NULL || ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000363
Gilles Peskined15c7402020-08-19 12:03:11 +0200364 ctx->md_info = md_info;
365 ctx->md_ctx = NULL;
366 ctx->hmac_ctx = NULL;
367
Gilles Peskine84867cf2019-07-19 15:46:03 +0200368 switch( md_info->type )
369 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200370#if defined(MBEDTLS_MD5_C)
371 case MBEDTLS_MD_MD5:
372 ALLOC( md5 );
373 break;
374#endif
375#if defined(MBEDTLS_RIPEMD160_C)
376 case MBEDTLS_MD_RIPEMD160:
377 ALLOC( ripemd160 );
378 break;
379#endif
380#if defined(MBEDTLS_SHA1_C)
381 case MBEDTLS_MD_SHA1:
382 ALLOC( sha1 );
383 break;
384#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200385#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200386 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200387 ALLOC( sha256 );
388 break;
389#endif
390#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200391 case MBEDTLS_MD_SHA256:
392 ALLOC( sha256 );
393 break;
394#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200395#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200396 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200397 ALLOC( sha512 );
398 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200399#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200400#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200401 case MBEDTLS_MD_SHA512:
402 ALLOC( sha512 );
403 break;
404#endif
405 default:
406 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
407 }
Paul Bakker17373852011-01-06 14:20:01 +0000408
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100409 if( hmac != 0 )
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100410 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200411 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100412 if( ctx->hmac_ctx == NULL )
413 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200414 mbedtls_md_free( ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100416 }
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100417 }
418
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200419 return( 0 );
Paul Bakker17373852011-01-06 14:20:01 +0000420}
Gilles Peskine84867cf2019-07-19 15:46:03 +0200421#undef ALLOC
Paul Bakker17373852011-01-06 14:20:01 +0000422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423int mbedtls_md_starts( mbedtls_md_context_t *ctx )
Paul Bakker562535d2011-01-20 16:42:01 +0000424{
425 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker562535d2011-01-20 16:42:01 +0000427
Gilles Peskine84867cf2019-07-19 15:46:03 +0200428 switch( ctx->md_info->type )
429 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200430#if defined(MBEDTLS_MD5_C)
431 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200432 return( mbedtls_md5_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200433#endif
434#if defined(MBEDTLS_RIPEMD160_C)
435 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200436 return( mbedtls_ripemd160_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200437#endif
438#if defined(MBEDTLS_SHA1_C)
439 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200440 return( mbedtls_sha1_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200441#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200442#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200443 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200444 return( mbedtls_sha256_starts( ctx->md_ctx, 1 ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200445#endif
446#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200447 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200448 return( mbedtls_sha256_starts( ctx->md_ctx, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200449#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200450#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200451 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200452 return( mbedtls_sha512_starts( ctx->md_ctx, 1 ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200453#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200454#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200455 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200456 return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200457#endif
458 default:
459 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
460 }
Paul Bakker562535d2011-01-20 16:42:01 +0000461}
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000464{
465 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000467
Gilles Peskine84867cf2019-07-19 15:46:03 +0200468 switch( ctx->md_info->type )
469 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200470#if defined(MBEDTLS_MD5_C)
471 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200472 return( mbedtls_md5_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200473#endif
474#if defined(MBEDTLS_RIPEMD160_C)
475 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200476 return( mbedtls_ripemd160_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200477#endif
478#if defined(MBEDTLS_SHA1_C)
479 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200480 return( mbedtls_sha1_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200481#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200482#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200483 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200484 return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200485#endif
486#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200487 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200488 return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200489#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200490#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200491 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200492 return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200493#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200494#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200495 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200496 return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200497#endif
498 default:
499 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
500 }
Paul Bakker17373852011-01-06 14:20:01 +0000501}
502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000504{
505 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000507
Gilles Peskine84867cf2019-07-19 15:46:03 +0200508 switch( ctx->md_info->type )
509 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200510#if defined(MBEDTLS_MD5_C)
511 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200512 return( mbedtls_md5_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200513#endif
514#if defined(MBEDTLS_RIPEMD160_C)
515 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200516 return( mbedtls_ripemd160_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200517#endif
518#if defined(MBEDTLS_SHA1_C)
519 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200520 return( mbedtls_sha1_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200521#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200522#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200523 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200524 return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200525#endif
526#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200527 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200528 return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200529#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200530#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200531 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200532 return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200533#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200534#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200535 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200536 return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200537#endif
538 default:
539 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
540 }
Paul Bakker17373852011-01-06 14:20:01 +0000541}
542
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
Paul Bakker17373852011-01-06 14:20:01 +0000544 unsigned char *output )
545{
Paul Bakker66d5d072014-06-17 16:39:18 +0200546 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000548
Gilles Peskine84867cf2019-07-19 15:46:03 +0200549 switch( md_info->type )
550 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200551#if defined(MBEDTLS_MD5_C)
552 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200553 return( mbedtls_md5( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200554#endif
555#if defined(MBEDTLS_RIPEMD160_C)
556 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200557 return( mbedtls_ripemd160( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200558#endif
559#if defined(MBEDTLS_SHA1_C)
560 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200561 return( mbedtls_sha1( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200562#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200563#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200564 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200565 return( mbedtls_sha256( input, ilen, output, 1 ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200566#endif
567#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200568 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200569 return( mbedtls_sha256( input, ilen, output, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200570#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200571#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200572 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200573 return( mbedtls_sha512( input, ilen, output, 1 ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200574#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200575#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200576 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200577 return( mbedtls_sha512( input, ilen, output, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200578#endif
579 default:
580 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
581 }
Paul Bakker17373852011-01-06 14:20:01 +0000582}
583
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200584#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000586{
Janos Follath24eed8d2019-11-22 13:21:35 +0000587 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200588 FILE *f;
589 size_t n;
590 mbedtls_md_context_t ctx;
591 unsigned char buf[1024];
Paul Bakker9c021ad2011-06-09 15:55:11 +0000592
Paul Bakker17373852011-01-06 14:20:01 +0000593 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000595
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200596 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnardbcc03082015-06-24 00:09:29 +0200597 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
598
599 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200600
601 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
602 goto cleanup;
603
Gilles Peskine84867cf2019-07-19 15:46:03 +0200604 if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100605 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200606
607 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200608 if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100609 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200610
611 if( ferror( f ) != 0 )
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200612 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
Andres Amaya Garciaeb132b62017-06-23 16:30:31 +0100613 else
Gilles Peskine84867cf2019-07-19 15:46:03 +0200614 ret = mbedtls_md_finish( &ctx, output );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200615
616cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500617 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200618 fclose( f );
619 mbedtls_md_free( &ctx );
Paul Bakker9c021ad2011-06-09 15:55:11 +0000620
Paul Bakker8913f822012-01-14 18:07:41 +0000621 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000622}
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200623#endif /* MBEDTLS_FS_IO */
Paul Bakker17373852011-01-06 14:20:01 +0000624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
Paul Bakker17373852011-01-06 14:20:01 +0000626{
Janos Follath24eed8d2019-11-22 13:21:35 +0000627 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100629 unsigned char *ipad, *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100630 size_t i;
631
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100632 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000634
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100635 if( keylen > (size_t) ctx->md_info->block_size )
636 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200637 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100638 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200639 if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100640 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200641 if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100642 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100643
644 keylen = ctx->md_info->size;
645 key = sum;
646 }
647
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100648 ipad = (unsigned char *) ctx->hmac_ctx;
649 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
650
651 memset( ipad, 0x36, ctx->md_info->block_size );
652 memset( opad, 0x5C, ctx->md_info->block_size );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100653
654 for( i = 0; i < keylen; i++ )
655 {
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100656 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
657 opad[i] = (unsigned char)( opad[i] ^ key[i] );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100658 }
659
Gilles Peskine84867cf2019-07-19 15:46:03 +0200660 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100661 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200662 if( ( ret = mbedtls_md_update( ctx, ipad,
663 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia42e5e102017-07-20 16:27:03 +0100664 goto cleanup;
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100665
666cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500667 mbedtls_platform_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100668
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100669 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000670}
671
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000673{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100674 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000676
Gilles Peskine84867cf2019-07-19 15:46:03 +0200677 return( mbedtls_md_update( ctx, input, ilen ) );
Paul Bakker17373852011-01-06 14:20:01 +0000678}
679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000681{
Janos Follath24eed8d2019-11-22 13:21:35 +0000682 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100684 unsigned char *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100685
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100686 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000688
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100689 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
690
Gilles Peskine84867cf2019-07-19 15:46:03 +0200691 if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100692 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200693 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100694 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200695 if( ( ret = mbedtls_md_update( ctx, opad,
696 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100697 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200698 if( ( ret = mbedtls_md_update( ctx, tmp,
699 ctx->md_info->size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100700 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200701 return( mbedtls_md_finish( ctx, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000702}
703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
Paul Bakker17373852011-01-06 14:20:01 +0000705{
Janos Follath24eed8d2019-11-22 13:21:35 +0000706 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100707 unsigned char *ipad;
708
709 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000711
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100712 ipad = (unsigned char *) ctx->hmac_ctx;
713
Gilles Peskine84867cf2019-07-19 15:46:03 +0200714 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100715 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200716 return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
Paul Bakker17373852011-01-06 14:20:01 +0000717}
718
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100719int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
720 const unsigned char *key, size_t keylen,
721 const unsigned char *input, size_t ilen,
722 unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000723{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_md_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000725 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100726
Paul Bakker17373852011-01-06 14:20:01 +0000727 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000729
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100731
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100733 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100734
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100735 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
736 goto cleanup;
737 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
738 goto cleanup;
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100739 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
740 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100741
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100742cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 mbedtls_md_free( &ctx );
Paul Bakker17373852011-01-06 14:20:01 +0000744
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100745 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000746}
747
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200748int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100749{
750 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100752
Gilles Peskine84867cf2019-07-19 15:46:03 +0200753 switch( ctx->md_info->type )
754 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200755#if defined(MBEDTLS_MD5_C)
756 case MBEDTLS_MD_MD5:
757 return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
758#endif
759#if defined(MBEDTLS_RIPEMD160_C)
760 case MBEDTLS_MD_RIPEMD160:
761 return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
762#endif
763#if defined(MBEDTLS_SHA1_C)
764 case MBEDTLS_MD_SHA1:
765 return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
766#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200767#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200768 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200769 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
770#endif
771#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200772 case MBEDTLS_MD_SHA256:
773 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
774#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200775#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200776 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200777 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200778#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200779#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200780 case MBEDTLS_MD_SHA512:
781 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
782#endif
783 default:
784 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
785 }
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100786}
787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100789{
790 if( md_info == NULL )
791 return( 0 );
792
793 return md_info->size;
794}
795
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100797{
798 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 return( MBEDTLS_MD_NONE );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100800
801 return md_info->type;
802}
803
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100805{
806 if( md_info == NULL )
807 return( NULL );
808
809 return md_info->name;
810}
811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#endif /* MBEDTLS_MD_C */