blob: de9706885cab908606dbd0702ea075bba5bbf7a1 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 */
19
20/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010021 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010022 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010037#include <stdio.h>
38#endif
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_SELF_TEST */
47#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050 * HMAC_DRBG context initialization
51 */
52void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
53{
54 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010055
Gavin Acquroff6aceb512020-03-01 17:06:11 -080056 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020057}
58
59/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010060 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010061 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020062int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
63 const unsigned char *additional,
64 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010065{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010067 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
68 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020070 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071
72 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
73 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010074 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020075 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
76 goto exit;
77 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
78 ctx->V, md_len ) ) != 0 )
79 goto exit;
80 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
81 sep, 1 ) ) != 0 )
82 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010083 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020084 {
85 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
86 additional, add_len ) ) != 0 )
87 goto exit;
88 }
89 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
90 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010091
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010092 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020093 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
94 goto exit;
95 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
96 ctx->V, md_len ) ) != 0 )
97 goto exit;
98 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
99 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100100 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200101
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200102exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200103 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200104 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100105}
106
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200107#if !defined(MBEDTLS_DEPRECATED_REMOVED)
108void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
109 const unsigned char *additional,
110 size_t add_len )
111{
112 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
113}
114#endif /* MBEDTLS_DEPRECATED_REMOVED */
115
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100116/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100117 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100118 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200119int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100121 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100122{
Janos Follath24eed8d2019-11-22 13:21:35 +0000123 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126 return( ret );
127
Gilles Peskineb791dc62021-01-31 00:06:51 +0100128#if defined(MBEDTLS_THREADING_C)
129 mbedtls_mutex_init( &ctx->mutex );
130#endif
131
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100132 /*
133 * Set initial working state.
134 * Use the V memory location, which is currently all 0, to initialize the
135 * MD context with an all-zero key. Then set V to its initial value.
136 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200137 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
138 mbedtls_md_get_size( md_info ) ) ) != 0 )
139 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100141
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200142 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
143 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100144
145 return( 0 );
146}
147
148/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100149 * Internal function used both for seeding and reseeding the DRBG.
150 * Comments starting with arabic numbers refer to section 10.1.2.4
151 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100152 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
154 const unsigned char *additional, size_t len,
155 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100156{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100158 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000159 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100161 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100162 size_t total_entropy_len;
163
164 if( use_nonce == 0 )
165 total_entropy_len = ctx->entropy_len;
166 else
167 total_entropy_len = ctx->entropy_len * 3 / 2;
168
169 /* III. Check input length */
170 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
171 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
172 {
173 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
174 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100175 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100178
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100179 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200180 if( ( ret = ctx->f_entropy( ctx->p_entropy,
181 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100182 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100184 }
185 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186
Hanno Beckera823d4c2019-08-27 06:47:18 +0100187 /* For initial seeding, allow adding of nonce generated
188 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
189 if( use_nonce )
190 {
191 /* Note: We don't merge the two calls to f_entropy() in order
192 * to avoid requesting too much entropy from f_entropy()
193 * at once. Specifically, if the underlying digest is not
194 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
195 * is larger than the maximum of 32 Bytes that our own
196 * entropy source implementation can emit in a single
197 * call in configurations disabling SHA-512. */
198 if( ( ret = ctx->f_entropy( ctx->p_entropy,
199 seed + seedlen,
200 ctx->entropy_len / 2 ) ) != 0 )
201 {
202 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
203 }
204
205 seedlen += ctx->entropy_len / 2;
206 }
207
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100209 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210 if( additional != NULL && len != 0 )
211 {
212 memcpy( seed + seedlen, additional, len );
213 seedlen += len;
214 }
215
216 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200217 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
218 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100219
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100220 /* 3. Reset reseed_counter */
221 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200223exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100224 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200225 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200226 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100227}
228
229/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100230 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
231 */
232int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
233 const unsigned char *additional, size_t len )
234{
235 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
236}
237
238/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100239 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100240 *
241 * The nonce is not passed as a separate parameter but extracted
242 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100243 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200244int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100246 int (*f_entropy)(void *, unsigned char *, size_t),
247 void *p_entropy,
248 const unsigned char *custom,
249 size_t len )
250{
Janos Follath24eed8d2019-11-22 13:21:35 +0000251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100252 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100255 return( ret );
256
Gilles Peskinee39b2192021-02-09 18:43:33 +0100257 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100258#if defined(MBEDTLS_THREADING_C)
259 mbedtls_mutex_init( &ctx->mutex );
260#endif
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100263
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100264 /*
265 * Set initial working state.
266 * Use the V memory location, which is currently all 0, to initialize the
267 * MD context with an all-zero key. Then set V to its initial value.
268 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200269 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
270 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100271 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100272
273 ctx->f_entropy = f_entropy;
274 ctx->p_entropy = p_entropy;
275
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200276 if( ctx->entropy_len == 0 )
277 {
278 /*
279 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
280 * each hash function, then according to SP800-90A rev1 10.1 table 2,
281 * min_entropy_len (in bits) is security_strength.
282 *
283 * (This also matches the sizes used in the NIST test vectors.)
284 */
285 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
286 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
287 32; /* better (256+) -> 256 bits */
288 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100289
Hanno Beckera823d4c2019-08-27 06:47:18 +0100290 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
291 1 /* add nonce */ ) ) != 0 )
292 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100293 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100294 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100295
296 return( 0 );
297}
298
299/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100300 * Set prediction resistance
301 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100303 int resistance )
304{
305 ctx->prediction_resistance = resistance;
306}
307
308/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200309 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100312{
313 ctx->entropy_len = len;
314}
315
316/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100317 * Set reseed interval
318 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100320{
321 ctx->reseed_interval = interval;
322}
323
324/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100325 * HMAC_DRBG random function with optional additional data:
326 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100327 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100329 unsigned char *output, size_t out_len,
330 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100331{
Janos Follath24eed8d2019-11-22 13:21:35 +0000332 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
334 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100335 size_t left = out_len;
336 unsigned char *out = output;
337
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100338 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
340 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100341
342 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
344 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100345
346 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100347 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100349 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100350 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100352 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100353
354 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100355 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100356
357 /* 2. Use additional data if any */
358 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200359 {
360 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
361 additional, add_len ) ) != 0 )
362 goto exit;
363 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100364
365 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100366 while( left != 0 )
367 {
368 size_t use_len = left > md_len ? md_len : left;
369
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200370 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
371 goto exit;
372 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
373 ctx->V, md_len ) ) != 0 )
374 goto exit;
375 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
376 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100377
378 memcpy( out, ctx->V, use_len );
379 out += use_len;
380 left -= use_len;
381 }
382
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200384 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
385 additional, add_len ) ) != 0 )
386 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100387
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100388 /* 7. Update reseed counter */
389 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100390
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200391exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200393 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100394}
395
396/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100397 * HMAC_DRBG random function
398 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100400{
Janos Follath24eed8d2019-11-22 13:21:35 +0000401 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100402 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
403
404#if defined(MBEDTLS_THREADING_C)
405 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
406 return( ret );
407#endif
408
409 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
410
411#if defined(MBEDTLS_THREADING_C)
412 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
413 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
414#endif
415
416 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417}
418
419/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800420 * This function resets HMAC_DRBG context to the state immediately
421 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100424{
425 if( ctx == NULL )
426 return;
427
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100428#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100429 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100430 if( ctx->md_ctx.md_info != NULL )
431 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100432#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500434 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800435 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100436}
437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#if defined(MBEDTLS_FS_IO)
439int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440{
Janos Follath24eed8d2019-11-22 13:21:35 +0000441 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444
445 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100449 goto exit;
450
451 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
452 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100454 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100455 }
456
457 ret = 0;
458
459exit:
460 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500461 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100462
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463 return( ret );
464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100468 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200469 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200472 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473
474 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476
Gilles Peskine82204662018-09-11 18:43:09 +0200477 n = fread( buf, 1, sizeof( buf ), f );
478 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 {
Gilles Peskine82204662018-09-11 18:43:09 +0200480 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
481 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100482 }
Gilles Peskine82204662018-09-11 18:43:09 +0200483 if( n == 0 || ferror( f ) )
484 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100485 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200486 goto exit;
487 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100488 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200489 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100490
Gilles Peskine82204662018-09-11 18:43:09 +0200491 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
492
493exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500494 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200495 if( f != NULL )
496 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100497 if( ret != 0 )
498 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100502
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100507/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100509{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200510 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100511 return( 0 );
512}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100513#else
514
515#define OUTPUT_LEN 80
516
517/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000518static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100519 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
520 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
521 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
522 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
523 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
524static const unsigned char result_pr[OUTPUT_LEN] = {
525 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
526 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
527 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
528 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
529 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
530 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
531 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
532
533/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000534static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
536 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
537 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
538 0xe9, 0x9d, 0xfe, 0xdf };
539static const unsigned char result_nopr[OUTPUT_LEN] = {
540 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
541 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
542 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
543 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
544 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
545 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
546 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
547
548/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100549static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100550static int hmac_drbg_self_test_entropy( void *data,
551 unsigned char *buf, size_t len )
552{
553 const unsigned char *p = data;
554 memcpy( buf, p + test_offset, len );
555 test_offset += len;
556 return( 0 );
557}
558
Paul Bakker7dc4c442014-02-01 22:50:26 +0100559#define CHK( c ) if( (c) != 0 ) \
560 { \
561 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100563 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564 }
565
566/*
567 * Checkup routine for HMAC_DRBG with SHA-1
568 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100570{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100574
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200575 mbedtls_hmac_drbg_init( &ctx );
576
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577 /*
578 * PR = True
579 */
580 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582
583 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200584 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000585 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
588 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
589 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100590 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100593 mbedtls_hmac_drbg_free( &ctx );
594
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597
598 /*
599 * PR = False
600 */
601 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100604 mbedtls_hmac_drbg_init( &ctx );
605
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200607 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000608 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
611 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
612 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100615
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100616 mbedtls_hmac_drbg_free( &ctx );
617
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100618 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
621 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623
624 return( 0 );
625}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626#endif /* MBEDTLS_SHA1_C */
627#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629#endif /* MBEDTLS_HMAC_DRBG_C */