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