xref: /optee_os/lib/libmbedtls/mbedtls/library/md.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1817466cbSJens Wiklander /**
27901324dSJerome Forissier  * \file md.c
3817466cbSJens Wiklander  *
4817466cbSJens Wiklander  * \brief Generic message digest wrapper for mbed TLS
5817466cbSJens Wiklander  *
6817466cbSJens Wiklander  * \author Adriaan de Jong <dejong@fox-it.com>
7817466cbSJens Wiklander  *
87901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
97901324dSJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
10817466cbSJens Wiklander  *
11817466cbSJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
12817466cbSJens Wiklander  *  not use this file except in compliance with the License.
13817466cbSJens Wiklander  *  You may obtain a copy of the License at
14817466cbSJens Wiklander  *
15817466cbSJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
16817466cbSJens Wiklander  *
17817466cbSJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
18817466cbSJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19817466cbSJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20817466cbSJens Wiklander  *  See the License for the specific language governing permissions and
21817466cbSJens Wiklander  *  limitations under the License.
22817466cbSJens Wiklander  */
23817466cbSJens Wiklander 
247901324dSJerome Forissier #include "common.h"
25817466cbSJens Wiklander 
26*32b31808SJens Wiklander /*
27*32b31808SJens Wiklander  * Availability of functions in this module is controlled by two
28*32b31808SJens Wiklander  * feature macros:
29*32b31808SJens Wiklander  * - MBEDTLS_MD_C enables the whole module;
30*32b31808SJens Wiklander  * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing
31*32b31808SJens Wiklander  * most hash metadata (everything except string names); is it
32*32b31808SJens Wiklander  * automatically set whenever MBEDTLS_MD_C is defined.
33*32b31808SJens Wiklander  *
34*32b31808SJens Wiklander  * In this file, functions from MD_LIGHT are at the top, MD_C at the end.
35*32b31808SJens Wiklander  *
36*32b31808SJens Wiklander  * In the future we may want to change the contract of some functions
37*32b31808SJens Wiklander  * (behaviour with NULL arguments) depending on whether MD_C is defined or
38*32b31808SJens Wiklander  * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary.
39*32b31808SJens Wiklander  *
40*32b31808SJens Wiklander  * For these reasons, we're keeping MD_LIGHT internal for now.
41*32b31808SJens Wiklander  */
42*32b31808SJens Wiklander #if defined(MBEDTLS_MD_LIGHT)
43817466cbSJens Wiklander 
44817466cbSJens Wiklander #include "mbedtls/md.h"
45*32b31808SJens Wiklander #include "md_wrap.h"
463d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
4711fa71b9SJerome Forissier #include "mbedtls/error.h"
4811fa71b9SJerome Forissier 
4911fa71b9SJerome Forissier #include "mbedtls/md5.h"
5011fa71b9SJerome Forissier #include "mbedtls/ripemd160.h"
5111fa71b9SJerome Forissier #include "mbedtls/sha1.h"
5211fa71b9SJerome Forissier #include "mbedtls/sha256.h"
5311fa71b9SJerome Forissier #include "mbedtls/sha512.h"
54817466cbSJens Wiklander 
55*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
56*32b31808SJens Wiklander #include <psa/crypto.h>
57*32b31808SJens Wiklander #include "psa_crypto_core.h"
58817466cbSJens Wiklander #endif
59817466cbSJens Wiklander 
60*32b31808SJens Wiklander #include "mbedtls/platform.h"
61*32b31808SJens Wiklander 
62817466cbSJens Wiklander #include <string.h>
63817466cbSJens Wiklander 
64817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO)
65817466cbSJens Wiklander #include <stdio.h>
66817466cbSJens Wiklander #endif
67817466cbSJens Wiklander 
68*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5)
6911fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_md5_info = {
7011fa71b9SJerome Forissier     "MD5",
7111fa71b9SJerome Forissier     MBEDTLS_MD_MD5,
7211fa71b9SJerome Forissier     16,
7311fa71b9SJerome Forissier     64,
7411fa71b9SJerome Forissier };
7511fa71b9SJerome Forissier #endif
7611fa71b9SJerome Forissier 
77*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160)
7811fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_ripemd160_info = {
7911fa71b9SJerome Forissier     "RIPEMD160",
8011fa71b9SJerome Forissier     MBEDTLS_MD_RIPEMD160,
8111fa71b9SJerome Forissier     20,
8211fa71b9SJerome Forissier     64,
8311fa71b9SJerome Forissier };
8411fa71b9SJerome Forissier #endif
8511fa71b9SJerome Forissier 
86*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1)
8711fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha1_info = {
8811fa71b9SJerome Forissier     "SHA1",
8911fa71b9SJerome Forissier     MBEDTLS_MD_SHA1,
9011fa71b9SJerome Forissier     20,
9111fa71b9SJerome Forissier     64,
9211fa71b9SJerome Forissier };
9311fa71b9SJerome Forissier #endif
9411fa71b9SJerome Forissier 
95*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224)
9611fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha224_info = {
9711fa71b9SJerome Forissier     "SHA224",
9811fa71b9SJerome Forissier     MBEDTLS_MD_SHA224,
9911fa71b9SJerome Forissier     28,
10011fa71b9SJerome Forissier     64,
10111fa71b9SJerome Forissier };
102*32b31808SJens Wiklander #endif
10311fa71b9SJerome Forissier 
104*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256)
10511fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha256_info = {
10611fa71b9SJerome Forissier     "SHA256",
10711fa71b9SJerome Forissier     MBEDTLS_MD_SHA256,
10811fa71b9SJerome Forissier     32,
10911fa71b9SJerome Forissier     64,
11011fa71b9SJerome Forissier };
11111fa71b9SJerome Forissier #endif
11211fa71b9SJerome Forissier 
113*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384)
11411fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha384_info = {
11511fa71b9SJerome Forissier     "SHA384",
11611fa71b9SJerome Forissier     MBEDTLS_MD_SHA384,
11711fa71b9SJerome Forissier     48,
11811fa71b9SJerome Forissier     128,
11911fa71b9SJerome Forissier };
12011fa71b9SJerome Forissier #endif
12111fa71b9SJerome Forissier 
122*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512)
12311fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha512_info = {
12411fa71b9SJerome Forissier     "SHA512",
12511fa71b9SJerome Forissier     MBEDTLS_MD_SHA512,
12611fa71b9SJerome Forissier     64,
12711fa71b9SJerome Forissier     128,
12811fa71b9SJerome Forissier };
12911fa71b9SJerome Forissier #endif
13011fa71b9SJerome Forissier 
131817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
132817466cbSJens Wiklander {
133*32b31808SJens Wiklander     switch (md_type) {
134*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5)
135817466cbSJens Wiklander         case MBEDTLS_MD_MD5:
136*32b31808SJens Wiklander             return &mbedtls_md5_info;
137817466cbSJens Wiklander #endif
138*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160)
139817466cbSJens Wiklander         case MBEDTLS_MD_RIPEMD160:
140*32b31808SJens Wiklander             return &mbedtls_ripemd160_info;
141817466cbSJens Wiklander #endif
142*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1)
143817466cbSJens Wiklander         case MBEDTLS_MD_SHA1:
144*32b31808SJens Wiklander             return &mbedtls_sha1_info;
145817466cbSJens Wiklander #endif
146*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224)
147817466cbSJens Wiklander         case MBEDTLS_MD_SHA224:
148*32b31808SJens Wiklander             return &mbedtls_sha224_info;
149*32b31808SJens Wiklander #endif
150*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256)
151817466cbSJens Wiklander         case MBEDTLS_MD_SHA256:
152*32b31808SJens Wiklander             return &mbedtls_sha256_info;
153817466cbSJens Wiklander #endif
154*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384)
155817466cbSJens Wiklander         case MBEDTLS_MD_SHA384:
156*32b31808SJens Wiklander             return &mbedtls_sha384_info;
15711fa71b9SJerome Forissier #endif
158*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512)
159817466cbSJens Wiklander         case MBEDTLS_MD_SHA512:
160*32b31808SJens Wiklander             return &mbedtls_sha512_info;
161817466cbSJens Wiklander #endif
162817466cbSJens Wiklander         default:
163*32b31808SJens Wiklander             return NULL;
164817466cbSJens Wiklander     }
165817466cbSJens Wiklander }
166817466cbSJens Wiklander 
167*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
168*32b31808SJens Wiklander static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info)
169*32b31808SJens Wiklander {
170*32b31808SJens Wiklander     switch (info->type) {
171*32b31808SJens Wiklander #if defined(MBEDTLS_MD_MD5_VIA_PSA)
172*32b31808SJens Wiklander         case MBEDTLS_MD_MD5:
173*32b31808SJens Wiklander             return PSA_ALG_MD5;
174*32b31808SJens Wiklander #endif
175*32b31808SJens Wiklander #if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA)
176*32b31808SJens Wiklander         case MBEDTLS_MD_RIPEMD160:
177*32b31808SJens Wiklander             return PSA_ALG_RIPEMD160;
178*32b31808SJens Wiklander #endif
179*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA1_VIA_PSA)
180*32b31808SJens Wiklander         case MBEDTLS_MD_SHA1:
181*32b31808SJens Wiklander             return PSA_ALG_SHA_1;
182*32b31808SJens Wiklander #endif
183*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA224_VIA_PSA)
184*32b31808SJens Wiklander         case MBEDTLS_MD_SHA224:
185*32b31808SJens Wiklander             return PSA_ALG_SHA_224;
186*32b31808SJens Wiklander #endif
187*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA256_VIA_PSA)
188*32b31808SJens Wiklander         case MBEDTLS_MD_SHA256:
189*32b31808SJens Wiklander             return PSA_ALG_SHA_256;
190*32b31808SJens Wiklander #endif
191*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA384_VIA_PSA)
192*32b31808SJens Wiklander         case MBEDTLS_MD_SHA384:
193*32b31808SJens Wiklander             return PSA_ALG_SHA_384;
194*32b31808SJens Wiklander #endif
195*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA512_VIA_PSA)
196*32b31808SJens Wiklander         case MBEDTLS_MD_SHA512:
197*32b31808SJens Wiklander             return PSA_ALG_SHA_512;
198*32b31808SJens Wiklander #endif
199*32b31808SJens Wiklander         default:
200*32b31808SJens Wiklander             return PSA_ALG_NONE;
201*32b31808SJens Wiklander     }
202*32b31808SJens Wiklander }
203*32b31808SJens Wiklander 
204*32b31808SJens Wiklander static int md_can_use_psa(const mbedtls_md_info_t *info)
205*32b31808SJens Wiklander {
206*32b31808SJens Wiklander     psa_algorithm_t alg = psa_alg_of_md(info);
207*32b31808SJens Wiklander     if (alg == PSA_ALG_NONE) {
208*32b31808SJens Wiklander         return 0;
209*32b31808SJens Wiklander     }
210*32b31808SJens Wiklander 
211*32b31808SJens Wiklander     return psa_can_do_hash(alg);
212*32b31808SJens Wiklander }
213*32b31808SJens Wiklander 
214*32b31808SJens Wiklander static int mbedtls_md_error_from_psa(psa_status_t status)
215*32b31808SJens Wiklander {
216*32b31808SJens Wiklander     switch (status) {
217*32b31808SJens Wiklander         case PSA_SUCCESS:
218*32b31808SJens Wiklander             return 0;
219*32b31808SJens Wiklander         case PSA_ERROR_NOT_SUPPORTED:
220*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
221*32b31808SJens Wiklander         case PSA_ERROR_INSUFFICIENT_MEMORY:
222*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_ALLOC_FAILED;
223*32b31808SJens Wiklander         default:
224*32b31808SJens Wiklander             return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
225*32b31808SJens Wiklander     }
226*32b31808SJens Wiklander }
227*32b31808SJens Wiklander #endif /* MBEDTLS_MD_SOME_PSA */
228*32b31808SJens Wiklander 
229817466cbSJens Wiklander void mbedtls_md_init(mbedtls_md_context_t *ctx)
230817466cbSJens Wiklander {
231*32b31808SJens Wiklander     /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */
232817466cbSJens Wiklander     memset(ctx, 0, sizeof(mbedtls_md_context_t));
233817466cbSJens Wiklander }
234817466cbSJens Wiklander 
235817466cbSJens Wiklander void mbedtls_md_free(mbedtls_md_context_t *ctx)
236817466cbSJens Wiklander {
237*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL) {
238817466cbSJens Wiklander         return;
239*32b31808SJens Wiklander     }
240817466cbSJens Wiklander 
241*32b31808SJens Wiklander     if (ctx->md_ctx != NULL) {
242*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
243*32b31808SJens Wiklander         if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
244*32b31808SJens Wiklander             psa_hash_abort(ctx->md_ctx);
245*32b31808SJens Wiklander         } else
24611fa71b9SJerome Forissier #endif
247*32b31808SJens Wiklander         switch (ctx->md_info->type) {
24811fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
24911fa71b9SJerome Forissier             case MBEDTLS_MD_MD5:
25011fa71b9SJerome Forissier                 mbedtls_md5_free(ctx->md_ctx);
25111fa71b9SJerome Forissier                 break;
25211fa71b9SJerome Forissier #endif
25311fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
25411fa71b9SJerome Forissier             case MBEDTLS_MD_RIPEMD160:
25511fa71b9SJerome Forissier                 mbedtls_ripemd160_free(ctx->md_ctx);
25611fa71b9SJerome Forissier                 break;
25711fa71b9SJerome Forissier #endif
25811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
25911fa71b9SJerome Forissier             case MBEDTLS_MD_SHA1:
26011fa71b9SJerome Forissier                 mbedtls_sha1_free(ctx->md_ctx);
26111fa71b9SJerome Forissier                 break;
26211fa71b9SJerome Forissier #endif
263*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
26411fa71b9SJerome Forissier             case MBEDTLS_MD_SHA224:
265*32b31808SJens Wiklander                 mbedtls_sha256_free(ctx->md_ctx);
266*32b31808SJens Wiklander                 break;
267*32b31808SJens Wiklander #endif
268*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C)
26911fa71b9SJerome Forissier             case MBEDTLS_MD_SHA256:
27011fa71b9SJerome Forissier                 mbedtls_sha256_free(ctx->md_ctx);
27111fa71b9SJerome Forissier                 break;
27211fa71b9SJerome Forissier #endif
273*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
27411fa71b9SJerome Forissier             case MBEDTLS_MD_SHA384:
275*32b31808SJens Wiklander                 mbedtls_sha512_free(ctx->md_ctx);
276*32b31808SJens Wiklander                 break;
27711fa71b9SJerome Forissier #endif
278*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C)
27911fa71b9SJerome Forissier             case MBEDTLS_MD_SHA512:
28011fa71b9SJerome Forissier                 mbedtls_sha512_free(ctx->md_ctx);
28111fa71b9SJerome Forissier                 break;
28211fa71b9SJerome Forissier #endif
28311fa71b9SJerome Forissier             default:
28411fa71b9SJerome Forissier                 /* Shouldn't happen */
28511fa71b9SJerome Forissier                 break;
28611fa71b9SJerome Forissier         }
28711fa71b9SJerome Forissier         mbedtls_free(ctx->md_ctx);
28811fa71b9SJerome Forissier     }
289817466cbSJens Wiklander 
290*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C)
291*32b31808SJens Wiklander     if (ctx->hmac_ctx != NULL) {
2923d3b0591SJens Wiklander         mbedtls_platform_zeroize(ctx->hmac_ctx,
2933d3b0591SJens Wiklander                                  2 * ctx->md_info->block_size);
294817466cbSJens Wiklander         mbedtls_free(ctx->hmac_ctx);
295817466cbSJens Wiklander     }
296*32b31808SJens Wiklander #endif
297817466cbSJens Wiklander 
2983d3b0591SJens Wiklander     mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t));
299817466cbSJens Wiklander }
300817466cbSJens Wiklander 
301817466cbSJens Wiklander int mbedtls_md_clone(mbedtls_md_context_t *dst,
302817466cbSJens Wiklander                      const mbedtls_md_context_t *src)
303817466cbSJens Wiklander {
304817466cbSJens Wiklander     if (dst == NULL || dst->md_info == NULL ||
305817466cbSJens Wiklander         src == NULL || src->md_info == NULL ||
306*32b31808SJens Wiklander         dst->md_info != src->md_info) {
307*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
308817466cbSJens Wiklander     }
309817466cbSJens Wiklander 
310*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
311*32b31808SJens Wiklander     if (src->engine != dst->engine) {
312*32b31808SJens Wiklander         /* This can happen with src set to legacy because PSA wasn't ready
313*32b31808SJens Wiklander          * yet, and dst to PSA because it became ready in the meantime.
314*32b31808SJens Wiklander          * We currently don't support that case (we'd need to re-allocate
315*32b31808SJens Wiklander          * md_ctx to the size of the appropriate MD context). */
316*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
317*32b31808SJens Wiklander     }
318*32b31808SJens Wiklander 
319*32b31808SJens Wiklander     if (src->engine == MBEDTLS_MD_ENGINE_PSA) {
320*32b31808SJens Wiklander         psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx);
321*32b31808SJens Wiklander         return mbedtls_md_error_from_psa(status);
322*32b31808SJens Wiklander     }
32311fa71b9SJerome Forissier #endif
324*32b31808SJens Wiklander 
325*32b31808SJens Wiklander     switch (src->md_info->type) {
32611fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
32711fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
32811fa71b9SJerome Forissier             mbedtls_md5_clone(dst->md_ctx, src->md_ctx);
32911fa71b9SJerome Forissier             break;
33011fa71b9SJerome Forissier #endif
33111fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
33211fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
33311fa71b9SJerome Forissier             mbedtls_ripemd160_clone(dst->md_ctx, src->md_ctx);
33411fa71b9SJerome Forissier             break;
33511fa71b9SJerome Forissier #endif
33611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
33711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
33811fa71b9SJerome Forissier             mbedtls_sha1_clone(dst->md_ctx, src->md_ctx);
33911fa71b9SJerome Forissier             break;
34011fa71b9SJerome Forissier #endif
341*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
34211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
343*32b31808SJens Wiklander             mbedtls_sha256_clone(dst->md_ctx, src->md_ctx);
344*32b31808SJens Wiklander             break;
345*32b31808SJens Wiklander #endif
346*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C)
34711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
34811fa71b9SJerome Forissier             mbedtls_sha256_clone(dst->md_ctx, src->md_ctx);
34911fa71b9SJerome Forissier             break;
35011fa71b9SJerome Forissier #endif
351*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
35211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
353*32b31808SJens Wiklander             mbedtls_sha512_clone(dst->md_ctx, src->md_ctx);
354*32b31808SJens Wiklander             break;
35511fa71b9SJerome Forissier #endif
356*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C)
35711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
35811fa71b9SJerome Forissier             mbedtls_sha512_clone(dst->md_ctx, src->md_ctx);
35911fa71b9SJerome Forissier             break;
36011fa71b9SJerome Forissier #endif
36111fa71b9SJerome Forissier         default:
362*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
36311fa71b9SJerome Forissier     }
364817466cbSJens Wiklander 
36512484fc7SEdison Ai     if (dst->hmac_ctx != NULL && src->hmac_ctx != NULL)
36612484fc7SEdison Ai         memcpy(dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size);
36712484fc7SEdison Ai 
368*32b31808SJens Wiklander     return 0;
369817466cbSJens Wiklander }
370817466cbSJens Wiklander 
37111fa71b9SJerome Forissier #define ALLOC(type)                                                   \
37211fa71b9SJerome Forissier     do {                                                                \
37311fa71b9SJerome Forissier         ctx->md_ctx = mbedtls_calloc(1, sizeof(mbedtls_##type##_context)); \
37411fa71b9SJerome Forissier         if (ctx->md_ctx == NULL)                                       \
375*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_ALLOC_FAILED;                      \
37611fa71b9SJerome Forissier         mbedtls_##type##_init(ctx->md_ctx);                           \
37711fa71b9SJerome Forissier     }                                                                   \
37811fa71b9SJerome Forissier     while (0)
37911fa71b9SJerome Forissier 
380817466cbSJens Wiklander int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac)
381817466cbSJens Wiklander {
382*32b31808SJens Wiklander     if (md_info == NULL || ctx == NULL) {
383*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
384*32b31808SJens Wiklander     }
385817466cbSJens Wiklander 
3867901324dSJerome Forissier     ctx->md_info = md_info;
3877901324dSJerome Forissier     ctx->md_ctx = NULL;
388*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C)
3897901324dSJerome Forissier     ctx->hmac_ctx = NULL;
390*32b31808SJens Wiklander #else
391*32b31808SJens Wiklander     if (hmac != 0) {
392*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
393*32b31808SJens Wiklander     }
394*32b31808SJens Wiklander #endif
3957901324dSJerome Forissier 
396*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
397*32b31808SJens Wiklander     if (md_can_use_psa(ctx->md_info)) {
398*32b31808SJens Wiklander         ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t));
399*32b31808SJens Wiklander         if (ctx->md_ctx == NULL) {
400*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_ALLOC_FAILED;
401*32b31808SJens Wiklander         }
402*32b31808SJens Wiklander         ctx->engine = MBEDTLS_MD_ENGINE_PSA;
403*32b31808SJens Wiklander     } else
40411fa71b9SJerome Forissier #endif
405*32b31808SJens Wiklander     switch (md_info->type) {
40611fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
40711fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
40811fa71b9SJerome Forissier             ALLOC(md5);
40911fa71b9SJerome Forissier             break;
41011fa71b9SJerome Forissier #endif
41111fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
41211fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
41311fa71b9SJerome Forissier             ALLOC(ripemd160);
41411fa71b9SJerome Forissier             break;
41511fa71b9SJerome Forissier #endif
41611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
41711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
41811fa71b9SJerome Forissier             ALLOC(sha1);
41911fa71b9SJerome Forissier             break;
42011fa71b9SJerome Forissier #endif
421*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
42211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
423*32b31808SJens Wiklander             ALLOC(sha256);
424*32b31808SJens Wiklander             break;
425*32b31808SJens Wiklander #endif
426*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C)
42711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
42811fa71b9SJerome Forissier             ALLOC(sha256);
42911fa71b9SJerome Forissier             break;
43011fa71b9SJerome Forissier #endif
431*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
43211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
433*32b31808SJens Wiklander             ALLOC(sha512);
434*32b31808SJens Wiklander             break;
43511fa71b9SJerome Forissier #endif
436*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C)
43711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
43811fa71b9SJerome Forissier             ALLOC(sha512);
43911fa71b9SJerome Forissier             break;
44011fa71b9SJerome Forissier #endif
44111fa71b9SJerome Forissier         default:
442*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
44311fa71b9SJerome Forissier     }
444817466cbSJens Wiklander 
445*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C)
446*32b31808SJens Wiklander     if (hmac != 0) {
447817466cbSJens Wiklander         ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size);
448*32b31808SJens Wiklander         if (ctx->hmac_ctx == NULL) {
44911fa71b9SJerome Forissier             mbedtls_md_free(ctx);
450*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_ALLOC_FAILED;
451817466cbSJens Wiklander         }
452817466cbSJens Wiklander     }
453*32b31808SJens Wiklander #endif
454817466cbSJens Wiklander 
455*32b31808SJens Wiklander     return 0;
456817466cbSJens Wiklander }
45711fa71b9SJerome Forissier #undef ALLOC
458817466cbSJens Wiklander 
459817466cbSJens Wiklander int mbedtls_md_starts(mbedtls_md_context_t *ctx)
460817466cbSJens Wiklander {
461*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL) {
462*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
463*32b31808SJens Wiklander     }
464817466cbSJens Wiklander 
465*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
466*32b31808SJens Wiklander     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
467*32b31808SJens Wiklander         psa_algorithm_t alg = psa_alg_of_md(ctx->md_info);
468*32b31808SJens Wiklander         psa_hash_abort(ctx->md_ctx);
469*32b31808SJens Wiklander         psa_status_t status = psa_hash_setup(ctx->md_ctx, alg);
470*32b31808SJens Wiklander         return mbedtls_md_error_from_psa(status);
471*32b31808SJens Wiklander     }
47211fa71b9SJerome Forissier #endif
473*32b31808SJens Wiklander 
474*32b31808SJens Wiklander     switch (ctx->md_info->type) {
47511fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
47611fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
477*32b31808SJens Wiklander             return mbedtls_md5_starts(ctx->md_ctx);
47811fa71b9SJerome Forissier #endif
47911fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
48011fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
481*32b31808SJens Wiklander             return mbedtls_ripemd160_starts(ctx->md_ctx);
48211fa71b9SJerome Forissier #endif
48311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
48411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
485*32b31808SJens Wiklander             return mbedtls_sha1_starts(ctx->md_ctx);
486*32b31808SJens Wiklander #endif
487*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
488*32b31808SJens Wiklander         case MBEDTLS_MD_SHA224:
489*32b31808SJens Wiklander             return mbedtls_sha256_starts(ctx->md_ctx, 1);
49011fa71b9SJerome Forissier #endif
49111fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
49211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
493*32b31808SJens Wiklander             return mbedtls_sha256_starts(ctx->md_ctx, 0);
494*32b31808SJens Wiklander #endif
495*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
496*32b31808SJens Wiklander         case MBEDTLS_MD_SHA384:
497*32b31808SJens Wiklander             return mbedtls_sha512_starts(ctx->md_ctx, 1);
49811fa71b9SJerome Forissier #endif
49911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
50011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
501*32b31808SJens Wiklander             return mbedtls_sha512_starts(ctx->md_ctx, 0);
50211fa71b9SJerome Forissier #endif
50311fa71b9SJerome Forissier         default:
504*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
50511fa71b9SJerome Forissier     }
506817466cbSJens Wiklander }
507817466cbSJens Wiklander 
508817466cbSJens Wiklander int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
509817466cbSJens Wiklander {
510*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL) {
511*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
512*32b31808SJens Wiklander     }
513817466cbSJens Wiklander 
514*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
515*32b31808SJens Wiklander     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
516*32b31808SJens Wiklander         psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen);
517*32b31808SJens Wiklander         return mbedtls_md_error_from_psa(status);
518*32b31808SJens Wiklander     }
51911fa71b9SJerome Forissier #endif
520*32b31808SJens Wiklander 
521*32b31808SJens Wiklander     switch (ctx->md_info->type) {
52211fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
52311fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
524*32b31808SJens Wiklander             return mbedtls_md5_update(ctx->md_ctx, input, ilen);
52511fa71b9SJerome Forissier #endif
52611fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
52711fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
528*32b31808SJens Wiklander             return mbedtls_ripemd160_update(ctx->md_ctx, input, ilen);
52911fa71b9SJerome Forissier #endif
53011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
53111fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
532*32b31808SJens Wiklander             return mbedtls_sha1_update(ctx->md_ctx, input, ilen);
533*32b31808SJens Wiklander #endif
534*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
535*32b31808SJens Wiklander         case MBEDTLS_MD_SHA224:
536*32b31808SJens Wiklander             return mbedtls_sha256_update(ctx->md_ctx, input, ilen);
53711fa71b9SJerome Forissier #endif
53811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
53911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
540*32b31808SJens Wiklander             return mbedtls_sha256_update(ctx->md_ctx, input, ilen);
541*32b31808SJens Wiklander #endif
542*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
543*32b31808SJens Wiklander         case MBEDTLS_MD_SHA384:
544*32b31808SJens Wiklander             return mbedtls_sha512_update(ctx->md_ctx, input, ilen);
54511fa71b9SJerome Forissier #endif
54611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
54711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
548*32b31808SJens Wiklander             return mbedtls_sha512_update(ctx->md_ctx, input, ilen);
54911fa71b9SJerome Forissier #endif
55011fa71b9SJerome Forissier         default:
551*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
55211fa71b9SJerome Forissier     }
553817466cbSJens Wiklander }
554817466cbSJens Wiklander 
555817466cbSJens Wiklander int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
556817466cbSJens Wiklander {
557*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL) {
558*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
559*32b31808SJens Wiklander     }
560817466cbSJens Wiklander 
561*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
562*32b31808SJens Wiklander     if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) {
563*32b31808SJens Wiklander         size_t size = ctx->md_info->size;
564*32b31808SJens Wiklander         psa_status_t status = psa_hash_finish(ctx->md_ctx,
565*32b31808SJens Wiklander                                               output, size, &size);
566*32b31808SJens Wiklander         return mbedtls_md_error_from_psa(status);
567*32b31808SJens Wiklander     }
56811fa71b9SJerome Forissier #endif
569*32b31808SJens Wiklander 
570*32b31808SJens Wiklander     switch (ctx->md_info->type) {
57111fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
57211fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
573*32b31808SJens Wiklander             return mbedtls_md5_finish(ctx->md_ctx, output);
57411fa71b9SJerome Forissier #endif
57511fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
57611fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
577*32b31808SJens Wiklander             return mbedtls_ripemd160_finish(ctx->md_ctx, output);
57811fa71b9SJerome Forissier #endif
57911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
58011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
581*32b31808SJens Wiklander             return mbedtls_sha1_finish(ctx->md_ctx, output);
582*32b31808SJens Wiklander #endif
583*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
584*32b31808SJens Wiklander         case MBEDTLS_MD_SHA224:
585*32b31808SJens Wiklander             return mbedtls_sha256_finish(ctx->md_ctx, output);
58611fa71b9SJerome Forissier #endif
58711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
58811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
589*32b31808SJens Wiklander             return mbedtls_sha256_finish(ctx->md_ctx, output);
590*32b31808SJens Wiklander #endif
591*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
592*32b31808SJens Wiklander         case MBEDTLS_MD_SHA384:
593*32b31808SJens Wiklander             return mbedtls_sha512_finish(ctx->md_ctx, output);
59411fa71b9SJerome Forissier #endif
59511fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
59611fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
597*32b31808SJens Wiklander             return mbedtls_sha512_finish(ctx->md_ctx, output);
59811fa71b9SJerome Forissier #endif
59911fa71b9SJerome Forissier         default:
600*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
60111fa71b9SJerome Forissier     }
602817466cbSJens Wiklander }
603817466cbSJens Wiklander 
604817466cbSJens Wiklander int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
605817466cbSJens Wiklander                unsigned char *output)
606817466cbSJens Wiklander {
607*32b31808SJens Wiklander     if (md_info == NULL) {
608*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
609*32b31808SJens Wiklander     }
610817466cbSJens Wiklander 
611*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA)
612*32b31808SJens Wiklander     if (md_can_use_psa(md_info)) {
613*32b31808SJens Wiklander         size_t size = md_info->size;
614*32b31808SJens Wiklander         psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info),
615*32b31808SJens Wiklander                                                input, ilen,
616*32b31808SJens Wiklander                                                output, size, &size);
617*32b31808SJens Wiklander         return mbedtls_md_error_from_psa(status);
618*32b31808SJens Wiklander     }
61911fa71b9SJerome Forissier #endif
620*32b31808SJens Wiklander 
621*32b31808SJens Wiklander     switch (md_info->type) {
62211fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
62311fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
624*32b31808SJens Wiklander             return mbedtls_md5(input, ilen, output);
62511fa71b9SJerome Forissier #endif
62611fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
62711fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
628*32b31808SJens Wiklander             return mbedtls_ripemd160(input, ilen, output);
62911fa71b9SJerome Forissier #endif
63011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
63111fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
632*32b31808SJens Wiklander             return mbedtls_sha1(input, ilen, output);
633*32b31808SJens Wiklander #endif
634*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C)
635*32b31808SJens Wiklander         case MBEDTLS_MD_SHA224:
636*32b31808SJens Wiklander             return mbedtls_sha256(input, ilen, output, 1);
63711fa71b9SJerome Forissier #endif
63811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
63911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
640*32b31808SJens Wiklander             return mbedtls_sha256(input, ilen, output, 0);
641*32b31808SJens Wiklander #endif
642*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C)
643*32b31808SJens Wiklander         case MBEDTLS_MD_SHA384:
644*32b31808SJens Wiklander             return mbedtls_sha512(input, ilen, output, 1);
64511fa71b9SJerome Forissier #endif
64611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
64711fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
648*32b31808SJens Wiklander             return mbedtls_sha512(input, ilen, output, 0);
64911fa71b9SJerome Forissier #endif
65011fa71b9SJerome Forissier         default:
651*32b31808SJens Wiklander             return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
65211fa71b9SJerome Forissier     }
653817466cbSJens Wiklander }
654817466cbSJens Wiklander 
655*32b31808SJens Wiklander unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
656*32b31808SJens Wiklander {
657*32b31808SJens Wiklander     if (md_info == NULL) {
658*32b31808SJens Wiklander         return 0;
659*32b31808SJens Wiklander     }
660*32b31808SJens Wiklander 
661*32b31808SJens Wiklander     return md_info->size;
662*32b31808SJens Wiklander }
663*32b31808SJens Wiklander 
664*32b31808SJens Wiklander mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
665*32b31808SJens Wiklander {
666*32b31808SJens Wiklander     if (md_info == NULL) {
667*32b31808SJens Wiklander         return MBEDTLS_MD_NONE;
668*32b31808SJens Wiklander     }
669*32b31808SJens Wiklander 
670*32b31808SJens Wiklander     return md_info->type;
671*32b31808SJens Wiklander }
672*32b31808SJens Wiklander 
673*32b31808SJens Wiklander /************************************************************************
674*32b31808SJens Wiklander  * Functions above this separator are part of MBEDTLS_MD_LIGHT,         *
675*32b31808SJens Wiklander  * functions below are only available when MBEDTLS_MD_C is set.         *
676*32b31808SJens Wiklander  ************************************************************************/
677*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C)
678*32b31808SJens Wiklander 
679*32b31808SJens Wiklander /*
680*32b31808SJens Wiklander  * Reminder: update profiles in x509_crt.c when adding a new hash!
681*32b31808SJens Wiklander  */
682*32b31808SJens Wiklander static const int supported_digests[] = {
683*32b31808SJens Wiklander 
684*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512)
685*32b31808SJens Wiklander     MBEDTLS_MD_SHA512,
686*32b31808SJens Wiklander #endif
687*32b31808SJens Wiklander 
688*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384)
689*32b31808SJens Wiklander     MBEDTLS_MD_SHA384,
690*32b31808SJens Wiklander #endif
691*32b31808SJens Wiklander 
692*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256)
693*32b31808SJens Wiklander     MBEDTLS_MD_SHA256,
694*32b31808SJens Wiklander #endif
695*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224)
696*32b31808SJens Wiklander     MBEDTLS_MD_SHA224,
697*32b31808SJens Wiklander #endif
698*32b31808SJens Wiklander 
699*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1)
700*32b31808SJens Wiklander     MBEDTLS_MD_SHA1,
701*32b31808SJens Wiklander #endif
702*32b31808SJens Wiklander 
703*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160)
704*32b31808SJens Wiklander     MBEDTLS_MD_RIPEMD160,
705*32b31808SJens Wiklander #endif
706*32b31808SJens Wiklander 
707*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5)
708*32b31808SJens Wiklander     MBEDTLS_MD_MD5,
709*32b31808SJens Wiklander #endif
710*32b31808SJens Wiklander 
711*32b31808SJens Wiklander     MBEDTLS_MD_NONE
712*32b31808SJens Wiklander };
713*32b31808SJens Wiklander 
714*32b31808SJens Wiklander const int *mbedtls_md_list(void)
715*32b31808SJens Wiklander {
716*32b31808SJens Wiklander     return supported_digests;
717*32b31808SJens Wiklander }
718*32b31808SJens Wiklander 
719*32b31808SJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name)
720*32b31808SJens Wiklander {
721*32b31808SJens Wiklander     if (NULL == md_name) {
722*32b31808SJens Wiklander         return NULL;
723*32b31808SJens Wiklander     }
724*32b31808SJens Wiklander 
725*32b31808SJens Wiklander     /* Get the appropriate digest information */
726*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5)
727*32b31808SJens Wiklander     if (!strcmp("MD5", md_name)) {
728*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
729*32b31808SJens Wiklander     }
730*32b31808SJens Wiklander #endif
731*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160)
732*32b31808SJens Wiklander     if (!strcmp("RIPEMD160", md_name)) {
733*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160);
734*32b31808SJens Wiklander     }
735*32b31808SJens Wiklander #endif
736*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1)
737*32b31808SJens Wiklander     if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) {
738*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
739*32b31808SJens Wiklander     }
740*32b31808SJens Wiklander #endif
741*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224)
742*32b31808SJens Wiklander     if (!strcmp("SHA224", md_name)) {
743*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
744*32b31808SJens Wiklander     }
745*32b31808SJens Wiklander #endif
746*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256)
747*32b31808SJens Wiklander     if (!strcmp("SHA256", md_name)) {
748*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
749*32b31808SJens Wiklander     }
750*32b31808SJens Wiklander #endif
751*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384)
752*32b31808SJens Wiklander     if (!strcmp("SHA384", md_name)) {
753*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
754*32b31808SJens Wiklander     }
755*32b31808SJens Wiklander #endif
756*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512)
757*32b31808SJens Wiklander     if (!strcmp("SHA512", md_name)) {
758*32b31808SJens Wiklander         return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
759*32b31808SJens Wiklander     }
760*32b31808SJens Wiklander #endif
761*32b31808SJens Wiklander     return NULL;
762*32b31808SJens Wiklander }
763*32b31808SJens Wiklander 
764*32b31808SJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_ctx(
765*32b31808SJens Wiklander     const mbedtls_md_context_t *ctx)
766*32b31808SJens Wiklander {
767*32b31808SJens Wiklander     if (ctx == NULL) {
768*32b31808SJens Wiklander         return NULL;
769*32b31808SJens Wiklander     }
770*32b31808SJens Wiklander 
771*32b31808SJens Wiklander     return ctx->MBEDTLS_PRIVATE(md_info);
772*32b31808SJens Wiklander }
773*32b31808SJens Wiklander 
774817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO)
775817466cbSJens Wiklander int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output)
776817466cbSJens Wiklander {
77711fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
778817466cbSJens Wiklander     FILE *f;
779817466cbSJens Wiklander     size_t n;
780817466cbSJens Wiklander     mbedtls_md_context_t ctx;
781817466cbSJens Wiklander     unsigned char buf[1024];
782817466cbSJens Wiklander 
783*32b31808SJens Wiklander     if (md_info == NULL) {
784*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
785*32b31808SJens Wiklander     }
786817466cbSJens Wiklander 
787*32b31808SJens Wiklander     if ((f = fopen(path, "rb")) == NULL) {
788*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_FILE_IO_ERROR;
789*32b31808SJens Wiklander     }
790*32b31808SJens Wiklander 
791*32b31808SJens Wiklander     /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
792*32b31808SJens Wiklander     mbedtls_setbuf(f, NULL);
793817466cbSJens Wiklander 
794817466cbSJens Wiklander     mbedtls_md_init(&ctx);
795817466cbSJens Wiklander 
796*32b31808SJens Wiklander     if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) {
797817466cbSJens Wiklander         goto cleanup;
798*32b31808SJens Wiklander     }
799817466cbSJens Wiklander 
800*32b31808SJens Wiklander     if ((ret = mbedtls_md_starts(&ctx)) != 0) {
8013d3b0591SJens Wiklander         goto cleanup;
802*32b31808SJens Wiklander     }
803817466cbSJens Wiklander 
804*32b31808SJens Wiklander     while ((n = fread(buf, 1, sizeof(buf), f)) > 0) {
805*32b31808SJens Wiklander         if ((ret = mbedtls_md_update(&ctx, buf, n)) != 0) {
8063d3b0591SJens Wiklander             goto cleanup;
807*32b31808SJens Wiklander         }
808*32b31808SJens Wiklander     }
809817466cbSJens Wiklander 
810*32b31808SJens Wiklander     if (ferror(f) != 0) {
811817466cbSJens Wiklander         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
812*32b31808SJens Wiklander     } else {
81311fa71b9SJerome Forissier         ret = mbedtls_md_finish(&ctx, output);
814*32b31808SJens Wiklander     }
815817466cbSJens Wiklander 
816817466cbSJens Wiklander cleanup:
8173d3b0591SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
818817466cbSJens Wiklander     fclose(f);
819817466cbSJens Wiklander     mbedtls_md_free(&ctx);
820817466cbSJens Wiklander 
821*32b31808SJens Wiklander     return ret;
822817466cbSJens Wiklander }
823817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */
824817466cbSJens Wiklander 
825817466cbSJens Wiklander int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen)
826817466cbSJens Wiklander {
82711fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
828817466cbSJens Wiklander     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
829817466cbSJens Wiklander     unsigned char *ipad, *opad;
830817466cbSJens Wiklander 
831*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
832*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
833*32b31808SJens Wiklander     }
834817466cbSJens Wiklander 
835*32b31808SJens Wiklander     if (keylen > (size_t) ctx->md_info->block_size) {
836*32b31808SJens Wiklander         if ((ret = mbedtls_md_starts(ctx)) != 0) {
8373d3b0591SJens Wiklander             goto cleanup;
838*32b31808SJens Wiklander         }
839*32b31808SJens Wiklander         if ((ret = mbedtls_md_update(ctx, key, keylen)) != 0) {
8403d3b0591SJens Wiklander             goto cleanup;
841*32b31808SJens Wiklander         }
842*32b31808SJens Wiklander         if ((ret = mbedtls_md_finish(ctx, sum)) != 0) {
8433d3b0591SJens Wiklander             goto cleanup;
844*32b31808SJens Wiklander         }
845817466cbSJens Wiklander 
846817466cbSJens Wiklander         keylen = ctx->md_info->size;
847817466cbSJens Wiklander         key = sum;
848817466cbSJens Wiklander     }
849817466cbSJens Wiklander 
850817466cbSJens Wiklander     ipad = (unsigned char *) ctx->hmac_ctx;
851817466cbSJens Wiklander     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
852817466cbSJens Wiklander 
853817466cbSJens Wiklander     memset(ipad, 0x36, ctx->md_info->block_size);
854817466cbSJens Wiklander     memset(opad, 0x5C, ctx->md_info->block_size);
855817466cbSJens Wiklander 
856*32b31808SJens Wiklander     mbedtls_xor(ipad, ipad, key, keylen);
857*32b31808SJens Wiklander     mbedtls_xor(opad, opad, key, keylen);
858817466cbSJens Wiklander 
859*32b31808SJens Wiklander     if ((ret = mbedtls_md_starts(ctx)) != 0) {
8603d3b0591SJens Wiklander         goto cleanup;
861*32b31808SJens Wiklander     }
86211fa71b9SJerome Forissier     if ((ret = mbedtls_md_update(ctx, ipad,
863*32b31808SJens Wiklander                                  ctx->md_info->block_size)) != 0) {
8643d3b0591SJens Wiklander         goto cleanup;
865*32b31808SJens Wiklander     }
866817466cbSJens Wiklander 
8673d3b0591SJens Wiklander cleanup:
8683d3b0591SJens Wiklander     mbedtls_platform_zeroize(sum, sizeof(sum));
869817466cbSJens Wiklander 
870*32b31808SJens Wiklander     return ret;
871817466cbSJens Wiklander }
872817466cbSJens Wiklander 
873817466cbSJens Wiklander int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
874817466cbSJens Wiklander {
875*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
876*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
877*32b31808SJens Wiklander     }
878817466cbSJens Wiklander 
879*32b31808SJens Wiklander     return mbedtls_md_update(ctx, input, ilen);
880817466cbSJens Wiklander }
881817466cbSJens Wiklander 
882817466cbSJens Wiklander int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output)
883817466cbSJens Wiklander {
88411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
885817466cbSJens Wiklander     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
886817466cbSJens Wiklander     unsigned char *opad;
887817466cbSJens Wiklander 
888*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
889*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
890*32b31808SJens Wiklander     }
891817466cbSJens Wiklander 
892817466cbSJens Wiklander     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
893817466cbSJens Wiklander 
894*32b31808SJens Wiklander     if ((ret = mbedtls_md_finish(ctx, tmp)) != 0) {
895*32b31808SJens Wiklander         return ret;
896*32b31808SJens Wiklander     }
897*32b31808SJens Wiklander     if ((ret = mbedtls_md_starts(ctx)) != 0) {
898*32b31808SJens Wiklander         return ret;
899*32b31808SJens Wiklander     }
90011fa71b9SJerome Forissier     if ((ret = mbedtls_md_update(ctx, opad,
901*32b31808SJens Wiklander                                  ctx->md_info->block_size)) != 0) {
902*32b31808SJens Wiklander         return ret;
903*32b31808SJens Wiklander     }
90411fa71b9SJerome Forissier     if ((ret = mbedtls_md_update(ctx, tmp,
905*32b31808SJens Wiklander                                  ctx->md_info->size)) != 0) {
906*32b31808SJens Wiklander         return ret;
907*32b31808SJens Wiklander     }
908*32b31808SJens Wiklander     return mbedtls_md_finish(ctx, output);
909817466cbSJens Wiklander }
910817466cbSJens Wiklander 
911817466cbSJens Wiklander int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx)
912817466cbSJens Wiklander {
91311fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
914817466cbSJens Wiklander     unsigned char *ipad;
915817466cbSJens Wiklander 
916*32b31808SJens Wiklander     if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) {
917*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
918*32b31808SJens Wiklander     }
919817466cbSJens Wiklander 
920817466cbSJens Wiklander     ipad = (unsigned char *) ctx->hmac_ctx;
921817466cbSJens Wiklander 
922*32b31808SJens Wiklander     if ((ret = mbedtls_md_starts(ctx)) != 0) {
923*32b31808SJens Wiklander         return ret;
924*32b31808SJens Wiklander     }
925*32b31808SJens Wiklander     return mbedtls_md_update(ctx, ipad, ctx->md_info->block_size);
926817466cbSJens Wiklander }
927817466cbSJens Wiklander 
9283d3b0591SJens Wiklander int mbedtls_md_hmac(const mbedtls_md_info_t *md_info,
9293d3b0591SJens Wiklander                     const unsigned char *key, size_t keylen,
930817466cbSJens Wiklander                     const unsigned char *input, size_t ilen,
931817466cbSJens Wiklander                     unsigned char *output)
932817466cbSJens Wiklander {
933817466cbSJens Wiklander     mbedtls_md_context_t ctx;
93411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
935817466cbSJens Wiklander 
936*32b31808SJens Wiklander     if (md_info == NULL) {
937*32b31808SJens Wiklander         return MBEDTLS_ERR_MD_BAD_INPUT_DATA;
938*32b31808SJens Wiklander     }
939817466cbSJens Wiklander 
940817466cbSJens Wiklander     mbedtls_md_init(&ctx);
941817466cbSJens Wiklander 
942*32b31808SJens Wiklander     if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0) {
9433d3b0591SJens Wiklander         goto cleanup;
944*32b31808SJens Wiklander     }
945817466cbSJens Wiklander 
946*32b31808SJens Wiklander     if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0) {
9473d3b0591SJens Wiklander         goto cleanup;
948*32b31808SJens Wiklander     }
949*32b31808SJens Wiklander     if ((ret = mbedtls_md_hmac_update(&ctx, input, ilen)) != 0) {
9503d3b0591SJens Wiklander         goto cleanup;
951*32b31808SJens Wiklander     }
952*32b31808SJens Wiklander     if ((ret = mbedtls_md_hmac_finish(&ctx, output)) != 0) {
9533d3b0591SJens Wiklander         goto cleanup;
954*32b31808SJens Wiklander     }
955817466cbSJens Wiklander 
9563d3b0591SJens Wiklander cleanup:
957817466cbSJens Wiklander     mbedtls_md_free(&ctx);
958817466cbSJens Wiklander 
959*32b31808SJens Wiklander     return ret;
960817466cbSJens Wiklander }
961817466cbSJens Wiklander 
962817466cbSJens Wiklander const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
963817466cbSJens Wiklander {
964*32b31808SJens Wiklander     if (md_info == NULL) {
965*32b31808SJens Wiklander         return NULL;
966*32b31808SJens Wiklander     }
967817466cbSJens Wiklander 
968817466cbSJens Wiklander     return md_info->name;
969817466cbSJens Wiklander }
970817466cbSJens Wiklander 
971817466cbSJens Wiklander #endif /* MBEDTLS_MD_C */
972*32b31808SJens Wiklander 
973*32b31808SJens Wiklander #endif /* MBEDTLS_MD_LIGHT */
974