• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /*
27  * Availability of functions in this module is controlled by two
28  * feature macros:
29  * - MBEDTLS_MD_C enables the whole module;
30  * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing
31  * most hash metadata (everything except string names); is it
32  * automatically set whenever MBEDTLS_MD_C is defined.
33  *
34  * In this file, functions from MD_LIGHT are at the top, MD_C at the end.
35  *
36  * In the future we may want to change the contract of some functions
37  * (behaviour with NULL arguments) depending on whether MD_C is defined or
38  * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary.
39  *
40  * For these reasons, we're keeping MD_LIGHT internal for now.
41  */
42 #if defined(MBEDTLS_MD_LIGHT)
43 
44 #include "mbedtls/md.h"
45 #include "md_wrap.h"
46 #include "mbedtls/platform_util.h"
47 #include "mbedtls/error.h"
48 
49 #include "mbedtls/md5.h"
50 #include "mbedtls/ripemd160.h"
51 #include "mbedtls/sha1.h"
52 #include "mbedtls/sha256.h"
53 #include "mbedtls/sha512.h"
54 
55 #if defined(MBEDTLS_MD_SOME_PSA)
56 #include <psa/crypto.h>
57 #include "psa_crypto_core.h"
58 #endif
59 
60 #include "mbedtls/platform.h"
61 
62 #include <string.h>
63 
64 #if defined(MBEDTLS_FS_IO)
65 #include <stdio.h>
66 #endif
67 
68 #if defined(MBEDTLS_MD_CAN_MD5)
69 const mbedtls_md_info_t mbedtls_md5_info = {
70     "MD5",
71     MBEDTLS_MD_MD5,
72     16,
73     64,
74 };
75 #endif
76 
77 #if defined(MBEDTLS_MD_CAN_RIPEMD160)
78 const mbedtls_md_info_t mbedtls_ripemd160_info = {
79     "RIPEMD160",
80     MBEDTLS_MD_RIPEMD160,
81     20,
82     64,
83 };
84 #endif
85 
86 #if defined(MBEDTLS_MD_CAN_SHA1)
87 const mbedtls_md_info_t mbedtls_sha1_info = {
88     "SHA1",
89     MBEDTLS_MD_SHA1,
90     20,
91     64,
92 };
93 #endif
94 
95 #if defined(MBEDTLS_MD_CAN_SHA224)
96 const mbedtls_md_info_t mbedtls_sha224_info = {
97     "SHA224",
98     MBEDTLS_MD_SHA224,
99     28,
100     64,
101 };
102 #endif
103 
104 #if defined(MBEDTLS_MD_CAN_SHA256)
105 const mbedtls_md_info_t mbedtls_sha256_info = {
106     "SHA256",
107     MBEDTLS_MD_SHA256,
108     32,
109     64,
110 };
111 #endif
112 
113 #if defined(MBEDTLS_MD_CAN_SHA384)
114 const mbedtls_md_info_t mbedtls_sha384_info = {
115     "SHA384",
116     MBEDTLS_MD_SHA384,
117     48,
118     128,
119 };
120 #endif
121 
122 #if defined(MBEDTLS_MD_CAN_SHA512)
123 const mbedtls_md_info_t mbedtls_sha512_info = {
124     "SHA512",
125     MBEDTLS_MD_SHA512,
126     64,
127     128,
128 };
129 #endif
130 
mbedtls_md_info_from_type(mbedtls_md_type_t md_type)131 const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
132 {
133     switch (md_type) {
134 #if defined(MBEDTLS_MD_CAN_MD5)
135         case MBEDTLS_MD_MD5:
136             return &mbedtls_md5_info;
137 #endif
138 #if defined(MBEDTLS_MD_CAN_RIPEMD160)
139         case MBEDTLS_MD_RIPEMD160:
140             return &mbedtls_ripemd160_info;
141 #endif
142 #if defined(MBEDTLS_MD_CAN_SHA1)
143         case MBEDTLS_MD_SHA1:
144             return &mbedtls_sha1_info;
145 #endif
146 #if defined(MBEDTLS_MD_CAN_SHA224)
147         case MBEDTLS_MD_SHA224:
148             return &mbedtls_sha224_info;
149 #endif
150 #if defined(MBEDTLS_MD_CAN_SHA256)
151         case MBEDTLS_MD_SHA256:
152             return &mbedtls_sha256_info;
153 #endif
154 #if defined(MBEDTLS_MD_CAN_SHA384)
155         case MBEDTLS_MD_SHA384:
156             return &mbedtls_sha384_info;
157 #endif
158 #if defined(MBEDTLS_MD_CAN_SHA512)
159         case MBEDTLS_MD_SHA512:
160             return &mbedtls_sha512_info;
161 #endif
162         default:
163             return NULL;
164     }
165 }
166 
167 #if defined(MBEDTLS_MD_SOME_PSA)
psa_alg_of_md(const mbedtls_md_info_t * info)168 static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info)
169 {
170     switch (info->type) {
171 #if defined(MBEDTLS_MD_MD5_VIA_PSA)
172         case MBEDTLS_MD_MD5:
173             return PSA_ALG_MD5;
174 #endif
175 #if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA)
176         case MBEDTLS_MD_RIPEMD160:
177             return PSA_ALG_RIPEMD160;
178 #endif
179 #if defined(MBEDTLS_MD_SHA1_VIA_PSA)
180         case MBEDTLS_MD_SHA1:
181             return PSA_ALG_SHA_1;
182 #endif
183 #if defined(MBEDTLS_MD_SHA224_VIA_PSA)
184         case MBEDTLS_MD_SHA224:
185             return PSA_ALG_SHA_224;
186 #endif
187 #if defined(MBEDTLS_MD_SHA256_VIA_PSA)
188         case MBEDTLS_MD_SHA256:
189             return PSA_ALG_SHA_256;
190 #endif
191 #if defined(MBEDTLS_MD_SHA384_VIA_PSA)
192         case MBEDTLS_MD_SHA384:
193             return PSA_ALG_SHA_384;
194 #endif
195 #if defined(MBEDTLS_MD_SHA512_VIA_PSA)
196         case MBEDTLS_MD_SHA512:
197             return PSA_ALG_SHA_512;
198 #endif
199         default:
200             return PSA_ALG_NONE;
201     }
202 }
203 
md_can_use_psa(const mbedtls_md_info_t * info)204 static int md_can_use_psa(const mbedtls_md_info_t *info)
205 {
206     psa_algorithm_t alg = psa_alg_of_md(info);
207     if (alg == PSA_ALG_NONE) {
208         return 0;
209     }
210 
211     return psa_can_do_hash(alg);
212 }
213 
mbedtls_md_error_from_psa(psa_status_t status)214 static int mbedtls_md_error_from_psa(psa_status_t status)
215 {
216     switch (status) {
217         case PSA_SUCCESS:
218             return 0;
219         case PSA_ERROR_NOT_SUPPORTED:
220             return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
221         case PSA_ERROR_INSUFFICIENT_MEMORY:
222             return MBEDTLS_ERR_MD_ALLOC_FAILED;
223         default:
224             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
225     }
226 }
227 #endif /* MBEDTLS_MD_SOME_PSA */
228 
mbedtls_md_init(mbedtls_md_context_t * ctx)229 void mbedtls_md_init(mbedtls_md_context_t *ctx)
230 {
231     /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */
232     memset(ctx, 0, sizeof(mbedtls_md_context_t));
233 }
234 
mbedtls_md_free(mbedtls_md_context_t * ctx)235 void mbedtls_md_free(mbedtls_md_context_t *ctx)
236 {
237     if (ctx == NULL || ctx->md_info == NULL) {
238         return;
239     }
240 
241     if (ctx->md_ctx != NULL) {
242 #if defined(MBEDTLS_MD_SOME_PSA)
243         if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
244             psa_hash_abort(ctx->md_ctx);
245         } else
246 #endif
247         switch (ctx->md_info->type) {
248 #if defined(MBEDTLS_MD5_C)
249             case MBEDTLS_MD_MD5:
250                 mbedtls_md5_free(ctx->md_ctx);
251                 break;
252 #endif
253 #if defined(MBEDTLS_RIPEMD160_C)
254             case MBEDTLS_MD_RIPEMD160:
255                 mbedtls_ripemd160_free(ctx->md_ctx);
256                 break;
257 #endif
258 #if defined(MBEDTLS_SHA1_C)
259             case MBEDTLS_MD_SHA1:
260                 mbedtls_sha1_free(ctx->md_ctx);
261                 break;
262 #endif
263 #if defined(MBEDTLS_SHA224_C)
264             case MBEDTLS_MD_SHA224:
265                 mbedtls_sha256_free(ctx->md_ctx);
266                 break;
267 #endif
268 #if defined(MBEDTLS_SHA256_C)
269             case MBEDTLS_MD_SHA256:
270                 mbedtls_sha256_free(ctx->md_ctx);
271                 break;
272 #endif
273 #if defined(MBEDTLS_SHA384_C)
274             case MBEDTLS_MD_SHA384:
275                 mbedtls_sha512_free(ctx->md_ctx);
276                 break;
277 #endif
278 #if defined(MBEDTLS_SHA512_C)
279             case MBEDTLS_MD_SHA512:
280                 mbedtls_sha512_free(ctx->md_ctx);
281                 break;
282 #endif
283             default:
284                 /* Shouldn't happen */
285                 break;
286         }
287         mbedtls_free(ctx->md_ctx);
288     }
289 
290 #if defined(MBEDTLS_MD_C)
291     if (ctx->hmac_ctx != NULL) {
292         mbedtls_platform_zeroize(ctx->hmac_ctx,
293                                  2 * ctx->md_info->block_size);
294         mbedtls_free(ctx->hmac_ctx);
295     }
296 #endif
297 
298     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t));
299 }
300 
mbedtls_md_clone(mbedtls_md_context_t * dst,const mbedtls_md_context_t * src)301 int mbedtls_md_clone(mbedtls_md_context_t *dst,
302                      const mbedtls_md_context_t *src)
303 {
304     if (dst == NULL || dst->md_info == NULL ||
305         src == NULL || src->md_info == NULL ||
306         dst->md_info != src->md_info) {
307         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
308     }
309 
310 #if defined(MBEDTLS_MD_SOME_PSA)
311     if (src->engine != dst->engine) {
312         /* This can happen with src set to legacy because PSA wasn't ready
313          * yet, and dst to PSA because it became ready in the meantime.
314          * We currently don't support that case (we'd need to re-allocate
315          * md_ctx to the size of the appropriate MD context). */
316         return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
317     }
318 
319     if (src->engine == MBEDTLS_MD_ENGINE_PSA) {
320         psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx);
321         return mbedtls_md_error_from_psa(status);
322     }
323 #endif
324 
325     switch (src->md_info->type) {
326 #if defined(MBEDTLS_MD5_C)
327         case MBEDTLS_MD_MD5:
328             mbedtls_md5_clone(dst->md_ctx, src->md_ctx);
329             break;
330 #endif
331 #if defined(MBEDTLS_RIPEMD160_C)
332         case MBEDTLS_MD_RIPEMD160:
333             mbedtls_ripemd160_clone(dst->md_ctx, src->md_ctx);
334             break;
335 #endif
336 #if defined(MBEDTLS_SHA1_C)
337         case MBEDTLS_MD_SHA1:
338             mbedtls_sha1_clone(dst->md_ctx, src->md_ctx);
339             break;
340 #endif
341 #if defined(MBEDTLS_SHA224_C)
342         case MBEDTLS_MD_SHA224:
343             mbedtls_sha256_clone(dst->md_ctx, src->md_ctx);
344             break;
345 #endif
346 #if defined(MBEDTLS_SHA256_C)
347         case MBEDTLS_MD_SHA256:
348             mbedtls_sha256_clone(dst->md_ctx, src->md_ctx);
349             break;
350 #endif
351 #if defined(MBEDTLS_SHA384_C)
352         case MBEDTLS_MD_SHA384:
353             mbedtls_sha512_clone(dst->md_ctx, src->md_ctx);
354             break;
355 #endif
356 #if defined(MBEDTLS_SHA512_C)
357         case MBEDTLS_MD_SHA512:
358             mbedtls_sha512_clone(dst->md_ctx, src->md_ctx);
359             break;
360 #endif
361         default:
362             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
363     }
364 
365     return 0;
366 }
367 
368 #define ALLOC(type)                                                   \
369     do {                                                                \
370         ctx->md_ctx = mbedtls_calloc(1, sizeof(mbedtls_##type##_context)); \
371         if (ctx->md_ctx == NULL)                                       \
372         return MBEDTLS_ERR_MD_ALLOC_FAILED;                      \
373         mbedtls_##type##_init(ctx->md_ctx);                           \
374     }                                                                   \
375     while (0)
376 
mbedtls_md_setup(mbedtls_md_context_t * ctx,const mbedtls_md_info_t * md_info,int hmac)377 int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac)
378 {
379     if (md_info == NULL || ctx == NULL) {
380         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
381     }
382 
383     ctx->md_info = md_info;
384     ctx->md_ctx = NULL;
385 #if defined(MBEDTLS_MD_C)
386     ctx->hmac_ctx = NULL;
387 #else
388     if (hmac != 0) {
389         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
390     }
391 #endif
392 
393 #if defined(MBEDTLS_MD_SOME_PSA)
394     if (md_can_use_psa(ctx->md_info)) {
395         ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t));
396         if (ctx->md_ctx == NULL) {
397             return MBEDTLS_ERR_MD_ALLOC_FAILED;
398         }
399         ctx->engine = MBEDTLS_MD_ENGINE_PSA;
400     } else
401 #endif
402     switch (md_info->type) {
403 #if defined(MBEDTLS_MD5_C)
404         case MBEDTLS_MD_MD5:
405             ALLOC(md5);
406             break;
407 #endif
408 #if defined(MBEDTLS_RIPEMD160_C)
409         case MBEDTLS_MD_RIPEMD160:
410             ALLOC(ripemd160);
411             break;
412 #endif
413 #if defined(MBEDTLS_SHA1_C)
414         case MBEDTLS_MD_SHA1:
415             ALLOC(sha1);
416             break;
417 #endif
418 #if defined(MBEDTLS_SHA224_C)
419         case MBEDTLS_MD_SHA224:
420             ALLOC(sha256);
421             break;
422 #endif
423 #if defined(MBEDTLS_SHA256_C)
424         case MBEDTLS_MD_SHA256:
425             ALLOC(sha256);
426             break;
427 #endif
428 #if defined(MBEDTLS_SHA384_C)
429         case MBEDTLS_MD_SHA384:
430             ALLOC(sha512);
431             break;
432 #endif
433 #if defined(MBEDTLS_SHA512_C)
434         case MBEDTLS_MD_SHA512:
435             ALLOC(sha512);
436             break;
437 #endif
438         default:
439             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
440     }
441 
442 #if defined(MBEDTLS_MD_C)
443     if (hmac != 0) {
444         ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size);
445         if (ctx->hmac_ctx == NULL) {
446             mbedtls_md_free(ctx);
447             return MBEDTLS_ERR_MD_ALLOC_FAILED;
448         }
449     }
450 #endif
451 
452     return 0;
453 }
454 #undef ALLOC
455 
mbedtls_md_starts(mbedtls_md_context_t * ctx)456 int mbedtls_md_starts(mbedtls_md_context_t *ctx)
457 {
458     if (ctx == NULL || ctx->md_info == NULL) {
459         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
460     }
461 
462 #if defined(MBEDTLS_MD_SOME_PSA)
463     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
464         psa_algorithm_t alg = psa_alg_of_md(ctx->md_info);
465         psa_hash_abort(ctx->md_ctx);
466         psa_status_t status = psa_hash_setup(ctx->md_ctx, alg);
467         return mbedtls_md_error_from_psa(status);
468     }
469 #endif
470 
471     switch (ctx->md_info->type) {
472 #if defined(MBEDTLS_MD5_C)
473         case MBEDTLS_MD_MD5:
474             return mbedtls_md5_starts(ctx->md_ctx);
475 #endif
476 #if defined(MBEDTLS_RIPEMD160_C)
477         case MBEDTLS_MD_RIPEMD160:
478             return mbedtls_ripemd160_starts(ctx->md_ctx);
479 #endif
480 #if defined(MBEDTLS_SHA1_C)
481         case MBEDTLS_MD_SHA1:
482             return mbedtls_sha1_starts(ctx->md_ctx);
483 #endif
484 #if defined(MBEDTLS_SHA224_C)
485         case MBEDTLS_MD_SHA224:
486             return mbedtls_sha256_starts(ctx->md_ctx, 1);
487 #endif
488 #if defined(MBEDTLS_SHA256_C)
489         case MBEDTLS_MD_SHA256:
490             return mbedtls_sha256_starts(ctx->md_ctx, 0);
491 #endif
492 #if defined(MBEDTLS_SHA384_C)
493         case MBEDTLS_MD_SHA384:
494             return mbedtls_sha512_starts(ctx->md_ctx, 1);
495 #endif
496 #if defined(MBEDTLS_SHA512_C)
497         case MBEDTLS_MD_SHA512:
498             return mbedtls_sha512_starts(ctx->md_ctx, 0);
499 #endif
500         default:
501             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
502     }
503 }
504 
mbedtls_md_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)505 int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
506 {
507     if (ctx == NULL || ctx->md_info == NULL) {
508         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
509     }
510 
511 #if defined(MBEDTLS_MD_SOME_PSA)
512     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
513         psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen);
514         return mbedtls_md_error_from_psa(status);
515     }
516 #endif
517 
518     switch (ctx->md_info->type) {
519 #if defined(MBEDTLS_MD5_C)
520         case MBEDTLS_MD_MD5:
521             return mbedtls_md5_update(ctx->md_ctx, input, ilen);
522 #endif
523 #if defined(MBEDTLS_RIPEMD160_C)
524         case MBEDTLS_MD_RIPEMD160:
525             return mbedtls_ripemd160_update(ctx->md_ctx, input, ilen);
526 #endif
527 #if defined(MBEDTLS_SHA1_C)
528         case MBEDTLS_MD_SHA1:
529             return mbedtls_sha1_update(ctx->md_ctx, input, ilen);
530 #endif
531 #if defined(MBEDTLS_SHA224_C)
532         case MBEDTLS_MD_SHA224:
533             return mbedtls_sha256_update(ctx->md_ctx, input, ilen);
534 #endif
535 #if defined(MBEDTLS_SHA256_C)
536         case MBEDTLS_MD_SHA256:
537             return mbedtls_sha256_update(ctx->md_ctx, input, ilen);
538 #endif
539 #if defined(MBEDTLS_SHA384_C)
540         case MBEDTLS_MD_SHA384:
541             return mbedtls_sha512_update(ctx->md_ctx, input, ilen);
542 #endif
543 #if defined(MBEDTLS_SHA512_C)
544         case MBEDTLS_MD_SHA512:
545             return mbedtls_sha512_update(ctx->md_ctx, input, ilen);
546 #endif
547         default:
548             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
549     }
550 }
551 
mbedtls_md_finish(mbedtls_md_context_t * ctx,unsigned char * output)552 int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
553 {
554     if (ctx == NULL || ctx->md_info == NULL) {
555         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
556     }
557 
558 #if defined(MBEDTLS_MD_SOME_PSA)
559     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
560         size_t size = ctx->md_info->size;
561         psa_status_t status = psa_hash_finish(ctx->md_ctx,
562                                               output, size, &size);
563         return mbedtls_md_error_from_psa(status);
564     }
565 #endif
566 
567     switch (ctx->md_info->type) {
568 #if defined(MBEDTLS_MD5_C)
569         case MBEDTLS_MD_MD5:
570             return mbedtls_md5_finish(ctx->md_ctx, output);
571 #endif
572 #if defined(MBEDTLS_RIPEMD160_C)
573         case MBEDTLS_MD_RIPEMD160:
574             return mbedtls_ripemd160_finish(ctx->md_ctx, output);
575 #endif
576 #if defined(MBEDTLS_SHA1_C)
577         case MBEDTLS_MD_SHA1:
578             return mbedtls_sha1_finish(ctx->md_ctx, output);
579 #endif
580 #if defined(MBEDTLS_SHA224_C)
581         case MBEDTLS_MD_SHA224:
582             return mbedtls_sha256_finish(ctx->md_ctx, output);
583 #endif
584 #if defined(MBEDTLS_SHA256_C)
585         case MBEDTLS_MD_SHA256:
586             return mbedtls_sha256_finish(ctx->md_ctx, output);
587 #endif
588 #if defined(MBEDTLS_SHA384_C)
589         case MBEDTLS_MD_SHA384:
590             return mbedtls_sha512_finish(ctx->md_ctx, output);
591 #endif
592 #if defined(MBEDTLS_SHA512_C)
593         case MBEDTLS_MD_SHA512:
594             return mbedtls_sha512_finish(ctx->md_ctx, output);
595 #endif
596         default:
597             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
598     }
599 }
600 
mbedtls_md(const mbedtls_md_info_t * md_info,const unsigned char * input,size_t ilen,unsigned char * output)601 int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
602                unsigned char *output)
603 {
604     if (md_info == NULL) {
605         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
606     }
607 
608 #if defined(MBEDTLS_MD_SOME_PSA)
609     if (md_can_use_psa(md_info)) {
610         size_t size = md_info->size;
611         psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info),
612                                                input, ilen,
613                                                output, size, &size);
614         return mbedtls_md_error_from_psa(status);
615     }
616 #endif
617 
618     switch (md_info->type) {
619 #if defined(MBEDTLS_MD5_C)
620         case MBEDTLS_MD_MD5:
621             return mbedtls_md5(input, ilen, output);
622 #endif
623 #if defined(MBEDTLS_RIPEMD160_C)
624         case MBEDTLS_MD_RIPEMD160:
625             return mbedtls_ripemd160(input, ilen, output);
626 #endif
627 #if defined(MBEDTLS_SHA1_C)
628         case MBEDTLS_MD_SHA1:
629             return mbedtls_sha1(input, ilen, output);
630 #endif
631 #if defined(MBEDTLS_SHA224_C)
632         case MBEDTLS_MD_SHA224:
633             return mbedtls_sha256(input, ilen, output, 1);
634 #endif
635 #if defined(MBEDTLS_SHA256_C)
636         case MBEDTLS_MD_SHA256:
637             return mbedtls_sha256(input, ilen, output, 0);
638 #endif
639 #if defined(MBEDTLS_SHA384_C)
640         case MBEDTLS_MD_SHA384:
641             return mbedtls_sha512(input, ilen, output, 1);
642 #endif
643 #if defined(MBEDTLS_SHA512_C)
644         case MBEDTLS_MD_SHA512:
645             return mbedtls_sha512(input, ilen, output, 0);
646 #endif
647         default:
648             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
649     }
650 }
651 
mbedtls_md_get_size(const mbedtls_md_info_t * md_info)652 unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
653 {
654     if (md_info == NULL) {
655         return 0;
656     }
657 
658     return md_info->size;
659 }
660 
mbedtls_md_get_type(const mbedtls_md_info_t * md_info)661 mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
662 {
663     if (md_info == NULL) {
664         return MBEDTLS_MD_NONE;
665     }
666 
667     return md_info->type;
668 }
669 
670 /************************************************************************
671  * Functions above this separator are part of MBEDTLS_MD_LIGHT,         *
672  * functions below are only available when MBEDTLS_MD_C is set.         *
673  ************************************************************************/
674 #if defined(MBEDTLS_MD_C)
675 
676 /*
677  * Reminder: update profiles in x509_crt.c when adding a new hash!
678  */
679 static const int supported_digests[] = {
680 
681 #if defined(MBEDTLS_MD_CAN_SHA512)
682     MBEDTLS_MD_SHA512,
683 #endif
684 
685 #if defined(MBEDTLS_MD_CAN_SHA384)
686     MBEDTLS_MD_SHA384,
687 #endif
688 
689 #if defined(MBEDTLS_MD_CAN_SHA256)
690     MBEDTLS_MD_SHA256,
691 #endif
692 #if defined(MBEDTLS_MD_CAN_SHA224)
693     MBEDTLS_MD_SHA224,
694 #endif
695 
696 #if defined(MBEDTLS_MD_CAN_SHA1)
697     MBEDTLS_MD_SHA1,
698 #endif
699 
700 #if defined(MBEDTLS_MD_CAN_RIPEMD160)
701     MBEDTLS_MD_RIPEMD160,
702 #endif
703 
704 #if defined(MBEDTLS_MD_CAN_MD5)
705     MBEDTLS_MD_MD5,
706 #endif
707 
708     MBEDTLS_MD_NONE
709 };
710 
mbedtls_md_list(void)711 const int *mbedtls_md_list(void)
712 {
713     return supported_digests;
714 }
715 
mbedtls_md_info_from_string(const char * md_name)716 const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
717 {
718     if (NULL == md_name) {
719         return NULL;
720     }
721 
722     /* Get the appropriate digest information */
723 #if defined(MBEDTLS_MD_CAN_MD5)
724     if (!strcmp("MD5", md_name)) {
725         return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
726     }
727 #endif
728 #if defined(MBEDTLS_MD_CAN_RIPEMD160)
729     if (!strcmp("RIPEMD160", md_name)) {
730         return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
731     }
732 #endif
733 #if defined(MBEDTLS_MD_CAN_SHA1)
734     if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) {
735         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
736     }
737 #endif
738 #if defined(MBEDTLS_MD_CAN_SHA224)
739     if (!strcmp("SHA224", md_name)) {
740         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
741     }
742 #endif
743 #if defined(MBEDTLS_MD_CAN_SHA256)
744     if (!strcmp("SHA256", md_name)) {
745         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
746     }
747 #endif
748 #if defined(MBEDTLS_MD_CAN_SHA384)
749     if (!strcmp("SHA384", md_name)) {
750         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
751     }
752 #endif
753 #if defined(MBEDTLS_MD_CAN_SHA512)
754     if (!strcmp("SHA512", md_name)) {
755         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
756     }
757 #endif
758     return NULL;
759 }
760 
mbedtls_md_info_from_ctx(const mbedtls_md_context_t * ctx)761 const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
762     const mbedtls_md_context_t *ctx)
763 {
764     if (ctx == NULL) {
765         return NULL;
766     }
767 
768     return ctx->MBEDTLS_PRIVATE(md_info);
769 }
770 
771 #if defined(MBEDTLS_FS_IO)
mbedtls_md_file(const mbedtls_md_info_t * md_info,const char * path,unsigned char * output)772 int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output)
773 {
774     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
775     FILE *f;
776     size_t n;
777     mbedtls_md_context_t ctx;
778     unsigned char buf[1024];
779 
780     if (md_info == NULL) {
781         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
782     }
783 
784     if ((f = fopen(path, "rb")) == NULL) {
785         return MBEDTLS_ERR_MD_FILE_IO_ERROR;
786     }
787 
788     /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
789     mbedtls_setbuf(f, NULL);
790 
791     mbedtls_md_init(&ctx);
792 
793     if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) {
794         goto cleanup;
795     }
796 
797     if ((ret = mbedtls_md_starts(&ctx)) != 0) {
798         goto cleanup;
799     }
800 
801     while ((n = fread(buf, 1, sizeof(buf), f)) > 0) {
802         if ((ret = mbedtls_md_update(&ctx, buf, n)) != 0) {
803             goto cleanup;
804         }
805     }
806 
807     if (ferror(f) != 0) {
808         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
809     } else {
810         ret = mbedtls_md_finish(&ctx, output);
811     }
812 
813 cleanup:
814     mbedtls_platform_zeroize(buf, sizeof(buf));
815     fclose(f);
816     mbedtls_md_free(&ctx);
817 
818     return ret;
819 }
820 #endif /* MBEDTLS_FS_IO */
821 
mbedtls_md_hmac_starts(mbedtls_md_context_t * ctx,const unsigned char * key,size_t keylen)822 int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen)
823 {
824     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
825     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
826     unsigned char *ipad, *opad;
827 
828     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
829         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
830     }
831 
832     if (keylen > (size_t) ctx->md_info->block_size) {
833         if ((ret = mbedtls_md_starts(ctx)) != 0) {
834             goto cleanup;
835         }
836         if ((ret = mbedtls_md_update(ctx, key, keylen)) != 0) {
837             goto cleanup;
838         }
839         if ((ret = mbedtls_md_finish(ctx, sum)) != 0) {
840             goto cleanup;
841         }
842 
843         keylen = ctx->md_info->size;
844         key = sum;
845     }
846 
847     ipad = (unsigned char *) ctx->hmac_ctx;
848     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
849 
850     memset(ipad, 0x36, ctx->md_info->block_size);
851     memset(opad, 0x5C, ctx->md_info->block_size);
852 
853     mbedtls_xor(ipad, ipad, key, keylen);
854     mbedtls_xor(opad, opad, key, keylen);
855 
856     if ((ret = mbedtls_md_starts(ctx)) != 0) {
857         goto cleanup;
858     }
859     if ((ret = mbedtls_md_update(ctx, ipad,
860                                  ctx->md_info->block_size)) != 0) {
861         goto cleanup;
862     }
863 
864 cleanup:
865     mbedtls_platform_zeroize(sum, sizeof(sum));
866 
867     return ret;
868 }
869 
mbedtls_md_hmac_update(mbedtls_md_context_t * ctx,const unsigned char * input,size_t ilen)870 int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
871 {
872     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
873         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
874     }
875 
876     return mbedtls_md_update(ctx, input, ilen);
877 }
878 
mbedtls_md_hmac_finish(mbedtls_md_context_t * ctx,unsigned char * output)879 int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output)
880 {
881     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
882     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
883     unsigned char *opad;
884 
885     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
886         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
887     }
888 
889     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
890 
891     if ((ret = mbedtls_md_finish(ctx, tmp)) != 0) {
892         return ret;
893     }
894     if ((ret = mbedtls_md_starts(ctx)) != 0) {
895         return ret;
896     }
897     if ((ret = mbedtls_md_update(ctx, opad,
898                                  ctx->md_info->block_size)) != 0) {
899         return ret;
900     }
901     if ((ret = mbedtls_md_update(ctx, tmp,
902                                  ctx->md_info->size)) != 0) {
903         return ret;
904     }
905     return mbedtls_md_finish(ctx, output);
906 }
907 
mbedtls_md_hmac_reset(mbedtls_md_context_t * ctx)908 int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx)
909 {
910     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
911     unsigned char *ipad;
912 
913     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
914         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
915     }
916 
917     ipad = (unsigned char *) ctx->hmac_ctx;
918 
919     if ((ret = mbedtls_md_starts(ctx)) != 0) {
920         return ret;
921     }
922     return mbedtls_md_update(ctx, ipad, ctx->md_info->block_size);
923 }
924 
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)925 int mbedtls_md_hmac(const mbedtls_md_info_t *md_info,
926                     const unsigned char *key, size_t keylen,
927                     const unsigned char *input, size_t ilen,
928                     unsigned char *output)
929 {
930     mbedtls_md_context_t ctx;
931     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
932 
933     if (md_info == NULL) {
934         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
935     }
936 
937     mbedtls_md_init(&ctx);
938 
939     if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0) {
940         goto cleanup;
941     }
942 
943     if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0) {
944         goto cleanup;
945     }
946     if ((ret = mbedtls_md_hmac_update(&ctx, input, ilen)) != 0) {
947         goto cleanup;
948     }
949     if ((ret = mbedtls_md_hmac_finish(&ctx, output)) != 0) {
950         goto cleanup;
951     }
952 
953 cleanup:
954     mbedtls_md_free(&ctx);
955 
956     return ret;
957 }
958 
mbedtls_md_get_name(const mbedtls_md_info_t * md_info)959 const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
960 {
961     if (md_info == NULL) {
962         return NULL;
963     }
964 
965     return md_info->name;
966 }
967 
968 #endif /* MBEDTLS_MD_C */
969 
970 #endif /* MBEDTLS_MD_LIGHT */
971