blob: a387da50a97ed8c3c7e2555c6af19efbb09510cc [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
Max Fillinger0bb38332021-12-28 16:32:00 +0100230const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
231 const mbedtls_md_context_t *ctx )
232{
233 if( ctx == NULL )
234 return NULL;
235
236 return( ctx->MBEDTLS_PRIVATE(md_info) );
237}
238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239void mbedtls_md_init( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200242}
243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244void mbedtls_md_free( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200245{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100246 if( ctx == NULL || ctx->md_info == NULL )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200247 return;
248
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100249 if( ctx->md_ctx != NULL )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200250 {
251 switch( ctx->md_info->type )
252 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200253#if defined(MBEDTLS_MD5_C)
254 case MBEDTLS_MD_MD5:
255 mbedtls_md5_free( ctx->md_ctx );
256 break;
257#endif
258#if defined(MBEDTLS_RIPEMD160_C)
259 case MBEDTLS_MD_RIPEMD160:
260 mbedtls_ripemd160_free( ctx->md_ctx );
261 break;
262#endif
263#if defined(MBEDTLS_SHA1_C)
264 case MBEDTLS_MD_SHA1:
265 mbedtls_sha1_free( ctx->md_ctx );
266 break;
267#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200268#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200269 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200270 mbedtls_sha256_free( ctx->md_ctx );
271 break;
272#endif
273#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200274 case MBEDTLS_MD_SHA256:
275 mbedtls_sha256_free( ctx->md_ctx );
276 break;
277#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200278#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200279 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200280 mbedtls_sha512_free( ctx->md_ctx );
281 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200282#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200283#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200284 case MBEDTLS_MD_SHA512:
285 mbedtls_sha512_free( ctx->md_ctx );
286 break;
287#endif
288 default:
289 /* Shouldn't happen */
290 break;
291 }
292 mbedtls_free( ctx->md_ctx );
293 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200294
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100295 if( ctx->hmac_ctx != NULL )
296 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500297 mbedtls_platform_zeroize( ctx->hmac_ctx,
298 2 * ctx->md_info->block_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 mbedtls_free( ctx->hmac_ctx );
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100300 }
301
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500302 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200303}
304
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200305int mbedtls_md_clone( mbedtls_md_context_t *dst,
306 const mbedtls_md_context_t *src )
307{
308 if( dst == NULL || dst->md_info == NULL ||
309 src == NULL || src->md_info == NULL ||
310 dst->md_info != src->md_info )
311 {
312 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
313 }
314
Gilles Peskine84867cf2019-07-19 15:46:03 +0200315 switch( src->md_info->type )
316 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200317#if defined(MBEDTLS_MD5_C)
318 case MBEDTLS_MD_MD5:
319 mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
320 break;
321#endif
322#if defined(MBEDTLS_RIPEMD160_C)
323 case MBEDTLS_MD_RIPEMD160:
324 mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
325 break;
326#endif
327#if defined(MBEDTLS_SHA1_C)
328 case MBEDTLS_MD_SHA1:
329 mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
330 break;
331#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200332#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200333 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200334 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
335 break;
336#endif
337#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200338 case MBEDTLS_MD_SHA256:
339 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
340 break;
341#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200342#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200343 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200344 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
345 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200346#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200347#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200348 case MBEDTLS_MD_SHA512:
349 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
350 break;
351#endif
352 default:
353 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
354 }
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200355
356 return( 0 );
357}
358
Gilles Peskine84867cf2019-07-19 15:46:03 +0200359#define ALLOC( type ) \
360 do { \
361 ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
362 if( ctx->md_ctx == NULL ) \
363 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
364 mbedtls_##type##_init( ctx->md_ctx ); \
365 } \
366 while( 0 )
367
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
Paul Bakker17373852011-01-06 14:20:01 +0000369{
Paul Bakker279432a2012-04-26 10:09:35 +0000370 if( md_info == NULL || ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000372
Gilles Peskined15c7402020-08-19 12:03:11 +0200373 ctx->md_info = md_info;
374 ctx->md_ctx = NULL;
375 ctx->hmac_ctx = NULL;
376
Gilles Peskine84867cf2019-07-19 15:46:03 +0200377 switch( md_info->type )
378 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200379#if defined(MBEDTLS_MD5_C)
380 case MBEDTLS_MD_MD5:
381 ALLOC( md5 );
382 break;
383#endif
384#if defined(MBEDTLS_RIPEMD160_C)
385 case MBEDTLS_MD_RIPEMD160:
386 ALLOC( ripemd160 );
387 break;
388#endif
389#if defined(MBEDTLS_SHA1_C)
390 case MBEDTLS_MD_SHA1:
391 ALLOC( sha1 );
392 break;
393#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200394#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200395 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200396 ALLOC( sha256 );
397 break;
398#endif
399#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200400 case MBEDTLS_MD_SHA256:
401 ALLOC( sha256 );
402 break;
403#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200404#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200405 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200406 ALLOC( sha512 );
407 break;
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200408#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200409#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200410 case MBEDTLS_MD_SHA512:
411 ALLOC( sha512 );
412 break;
413#endif
414 default:
415 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
416 }
Paul Bakker17373852011-01-06 14:20:01 +0000417
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100418 if( hmac != 0 )
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100419 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200420 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100421 if( ctx->hmac_ctx == NULL )
422 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200423 mbedtls_md_free( ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100425 }
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100426 }
427
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200428 return( 0 );
Paul Bakker17373852011-01-06 14:20:01 +0000429}
Gilles Peskine84867cf2019-07-19 15:46:03 +0200430#undef ALLOC
Paul Bakker17373852011-01-06 14:20:01 +0000431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432int mbedtls_md_starts( mbedtls_md_context_t *ctx )
Paul Bakker562535d2011-01-20 16:42:01 +0000433{
434 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker562535d2011-01-20 16:42:01 +0000436
Gilles Peskine84867cf2019-07-19 15:46:03 +0200437 switch( ctx->md_info->type )
438 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200439#if defined(MBEDTLS_MD5_C)
440 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200441 return( mbedtls_md5_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200442#endif
443#if defined(MBEDTLS_RIPEMD160_C)
444 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200445 return( mbedtls_ripemd160_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200446#endif
447#if defined(MBEDTLS_SHA1_C)
448 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200449 return( mbedtls_sha1_starts( ctx->md_ctx ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200450#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200451#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200452 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200453 return( mbedtls_sha256_starts( ctx->md_ctx, 1 ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200454#endif
455#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200456 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200457 return( mbedtls_sha256_starts( ctx->md_ctx, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200458#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200459#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200460 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200461 return( mbedtls_sha512_starts( ctx->md_ctx, 1 ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200462#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200463#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200464 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200465 return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200466#endif
467 default:
468 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
469 }
Paul Bakker562535d2011-01-20 16:42:01 +0000470}
471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000473{
474 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000476
Gilles Peskine84867cf2019-07-19 15:46:03 +0200477 switch( ctx->md_info->type )
478 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200479#if defined(MBEDTLS_MD5_C)
480 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200481 return( mbedtls_md5_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200482#endif
483#if defined(MBEDTLS_RIPEMD160_C)
484 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200485 return( mbedtls_ripemd160_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200486#endif
487#if defined(MBEDTLS_SHA1_C)
488 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200489 return( mbedtls_sha1_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200490#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200491#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200492 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200493 return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200494#endif
495#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200496 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200497 return( mbedtls_sha256_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200498#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200499#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200500 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200501 return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200502#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200503#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200504 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200505 return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200506#endif
507 default:
508 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
509 }
Paul Bakker17373852011-01-06 14:20:01 +0000510}
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000513{
514 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000516
Gilles Peskine84867cf2019-07-19 15:46:03 +0200517 switch( ctx->md_info->type )
518 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200519#if defined(MBEDTLS_MD5_C)
520 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200521 return( mbedtls_md5_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200522#endif
523#if defined(MBEDTLS_RIPEMD160_C)
524 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200525 return( mbedtls_ripemd160_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200526#endif
527#if defined(MBEDTLS_SHA1_C)
528 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200529 return( mbedtls_sha1_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200530#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200531#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200532 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200533 return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200534#endif
535#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200536 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200537 return( mbedtls_sha256_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200538#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200539#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200540 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200541 return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200542#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200543#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200544 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200545 return( mbedtls_sha512_finish( ctx->md_ctx, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200546#endif
547 default:
548 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
549 }
Paul Bakker17373852011-01-06 14:20:01 +0000550}
551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
Paul Bakker17373852011-01-06 14:20:01 +0000553 unsigned char *output )
554{
Paul Bakker66d5d072014-06-17 16:39:18 +0200555 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000557
Gilles Peskine84867cf2019-07-19 15:46:03 +0200558 switch( md_info->type )
559 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200560#if defined(MBEDTLS_MD5_C)
561 case MBEDTLS_MD_MD5:
TRodziewicz26371e42021-06-08 16:45:41 +0200562 return( mbedtls_md5( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200563#endif
564#if defined(MBEDTLS_RIPEMD160_C)
565 case MBEDTLS_MD_RIPEMD160:
TRodziewicz26371e42021-06-08 16:45:41 +0200566 return( mbedtls_ripemd160( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200567#endif
568#if defined(MBEDTLS_SHA1_C)
569 case MBEDTLS_MD_SHA1:
TRodziewicz26371e42021-06-08 16:45:41 +0200570 return( mbedtls_sha1( input, ilen, output ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200571#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200572#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200573 case MBEDTLS_MD_SHA224:
TRodziewicz26371e42021-06-08 16:45:41 +0200574 return( mbedtls_sha256( input, ilen, output, 1 ) );
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200575#endif
576#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200577 case MBEDTLS_MD_SHA256:
TRodziewicz26371e42021-06-08 16:45:41 +0200578 return( mbedtls_sha256( input, ilen, output, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200579#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200580#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200581 case MBEDTLS_MD_SHA384:
TRodziewicz26371e42021-06-08 16:45:41 +0200582 return( mbedtls_sha512( input, ilen, output, 1 ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200583#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200584#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200585 case MBEDTLS_MD_SHA512:
TRodziewicz26371e42021-06-08 16:45:41 +0200586 return( mbedtls_sha512( input, ilen, output, 0 ) );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200587#endif
588 default:
589 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
590 }
Paul Bakker17373852011-01-06 14:20:01 +0000591}
592
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200593#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000595{
Janos Follath24eed8d2019-11-22 13:21:35 +0000596 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200597 FILE *f;
598 size_t n;
599 mbedtls_md_context_t ctx;
600 unsigned char buf[1024];
Paul Bakker9c021ad2011-06-09 15:55:11 +0000601
Paul Bakker17373852011-01-06 14:20:01 +0000602 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000604
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200605 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnardbcc03082015-06-24 00:09:29 +0200606 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
607
Gilles Peskineda0913b2022-06-30 17:03:40 +0200608 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
609 mbedtls_setbuf( f, NULL );
610
Manuel Pégourié-Gonnardbcc03082015-06-24 00:09:29 +0200611 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200612
613 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
614 goto cleanup;
615
Gilles Peskine84867cf2019-07-19 15:46:03 +0200616 if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100617 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200618
619 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200620 if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100621 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200622
623 if( ferror( f ) != 0 )
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200624 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
Andres Amaya Garciaeb132b62017-06-23 16:30:31 +0100625 else
Gilles Peskine84867cf2019-07-19 15:46:03 +0200626 ret = mbedtls_md_finish( &ctx, output );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200627
628cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500629 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200630 fclose( f );
631 mbedtls_md_free( &ctx );
Paul Bakker9c021ad2011-06-09 15:55:11 +0000632
Paul Bakker8913f822012-01-14 18:07:41 +0000633 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000634}
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200635#endif /* MBEDTLS_FS_IO */
Paul Bakker17373852011-01-06 14:20:01 +0000636
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
Paul Bakker17373852011-01-06 14:20:01 +0000638{
Janos Follath24eed8d2019-11-22 13:21:35 +0000639 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100641 unsigned char *ipad, *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100642 size_t i;
643
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100644 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000646
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100647 if( keylen > (size_t) ctx->md_info->block_size )
648 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200649 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100650 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200651 if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100652 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200653 if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100654 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100655
656 keylen = ctx->md_info->size;
657 key = sum;
658 }
659
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100660 ipad = (unsigned char *) ctx->hmac_ctx;
661 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
662
663 memset( ipad, 0x36, ctx->md_info->block_size );
664 memset( opad, 0x5C, ctx->md_info->block_size );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100665
666 for( i = 0; i < keylen; i++ )
667 {
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100668 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
669 opad[i] = (unsigned char)( opad[i] ^ key[i] );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100670 }
671
Gilles Peskine84867cf2019-07-19 15:46:03 +0200672 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100673 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200674 if( ( ret = mbedtls_md_update( ctx, ipad,
675 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia42e5e102017-07-20 16:27:03 +0100676 goto cleanup;
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100677
678cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500679 mbedtls_platform_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100680
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100681 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000682}
683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000685{
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
Gilles Peskine84867cf2019-07-19 15:46:03 +0200689 return( mbedtls_md_update( ctx, input, ilen ) );
Paul Bakker17373852011-01-06 14:20:01 +0000690}
691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000693{
Janos Follath24eed8d2019-11-22 13:21:35 +0000694 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100696 unsigned char *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100697
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100698 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000700
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100701 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
702
Gilles Peskine84867cf2019-07-19 15:46:03 +0200703 if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100704 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200705 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100706 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200707 if( ( ret = mbedtls_md_update( ctx, opad,
708 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100709 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200710 if( ( ret = mbedtls_md_update( ctx, tmp,
711 ctx->md_info->size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100712 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200713 return( mbedtls_md_finish( ctx, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000714}
715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
Paul Bakker17373852011-01-06 14:20:01 +0000717{
Janos Follath24eed8d2019-11-22 13:21:35 +0000718 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100719 unsigned char *ipad;
720
721 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000723
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100724 ipad = (unsigned char *) ctx->hmac_ctx;
725
Gilles Peskine84867cf2019-07-19 15:46:03 +0200726 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100727 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200728 return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
Paul Bakker17373852011-01-06 14:20:01 +0000729}
730
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100731int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
732 const unsigned char *key, size_t keylen,
733 const unsigned char *input, size_t ilen,
734 unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000735{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 mbedtls_md_context_t ctx;
Janos Follath24eed8d2019-11-22 13:21:35 +0000737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100738
Paul Bakker17373852011-01-06 14:20:01 +0000739 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000741
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100743
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100745 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100746
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100747 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
748 goto cleanup;
749 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
750 goto cleanup;
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100751 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
752 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100753
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100754cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755 mbedtls_md_free( &ctx );
Paul Bakker17373852011-01-06 14:20:01 +0000756
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100757 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000758}
759
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100761{
762 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100764
Gilles Peskine84867cf2019-07-19 15:46:03 +0200765 switch( ctx->md_info->type )
766 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200767#if defined(MBEDTLS_MD5_C)
768 case MBEDTLS_MD_MD5:
769 return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
770#endif
771#if defined(MBEDTLS_RIPEMD160_C)
772 case MBEDTLS_MD_RIPEMD160:
773 return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
774#endif
775#if defined(MBEDTLS_SHA1_C)
776 case MBEDTLS_MD_SHA1:
777 return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
778#endif
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200779#if defined(MBEDTLS_SHA224_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200780 case MBEDTLS_MD_SHA224:
Mateusz Starzyke3c48b42021-04-19 16:46:28 +0200781 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
782#endif
783#if defined(MBEDTLS_SHA256_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200784 case MBEDTLS_MD_SHA256:
785 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
786#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200787#if defined(MBEDTLS_SHA384_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200788 case MBEDTLS_MD_SHA384:
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200789 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
Manuel Pégourié-Gonnardd6020842019-07-17 16:28:21 +0200790#endif
Mateusz Starzyk3352a532021-04-06 14:28:22 +0200791#if defined(MBEDTLS_SHA512_C)
Gilles Peskine84867cf2019-07-19 15:46:03 +0200792 case MBEDTLS_MD_SHA512:
793 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
794#endif
795 default:
796 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
797 }
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100798}
799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100801{
802 if( md_info == NULL )
803 return( 0 );
804
805 return md_info->size;
806}
807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100809{
810 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811 return( MBEDTLS_MD_NONE );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100812
813 return md_info->type;
814}
815
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100817{
818 if( md_info == NULL )
819 return( NULL );
820
821 return md_info->name;
822}
823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#endif /* MBEDTLS_MD_C */