blob: e1b5183b6a26b78938c3d205e0b157b72e516c99 [file] [log] [blame]
Paul Bakker17373852011-01-06 14:20:01 +00001/**
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002 * \file mbedtls_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 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02008 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000023 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker17373852011-01-06 14:20:01 +000024 */
25
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000027#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020028#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#endif
Paul Bakker17373852011-01-06 14:20:01 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_MD_C)
Paul Bakker17373852011-01-06 14:20:01 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/md.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020035#include "mbedtls/md_internal.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.h"
Paul Bakker17373852011-01-06 14:20:01 +000037
Gilles Peskine84867cf2019-07-19 15:46:03 +020038#include "mbedtls/md2.h"
39#include "mbedtls/md4.h"
40#include "mbedtls/md5.h"
41#include "mbedtls/ripemd160.h"
42#include "mbedtls/sha1.h"
43#include "mbedtls/sha256.h"
44#include "mbedtls/sha512.h"
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010047#include "mbedtls/platform.h"
48#else
Paul Bakker17373852011-01-06 14:20:01 +000049#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020050#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_free free
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010052#endif
53
Rich Evans00ab4702015-02-06 13:43:58 +000054#include <string.h>
Paul Bakker17373852011-01-06 14:20:01 +000055
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +020056#if defined(MBEDTLS_FS_IO)
57#include <stdio.h>
Paul Bakkeraf5c85f2011-04-18 03:47:52 +000058#endif
59
Gilles Peskine84867cf2019-07-19 15:46:03 +020060#if defined(MBEDTLS_MD2_C)
61const mbedtls_md_info_t mbedtls_md2_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020062 "MD2",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020063 MBEDTLS_MD_MD2,
Gilles Peskine84867cf2019-07-19 15:46:03 +020064 16,
65 16,
66};
67#endif
68
69#if defined(MBEDTLS_MD4_C)
70const mbedtls_md_info_t mbedtls_md4_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020071 "MD4",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020072 MBEDTLS_MD_MD4,
Gilles Peskine84867cf2019-07-19 15:46:03 +020073 16,
74 64,
75};
76#endif
77
78#if defined(MBEDTLS_MD5_C)
79const mbedtls_md_info_t mbedtls_md5_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020080 "MD5",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020081 MBEDTLS_MD_MD5,
Gilles Peskine84867cf2019-07-19 15:46:03 +020082 16,
83 64,
84};
85#endif
86
87#if defined(MBEDTLS_RIPEMD160_C)
88const mbedtls_md_info_t mbedtls_ripemd160_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020089 "RIPEMD160",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020090 MBEDTLS_MD_RIPEMD160,
Gilles Peskine84867cf2019-07-19 15:46:03 +020091 20,
92 64,
93};
94#endif
95
96#if defined(MBEDTLS_SHA1_C)
97const mbedtls_md_info_t mbedtls_sha1_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +020098 "SHA1",
Gilles Peskine2838b7b2019-07-19 16:03:39 +020099 MBEDTLS_MD_SHA1,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200100 20,
101 64,
102};
103#endif
104
105#if defined(MBEDTLS_SHA256_C)
106const mbedtls_md_info_t mbedtls_sha224_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200107 "SHA224",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200108 MBEDTLS_MD_SHA224,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200109 28,
110 64,
111};
112
113const mbedtls_md_info_t mbedtls_sha256_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200114 "SHA256",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200115 MBEDTLS_MD_SHA256,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200116 32,
117 64,
118};
119#endif
120
121#if defined(MBEDTLS_SHA512_C)
122const mbedtls_md_info_t mbedtls_sha384_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200123 "SHA384",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200124 MBEDTLS_MD_SHA384,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200125 48,
126 128,
127};
128
129const mbedtls_md_info_t mbedtls_sha512_info = {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200130 "SHA512",
Gilles Peskine2838b7b2019-07-19 16:03:39 +0200131 MBEDTLS_MD_SHA512,
Gilles Peskine84867cf2019-07-19 15:46:03 +0200132 64,
133 128,
134};
135#endif
136
Manuel Pégourié-Gonnard88db5da2015-06-15 14:34:59 +0200137/*
Jaeden Ameroebbc5f72019-02-22 16:52:44 +0000138 * Reminder: update profiles in Mbed TLS's x509_crt.c when adding a new hash!
Manuel Pégourié-Gonnard88db5da2015-06-15 14:34:59 +0200139 */
Paul Bakker72f62662011-01-16 21:27:44 +0000140static const int supported_digests[] = {
141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142#if defined(MBEDTLS_SHA512_C)
143 MBEDTLS_MD_SHA512,
144 MBEDTLS_MD_SHA384,
Paul Bakker72f62662011-01-16 21:27:44 +0000145#endif
146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147#if defined(MBEDTLS_SHA256_C)
148 MBEDTLS_MD_SHA256,
149 MBEDTLS_MD_SHA224,
Paul Bakker72f62662011-01-16 21:27:44 +0000150#endif
151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152#if defined(MBEDTLS_SHA1_C)
153 MBEDTLS_MD_SHA1,
Paul Bakker72f62662011-01-16 21:27:44 +0000154#endif
155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156#if defined(MBEDTLS_RIPEMD160_C)
157 MBEDTLS_MD_RIPEMD160,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200158#endif
159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160#if defined(MBEDTLS_MD5_C)
161 MBEDTLS_MD_MD5,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200162#endif
163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164#if defined(MBEDTLS_MD4_C)
165 MBEDTLS_MD_MD4,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200166#endif
167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168#if defined(MBEDTLS_MD2_C)
169 MBEDTLS_MD_MD2,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200170#endif
171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 MBEDTLS_MD_NONE
Paul Bakker72f62662011-01-16 21:27:44 +0000173};
174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175const int *mbedtls_md_list( void )
Paul Bakker72f62662011-01-16 21:27:44 +0000176{
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200177 return( supported_digests );
Paul Bakker72f62662011-01-16 21:27:44 +0000178}
179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
Paul Bakker17373852011-01-06 14:20:01 +0000181{
182 if( NULL == md_name )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200183 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000184
185 /* Get the appropriate digest information */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186#if defined(MBEDTLS_MD2_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200187 if( !strcmp( "MD2", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
Paul Bakker17373852011-01-06 14:20:01 +0000189#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190#if defined(MBEDTLS_MD4_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200191 if( !strcmp( "MD4", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
Paul Bakker17373852011-01-06 14:20:01 +0000193#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200194#if defined(MBEDTLS_MD5_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200195 if( !strcmp( "MD5", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
Paul Bakker17373852011-01-06 14:20:01 +0000197#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200199 if( !strcmp( "RIPEMD160", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100201#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200202#if defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200203 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Paul Bakker17373852011-01-06 14:20:01 +0000205#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200207 if( !strcmp( "SHA224", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200209 if( !strcmp( "SHA256", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
Paul Bakker17373852011-01-06 14:20:01 +0000211#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200212#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200213 if( !strcmp( "SHA384", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200215 if( !strcmp( "SHA512", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
Paul Bakker17373852011-01-06 14:20:01 +0000217#endif
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200218 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000219}
220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
Paul Bakker17373852011-01-06 14:20:01 +0000222{
223 switch( md_type )
224 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225#if defined(MBEDTLS_MD2_C)
226 case MBEDTLS_MD_MD2:
227 return( &mbedtls_md2_info );
Paul Bakker17373852011-01-06 14:20:01 +0000228#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229#if defined(MBEDTLS_MD4_C)
230 case MBEDTLS_MD_MD4:
231 return( &mbedtls_md4_info );
Paul Bakker17373852011-01-06 14:20:01 +0000232#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233#if defined(MBEDTLS_MD5_C)
234 case MBEDTLS_MD_MD5:
235 return( &mbedtls_md5_info );
Paul Bakker17373852011-01-06 14:20:01 +0000236#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237#if defined(MBEDTLS_RIPEMD160_C)
238 case MBEDTLS_MD_RIPEMD160:
239 return( &mbedtls_ripemd160_info );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100240#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#if defined(MBEDTLS_SHA1_C)
242 case MBEDTLS_MD_SHA1:
243 return( &mbedtls_sha1_info );
Paul Bakker17373852011-01-06 14:20:01 +0000244#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245#if defined(MBEDTLS_SHA256_C)
246 case MBEDTLS_MD_SHA224:
247 return( &mbedtls_sha224_info );
248 case MBEDTLS_MD_SHA256:
249 return( &mbedtls_sha256_info );
Paul Bakker17373852011-01-06 14:20:01 +0000250#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251#if defined(MBEDTLS_SHA512_C)
252 case MBEDTLS_MD_SHA384:
253 return( &mbedtls_sha384_info );
254 case MBEDTLS_MD_SHA512:
255 return( &mbedtls_sha512_info );
Paul Bakker17373852011-01-06 14:20:01 +0000256#endif
257 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200258 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000259 }
260}
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262void mbedtls_md_init( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200263{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200265}
266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267void mbedtls_md_free( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200268{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100269 if( ctx == NULL || ctx->md_info == NULL )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200270 return;
271
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100272 if( ctx->md_ctx != NULL )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200273 {
274 switch( ctx->md_info->type )
275 {
276#if defined(MBEDTLS_MD2_C)
277 case MBEDTLS_MD_MD2:
278 mbedtls_md2_free( ctx->md_ctx );
279 break;
280#endif
281#if defined(MBEDTLS_MD4_C)
282 case MBEDTLS_MD_MD4:
283 mbedtls_md4_free( ctx->md_ctx );
284 break;
285#endif
286#if defined(MBEDTLS_MD5_C)
287 case MBEDTLS_MD_MD5:
288 mbedtls_md5_free( ctx->md_ctx );
289 break;
290#endif
291#if defined(MBEDTLS_RIPEMD160_C)
292 case MBEDTLS_MD_RIPEMD160:
293 mbedtls_ripemd160_free( ctx->md_ctx );
294 break;
295#endif
296#if defined(MBEDTLS_SHA1_C)
297 case MBEDTLS_MD_SHA1:
298 mbedtls_sha1_free( ctx->md_ctx );
299 break;
300#endif
301#if defined(MBEDTLS_SHA256_C)
302 case MBEDTLS_MD_SHA224:
303 case MBEDTLS_MD_SHA256:
304 mbedtls_sha256_free( ctx->md_ctx );
305 break;
306#endif
307#if defined(MBEDTLS_SHA512_C)
308 case MBEDTLS_MD_SHA384:
309 case MBEDTLS_MD_SHA512:
310 mbedtls_sha512_free( ctx->md_ctx );
311 break;
312#endif
313 default:
314 /* Shouldn't happen */
315 break;
316 }
317 mbedtls_free( ctx->md_ctx );
318 }
Paul Bakker84bbeb52014-07-01 14:53:22 +0200319
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100320 if( ctx->hmac_ctx != NULL )
321 {
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500322 mbedtls_platform_zeroize( ctx->hmac_ctx,
323 2 * ctx->md_info->block_size );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 mbedtls_free( ctx->hmac_ctx );
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100325 }
326
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500327 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200328}
329
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200330int mbedtls_md_clone( mbedtls_md_context_t *dst,
331 const mbedtls_md_context_t *src )
332{
333 if( dst == NULL || dst->md_info == NULL ||
334 src == NULL || src->md_info == NULL ||
335 dst->md_info != src->md_info )
336 {
337 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
338 }
339
Gilles Peskine84867cf2019-07-19 15:46:03 +0200340 switch( src->md_info->type )
341 {
342#if defined(MBEDTLS_MD2_C)
343 case MBEDTLS_MD_MD2:
344 mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
345 break;
346#endif
347#if defined(MBEDTLS_MD4_C)
348 case MBEDTLS_MD_MD4:
349 mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
350 break;
351#endif
352#if defined(MBEDTLS_MD5_C)
353 case MBEDTLS_MD_MD5:
354 mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
355 break;
356#endif
357#if defined(MBEDTLS_RIPEMD160_C)
358 case MBEDTLS_MD_RIPEMD160:
359 mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
360 break;
361#endif
362#if defined(MBEDTLS_SHA1_C)
363 case MBEDTLS_MD_SHA1:
364 mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
365 break;
366#endif
367#if defined(MBEDTLS_SHA256_C)
368 case MBEDTLS_MD_SHA224:
369 case MBEDTLS_MD_SHA256:
370 mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
371 break;
372#endif
373#if defined(MBEDTLS_SHA512_C)
374 case MBEDTLS_MD_SHA384:
375 case MBEDTLS_MD_SHA512:
376 mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
377 break;
378#endif
379 default:
380 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
381 }
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200382
383 return( 0 );
384}
385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
387int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnard147fa092015-03-25 16:43:14 +0100388{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 return mbedtls_md_setup( ctx, md_info, 1 );
Manuel Pégourié-Gonnard147fa092015-03-25 16:43:14 +0100390}
391#endif
392
Gilles Peskine84867cf2019-07-19 15:46:03 +0200393#define ALLOC( type ) \
394 do { \
395 ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
396 if( ctx->md_ctx == NULL ) \
397 return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
398 mbedtls_##type##_init( ctx->md_ctx ); \
399 } \
400 while( 0 )
401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
Paul Bakker17373852011-01-06 14:20:01 +0000403{
Paul Bakker279432a2012-04-26 10:09:35 +0000404 if( md_info == NULL || ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000406
Gilles Peskine84867cf2019-07-19 15:46:03 +0200407 switch( md_info->type )
408 {
409#if defined(MBEDTLS_MD2_C)
410 case MBEDTLS_MD_MD2:
411 ALLOC( md2 );
412 break;
413#endif
414#if defined(MBEDTLS_MD4_C)
415 case MBEDTLS_MD_MD4:
416 ALLOC( md4 );
417 break;
418#endif
419#if defined(MBEDTLS_MD5_C)
420 case MBEDTLS_MD_MD5:
421 ALLOC( md5 );
422 break;
423#endif
424#if defined(MBEDTLS_RIPEMD160_C)
425 case MBEDTLS_MD_RIPEMD160:
426 ALLOC( ripemd160 );
427 break;
428#endif
429#if defined(MBEDTLS_SHA1_C)
430 case MBEDTLS_MD_SHA1:
431 ALLOC( sha1 );
432 break;
433#endif
434#if defined(MBEDTLS_SHA256_C)
435 case MBEDTLS_MD_SHA224:
436 case MBEDTLS_MD_SHA256:
437 ALLOC( sha256 );
438 break;
439#endif
440#if defined(MBEDTLS_SHA512_C)
441 case MBEDTLS_MD_SHA384:
442 case MBEDTLS_MD_SHA512:
443 ALLOC( sha512 );
444 break;
445#endif
446 default:
447 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
448 }
Paul Bakker17373852011-01-06 14:20:01 +0000449
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100450 if( hmac != 0 )
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100451 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200452 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100453 if( ctx->hmac_ctx == NULL )
454 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200455 mbedtls_md_free( ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100457 }
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100458 }
459
Paul Bakker17373852011-01-06 14:20:01 +0000460 ctx->md_info = md_info;
461
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200462 return( 0 );
Paul Bakker17373852011-01-06 14:20:01 +0000463}
Gilles Peskine84867cf2019-07-19 15:46:03 +0200464#undef ALLOC
Paul Bakker17373852011-01-06 14:20:01 +0000465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_md_starts( mbedtls_md_context_t *ctx )
Paul Bakker562535d2011-01-20 16:42:01 +0000467{
468 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker562535d2011-01-20 16:42:01 +0000470
Gilles Peskine84867cf2019-07-19 15:46:03 +0200471 switch( ctx->md_info->type )
472 {
473#if defined(MBEDTLS_MD2_C)
474 case MBEDTLS_MD_MD2:
475 return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
476#endif
477#if defined(MBEDTLS_MD4_C)
478 case MBEDTLS_MD_MD4:
479 return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
480#endif
481#if defined(MBEDTLS_MD5_C)
482 case MBEDTLS_MD_MD5:
483 return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
484#endif
485#if defined(MBEDTLS_RIPEMD160_C)
486 case MBEDTLS_MD_RIPEMD160:
487 return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
488#endif
489#if defined(MBEDTLS_SHA1_C)
490 case MBEDTLS_MD_SHA1:
491 return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
492#endif
493#if defined(MBEDTLS_SHA256_C)
494 case MBEDTLS_MD_SHA224:
495 return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
496 case MBEDTLS_MD_SHA256:
497 return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
498#endif
499#if defined(MBEDTLS_SHA512_C)
500 case MBEDTLS_MD_SHA384:
501 return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
502 case MBEDTLS_MD_SHA512:
503 return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
504#endif
505 default:
506 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
507 }
Paul Bakker562535d2011-01-20 16:42:01 +0000508}
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000511{
512 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000514
Gilles Peskine84867cf2019-07-19 15:46:03 +0200515 switch( ctx->md_info->type )
516 {
517#if defined(MBEDTLS_MD2_C)
518 case MBEDTLS_MD_MD2:
519 return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
520#endif
521#if defined(MBEDTLS_MD4_C)
522 case MBEDTLS_MD_MD4:
523 return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
524#endif
525#if defined(MBEDTLS_MD5_C)
526 case MBEDTLS_MD_MD5:
527 return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
528#endif
529#if defined(MBEDTLS_RIPEMD160_C)
530 case MBEDTLS_MD_RIPEMD160:
531 return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
532#endif
533#if defined(MBEDTLS_SHA1_C)
534 case MBEDTLS_MD_SHA1:
535 return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
536#endif
537#if defined(MBEDTLS_SHA256_C)
538 case MBEDTLS_MD_SHA224:
539 return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
540 case MBEDTLS_MD_SHA256:
541 return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
542#endif
543#if defined(MBEDTLS_SHA512_C)
544 case MBEDTLS_MD_SHA384:
545 return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
546 case MBEDTLS_MD_SHA512:
547 return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
548#endif
549 default:
550 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
551 }
Paul Bakker17373852011-01-06 14:20:01 +0000552}
553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000555{
556 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000558
Gilles Peskine84867cf2019-07-19 15:46:03 +0200559 switch( ctx->md_info->type )
560 {
561#if defined(MBEDTLS_MD2_C)
562 case MBEDTLS_MD_MD2:
563 return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
564#endif
565#if defined(MBEDTLS_MD4_C)
566 case MBEDTLS_MD_MD4:
567 return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
568#endif
569#if defined(MBEDTLS_MD5_C)
570 case MBEDTLS_MD_MD5:
571 return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
572#endif
573#if defined(MBEDTLS_RIPEMD160_C)
574 case MBEDTLS_MD_RIPEMD160:
575 return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
576#endif
577#if defined(MBEDTLS_SHA1_C)
578 case MBEDTLS_MD_SHA1:
579 return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
580#endif
581#if defined(MBEDTLS_SHA256_C)
582 case MBEDTLS_MD_SHA224:
583 return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
584 case MBEDTLS_MD_SHA256:
585 return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
586#endif
587#if defined(MBEDTLS_SHA512_C)
588 case MBEDTLS_MD_SHA384:
589 return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
590 case MBEDTLS_MD_SHA512:
591 return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
592#endif
593 default:
594 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
595 }
Paul Bakker17373852011-01-06 14:20:01 +0000596}
597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
Paul Bakker17373852011-01-06 14:20:01 +0000599 unsigned char *output )
600{
Paul Bakker66d5d072014-06-17 16:39:18 +0200601 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000603
Gilles Peskine84867cf2019-07-19 15:46:03 +0200604 switch( md_info->type )
605 {
606#if defined(MBEDTLS_MD2_C)
607 case MBEDTLS_MD_MD2:
608 return( mbedtls_md2_ret( input, ilen, output ) );
609#endif
610#if defined(MBEDTLS_MD4_C)
611 case MBEDTLS_MD_MD4:
612 return( mbedtls_md4_ret( input, ilen, output ) );
613#endif
614#if defined(MBEDTLS_MD5_C)
615 case MBEDTLS_MD_MD5:
616 return( mbedtls_md5_ret( input, ilen, output ) );
617#endif
618#if defined(MBEDTLS_RIPEMD160_C)
619 case MBEDTLS_MD_RIPEMD160:
620 return( mbedtls_ripemd160_ret( input, ilen, output ) );
621#endif
622#if defined(MBEDTLS_SHA1_C)
623 case MBEDTLS_MD_SHA1:
624 return( mbedtls_sha1_ret( input, ilen, output ) );
625#endif
626#if defined(MBEDTLS_SHA256_C)
627 case MBEDTLS_MD_SHA224:
628 return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
629 case MBEDTLS_MD_SHA256:
630 return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
631#endif
632#if defined(MBEDTLS_SHA512_C)
633 case MBEDTLS_MD_SHA384:
634 return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
635 case MBEDTLS_MD_SHA512:
636 return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
637#endif
638 default:
639 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
640 }
Paul Bakker17373852011-01-06 14:20:01 +0000641}
642
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200643#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000645{
Paul Bakker9c021ad2011-06-09 15:55:11 +0000646 int ret;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200647 FILE *f;
648 size_t n;
649 mbedtls_md_context_t ctx;
650 unsigned char buf[1024];
Paul Bakker9c021ad2011-06-09 15:55:11 +0000651
Paul Bakker17373852011-01-06 14:20:01 +0000652 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000654
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200655 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnardbcc03082015-06-24 00:09:29 +0200656 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
657
658 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200659
660 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
661 goto cleanup;
662
Gilles Peskine84867cf2019-07-19 15:46:03 +0200663 if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100664 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200665
666 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Gilles Peskine84867cf2019-07-19 15:46:03 +0200667 if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100668 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200669
670 if( ferror( f ) != 0 )
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200671 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
Andres Amaya Garciaeb132b62017-06-23 16:30:31 +0100672 else
Gilles Peskine84867cf2019-07-19 15:46:03 +0200673 ret = mbedtls_md_finish( &ctx, output );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200674
675cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500676 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200677 fclose( f );
678 mbedtls_md_free( &ctx );
Paul Bakker9c021ad2011-06-09 15:55:11 +0000679
Paul Bakker8913f822012-01-14 18:07:41 +0000680 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000681}
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200682#endif /* MBEDTLS_FS_IO */
Paul Bakker17373852011-01-06 14:20:01 +0000683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
Paul Bakker17373852011-01-06 14:20:01 +0000685{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100686 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100688 unsigned char *ipad, *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100689 size_t i;
690
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100691 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000693
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100694 if( keylen > (size_t) ctx->md_info->block_size )
695 {
Gilles Peskine84867cf2019-07-19 15:46:03 +0200696 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100697 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200698 if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100699 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200700 if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100701 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100702
703 keylen = ctx->md_info->size;
704 key = sum;
705 }
706
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100707 ipad = (unsigned char *) ctx->hmac_ctx;
708 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
709
710 memset( ipad, 0x36, ctx->md_info->block_size );
711 memset( opad, 0x5C, ctx->md_info->block_size );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100712
713 for( i = 0; i < keylen; i++ )
714 {
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100715 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
716 opad[i] = (unsigned char)( opad[i] ^ key[i] );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100717 }
718
Gilles Peskine84867cf2019-07-19 15:46:03 +0200719 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100720 goto cleanup;
Gilles Peskine84867cf2019-07-19 15:46:03 +0200721 if( ( ret = mbedtls_md_update( ctx, ipad,
722 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia42e5e102017-07-20 16:27:03 +0100723 goto cleanup;
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100724
725cleanup:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500726 mbedtls_platform_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100727
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100728 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000729}
730
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000732{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100733 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000735
Gilles Peskine84867cf2019-07-19 15:46:03 +0200736 return( mbedtls_md_update( ctx, input, ilen ) );
Paul Bakker17373852011-01-06 14:20:01 +0000737}
738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000740{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100741 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100743 unsigned char *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100744
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100745 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000747
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100748 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
749
Gilles Peskine84867cf2019-07-19 15:46:03 +0200750 if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100751 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200752 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100753 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200754 if( ( ret = mbedtls_md_update( ctx, opad,
755 ctx->md_info->block_size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100756 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200757 if( ( ret = mbedtls_md_update( ctx, tmp,
758 ctx->md_info->size ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100759 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200760 return( mbedtls_md_finish( ctx, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000761}
762
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
Paul Bakker17373852011-01-06 14:20:01 +0000764{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100765 int ret;
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100766 unsigned char *ipad;
767
768 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000770
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100771 ipad = (unsigned char *) ctx->hmac_ctx;
772
Gilles Peskine84867cf2019-07-19 15:46:03 +0200773 if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100774 return( ret );
Gilles Peskine84867cf2019-07-19 15:46:03 +0200775 return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
Paul Bakker17373852011-01-06 14:20:01 +0000776}
777
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100778int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
779 const unsigned char *key, size_t keylen,
780 const unsigned char *input, size_t ilen,
781 unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000782{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_md_context_t ctx;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100784 int ret;
785
Paul Bakker17373852011-01-06 14:20:01 +0000786 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100792 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100793
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100794 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
795 goto cleanup;
796 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
797 goto cleanup;
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100798 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
799 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100800
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100801cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802 mbedtls_md_free( &ctx );
Paul Bakker17373852011-01-06 14:20:01 +0000803
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100804 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000805}
806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100808{
809 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100811
Gilles Peskine84867cf2019-07-19 15:46:03 +0200812 switch( ctx->md_info->type )
813 {
814#if defined(MBEDTLS_MD2_C)
815 case MBEDTLS_MD_MD2:
816 return( mbedtls_internal_md2_process( ctx->md_ctx ) );
817#endif
818#if defined(MBEDTLS_MD4_C)
819 case MBEDTLS_MD_MD4:
820 return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
821#endif
822#if defined(MBEDTLS_MD5_C)
823 case MBEDTLS_MD_MD5:
824 return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
825#endif
826#if defined(MBEDTLS_RIPEMD160_C)
827 case MBEDTLS_MD_RIPEMD160:
828 return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
829#endif
830#if defined(MBEDTLS_SHA1_C)
831 case MBEDTLS_MD_SHA1:
832 return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
833#endif
834#if defined(MBEDTLS_SHA256_C)
835 case MBEDTLS_MD_SHA224:
836 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
837 case MBEDTLS_MD_SHA256:
838 return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
839#endif
840#if defined(MBEDTLS_SHA512_C)
841 case MBEDTLS_MD_SHA384:
842 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
843 case MBEDTLS_MD_SHA512:
844 return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
845#endif
846 default:
847 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
848 }
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100849}
850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100852{
853 if( md_info == NULL )
854 return( 0 );
855
856 return md_info->size;
857}
858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100860{
861 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 return( MBEDTLS_MD_NONE );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100863
864 return md_info->type;
865}
866
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100868{
869 if( md_info == NULL )
870 return( NULL );
871
872 return md_info->name;
873}
874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#endif /* MBEDTLS_MD_C */