blob: 50ac66044ad82edf165b01a80636a9a4a033290f [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010020 */
21
22/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010025 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010026 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010042#include <stdio.h>
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_SELF_TEST */
52#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010054/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020055 * HMAC_DRBG context initialization
56 */
57void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
58{
59 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010060
61#if defined(MBEDTLS_THREADING_C)
62 mbedtls_mutex_init( &ctx->mutex );
63#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020064}
65
66/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010067 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010068 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020069int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
70 const unsigned char *additional,
71 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010072{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010074 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
75 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +020077 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010078
79 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
80 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010081 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020082 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
83 goto exit;
84 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
85 ctx->V, md_len ) ) != 0 )
86 goto exit;
87 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
88 sep, 1 ) ) != 0 )
89 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010090 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020091 {
92 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
93 additional, add_len ) ) != 0 )
94 goto exit;
95 }
96 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
97 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010098
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010099 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
101 goto exit;
102 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
103 ctx->V, md_len ) ) != 0 )
104 goto exit;
105 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
106 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100107 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200108
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200109exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200110 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200111 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100112}
113
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200114#if !defined(MBEDTLS_DEPRECATED_REMOVED)
115void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
116 const unsigned char *additional,
117 size_t add_len )
118{
119 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
120}
121#endif /* MBEDTLS_DEPRECATED_REMOVED */
122
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100123/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100124 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100125 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200126int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100128 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100129{
130 int ret;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100133 return( ret );
134
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100135 /*
136 * Set initial working state.
137 * Use the V memory location, which is currently all 0, to initialize the
138 * MD context with an all-zero key. Then set V to its initial value.
139 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200140 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
141 mbedtls_md_get_size( md_info ) ) ) != 0 )
142 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100144
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200145 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
146 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100147
148 return( 0 );
149}
150
Hanno Beckereab304c2019-08-26 15:29:14 +0100151static int hmac_drbg_reseed_internal( mbedtls_hmac_drbg_context *ctx,
152 const unsigned char *additional, size_t len,
153 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100154{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckereab304c2019-08-26 15:29:14 +0100156 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200157 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100158
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100159 {
Hanno Beckereab304c2019-08-26 15:29:14 +0100160 size_t total_entropy_len;
161
162 if( use_nonce == 0 )
163 total_entropy_len = ctx->entropy_len;
164 else
165 total_entropy_len = ctx->entropy_len * 3 / 2;
166
167 /* III. Check input length */
168 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
169 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
170 {
171 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
172 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100173 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100176
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100177 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200178 if( ( ret = ctx->f_entropy( ctx->p_entropy,
179 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100180 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckereab304c2019-08-26 15:29:14 +0100182 }
183 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184
Hanno Beckereab304c2019-08-26 15:29:14 +0100185 /* IV'. For initial seeding, allow adding of nonce generated
186 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
187 if( use_nonce )
188 {
189 /* Note: We don't merge the two calls to f_entropy() in order
190 * to avoid requesting too much entropy from f_entropy()
191 * at once. Specifically, if the underlying digest is not
192 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
193 * is larger than the maximum of 32 Bytes that our own
194 * entropy source implementation can emit in a single
195 * call in configurations disabling SHA-512. */
196 if( ( ret = ctx->f_entropy( ctx->p_entropy,
197 seed + seedlen,
198 ctx->entropy_len / 2 ) ) != 0 )
199 {
200 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
201 }
202
203 seedlen += ctx->entropy_len / 2;
204 }
205
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100207 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208 if( additional != NULL && len != 0 )
209 {
210 memcpy( seed + seedlen, additional, len );
211 seedlen += len;
212 }
213
214 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200215 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
216 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100218 /* 3. Reset reseed_counter */
219 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100220
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200221exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200223 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200224 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100225}
226
227/*
Hanno Beckereab304c2019-08-26 15:29:14 +0100228 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
229 */
230int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
231 const unsigned char *additional, size_t len )
232{
233 return( hmac_drbg_reseed_internal( ctx, additional, len, 0 ) );
234}
235
236/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100237 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100238 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200239int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100241 int (*f_entropy)(void *, unsigned char *, size_t),
242 void *p_entropy,
243 const unsigned char *custom,
244 size_t len )
245{
246 int ret;
Hanno Beckereab304c2019-08-26 15:29:14 +0100247 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100250 return( ret );
251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100253
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100254 /*
255 * Set initial working state.
256 * Use the V memory location, which is currently all 0, to initialize the
257 * MD context with an all-zero key. Then set V to its initial value.
258 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200259 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
260 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100261 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100262
263 ctx->f_entropy = f_entropy;
264 ctx->p_entropy = p_entropy;
265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100267
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100268 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100269 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
270 * each hash function, then according to SP800-90A rev1 10.1 table 2,
271 * min_entropy_len (in bits) is security_strength.
272 *
273 * (This also matches the sizes used in the NIST test vectors.)
274 */
Hanno Beckereab304c2019-08-26 15:29:14 +0100275 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
276 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
277 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100278
Hanno Beckereab304c2019-08-26 15:29:14 +0100279 if( ( ret = hmac_drbg_reseed_internal( ctx, custom, len,
280 1 /* add nonce */ ) ) != 0 )
281 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100282 return( ret );
Hanno Beckereab304c2019-08-26 15:29:14 +0100283 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100284
285 return( 0 );
286}
287
288/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100289 * Set prediction resistance
290 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100292 int resistance )
293{
294 ctx->prediction_resistance = resistance;
295}
296
297/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100298 * Set entropy length grabbed for reseeds
299 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100301{
302 ctx->entropy_len = len;
303}
304
305/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100306 * Set reseed interval
307 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100309{
310 ctx->reseed_interval = interval;
311}
312
313/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100314 * HMAC_DRBG random function with optional additional data:
315 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100316 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100318 unsigned char *output, size_t out_len,
319 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100320{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100321 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
323 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100324 size_t left = out_len;
325 unsigned char *out = output;
326
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100327 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
329 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100330
331 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
333 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100334
335 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100336 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100338 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100339 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100341 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100342
343 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100344 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100345
346 /* 2. Use additional data if any */
347 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200348 {
349 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
350 additional, add_len ) ) != 0 )
351 goto exit;
352 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100353
354 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100355 while( left != 0 )
356 {
357 size_t use_len = left > md_len ? md_len : left;
358
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200359 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
360 goto exit;
361 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
362 ctx->V, md_len ) ) != 0 )
363 goto exit;
364 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
365 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100366
367 memcpy( out, ctx->V, use_len );
368 out += use_len;
369 left -= use_len;
370 }
371
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100372 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200373 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
374 additional, add_len ) ) != 0 )
375 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100376
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100377 /* 7. Update reseed counter */
378 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100379
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200380exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100381 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200382 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100383}
384
385/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100386 * HMAC_DRBG random function
387 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100389{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100390 int ret;
391 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
392
393#if defined(MBEDTLS_THREADING_C)
394 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
395 return( ret );
396#endif
397
398 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
399
400#if defined(MBEDTLS_THREADING_C)
401 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
402 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
403#endif
404
405 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100406}
407
408/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100409 * Free an HMAC_DRBG context
410 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100412{
413 if( ctx == NULL )
414 return;
415
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100416#if defined(MBEDTLS_THREADING_C)
417 mbedtls_mutex_free( &ctx->mutex );
418#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500420 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421}
422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423#if defined(MBEDTLS_FS_IO)
424int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100425{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100426 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100427 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100429
430 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100434 goto exit;
435
436 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
437 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100439 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440 }
441
442 ret = 0;
443
444exit:
445 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500446 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100447
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100448 return( ret );
449}
450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100453 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200454 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100455 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200457 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458
459 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461
Gilles Peskine82204662018-09-11 18:43:09 +0200462 n = fread( buf, 1, sizeof( buf ), f );
463 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464 {
Gilles Peskine82204662018-09-11 18:43:09 +0200465 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
466 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467 }
Gilles Peskine82204662018-09-11 18:43:09 +0200468 if( n == 0 || ferror( f ) )
469 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100470 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200471 goto exit;
472 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200474 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475
Gilles Peskine82204662018-09-11 18:43:09 +0200476 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
477
478exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500479 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200480 if( f != NULL )
481 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100482 if( ret != 0 )
483 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100485}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100487
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100492/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100494{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200495 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100496 return( 0 );
497}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100498#else
499
500#define OUTPUT_LEN 80
501
502/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000503static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100504 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
505 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
506 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
507 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
508 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
509static const unsigned char result_pr[OUTPUT_LEN] = {
510 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
511 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
512 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
513 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
514 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
515 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
516 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
517
518/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000519static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100520 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
521 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
522 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
523 0xe9, 0x9d, 0xfe, 0xdf };
524static const unsigned char result_nopr[OUTPUT_LEN] = {
525 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
526 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
527 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
528 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
529 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
530 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
531 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
532
533/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100534static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535static int hmac_drbg_self_test_entropy( void *data,
536 unsigned char *buf, size_t len )
537{
538 const unsigned char *p = data;
539 memcpy( buf, p + test_offset, len );
540 test_offset += len;
541 return( 0 );
542}
543
Paul Bakker7dc4c442014-02-01 22:50:26 +0100544#define CHK( c ) if( (c) != 0 ) \
545 { \
546 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100548 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100549 }
550
551/*
552 * Checkup routine for HMAC_DRBG with SHA-1
553 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100555{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100559
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200560 mbedtls_hmac_drbg_init( &ctx );
561
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100562 /*
563 * PR = True
564 */
565 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567
568 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200569 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000570 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
573 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
574 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100575 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100578 mbedtls_hmac_drbg_free( &ctx );
579
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100580 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582
583 /*
584 * PR = False
585 */
586 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100589 mbedtls_hmac_drbg_init( &ctx );
590
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200592 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000593 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
596 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
597 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100601 mbedtls_hmac_drbg_free( &ctx );
602
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605
606 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608
609 return( 0 );
610}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611#endif /* MBEDTLS_SHA1_C */
612#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614#endif /* MBEDTLS_HMAC_DRBG_C */