1 | /** |
2 | * \file 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 |
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. |
22 | */ |
23 | |
24 | #include "common.h" |
25 | |
26 | #if defined(MBEDTLS_MD_C) |
27 | |
28 | #include "mbedtls/md.h" |
29 | #include "md_wrap.h" |
30 | #include "mbedtls/platform_util.h" |
31 | #include "mbedtls/error.h" |
32 | |
33 | #if defined(MBEDTLS_MD5_C) |
34 | #include "mbedtls/md5.h" |
35 | #endif |
36 | #if defined(MBEDTLS_RIPEMD160_C) |
37 | #include "mbedtls/ripemd160.h" |
38 | #endif |
39 | #if defined(MBEDTLS_SHA1_C) |
40 | #include "mbedtls/sha1.h" |
41 | #endif |
42 | #if defined(MBEDTLS_SHA256_C) |
43 | #include "mbedtls/sha256.h" |
44 | #endif |
45 | #if defined(MBEDTLS_SHA512_C) |
46 | #include "mbedtls/sha512.h" |
47 | #endif |
48 | |
49 | #if defined(MBEDTLS_PLATFORM_C) |
50 | #include "mbedtls/platform.h" |
51 | #else |
52 | #include <stdlib.h> |
53 | #define mbedtls_calloc calloc |
54 | #define mbedtls_free free |
55 | #endif |
56 | |
57 | #include <string.h> |
58 | |
59 | #if defined(MBEDTLS_FS_IO) |
60 | #include <stdio.h> |
61 | #endif |
62 | |
63 | #if defined(MBEDTLS_MD5_C) |
64 | const mbedtls_md_info_t mbedtls_md5_info = { |
65 | "MD5" , |
66 | MBEDTLS_MD_MD5, |
67 | 16, |
68 | 64, |
69 | }; |
70 | #endif |
71 | |
72 | #if defined(MBEDTLS_RIPEMD160_C) |
73 | const mbedtls_md_info_t mbedtls_ripemd160_info = { |
74 | "RIPEMD160" , |
75 | MBEDTLS_MD_RIPEMD160, |
76 | 20, |
77 | 64, |
78 | }; |
79 | #endif |
80 | |
81 | #if defined(MBEDTLS_SHA1_C) |
82 | const mbedtls_md_info_t mbedtls_sha1_info = { |
83 | "SHA1" , |
84 | MBEDTLS_MD_SHA1, |
85 | 20, |
86 | 64, |
87 | }; |
88 | #endif |
89 | |
90 | #if defined(MBEDTLS_SHA224_C) |
91 | const mbedtls_md_info_t mbedtls_sha224_info = { |
92 | .name: "SHA224" , |
93 | .type: MBEDTLS_MD_SHA224, |
94 | .size: 28, |
95 | .block_size: 64, |
96 | }; |
97 | #endif |
98 | |
99 | #if defined(MBEDTLS_SHA256_C) |
100 | const mbedtls_md_info_t mbedtls_sha256_info = { |
101 | .name: "SHA256" , |
102 | .type: MBEDTLS_MD_SHA256, |
103 | .size: 32, |
104 | .block_size: 64, |
105 | }; |
106 | #endif |
107 | |
108 | #if defined(MBEDTLS_SHA384_C) |
109 | const mbedtls_md_info_t mbedtls_sha384_info = { |
110 | "SHA384" , |
111 | MBEDTLS_MD_SHA384, |
112 | 48, |
113 | 128, |
114 | }; |
115 | #endif |
116 | |
117 | #if defined(MBEDTLS_SHA512_C) |
118 | const mbedtls_md_info_t mbedtls_sha512_info = { |
119 | "SHA512" , |
120 | MBEDTLS_MD_SHA512, |
121 | 64, |
122 | 128, |
123 | }; |
124 | #endif |
125 | |
126 | /* |
127 | * Reminder: update profiles in x509_crt.c when adding a new hash! |
128 | */ |
129 | static const int supported_digests[] = { |
130 | |
131 | #if defined(MBEDTLS_SHA512_C) |
132 | MBEDTLS_MD_SHA512, |
133 | #endif |
134 | |
135 | #if defined(MBEDTLS_SHA384_C) |
136 | MBEDTLS_MD_SHA384, |
137 | #endif |
138 | |
139 | #if defined(MBEDTLS_SHA256_C) |
140 | MBEDTLS_MD_SHA256, |
141 | #endif |
142 | #if defined(MBEDTLS_SHA224_C) |
143 | MBEDTLS_MD_SHA224, |
144 | #endif |
145 | |
146 | #if defined(MBEDTLS_SHA1_C) |
147 | MBEDTLS_MD_SHA1, |
148 | #endif |
149 | |
150 | #if defined(MBEDTLS_RIPEMD160_C) |
151 | MBEDTLS_MD_RIPEMD160, |
152 | #endif |
153 | |
154 | #if defined(MBEDTLS_MD5_C) |
155 | MBEDTLS_MD_MD5, |
156 | #endif |
157 | |
158 | MBEDTLS_MD_NONE |
159 | }; |
160 | |
161 | const int *mbedtls_md_list( void ) |
162 | { |
163 | return( supported_digests ); |
164 | } |
165 | |
166 | const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) |
167 | { |
168 | if( NULL == md_name ) |
169 | return( NULL ); |
170 | |
171 | /* Get the appropriate digest information */ |
172 | #if defined(MBEDTLS_MD5_C) |
173 | if( !strcmp( "MD5" , md_name ) ) |
174 | return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); |
175 | #endif |
176 | #if defined(MBEDTLS_RIPEMD160_C) |
177 | if( !strcmp( "RIPEMD160" , md_name ) ) |
178 | return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); |
179 | #endif |
180 | #if defined(MBEDTLS_SHA1_C) |
181 | if( !strcmp( "SHA1" , md_name ) || !strcmp( "SHA" , md_name ) ) |
182 | return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); |
183 | #endif |
184 | #if defined(MBEDTLS_SHA224_C) |
185 | if( !strcmp( s1: "SHA224" , s2: md_name ) ) |
186 | return mbedtls_md_info_from_type( md_type: MBEDTLS_MD_SHA224 ); |
187 | #endif |
188 | #if defined(MBEDTLS_SHA256_C) |
189 | if( !strcmp( s1: "SHA256" , s2: md_name ) ) |
190 | return mbedtls_md_info_from_type( md_type: MBEDTLS_MD_SHA256 ); |
191 | #endif |
192 | #if defined(MBEDTLS_SHA384_C) |
193 | if( !strcmp( "SHA384" , md_name ) ) |
194 | return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); |
195 | #endif |
196 | #if defined(MBEDTLS_SHA512_C) |
197 | if( !strcmp( "SHA512" , md_name ) ) |
198 | return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); |
199 | #endif |
200 | return( NULL ); |
201 | } |
202 | |
203 | const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) |
204 | { |
205 | switch( md_type ) |
206 | { |
207 | #if defined(MBEDTLS_MD5_C) |
208 | case MBEDTLS_MD_MD5: |
209 | return( &mbedtls_md5_info ); |
210 | #endif |
211 | #if defined(MBEDTLS_RIPEMD160_C) |
212 | case MBEDTLS_MD_RIPEMD160: |
213 | return( &mbedtls_ripemd160_info ); |
214 | #endif |
215 | #if defined(MBEDTLS_SHA1_C) |
216 | case MBEDTLS_MD_SHA1: |
217 | return( &mbedtls_sha1_info ); |
218 | #endif |
219 | #if defined(MBEDTLS_SHA224_C) |
220 | case MBEDTLS_MD_SHA224: |
221 | return( &mbedtls_sha224_info ); |
222 | #endif |
223 | #if defined(MBEDTLS_SHA256_C) |
224 | case MBEDTLS_MD_SHA256: |
225 | return( &mbedtls_sha256_info ); |
226 | #endif |
227 | #if defined(MBEDTLS_SHA384_C) |
228 | case MBEDTLS_MD_SHA384: |
229 | return( &mbedtls_sha384_info ); |
230 | #endif |
231 | #if defined(MBEDTLS_SHA512_C) |
232 | case MBEDTLS_MD_SHA512: |
233 | return( &mbedtls_sha512_info ); |
234 | #endif |
235 | default: |
236 | return( NULL ); |
237 | } |
238 | } |
239 | |
240 | void mbedtls_md_init( mbedtls_md_context_t *ctx ) |
241 | { |
242 | memset( s: ctx, c: 0, n: sizeof( mbedtls_md_context_t ) ); |
243 | } |
244 | |
245 | void mbedtls_md_free( mbedtls_md_context_t *ctx ) |
246 | { |
247 | if( ctx == NULL || ctx->md_info == NULL ) |
248 | return; |
249 | |
250 | if( ctx->md_ctx != NULL ) |
251 | { |
252 | switch( ctx->md_info->type ) |
253 | { |
254 | #if defined(MBEDTLS_MD5_C) |
255 | case MBEDTLS_MD_MD5: |
256 | mbedtls_md5_free( ctx->md_ctx ); |
257 | break; |
258 | #endif |
259 | #if defined(MBEDTLS_RIPEMD160_C) |
260 | case MBEDTLS_MD_RIPEMD160: |
261 | mbedtls_ripemd160_free( ctx->md_ctx ); |
262 | break; |
263 | #endif |
264 | #if defined(MBEDTLS_SHA1_C) |
265 | case MBEDTLS_MD_SHA1: |
266 | mbedtls_sha1_free( ctx->md_ctx ); |
267 | break; |
268 | #endif |
269 | #if defined(MBEDTLS_SHA224_C) |
270 | case MBEDTLS_MD_SHA224: |
271 | mbedtls_sha256_free(ctx: (mbedtls_sha256_context *) ctx->md_ctx ); |
272 | break; |
273 | #endif |
274 | #if defined(MBEDTLS_SHA256_C) |
275 | case MBEDTLS_MD_SHA256: |
276 | mbedtls_sha256_free(ctx: (mbedtls_sha256_context *) ctx->md_ctx ); |
277 | break; |
278 | #endif |
279 | #if defined(MBEDTLS_SHA384_C) |
280 | case MBEDTLS_MD_SHA384: |
281 | mbedtls_sha512_free( ctx->md_ctx ); |
282 | break; |
283 | #endif |
284 | #if defined(MBEDTLS_SHA512_C) |
285 | case MBEDTLS_MD_SHA512: |
286 | mbedtls_sha512_free( ctx->md_ctx ); |
287 | break; |
288 | #endif |
289 | default: |
290 | /* Shouldn't happen */ |
291 | break; |
292 | } |
293 | mbedtls_free( ptr: ctx->md_ctx ); |
294 | } |
295 | |
296 | if( ctx->hmac_ctx != NULL ) |
297 | { |
298 | mbedtls_platform_zeroize( buf: ctx->hmac_ctx, |
299 | len: 2 * ctx->md_info->block_size ); |
300 | mbedtls_free( ptr: ctx->hmac_ctx ); |
301 | } |
302 | |
303 | mbedtls_platform_zeroize( buf: ctx, len: sizeof( mbedtls_md_context_t ) ); |
304 | } |
305 | |
306 | int mbedtls_md_clone( mbedtls_md_context_t *dst, |
307 | const mbedtls_md_context_t *src ) |
308 | { |
309 | if( dst == NULL || dst->md_info == NULL || |
310 | src == NULL || src->md_info == NULL || |
311 | dst->md_info != src->md_info ) |
312 | { |
313 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
314 | } |
315 | |
316 | switch( src->md_info->type ) |
317 | { |
318 | #if defined(MBEDTLS_MD5_C) |
319 | case MBEDTLS_MD_MD5: |
320 | mbedtls_md5_clone( dst->md_ctx, src->md_ctx ); |
321 | break; |
322 | #endif |
323 | #if defined(MBEDTLS_RIPEMD160_C) |
324 | case MBEDTLS_MD_RIPEMD160: |
325 | mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx ); |
326 | break; |
327 | #endif |
328 | #if defined(MBEDTLS_SHA1_C) |
329 | case MBEDTLS_MD_SHA1: |
330 | mbedtls_sha1_clone( dst->md_ctx, src->md_ctx ); |
331 | break; |
332 | #endif |
333 | #if defined(MBEDTLS_SHA224_C) |
334 | case MBEDTLS_MD_SHA224: |
335 | mbedtls_sha256_clone(dst: (mbedtls_sha256_context *) dst->md_ctx, src: (mbedtls_sha256_context *) src->md_ctx ); |
336 | break; |
337 | #endif |
338 | #if defined(MBEDTLS_SHA256_C) |
339 | case MBEDTLS_MD_SHA256: |
340 | mbedtls_sha256_clone(dst: (mbedtls_sha256_context *) dst->md_ctx, src: (mbedtls_sha256_context *)src->md_ctx ); |
341 | break; |
342 | #endif |
343 | #if defined(MBEDTLS_SHA384_C) |
344 | case MBEDTLS_MD_SHA384: |
345 | mbedtls_sha512_clone( dst->md_ctx, src->md_ctx ); |
346 | break; |
347 | #endif |
348 | #if defined(MBEDTLS_SHA512_C) |
349 | case MBEDTLS_MD_SHA512: |
350 | mbedtls_sha512_clone( dst->md_ctx, src->md_ctx ); |
351 | break; |
352 | #endif |
353 | default: |
354 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
355 | } |
356 | |
357 | return( 0 ); |
358 | } |
359 | |
360 | #define ALLOC( type ) \ |
361 | do { \ |
362 | ctx->md_ctx = (mbedtls_##type##_context*) mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \ |
363 | if( ctx->md_ctx == NULL ) \ |
364 | return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \ |
365 | mbedtls_##type##_init((mbedtls_##type##_context*) ctx->md_ctx ); \ |
366 | } \ |
367 | while( 0 ) |
368 | |
369 | int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) |
370 | { |
371 | if( md_info == NULL || ctx == NULL ) |
372 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
373 | |
374 | ctx->md_info = md_info; |
375 | ctx->md_ctx = NULL; |
376 | ctx->hmac_ctx = NULL; |
377 | |
378 | switch( md_info->type ) |
379 | { |
380 | #if defined(MBEDTLS_MD5_C) |
381 | case MBEDTLS_MD_MD5: |
382 | ALLOC( md5 ); |
383 | break; |
384 | #endif |
385 | #if defined(MBEDTLS_RIPEMD160_C) |
386 | case MBEDTLS_MD_RIPEMD160: |
387 | ALLOC( ripemd160 ); |
388 | break; |
389 | #endif |
390 | #if defined(MBEDTLS_SHA1_C) |
391 | case MBEDTLS_MD_SHA1: |
392 | ALLOC( sha1 ); |
393 | break; |
394 | #endif |
395 | #if defined(MBEDTLS_SHA224_C) |
396 | case MBEDTLS_MD_SHA224: |
397 | ALLOC( sha256 ); |
398 | break; |
399 | #endif |
400 | #if defined(MBEDTLS_SHA256_C) |
401 | case MBEDTLS_MD_SHA256: |
402 | ALLOC( sha256 ); |
403 | break; |
404 | #endif |
405 | #if defined(MBEDTLS_SHA384_C) |
406 | case MBEDTLS_MD_SHA384: |
407 | ALLOC( sha512 ); |
408 | break; |
409 | #endif |
410 | #if defined(MBEDTLS_SHA512_C) |
411 | case MBEDTLS_MD_SHA512: |
412 | ALLOC( sha512 ); |
413 | break; |
414 | #endif |
415 | default: |
416 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
417 | } |
418 | |
419 | if( hmac != 0 ) |
420 | { |
421 | ctx->hmac_ctx = mbedtls_calloc( nmemb: 2, size: md_info->block_size ); |
422 | if( ctx->hmac_ctx == NULL ) |
423 | { |
424 | mbedtls_md_free( ctx ); |
425 | return( MBEDTLS_ERR_MD_ALLOC_FAILED ); |
426 | } |
427 | } |
428 | |
429 | return( 0 ); |
430 | } |
431 | #undef ALLOC |
432 | |
433 | int mbedtls_md_starts( mbedtls_md_context_t *ctx ) |
434 | { |
435 | if( ctx == NULL || ctx->md_info == NULL ) |
436 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
437 | |
438 | switch( ctx->md_info->type ) |
439 | { |
440 | #if defined(MBEDTLS_MD5_C) |
441 | case MBEDTLS_MD_MD5: |
442 | return( mbedtls_md5_starts( ctx->md_ctx ) ); |
443 | #endif |
444 | #if defined(MBEDTLS_RIPEMD160_C) |
445 | case MBEDTLS_MD_RIPEMD160: |
446 | return( mbedtls_ripemd160_starts( ctx->md_ctx ) ); |
447 | #endif |
448 | #if defined(MBEDTLS_SHA1_C) |
449 | case MBEDTLS_MD_SHA1: |
450 | return( mbedtls_sha1_starts( ctx->md_ctx ) ); |
451 | #endif |
452 | #if defined(MBEDTLS_SHA224_C) |
453 | case MBEDTLS_MD_SHA224: |
454 | return( mbedtls_sha256_starts( ctx: (mbedtls_sha256_context *)ctx->md_ctx, is224: 1 ) ); |
455 | #endif |
456 | #if defined(MBEDTLS_SHA256_C) |
457 | case MBEDTLS_MD_SHA256: |
458 | return( mbedtls_sha256_starts( ctx: (mbedtls_sha256_context *) ctx->md_ctx, is224: 0 ) ); |
459 | #endif |
460 | #if defined(MBEDTLS_SHA384_C) |
461 | case MBEDTLS_MD_SHA384: |
462 | return( mbedtls_sha512_starts( ctx->md_ctx, 1 ) ); |
463 | #endif |
464 | #if defined(MBEDTLS_SHA512_C) |
465 | case MBEDTLS_MD_SHA512: |
466 | return( mbedtls_sha512_starts( ctx->md_ctx, 0 ) ); |
467 | #endif |
468 | default: |
469 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
470 | } |
471 | } |
472 | |
473 | int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) |
474 | { |
475 | if( ctx == NULL || ctx->md_info == NULL ) |
476 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
477 | |
478 | switch( ctx->md_info->type ) |
479 | { |
480 | #if defined(MBEDTLS_MD5_C) |
481 | case MBEDTLS_MD_MD5: |
482 | return( mbedtls_md5_update( ctx->md_ctx, input, ilen ) ); |
483 | #endif |
484 | #if defined(MBEDTLS_RIPEMD160_C) |
485 | case MBEDTLS_MD_RIPEMD160: |
486 | return( mbedtls_ripemd160_update( ctx->md_ctx, input, ilen ) ); |
487 | #endif |
488 | #if defined(MBEDTLS_SHA1_C) |
489 | case MBEDTLS_MD_SHA1: |
490 | return( mbedtls_sha1_update( ctx->md_ctx, input, ilen ) ); |
491 | #endif |
492 | #if defined(MBEDTLS_SHA224_C) |
493 | case MBEDTLS_MD_SHA224: |
494 | return( mbedtls_sha256_update( ctx: (mbedtls_sha256_context *)ctx->md_ctx, input, ilen ) ); |
495 | #endif |
496 | #if defined(MBEDTLS_SHA256_C) |
497 | case MBEDTLS_MD_SHA256: |
498 | return( mbedtls_sha256_update( ctx: (mbedtls_sha256_context *)ctx->md_ctx, input, ilen ) ); |
499 | #endif |
500 | #if defined(MBEDTLS_SHA384_C) |
501 | case MBEDTLS_MD_SHA384: |
502 | return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) ); |
503 | #endif |
504 | #if defined(MBEDTLS_SHA512_C) |
505 | case MBEDTLS_MD_SHA512: |
506 | return( mbedtls_sha512_update( ctx->md_ctx, input, ilen ) ); |
507 | #endif |
508 | default: |
509 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
510 | } |
511 | } |
512 | |
513 | int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) |
514 | { |
515 | if( ctx == NULL || ctx->md_info == NULL ) |
516 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
517 | |
518 | switch( ctx->md_info->type ) |
519 | { |
520 | #if defined(MBEDTLS_MD5_C) |
521 | case MBEDTLS_MD_MD5: |
522 | return( mbedtls_md5_finish( ctx->md_ctx, output ) ); |
523 | #endif |
524 | #if defined(MBEDTLS_RIPEMD160_C) |
525 | case MBEDTLS_MD_RIPEMD160: |
526 | return( mbedtls_ripemd160_finish( ctx->md_ctx, output ) ); |
527 | #endif |
528 | #if defined(MBEDTLS_SHA1_C) |
529 | case MBEDTLS_MD_SHA1: |
530 | return( mbedtls_sha1_finish( ctx->md_ctx, output ) ); |
531 | #endif |
532 | #if defined(MBEDTLS_SHA224_C) |
533 | case MBEDTLS_MD_SHA224: |
534 | return( mbedtls_sha256_finish(ctx: (mbedtls_sha256_context *) ctx->md_ctx, output ) ); |
535 | #endif |
536 | #if defined(MBEDTLS_SHA256_C) |
537 | case MBEDTLS_MD_SHA256: |
538 | return( mbedtls_sha256_finish(ctx: (mbedtls_sha256_context *) (mbedtls_sha256_context *)ctx->md_ctx, output ) ); |
539 | #endif |
540 | #if defined(MBEDTLS_SHA384_C) |
541 | case MBEDTLS_MD_SHA384: |
542 | return( mbedtls_sha512_finish( ctx->md_ctx, output ) ); |
543 | #endif |
544 | #if defined(MBEDTLS_SHA512_C) |
545 | case MBEDTLS_MD_SHA512: |
546 | return( mbedtls_sha512_finish( ctx->md_ctx, output ) ); |
547 | #endif |
548 | default: |
549 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
550 | } |
551 | } |
552 | |
553 | int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, |
554 | unsigned char *output ) |
555 | { |
556 | if( md_info == NULL ) |
557 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
558 | |
559 | switch( md_info->type ) |
560 | { |
561 | #if defined(MBEDTLS_MD5_C) |
562 | case MBEDTLS_MD_MD5: |
563 | return( mbedtls_md5( input, ilen, output ) ); |
564 | #endif |
565 | #if defined(MBEDTLS_RIPEMD160_C) |
566 | case MBEDTLS_MD_RIPEMD160: |
567 | return( mbedtls_ripemd160( input, ilen, output ) ); |
568 | #endif |
569 | #if defined(MBEDTLS_SHA1_C) |
570 | case MBEDTLS_MD_SHA1: |
571 | return( mbedtls_sha1( input, ilen, output ) ); |
572 | #endif |
573 | #if defined(MBEDTLS_SHA224_C) |
574 | case MBEDTLS_MD_SHA224: |
575 | return( mbedtls_sha256( input, ilen, output, is224: 1 ) ); |
576 | #endif |
577 | #if defined(MBEDTLS_SHA256_C) |
578 | case MBEDTLS_MD_SHA256: |
579 | return( mbedtls_sha256( input, ilen, output, is224: 0 ) ); |
580 | #endif |
581 | #if defined(MBEDTLS_SHA384_C) |
582 | case MBEDTLS_MD_SHA384: |
583 | return( mbedtls_sha512( input, ilen, output, 1 ) ); |
584 | #endif |
585 | #if defined(MBEDTLS_SHA512_C) |
586 | case MBEDTLS_MD_SHA512: |
587 | return( mbedtls_sha512( input, ilen, output, 0 ) ); |
588 | #endif |
589 | default: |
590 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
591 | } |
592 | } |
593 | |
594 | #if defined(MBEDTLS_FS_IO) |
595 | int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) |
596 | { |
597 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
598 | FILE *f; |
599 | size_t n; |
600 | mbedtls_md_context_t ctx; |
601 | unsigned char buf[1024]; |
602 | |
603 | if( md_info == NULL ) |
604 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
605 | |
606 | if( ( f = fopen( path, "rb" ) ) == NULL ) |
607 | return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); |
608 | |
609 | mbedtls_md_init( &ctx ); |
610 | |
611 | if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) |
612 | goto cleanup; |
613 | |
614 | if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 ) |
615 | goto cleanup; |
616 | |
617 | while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) |
618 | if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 ) |
619 | goto cleanup; |
620 | |
621 | if( ferror( f ) != 0 ) |
622 | ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; |
623 | else |
624 | ret = mbedtls_md_finish( &ctx, output ); |
625 | |
626 | cleanup: |
627 | mbedtls_platform_zeroize( buf, sizeof( buf ) ); |
628 | fclose( f ); |
629 | mbedtls_md_free( &ctx ); |
630 | |
631 | return( ret ); |
632 | } |
633 | #endif /* MBEDTLS_FS_IO */ |
634 | |
635 | int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) |
636 | { |
637 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
638 | unsigned char sum[MBEDTLS_MD_MAX_SIZE]; |
639 | unsigned char *ipad, *opad; |
640 | size_t i; |
641 | |
642 | if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
643 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
644 | |
645 | if( keylen > (size_t) ctx->md_info->block_size ) |
646 | { |
647 | if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) |
648 | goto cleanup; |
649 | if( ( ret = mbedtls_md_update( ctx, input: key, ilen: keylen ) ) != 0 ) |
650 | goto cleanup; |
651 | if( ( ret = mbedtls_md_finish( ctx, output: sum ) ) != 0 ) |
652 | goto cleanup; |
653 | |
654 | keylen = ctx->md_info->size; |
655 | key = sum; |
656 | } |
657 | |
658 | ipad = (unsigned char *) ctx->hmac_ctx; |
659 | opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; |
660 | |
661 | memset( s: ipad, c: 0x36, n: ctx->md_info->block_size ); |
662 | memset( s: opad, c: 0x5C, n: ctx->md_info->block_size ); |
663 | |
664 | for( i = 0; i < keylen; i++ ) |
665 | { |
666 | ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); |
667 | opad[i] = (unsigned char)( opad[i] ^ key[i] ); |
668 | } |
669 | |
670 | if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) |
671 | goto cleanup; |
672 | if( ( ret = mbedtls_md_update( ctx, input: ipad, |
673 | ilen: ctx->md_info->block_size ) ) != 0 ) |
674 | goto cleanup; |
675 | |
676 | cleanup: |
677 | mbedtls_platform_zeroize( buf: sum, len: sizeof( sum ) ); |
678 | |
679 | return( ret ); |
680 | } |
681 | |
682 | int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) |
683 | { |
684 | if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
685 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
686 | |
687 | return( mbedtls_md_update( ctx, input, ilen ) ); |
688 | } |
689 | |
690 | int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) |
691 | { |
692 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
693 | unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; |
694 | unsigned char *opad; |
695 | |
696 | if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
697 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
698 | |
699 | opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; |
700 | |
701 | if( ( ret = mbedtls_md_finish( ctx, output: tmp ) ) != 0 ) |
702 | return( ret ); |
703 | if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) |
704 | return( ret ); |
705 | if( ( ret = mbedtls_md_update( ctx, input: opad, |
706 | ilen: ctx->md_info->block_size ) ) != 0 ) |
707 | return( ret ); |
708 | if( ( ret = mbedtls_md_update( ctx, input: tmp, |
709 | ilen: ctx->md_info->size ) ) != 0 ) |
710 | return( ret ); |
711 | return( mbedtls_md_finish( ctx, output ) ); |
712 | } |
713 | |
714 | int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) |
715 | { |
716 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
717 | unsigned char *ipad; |
718 | |
719 | if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) |
720 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
721 | |
722 | ipad = (unsigned char *) ctx->hmac_ctx; |
723 | |
724 | if( ( ret = mbedtls_md_starts( ctx ) ) != 0 ) |
725 | return( ret ); |
726 | return( mbedtls_md_update( ctx, input: ipad, ilen: ctx->md_info->block_size ) ); |
727 | } |
728 | |
729 | int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, |
730 | const unsigned char *key, size_t keylen, |
731 | const unsigned char *input, size_t ilen, |
732 | unsigned char *output ) |
733 | { |
734 | mbedtls_md_context_t ctx; |
735 | int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; |
736 | |
737 | if( md_info == NULL ) |
738 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
739 | |
740 | mbedtls_md_init( ctx: &ctx ); |
741 | |
742 | if( ( ret = mbedtls_md_setup( ctx: &ctx, md_info, hmac: 1 ) ) != 0 ) |
743 | goto cleanup; |
744 | |
745 | if( ( ret = mbedtls_md_hmac_starts( ctx: &ctx, key, keylen ) ) != 0 ) |
746 | goto cleanup; |
747 | if( ( ret = mbedtls_md_hmac_update( ctx: &ctx, input, ilen ) ) != 0 ) |
748 | goto cleanup; |
749 | if( ( ret = mbedtls_md_hmac_finish( ctx: &ctx, output ) ) != 0 ) |
750 | goto cleanup; |
751 | |
752 | cleanup: |
753 | mbedtls_md_free( ctx: &ctx ); |
754 | |
755 | return( ret ); |
756 | } |
757 | |
758 | int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) |
759 | { |
760 | if( ctx == NULL || ctx->md_info == NULL ) |
761 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
762 | |
763 | switch( ctx->md_info->type ) |
764 | { |
765 | #if defined(MBEDTLS_MD5_C) |
766 | case MBEDTLS_MD_MD5: |
767 | return( mbedtls_internal_md5_process( ctx->md_ctx, data ) ); |
768 | #endif |
769 | #if defined(MBEDTLS_RIPEMD160_C) |
770 | case MBEDTLS_MD_RIPEMD160: |
771 | return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) ); |
772 | #endif |
773 | #if defined(MBEDTLS_SHA1_C) |
774 | case MBEDTLS_MD_SHA1: |
775 | return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) ); |
776 | #endif |
777 | #if defined(MBEDTLS_SHA224_C) |
778 | case MBEDTLS_MD_SHA224: |
779 | return( mbedtls_internal_sha256_process(ctx: (mbedtls_sha256_context *) ctx->md_ctx, data ) ); |
780 | #endif |
781 | #if defined(MBEDTLS_SHA256_C) |
782 | case MBEDTLS_MD_SHA256: |
783 | return( mbedtls_internal_sha256_process(ctx: (mbedtls_sha256_context *) ctx->md_ctx, data ) ); |
784 | #endif |
785 | #if defined(MBEDTLS_SHA384_C) |
786 | case MBEDTLS_MD_SHA384: |
787 | return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) ); |
788 | #endif |
789 | #if defined(MBEDTLS_SHA512_C) |
790 | case MBEDTLS_MD_SHA512: |
791 | return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) ); |
792 | #endif |
793 | default: |
794 | return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); |
795 | } |
796 | } |
797 | |
798 | unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) |
799 | { |
800 | if( md_info == NULL ) |
801 | return( 0 ); |
802 | |
803 | return md_info->size; |
804 | } |
805 | |
806 | mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) |
807 | { |
808 | if( md_info == NULL ) |
809 | return( MBEDTLS_MD_NONE ); |
810 | |
811 | return md_info->type; |
812 | } |
813 | |
814 | const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) |
815 | { |
816 | if( md_info == NULL ) |
817 | return( NULL ); |
818 | |
819 | return md_info->name; |
820 | } |
821 | |
822 | #endif /* MBEDTLS_MD_C */ |
823 | |