1 /**
2 * \file mbedtls_md.c
3 *
4 * \brief Generic message digest wrapper for mbed TLS
5 *
6 * \author Adriaan de Jong <dejong@fox-it.com>
7 *
8 * Copyright The Mbed TLS Contributors
9 * 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:
16 *
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.
28 *
29 * **********
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 * **********
49 */
50
51 #if !defined(MBEDTLS_CONFIG_FILE)
52 #include "mbedtls/config.h"
53 #else
54 #include MBEDTLS_CONFIG_FILE
55 #endif
56
57 #if defined(MBEDTLS_MD_C)
58
59 #include "mbedtls/md.h"
60 #include "mbedtls/md_internal.h"
61
62 #if defined(MBEDTLS_PLATFORM_C)
63 #include "mbedtls/platform.h"
64 #else
65 #include <stdlib.h>
66 #define mbedtls_calloc calloc
67 #define mbedtls_free free
68 #endif
69
70 #include <string.h>
71
72 #if defined(MBEDTLS_FS_IO)
73 #include <stdio.h>
74 #endif
75
76 /* Implementation that should never be optimized out by the compiler */
mbedtls_zeroize(void * v,size_t n)77 static void mbedtls_zeroize( void *v, size_t n ) {
78 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
79 }
80
81 /*
82 * Reminder: update profiles in x509_crt.c when adding a new hash!
83 */
84 static const int supported_digests[] = {
85
86 #if defined(MBEDTLS_SHA512_C)
87 MBEDTLS_MD_SHA512,
88 MBEDTLS_MD_SHA384,
89 #endif
90
91 #if defined(MBEDTLS_SHA256_C)
92 MBEDTLS_MD_SHA256,
93 MBEDTLS_MD_SHA224,
94 #endif
95
96 #if defined(MBEDTLS_SHA1_C)
97 MBEDTLS_MD_SHA1,
98 #endif
99
100 #if defined(MBEDTLS_RIPEMD160_C)
101 MBEDTLS_MD_RIPEMD160,
102 #endif
103
104 #if defined(MBEDTLS_MD5_C)
105 MBEDTLS_MD_MD5,
106 #endif
107
108 #if defined(MBEDTLS_MD4_C)
109 MBEDTLS_MD_MD4,
110 #endif
111
112 #if defined(MBEDTLS_MD2_C)
113 MBEDTLS_MD_MD2,
114 #endif
115
116 MBEDTLS_MD_NONE
117 };
118
mbedtls_md_list(void)119 const int *mbedtls_md_list( void )
120 {
121 return( supported_digests );
122 }
123
mbedtls_md_info_from_string(const char * md_name)124 const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
125 {
126 if( NULL == md_name )
127 return( NULL );
128
129 /* Get the appropriate digest information */
130 #if defined(MBEDTLS_MD2_C)
131 if( !strcmp( "MD2", md_name ) )
132 return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
133 #endif
134 #if defined(MBEDTLS_MD4_C)
135 if( !strcmp( "MD4", md_name ) )
136 return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
137 #endif
138 #if defined(MBEDTLS_MD5_C)
139 if( !strcmp( "MD5", md_name ) )
140 return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
141 #endif
142 #if defined(MBEDTLS_RIPEMD160_C)
143 if( !strcmp( "RIPEMD160", md_name ) )
144 return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
145 #endif
146 #if defined(MBEDTLS_SHA1_C)
147 if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
148 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
149 #endif
150 #if defined(MBEDTLS_SHA256_C)
151 if( !strcmp( "SHA224", md_name ) )
152 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
153 if( !strcmp( "SHA256", md_name ) )
154 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
155 #endif
156 #if defined(MBEDTLS_SHA512_C)
157 if( !strcmp( "SHA384", md_name ) )
158 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
159 if( !strcmp( "SHA512", md_name ) )
160 return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
161 #endif
162 return( NULL );
163 }
164
mbedtls_md_info_from_type(mbedtls_md_type_t md_type)165 const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
166 {
167 switch( md_type )
168 {
169 #if defined(MBEDTLS_MD2_C)
170 case MBEDTLS_MD_MD2:
171 return( &mbedtls_md2_info );
172 #endif
173 #if defined(MBEDTLS_MD4_C)
174 case MBEDTLS_MD_MD4:
175 return( &mbedtls_md4_info );
176 #endif
177 #if defined(MBEDTLS_MD5_C)
178 case MBEDTLS_MD_MD5:
179 return( &mbedtls_md5_info );
180 #endif
181 #if defined(MBEDTLS_RIPEMD160_C)
182 case MBEDTLS_MD_RIPEMD160:
183 return( &mbedtls_ripemd160_info );
184 #endif
185 #if defined(MBEDTLS_SHA1_C)
186 case MBEDTLS_MD_SHA1:
187 return( &mbedtls_sha1_info );
188 #endif
189 #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 );
194 #endif
195 #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 );
200 #endif
201 default:
202 return( NULL );
203 }
204 }
205
mbedtls_md_init(mbedtls_md_context_t * ctx)206 void mbedtls_md_init( mbedtls_md_context_t *ctx )
207 {
208 memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
209 }
210
mbedtls_md_free(mbedtls_md_context_t * ctx)211 void mbedtls_md_free( mbedtls_md_context_t *ctx )
212 {
213 if( ctx == NULL || ctx->md_info == NULL )
214 return;
215
216 if( ctx->md_ctx != NULL )
217 ctx->md_info->ctx_free_func( ctx->md_ctx );
218
219 if( ctx->hmac_ctx != NULL )
220 {
221 mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size );
222 mbedtls_free( ctx->hmac_ctx );
223 }
224
225 mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
226 }
227
mbedtls_md_clone(mbedtls_md_context_t * dst,const mbedtls_md_context_t * src)228 int 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
243 #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
mbedtls_md_init_ctx(mbedtls_md_context_t * ctx,const mbedtls_md_info_t * md_info)244 int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
245 {
246 return mbedtls_md_setup( ctx, md_info, 1 );
247 }
248 #endif
249
mbedtls_md_setup(mbedtls_md_context_t * ctx,const mbedtls_md_info_t * md_info,int hmac)250 int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
251 {
252 if( md_info == NULL || ctx == NULL )
253 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
254
255 if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
256 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
257
258 if( hmac != 0 )
259 {
260 ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
261 if( ctx->hmac_ctx == NULL )
262 {
263 md_info->ctx_free_func( ctx->md_ctx );
264 return( MBEDTLS_ERR_MD_ALLOC_FAILED );
265 }
266 }
267
268 ctx->md_info = md_info;
269
270 return( 0 );
271 }
272
mbedtls_md_starts(mbedtls_md_context_t * ctx)273 int mbedtls_md_starts( mbedtls_md_context_t *ctx )
274 {
275 if( ctx == NULL || ctx->md_info == NULL )
276 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
277
278 return( ctx->md_info->starts_func( ctx->md_ctx ) );
279 }
280
mbedtls_md_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)281 int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
282 {
283 if( ctx == NULL || ctx->md_info == NULL )
284 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
285
286 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
287 }
288
mbedtls_md_finish(mbedtls_md_context_t * ctx,unsigned char * output)289 int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
290 {
291 if( ctx == NULL || ctx->md_info == NULL )
292 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
293
294 return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
295 }
296
mbedtls_md(const mbedtls_md_info_t * md_info,const unsigned char * input,size_t ilen,unsigned char * output)297 int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
298 unsigned char *output )
299 {
300 if( md_info == NULL )
301 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
302
303 return( md_info->digest_func( input, ilen, output ) );
304 }
305
306 #if defined(MBEDTLS_FS_IO)
mbedtls_md_file(const mbedtls_md_info_t * md_info,const char * path,unsigned char * output)307 int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
308 {
309 int ret;
310 FILE *f;
311 size_t n;
312 mbedtls_md_context_t ctx;
313 unsigned char buf[1024];
314
315 if( md_info == NULL )
316 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
317
318 if( ( f = fopen( path, "rb" ) ) == NULL )
319 return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
320
321 mbedtls_md_init( &ctx );
322
323 if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
324 goto cleanup;
325
326 if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
327 goto cleanup;
328
329 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
330 if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
331 goto cleanup;
332
333 if( ferror( f ) != 0 )
334 ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
335 else
336 ret = md_info->finish_func( ctx.md_ctx, output );
337
338 cleanup:
339 mbedtls_zeroize( buf, sizeof( buf ) );
340 fclose( f );
341 mbedtls_md_free( &ctx );
342
343 return( ret );
344 }
345 #endif /* MBEDTLS_FS_IO */
346
mbedtls_md_hmac_starts(mbedtls_md_context_t * ctx,const unsigned char * key,size_t keylen)347 int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
348 {
349 int ret;
350 unsigned char sum[MBEDTLS_MD_MAX_SIZE];
351 unsigned char *ipad, *opad;
352 size_t i;
353
354 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
355 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
356
357 if( keylen > (size_t) ctx->md_info->block_size )
358 {
359 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;
365
366 keylen = ctx->md_info->size;
367 key = sum;
368 }
369
370 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 );
375
376 for( i = 0; i < keylen; i++ )
377 {
378 ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
379 opad[i] = (unsigned char)( opad[i] ^ key[i] );
380 }
381
382 if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
383 goto cleanup;
384 if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
385 ctx->md_info->block_size ) ) != 0 )
386 goto cleanup;
387
388 cleanup:
389 mbedtls_zeroize( sum, sizeof( sum ) );
390
391 return( ret );
392 }
393
mbedtls_md_hmac_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)394 int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
395 {
396 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
397 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
398
399 return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
400 }
401
mbedtls_md_hmac_finish(mbedtls_md_context_t * ctx,unsigned char * output)402 int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
403 {
404 int ret;
405 unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
406 unsigned char *opad;
407
408 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
409 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
410
411 opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
412
413 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 ) );
424 }
425
mbedtls_md_hmac_reset(mbedtls_md_context_t * ctx)426 int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
427 {
428 int ret;
429 unsigned char *ipad;
430
431 if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
432 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
433
434 ipad = (unsigned char *) ctx->hmac_ctx;
435
436 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 ) );
440 }
441
mbedtls_md_hmac(const mbedtls_md_info_t * md_info,const unsigned char * key,size_t keylen,const unsigned char * input,size_t ilen,unsigned char * output)442 int 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 )
446 {
447 mbedtls_md_context_t ctx;
448 int ret;
449
450 if( md_info == NULL )
451 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
452
453 mbedtls_md_init( &ctx );
454
455 if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
456 goto cleanup;
457
458 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;
462 if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
463 goto cleanup;
464
465 cleanup:
466 mbedtls_md_free( &ctx );
467
468 return( ret );
469 }
470
mbedtls_md_process(mbedtls_md_context_t * ctx,const unsigned char * data)471 int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
472 {
473 if( ctx == NULL || ctx->md_info == NULL )
474 return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
475
476 return( ctx->md_info->process_func( ctx->md_ctx, data ) );
477 }
478
mbedtls_md_get_size(const mbedtls_md_info_t * md_info)479 unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
480 {
481 if( md_info == NULL )
482 return( 0 );
483
484 return md_info->size;
485 }
486
mbedtls_md_get_type(const mbedtls_md_info_t * md_info)487 mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
488 {
489 if( md_info == NULL )
490 return( MBEDTLS_MD_NONE );
491
492 return md_info->type;
493 }
494
mbedtls_md_get_name(const mbedtls_md_info_t * md_info)495 const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
496 {
497 if( md_info == NULL )
498 return( NULL );
499
500 return md_info->name;
501 }
502
503 #endif /* MBEDTLS_MD_C */
504