blob: ba48471c6cb50f87735f5e6fce7f2caa8adccfd0 [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 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02008 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02009 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10 *
11 * This file is provided under the Apache License 2.0, or the
12 * GNU General Public License v2.0 or later.
13 *
14 * **********
15 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020016 *
17 * Licensed under the Apache License, Version 2.0 (the "License"); you may
18 * not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 * http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
25 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
Paul Bakker17373852011-01-06 14:20:01 +000028 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020029 * **********
30 *
31 * **********
32 * GNU General Public License v2.0 or later:
33 *
34 * This program is free software; you can redistribute it and/or modify
35 * it under the terms of the GNU General Public License as published by
36 * the Free Software Foundation; either version 2 of the License, or
37 * (at your option) any later version.
38 *
39 * This program is distributed in the hope that it will be useful,
40 * but WITHOUT ANY WARRANTY; without even the implied warranty of
41 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 * GNU General Public License for more details.
43 *
44 * You should have received a copy of the GNU General Public License along
45 * with this program; if not, write to the Free Software Foundation, Inc.,
46 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
47 *
48 * **********
Paul Bakker17373852011-01-06 14:20:01 +000049 */
50
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000052#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020053#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#endif
Paul Bakker17373852011-01-06 14:20:01 +000056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_MD_C)
Paul Bakker17373852011-01-06 14:20:01 +000058
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000059#include "mbedtls/md.h"
Manuel Pégourié-Gonnard50518f42015-05-26 11:04:15 +020060#include "mbedtls/md_internal.h"
Paul Bakker17373852011-01-06 14:20:01 +000061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010063#include "mbedtls/platform.h"
64#else
Paul Bakker17373852011-01-06 14:20:01 +000065#include <stdlib.h>
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020066#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#define mbedtls_free free
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +010068#endif
69
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <string.h>
Paul Bakker17373852011-01-06 14:20:01 +000071
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +020072#if defined(MBEDTLS_FS_IO)
73#include <stdio.h>
Paul Bakkeraf5c85f2011-04-18 03:47:52 +000074#endif
75
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020078 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
79}
80
Manuel Pégourié-Gonnard88db5da2015-06-15 14:34:59 +020081/*
82 * Reminder: update profiles in x509_crt.c when adding a new hash!
83 */
Paul Bakker72f62662011-01-16 21:27:44 +000084static const int supported_digests[] = {
85
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020086#if defined(MBEDTLS_SHA512_C)
87 MBEDTLS_MD_SHA512,
88 MBEDTLS_MD_SHA384,
Paul Bakker72f62662011-01-16 21:27:44 +000089#endif
90
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020091#if defined(MBEDTLS_SHA256_C)
92 MBEDTLS_MD_SHA256,
93 MBEDTLS_MD_SHA224,
Paul Bakker72f62662011-01-16 21:27:44 +000094#endif
95
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096#if defined(MBEDTLS_SHA1_C)
97 MBEDTLS_MD_SHA1,
Paul Bakker72f62662011-01-16 21:27:44 +000098#endif
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100#if defined(MBEDTLS_RIPEMD160_C)
101 MBEDTLS_MD_RIPEMD160,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200102#endif
103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104#if defined(MBEDTLS_MD5_C)
105 MBEDTLS_MD_MD5,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200106#endif
107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108#if defined(MBEDTLS_MD4_C)
109 MBEDTLS_MD_MD4,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200110#endif
111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112#if defined(MBEDTLS_MD2_C)
113 MBEDTLS_MD_MD2,
Manuel Pégourié-Gonnardbd772542014-07-07 14:02:33 +0200114#endif
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 MBEDTLS_MD_NONE
Paul Bakker72f62662011-01-16 21:27:44 +0000117};
118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200119const int *mbedtls_md_list( void )
Paul Bakker72f62662011-01-16 21:27:44 +0000120{
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200121 return( supported_digests );
Paul Bakker72f62662011-01-16 21:27:44 +0000122}
123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
Paul Bakker17373852011-01-06 14:20:01 +0000125{
126 if( NULL == md_name )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200127 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000128
129 /* Get the appropriate digest information */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200130#if defined(MBEDTLS_MD2_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200131 if( !strcmp( "MD2", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
Paul Bakker17373852011-01-06 14:20:01 +0000133#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134#if defined(MBEDTLS_MD4_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200135 if( !strcmp( "MD4", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
Paul Bakker17373852011-01-06 14:20:01 +0000137#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138#if defined(MBEDTLS_MD5_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200139 if( !strcmp( "MD5", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
Paul Bakker17373852011-01-06 14:20:01 +0000141#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142#if defined(MBEDTLS_RIPEMD160_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200143 if( !strcmp( "RIPEMD160", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100145#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146#if defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200147 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Paul Bakker17373852011-01-06 14:20:01 +0000149#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150#if defined(MBEDTLS_SHA256_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200151 if( !strcmp( "SHA224", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200153 if( !strcmp( "SHA256", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
Paul Bakker17373852011-01-06 14:20:01 +0000155#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156#if defined(MBEDTLS_SHA512_C)
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200157 if( !strcmp( "SHA384", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
Manuel Pégourié-Gonnardcb46fd82015-05-28 17:06:07 +0200159 if( !strcmp( "SHA512", md_name ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
Paul Bakker17373852011-01-06 14:20:01 +0000161#endif
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200162 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000163}
164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
Paul Bakker17373852011-01-06 14:20:01 +0000166{
167 switch( md_type )
168 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169#if defined(MBEDTLS_MD2_C)
170 case MBEDTLS_MD_MD2:
171 return( &mbedtls_md2_info );
Paul Bakker17373852011-01-06 14:20:01 +0000172#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173#if defined(MBEDTLS_MD4_C)
174 case MBEDTLS_MD_MD4:
175 return( &mbedtls_md4_info );
Paul Bakker17373852011-01-06 14:20:01 +0000176#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177#if defined(MBEDTLS_MD5_C)
178 case MBEDTLS_MD_MD5:
179 return( &mbedtls_md5_info );
Paul Bakker17373852011-01-06 14:20:01 +0000180#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181#if defined(MBEDTLS_RIPEMD160_C)
182 case MBEDTLS_MD_RIPEMD160:
183 return( &mbedtls_ripemd160_info );
Manuel Pégourié-Gonnarde4d47a62014-01-17 20:41:32 +0100184#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185#if defined(MBEDTLS_SHA1_C)
186 case MBEDTLS_MD_SHA1:
187 return( &mbedtls_sha1_info );
Paul Bakker17373852011-01-06 14:20:01 +0000188#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189#if defined(MBEDTLS_SHA256_C)
190 case MBEDTLS_MD_SHA224:
191 return( &mbedtls_sha224_info );
192 case MBEDTLS_MD_SHA256:
193 return( &mbedtls_sha256_info );
Paul Bakker17373852011-01-06 14:20:01 +0000194#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#if defined(MBEDTLS_SHA512_C)
196 case MBEDTLS_MD_SHA384:
197 return( &mbedtls_sha384_info );
198 case MBEDTLS_MD_SHA512:
199 return( &mbedtls_sha512_info );
Paul Bakker17373852011-01-06 14:20:01 +0000200#endif
201 default:
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200202 return( NULL );
Paul Bakker17373852011-01-06 14:20:01 +0000203 }
204}
205
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200206void mbedtls_md_init( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200207{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200209}
210
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211void mbedtls_md_free( mbedtls_md_context_t *ctx )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200212{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100213 if( ctx == NULL || ctx->md_info == NULL )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200214 return;
215
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100216 if( ctx->md_ctx != NULL )
Paul Bakker84bbeb52014-07-01 14:53:22 +0200217 ctx->md_info->ctx_free_func( ctx->md_ctx );
218
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100219 if( ctx->hmac_ctx != NULL )
220 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221 mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
222 mbedtls_free( ctx->hmac_ctx );
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100223 }
224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
Paul Bakker84bbeb52014-07-01 14:53:22 +0200226}
227
Manuel Pégourié-Gonnard052a6c92015-07-06 16:06:02 +0200228int mbedtls_md_clone( mbedtls_md_context_t *dst,
229 const mbedtls_md_context_t *src )
230{
231 if( dst == NULL || dst->md_info == NULL ||
232 src == NULL || src->md_info == NULL ||
233 dst->md_info != src->md_info )
234 {
235 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
236 }
237
238 dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
239
240 return( 0 );
241}
242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
244int 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 +0100245{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 return mbedtls_md_setup( ctx, md_info, 1 );
Manuel Pégourié-Gonnard147fa092015-03-25 16:43:14 +0100247}
248#endif
249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
Paul Bakker17373852011-01-06 14:20:01 +0000251{
Paul Bakker279432a2012-04-26 10:09:35 +0000252 if( md_info == NULL || ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000254
Paul Bakker17373852011-01-06 14:20:01 +0000255 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
Paul Bakker17373852011-01-06 14:20:01 +0000257
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100258 if( hmac != 0 )
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100259 {
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200260 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100261 if( ctx->hmac_ctx == NULL )
262 {
263 md_info->ctx_free_func( ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
Manuel Pégourié-Gonnard4063ceb2015-03-25 16:08:53 +0100265 }
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100266 }
267
Paul Bakker17373852011-01-06 14:20:01 +0000268 ctx->md_info = md_info;
269
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200270 return( 0 );
Paul Bakker17373852011-01-06 14:20:01 +0000271}
272
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273int mbedtls_md_starts( mbedtls_md_context_t *ctx )
Paul Bakker562535d2011-01-20 16:42:01 +0000274{
275 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker562535d2011-01-20 16:42:01 +0000277
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100278 return( ctx->md_info->starts_func( ctx->md_ctx ) );
Paul Bakker562535d2011-01-20 16:42:01 +0000279}
280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000282{
283 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000285
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100286 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
Paul Bakker17373852011-01-06 14:20:01 +0000287}
288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000290{
291 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000293
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100294 return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000295}
296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
Paul Bakker17373852011-01-06 14:20:01 +0000298 unsigned char *output )
299{
Paul Bakker66d5d072014-06-17 16:39:18 +0200300 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000302
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100303 return( md_info->digest_func( input, ilen, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000304}
305
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200306#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000308{
Paul Bakker9c021ad2011-06-09 15:55:11 +0000309 int ret;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200310 FILE *f;
311 size_t n;
312 mbedtls_md_context_t ctx;
313 unsigned char buf[1024];
Paul Bakker9c021ad2011-06-09 15:55:11 +0000314
Paul Bakker17373852011-01-06 14:20:01 +0000315 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000317
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200318 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnardbcc03082015-06-24 00:09:29 +0200319 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
320
321 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200322
323 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
324 goto cleanup;
325
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100326 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
327 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200328
329 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100330 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
331 goto cleanup;
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200332
333 if( ferror( f ) != 0 )
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200334 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
Andres Amaya Garciaeb132b62017-06-23 16:30:31 +0100335 else
Jaeden Amero66954e12018-01-25 16:05:54 +0000336 ret = md_info->finish_func( ctx.md_ctx, output );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200337
338cleanup:
Jaeden Amero66954e12018-01-25 16:05:54 +0000339 mbedtls_zeroize( buf, sizeof( buf ) );
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200340 fclose( f );
341 mbedtls_md_free( &ctx );
Paul Bakker9c021ad2011-06-09 15:55:11 +0000342
Paul Bakker8913f822012-01-14 18:07:41 +0000343 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000344}
Manuel Pégourié-Gonnardbfffa902015-05-28 14:44:00 +0200345#endif /* MBEDTLS_FS_IO */
Paul Bakker17373852011-01-06 14:20:01 +0000346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
Paul Bakker17373852011-01-06 14:20:01 +0000348{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100349 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100351 unsigned char *ipad, *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100352 size_t i;
353
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100354 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000356
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100357 if( keylen > (size_t) ctx->md_info->block_size )
358 {
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100359 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
360 goto cleanup;
361 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
362 goto cleanup;
363 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
364 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100365
366 keylen = ctx->md_info->size;
367 key = sum;
368 }
369
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100370 ipad = (unsigned char *) ctx->hmac_ctx;
371 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
372
373 memset( ipad, 0x36, ctx->md_info->block_size );
374 memset( opad, 0x5C, ctx->md_info->block_size );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100375
376 for( i = 0; i < keylen; i++ )
377 {
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100378 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
379 opad[i] = (unsigned char)( opad[i] ^ key[i] );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100380 }
381
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100382 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
383 goto cleanup;
Andres Amaya Garcia42e5e102017-07-20 16:27:03 +0100384 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
385 ctx->md_info->block_size ) ) != 0 )
386 goto cleanup;
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100387
388cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_zeroize( sum, sizeof( sum ) );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100390
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100391 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000392}
393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
Paul Bakker17373852011-01-06 14:20:01 +0000395{
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100396 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000398
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100399 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
Paul Bakker17373852011-01-06 14:20:01 +0000400}
401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000403{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100404 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100406 unsigned char *opad;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100407
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100408 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000410
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100411 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
412
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100413 if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
414 return( ret );
415 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
416 return( ret );
417 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
418 ctx->md_info->block_size ) ) != 0 )
419 return( ret );
420 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
421 ctx->md_info->size ) ) != 0 )
422 return( ret );
423 return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
Paul Bakker17373852011-01-06 14:20:01 +0000424}
425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
Paul Bakker17373852011-01-06 14:20:01 +0000427{
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100428 int ret;
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100429 unsigned char *ipad;
430
431 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000433
Manuel Pégourié-Gonnarddfb3dc82015-03-25 11:49:07 +0100434 ipad = (unsigned char *) ctx->hmac_ctx;
435
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100436 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
437 return( ret );
438 return( ctx->md_info->update_func( ctx->md_ctx, ipad,
439 ctx->md_info->block_size ) );
Paul Bakker17373852011-01-06 14:20:01 +0000440}
441
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100442int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
443 const unsigned char *key, size_t keylen,
444 const unsigned char *input, size_t ilen,
445 unsigned char *output )
Paul Bakker17373852011-01-06 14:20:01 +0000446{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 mbedtls_md_context_t ctx;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100448 int ret;
449
Paul Bakker17373852011-01-06 14:20:01 +0000450 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker17373852011-01-06 14:20:01 +0000452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_md_init( &ctx );
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100456 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100457
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100458 if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
459 goto cleanup;
460 if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
461 goto cleanup;
Andres Amaya Garciaaa464ef2017-07-21 14:21:53 +0100462 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
463 goto cleanup;
Manuel Pégourié-Gonnard8379a822015-03-24 16:48:22 +0100464
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100465cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 mbedtls_md_free( &ctx );
Paul Bakker17373852011-01-06 14:20:01 +0000467
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100468 return( ret );
Paul Bakker17373852011-01-06 14:20:01 +0000469}
470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100472{
473 if( ctx == NULL || ctx->md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100475
Andres Amaya Garcia0dd4fa02017-06-28 14:16:07 +0100476 return( ctx->md_info->process_func( ctx->md_ctx, data ) );
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100477}
478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100480{
481 if( md_info == NULL )
482 return( 0 );
483
484 return md_info->size;
485}
486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100488{
489 if( md_info == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 return( MBEDTLS_MD_NONE );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100491
492 return md_info->type;
493}
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100496{
497 if( md_info == NULL )
498 return( NULL );
499
500 return md_info->name;
501}
502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503#endif /* MBEDTLS_MD_C */