xref: /optee_os/lib/libmbedtls/mbedtls/library/md.c (revision 7901324d9530594155991c8b283023d567741cc7)
1817466cbSJens Wiklander /**
2*7901324dSJerome 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  *
8*7901324dSJerome Forissier  *  Copyright The Mbed TLS Contributors
9*7901324dSJerome 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 
24*7901324dSJerome Forissier #include "common.h"
25817466cbSJens Wiklander 
26817466cbSJens Wiklander #if defined(MBEDTLS_MD_C)
27817466cbSJens Wiklander 
28817466cbSJens Wiklander #include "mbedtls/md.h"
29817466cbSJens Wiklander #include "mbedtls/md_internal.h"
303d3b0591SJens Wiklander #include "mbedtls/platform_util.h"
3111fa71b9SJerome Forissier #include "mbedtls/error.h"
3211fa71b9SJerome Forissier 
3311fa71b9SJerome Forissier #include "mbedtls/md2.h"
3411fa71b9SJerome Forissier #include "mbedtls/md4.h"
3511fa71b9SJerome Forissier #include "mbedtls/md5.h"
3611fa71b9SJerome Forissier #include "mbedtls/ripemd160.h"
3711fa71b9SJerome Forissier #include "mbedtls/sha1.h"
3811fa71b9SJerome Forissier #include "mbedtls/sha256.h"
3911fa71b9SJerome Forissier #include "mbedtls/sha512.h"
40817466cbSJens Wiklander 
41817466cbSJens Wiklander #if defined(MBEDTLS_PLATFORM_C)
42817466cbSJens Wiklander #include "mbedtls/platform.h"
43817466cbSJens Wiklander #else
44817466cbSJens Wiklander #include <stdlib.h>
45817466cbSJens Wiklander #define mbedtls_calloc    calloc
46817466cbSJens Wiklander #define mbedtls_free       free
47817466cbSJens Wiklander #endif
48817466cbSJens Wiklander 
49817466cbSJens Wiklander #include <string.h>
50817466cbSJens Wiklander 
51817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO)
52817466cbSJens Wiklander #include <stdio.h>
53817466cbSJens Wiklander #endif
54817466cbSJens Wiklander 
5511fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
5611fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_md2_info = {
5711fa71b9SJerome Forissier     "MD2",
5811fa71b9SJerome Forissier     MBEDTLS_MD_MD2,
5911fa71b9SJerome Forissier     16,
6011fa71b9SJerome Forissier     16,
6111fa71b9SJerome Forissier };
6211fa71b9SJerome Forissier #endif
6311fa71b9SJerome Forissier 
6411fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
6511fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_md4_info = {
6611fa71b9SJerome Forissier     "MD4",
6711fa71b9SJerome Forissier     MBEDTLS_MD_MD4,
6811fa71b9SJerome Forissier     16,
6911fa71b9SJerome Forissier     64,
7011fa71b9SJerome Forissier };
7111fa71b9SJerome Forissier #endif
7211fa71b9SJerome Forissier 
7311fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
7411fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_md5_info = {
7511fa71b9SJerome Forissier     "MD5",
7611fa71b9SJerome Forissier     MBEDTLS_MD_MD5,
7711fa71b9SJerome Forissier     16,
7811fa71b9SJerome Forissier     64,
7911fa71b9SJerome Forissier };
8011fa71b9SJerome Forissier #endif
8111fa71b9SJerome Forissier 
8211fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
8311fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_ripemd160_info = {
8411fa71b9SJerome Forissier     "RIPEMD160",
8511fa71b9SJerome Forissier     MBEDTLS_MD_RIPEMD160,
8611fa71b9SJerome Forissier     20,
8711fa71b9SJerome Forissier     64,
8811fa71b9SJerome Forissier };
8911fa71b9SJerome Forissier #endif
9011fa71b9SJerome Forissier 
9111fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
9211fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha1_info = {
9311fa71b9SJerome Forissier     "SHA1",
9411fa71b9SJerome Forissier     MBEDTLS_MD_SHA1,
9511fa71b9SJerome Forissier     20,
9611fa71b9SJerome Forissier     64,
9711fa71b9SJerome Forissier };
9811fa71b9SJerome Forissier #endif
9911fa71b9SJerome Forissier 
10011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
10111fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha224_info = {
10211fa71b9SJerome Forissier     "SHA224",
10311fa71b9SJerome Forissier     MBEDTLS_MD_SHA224,
10411fa71b9SJerome Forissier     28,
10511fa71b9SJerome Forissier     64,
10611fa71b9SJerome Forissier };
10711fa71b9SJerome Forissier 
10811fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha256_info = {
10911fa71b9SJerome Forissier     "SHA256",
11011fa71b9SJerome Forissier     MBEDTLS_MD_SHA256,
11111fa71b9SJerome Forissier     32,
11211fa71b9SJerome Forissier     64,
11311fa71b9SJerome Forissier };
11411fa71b9SJerome Forissier #endif
11511fa71b9SJerome Forissier 
11611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
11711fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
11811fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha384_info = {
11911fa71b9SJerome Forissier     "SHA384",
12011fa71b9SJerome Forissier     MBEDTLS_MD_SHA384,
12111fa71b9SJerome Forissier     48,
12211fa71b9SJerome Forissier     128,
12311fa71b9SJerome Forissier };
12411fa71b9SJerome Forissier #endif
12511fa71b9SJerome Forissier 
12611fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha512_info = {
12711fa71b9SJerome Forissier     "SHA512",
12811fa71b9SJerome Forissier     MBEDTLS_MD_SHA512,
12911fa71b9SJerome Forissier     64,
13011fa71b9SJerome Forissier     128,
13111fa71b9SJerome Forissier };
13211fa71b9SJerome Forissier #endif
13311fa71b9SJerome Forissier 
134817466cbSJens Wiklander /*
135817466cbSJens Wiklander  * Reminder: update profiles in x509_crt.c when adding a new hash!
136817466cbSJens Wiklander  */
137817466cbSJens Wiklander static const int supported_digests[] = {
138817466cbSJens Wiklander 
139817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C)
140817466cbSJens Wiklander         MBEDTLS_MD_SHA512,
14111fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
142817466cbSJens Wiklander         MBEDTLS_MD_SHA384,
143817466cbSJens Wiklander #endif
14411fa71b9SJerome Forissier #endif
145817466cbSJens Wiklander 
146817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C)
147817466cbSJens Wiklander         MBEDTLS_MD_SHA256,
148817466cbSJens Wiklander         MBEDTLS_MD_SHA224,
149817466cbSJens Wiklander #endif
150817466cbSJens Wiklander 
151817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C)
152817466cbSJens Wiklander         MBEDTLS_MD_SHA1,
153817466cbSJens Wiklander #endif
154817466cbSJens Wiklander 
155817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C)
156817466cbSJens Wiklander         MBEDTLS_MD_RIPEMD160,
157817466cbSJens Wiklander #endif
158817466cbSJens Wiklander 
159817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C)
160817466cbSJens Wiklander         MBEDTLS_MD_MD5,
161817466cbSJens Wiklander #endif
162817466cbSJens Wiklander 
163817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C)
164817466cbSJens Wiklander         MBEDTLS_MD_MD4,
165817466cbSJens Wiklander #endif
166817466cbSJens Wiklander 
167817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C)
168817466cbSJens Wiklander         MBEDTLS_MD_MD2,
169817466cbSJens Wiklander #endif
170817466cbSJens Wiklander 
171817466cbSJens Wiklander         MBEDTLS_MD_NONE
172817466cbSJens Wiklander };
173817466cbSJens Wiklander 
174817466cbSJens Wiklander const int *mbedtls_md_list( void )
175817466cbSJens Wiklander {
176817466cbSJens Wiklander     return( supported_digests );
177817466cbSJens Wiklander }
178817466cbSJens Wiklander 
179817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
180817466cbSJens Wiklander {
181817466cbSJens Wiklander     if( NULL == md_name )
182817466cbSJens Wiklander         return( NULL );
183817466cbSJens Wiklander 
184817466cbSJens Wiklander     /* Get the appropriate digest information */
185817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C)
186817466cbSJens Wiklander     if( !strcmp( "MD2", md_name ) )
187817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 );
188817466cbSJens Wiklander #endif
189817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C)
190817466cbSJens Wiklander     if( !strcmp( "MD4", md_name ) )
191817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 );
192817466cbSJens Wiklander #endif
193817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C)
194817466cbSJens Wiklander     if( !strcmp( "MD5", md_name ) )
195817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 );
196817466cbSJens Wiklander #endif
197817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C)
198817466cbSJens Wiklander     if( !strcmp( "RIPEMD160", md_name ) )
199817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 );
200817466cbSJens Wiklander #endif
201817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C)
202817466cbSJens Wiklander     if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) )
203817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
204817466cbSJens Wiklander #endif
205817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C)
206817466cbSJens Wiklander     if( !strcmp( "SHA224", md_name ) )
207817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 );
208817466cbSJens Wiklander     if( !strcmp( "SHA256", md_name ) )
209817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
210817466cbSJens Wiklander #endif
211817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C)
21211fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
213817466cbSJens Wiklander     if( !strcmp( "SHA384", md_name ) )
214817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
21511fa71b9SJerome Forissier #endif
216817466cbSJens Wiklander     if( !strcmp( "SHA512", md_name ) )
217817466cbSJens Wiklander         return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
218817466cbSJens Wiklander #endif
219817466cbSJens Wiklander     return( NULL );
220817466cbSJens Wiklander }
221817466cbSJens Wiklander 
222817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
223817466cbSJens Wiklander {
224817466cbSJens Wiklander     switch( md_type )
225817466cbSJens Wiklander     {
226817466cbSJens Wiklander #if defined(MBEDTLS_MD2_C)
227817466cbSJens Wiklander         case MBEDTLS_MD_MD2:
228817466cbSJens Wiklander             return( &mbedtls_md2_info );
229817466cbSJens Wiklander #endif
230817466cbSJens Wiklander #if defined(MBEDTLS_MD4_C)
231817466cbSJens Wiklander         case MBEDTLS_MD_MD4:
232817466cbSJens Wiklander             return( &mbedtls_md4_info );
233817466cbSJens Wiklander #endif
234817466cbSJens Wiklander #if defined(MBEDTLS_MD5_C)
235817466cbSJens Wiklander         case MBEDTLS_MD_MD5:
236817466cbSJens Wiklander             return( &mbedtls_md5_info );
237817466cbSJens Wiklander #endif
238817466cbSJens Wiklander #if defined(MBEDTLS_RIPEMD160_C)
239817466cbSJens Wiklander         case MBEDTLS_MD_RIPEMD160:
240817466cbSJens Wiklander             return( &mbedtls_ripemd160_info );
241817466cbSJens Wiklander #endif
242817466cbSJens Wiklander #if defined(MBEDTLS_SHA1_C)
243817466cbSJens Wiklander         case MBEDTLS_MD_SHA1:
244817466cbSJens Wiklander             return( &mbedtls_sha1_info );
245817466cbSJens Wiklander #endif
246817466cbSJens Wiklander #if defined(MBEDTLS_SHA256_C)
247817466cbSJens Wiklander         case MBEDTLS_MD_SHA224:
248817466cbSJens Wiklander             return( &mbedtls_sha224_info );
249817466cbSJens Wiklander         case MBEDTLS_MD_SHA256:
250817466cbSJens Wiklander             return( &mbedtls_sha256_info );
251817466cbSJens Wiklander #endif
252817466cbSJens Wiklander #if defined(MBEDTLS_SHA512_C)
25311fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
254817466cbSJens Wiklander         case MBEDTLS_MD_SHA384:
255817466cbSJens Wiklander             return( &mbedtls_sha384_info );
25611fa71b9SJerome Forissier #endif
257817466cbSJens Wiklander         case MBEDTLS_MD_SHA512:
258817466cbSJens Wiklander             return( &mbedtls_sha512_info );
259817466cbSJens Wiklander #endif
260817466cbSJens Wiklander         default:
261817466cbSJens Wiklander             return( NULL );
262817466cbSJens Wiklander     }
263817466cbSJens Wiklander }
264817466cbSJens Wiklander 
265817466cbSJens Wiklander void mbedtls_md_init( mbedtls_md_context_t *ctx )
266817466cbSJens Wiklander {
267817466cbSJens Wiklander     memset( ctx, 0, sizeof( mbedtls_md_context_t ) );
268817466cbSJens Wiklander }
269817466cbSJens Wiklander 
270817466cbSJens Wiklander void mbedtls_md_free( mbedtls_md_context_t *ctx )
271817466cbSJens Wiklander {
272817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL )
273817466cbSJens Wiklander         return;
274817466cbSJens Wiklander 
275817466cbSJens Wiklander     if( ctx->md_ctx != NULL )
27611fa71b9SJerome Forissier     {
27711fa71b9SJerome Forissier         switch( ctx->md_info->type )
27811fa71b9SJerome Forissier         {
27911fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
28011fa71b9SJerome Forissier             case MBEDTLS_MD_MD2:
28111fa71b9SJerome Forissier                 mbedtls_md2_free( ctx->md_ctx );
28211fa71b9SJerome Forissier                 break;
28311fa71b9SJerome Forissier #endif
28411fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
28511fa71b9SJerome Forissier             case MBEDTLS_MD_MD4:
28611fa71b9SJerome Forissier                 mbedtls_md4_free( ctx->md_ctx );
28711fa71b9SJerome Forissier                 break;
28811fa71b9SJerome Forissier #endif
28911fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
29011fa71b9SJerome Forissier             case MBEDTLS_MD_MD5:
29111fa71b9SJerome Forissier                 mbedtls_md5_free( ctx->md_ctx );
29211fa71b9SJerome Forissier                 break;
29311fa71b9SJerome Forissier #endif
29411fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
29511fa71b9SJerome Forissier             case MBEDTLS_MD_RIPEMD160:
29611fa71b9SJerome Forissier                 mbedtls_ripemd160_free( ctx->md_ctx );
29711fa71b9SJerome Forissier                 break;
29811fa71b9SJerome Forissier #endif
29911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
30011fa71b9SJerome Forissier             case MBEDTLS_MD_SHA1:
30111fa71b9SJerome Forissier                 mbedtls_sha1_free( ctx->md_ctx );
30211fa71b9SJerome Forissier                 break;
30311fa71b9SJerome Forissier #endif
30411fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
30511fa71b9SJerome Forissier             case MBEDTLS_MD_SHA224:
30611fa71b9SJerome Forissier             case MBEDTLS_MD_SHA256:
30711fa71b9SJerome Forissier                 mbedtls_sha256_free( ctx->md_ctx );
30811fa71b9SJerome Forissier                 break;
30911fa71b9SJerome Forissier #endif
31011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
31111fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
31211fa71b9SJerome Forissier             case MBEDTLS_MD_SHA384:
31311fa71b9SJerome Forissier #endif
31411fa71b9SJerome Forissier             case MBEDTLS_MD_SHA512:
31511fa71b9SJerome Forissier                 mbedtls_sha512_free( ctx->md_ctx );
31611fa71b9SJerome Forissier                 break;
31711fa71b9SJerome Forissier #endif
31811fa71b9SJerome Forissier             default:
31911fa71b9SJerome Forissier                 /* Shouldn't happen */
32011fa71b9SJerome Forissier                 break;
32111fa71b9SJerome Forissier         }
32211fa71b9SJerome Forissier         mbedtls_free( ctx->md_ctx );
32311fa71b9SJerome Forissier     }
324817466cbSJens Wiklander 
325817466cbSJens Wiklander     if( ctx->hmac_ctx != NULL )
326817466cbSJens Wiklander     {
3273d3b0591SJens Wiklander         mbedtls_platform_zeroize( ctx->hmac_ctx,
3283d3b0591SJens Wiklander                                   2 * ctx->md_info->block_size );
329817466cbSJens Wiklander         mbedtls_free( ctx->hmac_ctx );
330817466cbSJens Wiklander     }
331817466cbSJens Wiklander 
3323d3b0591SJens Wiklander     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md_context_t ) );
333817466cbSJens Wiklander }
334817466cbSJens Wiklander 
335817466cbSJens Wiklander int mbedtls_md_clone( mbedtls_md_context_t *dst,
336817466cbSJens Wiklander                       const mbedtls_md_context_t *src )
337817466cbSJens Wiklander {
338817466cbSJens Wiklander     if( dst == NULL || dst->md_info == NULL ||
339817466cbSJens Wiklander         src == NULL || src->md_info == NULL ||
340817466cbSJens Wiklander         dst->md_info != src->md_info )
341817466cbSJens Wiklander     {
342817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
343817466cbSJens Wiklander     }
344817466cbSJens Wiklander 
34511fa71b9SJerome Forissier     switch( src->md_info->type )
34611fa71b9SJerome Forissier     {
34711fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
34811fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
34911fa71b9SJerome Forissier             mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
35011fa71b9SJerome Forissier             break;
35111fa71b9SJerome Forissier #endif
35211fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
35311fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
35411fa71b9SJerome Forissier             mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
35511fa71b9SJerome Forissier             break;
35611fa71b9SJerome Forissier #endif
35711fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
35811fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
35911fa71b9SJerome Forissier             mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
36011fa71b9SJerome Forissier             break;
36111fa71b9SJerome Forissier #endif
36211fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
36311fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
36411fa71b9SJerome Forissier             mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
36511fa71b9SJerome Forissier             break;
36611fa71b9SJerome Forissier #endif
36711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
36811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
36911fa71b9SJerome Forissier             mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
37011fa71b9SJerome Forissier             break;
37111fa71b9SJerome Forissier #endif
37211fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
37311fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
37411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
37511fa71b9SJerome Forissier             mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
37611fa71b9SJerome Forissier             break;
37711fa71b9SJerome Forissier #endif
37811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
37911fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
38011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
38111fa71b9SJerome Forissier #endif
38211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
38311fa71b9SJerome Forissier             mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
38411fa71b9SJerome Forissier             break;
38511fa71b9SJerome Forissier #endif
38611fa71b9SJerome Forissier         default:
38711fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
38811fa71b9SJerome Forissier     }
389817466cbSJens Wiklander 
39012484fc7SEdison Ai     if( dst->hmac_ctx != NULL && src->hmac_ctx != NULL )
39112484fc7SEdison Ai         memcpy( dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size );
39212484fc7SEdison Ai 
393817466cbSJens Wiklander     return( 0 );
394817466cbSJens Wiklander }
395817466cbSJens Wiklander 
396817466cbSJens Wiklander #if ! defined(MBEDTLS_DEPRECATED_REMOVED)
397817466cbSJens Wiklander int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info )
398817466cbSJens Wiklander {
399817466cbSJens Wiklander     return mbedtls_md_setup( ctx, md_info, 1 );
400817466cbSJens Wiklander }
401817466cbSJens Wiklander #endif
402817466cbSJens Wiklander 
40311fa71b9SJerome Forissier #define ALLOC( type )                                                   \
40411fa71b9SJerome Forissier     do {                                                                \
40511fa71b9SJerome Forissier         ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
40611fa71b9SJerome Forissier         if( ctx->md_ctx == NULL )                                       \
40711fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_ALLOC_FAILED );                      \
40811fa71b9SJerome Forissier         mbedtls_##type##_init( ctx->md_ctx );                           \
40911fa71b9SJerome Forissier     }                                                                   \
41011fa71b9SJerome Forissier     while( 0 )
41111fa71b9SJerome Forissier 
412817466cbSJens Wiklander int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
413817466cbSJens Wiklander {
414817466cbSJens Wiklander     if( md_info == NULL || ctx == NULL )
415817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
416817466cbSJens Wiklander 
417*7901324dSJerome Forissier     ctx->md_info = md_info;
418*7901324dSJerome Forissier     ctx->md_ctx = NULL;
419*7901324dSJerome Forissier     ctx->hmac_ctx = NULL;
420*7901324dSJerome Forissier 
42111fa71b9SJerome Forissier     switch( md_info->type )
42211fa71b9SJerome Forissier     {
42311fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
42411fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
42511fa71b9SJerome Forissier             ALLOC( md2 );
42611fa71b9SJerome Forissier             break;
42711fa71b9SJerome Forissier #endif
42811fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
42911fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
43011fa71b9SJerome Forissier             ALLOC( md4 );
43111fa71b9SJerome Forissier             break;
43211fa71b9SJerome Forissier #endif
43311fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
43411fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
43511fa71b9SJerome Forissier             ALLOC( md5 );
43611fa71b9SJerome Forissier             break;
43711fa71b9SJerome Forissier #endif
43811fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
43911fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
44011fa71b9SJerome Forissier             ALLOC( ripemd160 );
44111fa71b9SJerome Forissier             break;
44211fa71b9SJerome Forissier #endif
44311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
44411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
44511fa71b9SJerome Forissier             ALLOC( sha1 );
44611fa71b9SJerome Forissier             break;
44711fa71b9SJerome Forissier #endif
44811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
44911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
45011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
45111fa71b9SJerome Forissier             ALLOC( sha256 );
45211fa71b9SJerome Forissier             break;
45311fa71b9SJerome Forissier #endif
45411fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
45511fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
45611fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
45711fa71b9SJerome Forissier #endif
45811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
45911fa71b9SJerome Forissier             ALLOC( sha512 );
46011fa71b9SJerome Forissier             break;
46111fa71b9SJerome Forissier #endif
46211fa71b9SJerome Forissier         default:
46311fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
46411fa71b9SJerome Forissier     }
465817466cbSJens Wiklander 
466817466cbSJens Wiklander     if( hmac != 0 )
467817466cbSJens Wiklander     {
468817466cbSJens Wiklander         ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
469817466cbSJens Wiklander         if( ctx->hmac_ctx == NULL )
470817466cbSJens Wiklander         {
47111fa71b9SJerome Forissier             mbedtls_md_free( ctx );
472817466cbSJens Wiklander             return( MBEDTLS_ERR_MD_ALLOC_FAILED );
473817466cbSJens Wiklander         }
474817466cbSJens Wiklander     }
475817466cbSJens Wiklander 
476817466cbSJens Wiklander     return( 0 );
477817466cbSJens Wiklander }
47811fa71b9SJerome Forissier #undef ALLOC
479817466cbSJens Wiklander 
480817466cbSJens Wiklander int mbedtls_md_starts( mbedtls_md_context_t *ctx )
481817466cbSJens Wiklander {
482817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL )
483817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
484817466cbSJens Wiklander 
48511fa71b9SJerome Forissier     switch( ctx->md_info->type )
48611fa71b9SJerome Forissier     {
48711fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
48811fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
48911fa71b9SJerome Forissier             return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
49011fa71b9SJerome Forissier #endif
49111fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
49211fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
49311fa71b9SJerome Forissier             return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
49411fa71b9SJerome Forissier #endif
49511fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
49611fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
49711fa71b9SJerome Forissier             return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
49811fa71b9SJerome Forissier #endif
49911fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
50011fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
50111fa71b9SJerome Forissier             return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
50211fa71b9SJerome Forissier #endif
50311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
50411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
50511fa71b9SJerome Forissier             return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
50611fa71b9SJerome Forissier #endif
50711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
50811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
50911fa71b9SJerome Forissier             return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
51011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
51111fa71b9SJerome Forissier             return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
51211fa71b9SJerome Forissier #endif
51311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
51411fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
51511fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
51611fa71b9SJerome Forissier             return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
51711fa71b9SJerome Forissier #endif
51811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
51911fa71b9SJerome Forissier             return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
52011fa71b9SJerome Forissier #endif
52111fa71b9SJerome Forissier         default:
52211fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
52311fa71b9SJerome Forissier     }
524817466cbSJens Wiklander }
525817466cbSJens Wiklander 
526817466cbSJens Wiklander int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
527817466cbSJens Wiklander {
528817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL )
529817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
530817466cbSJens Wiklander 
53111fa71b9SJerome Forissier     switch( ctx->md_info->type )
53211fa71b9SJerome Forissier     {
53311fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
53411fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
53511fa71b9SJerome Forissier             return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
53611fa71b9SJerome Forissier #endif
53711fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
53811fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
53911fa71b9SJerome Forissier             return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
54011fa71b9SJerome Forissier #endif
54111fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
54211fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
54311fa71b9SJerome Forissier             return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
54411fa71b9SJerome Forissier #endif
54511fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
54611fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
54711fa71b9SJerome Forissier             return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
54811fa71b9SJerome Forissier #endif
54911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
55011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
55111fa71b9SJerome Forissier             return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
55211fa71b9SJerome Forissier #endif
55311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
55411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
55511fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
55611fa71b9SJerome Forissier             return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
55711fa71b9SJerome Forissier #endif
55811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
55911fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
56011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
56111fa71b9SJerome Forissier #endif
56211fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
56311fa71b9SJerome Forissier             return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
56411fa71b9SJerome Forissier #endif
56511fa71b9SJerome Forissier         default:
56611fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
56711fa71b9SJerome Forissier     }
568817466cbSJens Wiklander }
569817466cbSJens Wiklander 
570817466cbSJens Wiklander int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
571817466cbSJens Wiklander {
572817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL )
573817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
574817466cbSJens Wiklander 
57511fa71b9SJerome Forissier     switch( ctx->md_info->type )
57611fa71b9SJerome Forissier     {
57711fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
57811fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
57911fa71b9SJerome Forissier             return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
58011fa71b9SJerome Forissier #endif
58111fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
58211fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
58311fa71b9SJerome Forissier             return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
58411fa71b9SJerome Forissier #endif
58511fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
58611fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
58711fa71b9SJerome Forissier             return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
58811fa71b9SJerome Forissier #endif
58911fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
59011fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
59111fa71b9SJerome Forissier             return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
59211fa71b9SJerome Forissier #endif
59311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
59411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
59511fa71b9SJerome Forissier             return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
59611fa71b9SJerome Forissier #endif
59711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
59811fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
59911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
60011fa71b9SJerome Forissier             return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
60111fa71b9SJerome Forissier #endif
60211fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
60311fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
60411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
60511fa71b9SJerome Forissier #endif
60611fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
60711fa71b9SJerome Forissier             return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
60811fa71b9SJerome Forissier #endif
60911fa71b9SJerome Forissier         default:
61011fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
61111fa71b9SJerome Forissier     }
612817466cbSJens Wiklander }
613817466cbSJens Wiklander 
614817466cbSJens Wiklander int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
615817466cbSJens Wiklander             unsigned char *output )
616817466cbSJens Wiklander {
617817466cbSJens Wiklander     if( md_info == NULL )
618817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
619817466cbSJens Wiklander 
62011fa71b9SJerome Forissier     switch( md_info->type )
62111fa71b9SJerome Forissier     {
62211fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
62311fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
62411fa71b9SJerome Forissier             return( mbedtls_md2_ret( input, ilen, output ) );
62511fa71b9SJerome Forissier #endif
62611fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
62711fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
62811fa71b9SJerome Forissier             return( mbedtls_md4_ret( input, ilen, output ) );
62911fa71b9SJerome Forissier #endif
63011fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
63111fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
63211fa71b9SJerome Forissier             return( mbedtls_md5_ret( input, ilen, output ) );
63311fa71b9SJerome Forissier #endif
63411fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
63511fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
63611fa71b9SJerome Forissier             return( mbedtls_ripemd160_ret( input, ilen, output ) );
63711fa71b9SJerome Forissier #endif
63811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
63911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
64011fa71b9SJerome Forissier             return( mbedtls_sha1_ret( input, ilen, output ) );
64111fa71b9SJerome Forissier #endif
64211fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
64311fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
64411fa71b9SJerome Forissier             return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
64511fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
64611fa71b9SJerome Forissier             return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
64711fa71b9SJerome Forissier #endif
64811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
64911fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
65011fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
65111fa71b9SJerome Forissier             return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
65211fa71b9SJerome Forissier #endif
65311fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
65411fa71b9SJerome Forissier             return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
65511fa71b9SJerome Forissier #endif
65611fa71b9SJerome Forissier         default:
65711fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
65811fa71b9SJerome Forissier     }
659817466cbSJens Wiklander }
660817466cbSJens Wiklander 
661817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO)
662817466cbSJens Wiklander int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
663817466cbSJens Wiklander {
66411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
665817466cbSJens Wiklander     FILE *f;
666817466cbSJens Wiklander     size_t n;
667817466cbSJens Wiklander     mbedtls_md_context_t ctx;
668817466cbSJens Wiklander     unsigned char buf[1024];
669817466cbSJens Wiklander 
670817466cbSJens Wiklander     if( md_info == NULL )
671817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
672817466cbSJens Wiklander 
673817466cbSJens Wiklander     if( ( f = fopen( path, "rb" ) ) == NULL )
674817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_FILE_IO_ERROR );
675817466cbSJens Wiklander 
676817466cbSJens Wiklander     mbedtls_md_init( &ctx );
677817466cbSJens Wiklander 
678817466cbSJens Wiklander     if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
679817466cbSJens Wiklander         goto cleanup;
680817466cbSJens Wiklander 
68111fa71b9SJerome Forissier     if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
6823d3b0591SJens Wiklander         goto cleanup;
683817466cbSJens Wiklander 
684817466cbSJens Wiklander     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
68511fa71b9SJerome Forissier         if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
6863d3b0591SJens Wiklander             goto cleanup;
687817466cbSJens Wiklander 
688817466cbSJens Wiklander     if( ferror( f ) != 0 )
689817466cbSJens Wiklander         ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
6903d3b0591SJens Wiklander     else
69111fa71b9SJerome Forissier         ret = mbedtls_md_finish( &ctx, output );
692817466cbSJens Wiklander 
693817466cbSJens Wiklander cleanup:
6943d3b0591SJens Wiklander     mbedtls_platform_zeroize( buf, sizeof( buf ) );
695817466cbSJens Wiklander     fclose( f );
696817466cbSJens Wiklander     mbedtls_md_free( &ctx );
697817466cbSJens Wiklander 
698817466cbSJens Wiklander     return( ret );
699817466cbSJens Wiklander }
700817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */
701817466cbSJens Wiklander 
702817466cbSJens Wiklander int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
703817466cbSJens Wiklander {
70411fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
705817466cbSJens Wiklander     unsigned char sum[MBEDTLS_MD_MAX_SIZE];
706817466cbSJens Wiklander     unsigned char *ipad, *opad;
707817466cbSJens Wiklander     size_t i;
708817466cbSJens Wiklander 
709817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
710817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
711817466cbSJens Wiklander 
712817466cbSJens Wiklander     if( keylen > (size_t) ctx->md_info->block_size )
713817466cbSJens Wiklander     {
71411fa71b9SJerome Forissier         if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
7153d3b0591SJens Wiklander             goto cleanup;
71611fa71b9SJerome Forissier         if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
7173d3b0591SJens Wiklander             goto cleanup;
71811fa71b9SJerome Forissier         if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
7193d3b0591SJens Wiklander             goto cleanup;
720817466cbSJens Wiklander 
721817466cbSJens Wiklander         keylen = ctx->md_info->size;
722817466cbSJens Wiklander         key = sum;
723817466cbSJens Wiklander     }
724817466cbSJens Wiklander 
725817466cbSJens Wiklander     ipad = (unsigned char *) ctx->hmac_ctx;
726817466cbSJens Wiklander     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
727817466cbSJens Wiklander 
728817466cbSJens Wiklander     memset( ipad, 0x36, ctx->md_info->block_size );
729817466cbSJens Wiklander     memset( opad, 0x5C, ctx->md_info->block_size );
730817466cbSJens Wiklander 
731817466cbSJens Wiklander     for( i = 0; i < keylen; i++ )
732817466cbSJens Wiklander     {
733817466cbSJens Wiklander         ipad[i] = (unsigned char)( ipad[i] ^ key[i] );
734817466cbSJens Wiklander         opad[i] = (unsigned char)( opad[i] ^ key[i] );
735817466cbSJens Wiklander     }
736817466cbSJens Wiklander 
73711fa71b9SJerome Forissier     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
7383d3b0591SJens Wiklander         goto cleanup;
73911fa71b9SJerome Forissier     if( ( ret = mbedtls_md_update( ctx, ipad,
7403d3b0591SJens Wiklander                                    ctx->md_info->block_size ) ) != 0 )
7413d3b0591SJens Wiklander         goto cleanup;
742817466cbSJens Wiklander 
7433d3b0591SJens Wiklander cleanup:
7443d3b0591SJens Wiklander     mbedtls_platform_zeroize( sum, sizeof( sum ) );
745817466cbSJens Wiklander 
7463d3b0591SJens Wiklander     return( ret );
747817466cbSJens Wiklander }
748817466cbSJens Wiklander 
749817466cbSJens Wiklander int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
750817466cbSJens Wiklander {
751817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
752817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
753817466cbSJens Wiklander 
75411fa71b9SJerome Forissier     return( mbedtls_md_update( ctx, input, ilen ) );
755817466cbSJens Wiklander }
756817466cbSJens Wiklander 
757817466cbSJens Wiklander int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
758817466cbSJens Wiklander {
75911fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
760817466cbSJens Wiklander     unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
761817466cbSJens Wiklander     unsigned char *opad;
762817466cbSJens Wiklander 
763817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
764817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
765817466cbSJens Wiklander 
766817466cbSJens Wiklander     opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
767817466cbSJens Wiklander 
76811fa71b9SJerome Forissier     if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
7693d3b0591SJens Wiklander         return( ret );
77011fa71b9SJerome Forissier     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
7713d3b0591SJens Wiklander         return( ret );
77211fa71b9SJerome Forissier     if( ( ret = mbedtls_md_update( ctx, opad,
7733d3b0591SJens Wiklander                                    ctx->md_info->block_size ) ) != 0 )
7743d3b0591SJens Wiklander         return( ret );
77511fa71b9SJerome Forissier     if( ( ret = mbedtls_md_update( ctx, tmp,
7763d3b0591SJens Wiklander                                    ctx->md_info->size ) ) != 0 )
7773d3b0591SJens Wiklander         return( ret );
77811fa71b9SJerome Forissier     return( mbedtls_md_finish( ctx, output ) );
779817466cbSJens Wiklander }
780817466cbSJens Wiklander 
781817466cbSJens Wiklander int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
782817466cbSJens Wiklander {
78311fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
784817466cbSJens Wiklander     unsigned char *ipad;
785817466cbSJens Wiklander 
786817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
787817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
788817466cbSJens Wiklander 
789817466cbSJens Wiklander     ipad = (unsigned char *) ctx->hmac_ctx;
790817466cbSJens Wiklander 
79111fa71b9SJerome Forissier     if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
7923d3b0591SJens Wiklander         return( ret );
79311fa71b9SJerome Forissier     return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
794817466cbSJens Wiklander }
795817466cbSJens Wiklander 
7963d3b0591SJens Wiklander int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
7973d3b0591SJens Wiklander                      const unsigned char *key, size_t keylen,
798817466cbSJens Wiklander                      const unsigned char *input, size_t ilen,
799817466cbSJens Wiklander                      unsigned char *output )
800817466cbSJens Wiklander {
801817466cbSJens Wiklander     mbedtls_md_context_t ctx;
80211fa71b9SJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
803817466cbSJens Wiklander 
804817466cbSJens Wiklander     if( md_info == NULL )
805817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
806817466cbSJens Wiklander 
807817466cbSJens Wiklander     mbedtls_md_init( &ctx );
808817466cbSJens Wiklander 
809817466cbSJens Wiklander     if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 )
8103d3b0591SJens Wiklander         goto cleanup;
811817466cbSJens Wiklander 
8123d3b0591SJens Wiklander     if( ( ret = mbedtls_md_hmac_starts( &ctx, key, keylen ) ) != 0 )
8133d3b0591SJens Wiklander         goto cleanup;
8143d3b0591SJens Wiklander     if( ( ret = mbedtls_md_hmac_update( &ctx, input, ilen ) ) != 0 )
8153d3b0591SJens Wiklander         goto cleanup;
8163d3b0591SJens Wiklander     if( ( ret = mbedtls_md_hmac_finish( &ctx, output ) ) != 0 )
8173d3b0591SJens Wiklander         goto cleanup;
818817466cbSJens Wiklander 
8193d3b0591SJens Wiklander cleanup:
820817466cbSJens Wiklander     mbedtls_md_free( &ctx );
821817466cbSJens Wiklander 
8223d3b0591SJens Wiklander     return( ret );
823817466cbSJens Wiklander }
824817466cbSJens Wiklander 
825817466cbSJens Wiklander int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
826817466cbSJens Wiklander {
827817466cbSJens Wiklander     if( ctx == NULL || ctx->md_info == NULL )
828817466cbSJens Wiklander         return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
829817466cbSJens Wiklander 
83011fa71b9SJerome Forissier     switch( ctx->md_info->type )
83111fa71b9SJerome Forissier     {
83211fa71b9SJerome Forissier #if defined(MBEDTLS_MD2_C)
83311fa71b9SJerome Forissier         case MBEDTLS_MD_MD2:
83411fa71b9SJerome Forissier             return( mbedtls_internal_md2_process( ctx->md_ctx ) );
83511fa71b9SJerome Forissier #endif
83611fa71b9SJerome Forissier #if defined(MBEDTLS_MD4_C)
83711fa71b9SJerome Forissier         case MBEDTLS_MD_MD4:
83811fa71b9SJerome Forissier             return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
83911fa71b9SJerome Forissier #endif
84011fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C)
84111fa71b9SJerome Forissier         case MBEDTLS_MD_MD5:
84211fa71b9SJerome Forissier             return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
84311fa71b9SJerome Forissier #endif
84411fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C)
84511fa71b9SJerome Forissier         case MBEDTLS_MD_RIPEMD160:
84611fa71b9SJerome Forissier             return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
84711fa71b9SJerome Forissier #endif
84811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C)
84911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA1:
85011fa71b9SJerome Forissier             return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
85111fa71b9SJerome Forissier #endif
85211fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C)
85311fa71b9SJerome Forissier         case MBEDTLS_MD_SHA224:
85411fa71b9SJerome Forissier         case MBEDTLS_MD_SHA256:
85511fa71b9SJerome Forissier             return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
85611fa71b9SJerome Forissier #endif
85711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C)
85811fa71b9SJerome Forissier #if !defined(MBEDTLS_SHA512_NO_SHA384)
85911fa71b9SJerome Forissier         case MBEDTLS_MD_SHA384:
86011fa71b9SJerome Forissier #endif
86111fa71b9SJerome Forissier         case MBEDTLS_MD_SHA512:
86211fa71b9SJerome Forissier             return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
86311fa71b9SJerome Forissier #endif
86411fa71b9SJerome Forissier         default:
86511fa71b9SJerome Forissier             return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
86611fa71b9SJerome Forissier     }
867817466cbSJens Wiklander }
868817466cbSJens Wiklander 
869817466cbSJens Wiklander unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
870817466cbSJens Wiklander {
871817466cbSJens Wiklander     if( md_info == NULL )
872817466cbSJens Wiklander         return( 0 );
873817466cbSJens Wiklander 
874817466cbSJens Wiklander     return md_info->size;
875817466cbSJens Wiklander }
876817466cbSJens Wiklander 
877817466cbSJens Wiklander mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info )
878817466cbSJens Wiklander {
879817466cbSJens Wiklander     if( md_info == NULL )
880817466cbSJens Wiklander         return( MBEDTLS_MD_NONE );
881817466cbSJens Wiklander 
882817466cbSJens Wiklander     return md_info->type;
883817466cbSJens Wiklander }
884817466cbSJens Wiklander 
885817466cbSJens Wiklander const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info )
886817466cbSJens Wiklander {
887817466cbSJens Wiklander     if( md_info == NULL )
888817466cbSJens Wiklander         return( NULL );
889817466cbSJens Wiklander 
890817466cbSJens Wiklander     return md_info->name;
891817466cbSJens Wiklander }
892817466cbSJens Wiklander 
893817466cbSJens Wiklander #endif /* MBEDTLS_MD_C */
894