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