blob: 3c89f5749dadf631dff8ee59e2e188b3480f4d07 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010044/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020045 * HMAC_DRBG context initialization
46 */
47void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
48{
49 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010050
Gavin Acquroff6aceb512020-03-01 17:06:11 -080051 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020052}
53
54/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010055 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010056 */
TRodziewicz26371e42021-06-08 16:45:41 +020057int mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +020058 const unsigned char *additional,
59 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010062 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
63 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020065 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010066
67 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
68 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010069 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020070 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
71 goto exit;
72 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
73 ctx->V, md_len ) ) != 0 )
74 goto exit;
75 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
76 sep, 1 ) ) != 0 )
77 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010078 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020079 {
80 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
81 additional, add_len ) ) != 0 )
82 goto exit;
83 }
84 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
85 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010086
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010087 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020088 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
89 goto exit;
90 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
91 ctx->V, md_len ) ) != 0 )
92 goto exit;
93 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
94 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095 }
Gilles Peskineafa80372018-09-11 15:35:41 +020096
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097exit:
Gilles Peskineafa80372018-09-11 15:35:41 +020098 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +020099 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100100}
101
102/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100103 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200105int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100107 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100108{
Janos Follath24eed8d2019-11-22 13:21:35 +0000109 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100112 return( ret );
113
Gilles Peskineb791dc62021-01-31 00:06:51 +0100114#if defined(MBEDTLS_THREADING_C)
115 mbedtls_mutex_init( &ctx->mutex );
116#endif
117
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100118 /*
119 * Set initial working state.
120 * Use the V memory location, which is currently all 0, to initialize the
121 * MD context with an all-zero key. Then set V to its initial value.
122 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200123 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
124 mbedtls_md_get_size( md_info ) ) ) != 0 )
125 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100127
TRodziewicz26371e42021-06-08 16:45:41 +0200128 if( ( ret = mbedtls_hmac_drbg_update( ctx, data, data_len ) ) != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200129 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130
131 return( 0 );
132}
133
134/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100135 * Internal function used both for seeding and reseeding the DRBG.
136 * Comments starting with arabic numbers refer to section 10.1.2.4
137 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100138 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100139static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
140 const unsigned char *additional, size_t len,
141 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100142{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100144 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000145 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100146
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100147 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100148 size_t total_entropy_len;
149
150 if( use_nonce == 0 )
151 total_entropy_len = ctx->entropy_len;
152 else
153 total_entropy_len = ctx->entropy_len * 3 / 2;
154
155 /* III. Check input length */
156 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
157 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
158 {
159 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
160 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100161 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100164
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100165 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200166 if( ( ret = ctx->f_entropy( ctx->p_entropy,
167 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100168 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100170 }
171 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100172
Hanno Beckera823d4c2019-08-27 06:47:18 +0100173 /* For initial seeding, allow adding of nonce generated
174 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
175 if( use_nonce )
176 {
177 /* Note: We don't merge the two calls to f_entropy() in order
178 * to avoid requesting too much entropy from f_entropy()
179 * at once. Specifically, if the underlying digest is not
180 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
181 * is larger than the maximum of 32 Bytes that our own
182 * entropy source implementation can emit in a single
183 * call in configurations disabling SHA-512. */
184 if( ( ret = ctx->f_entropy( ctx->p_entropy,
185 seed + seedlen,
186 ctx->entropy_len / 2 ) ) != 0 )
187 {
188 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
189 }
190
191 seedlen += ctx->entropy_len / 2;
192 }
193
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100194
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100195 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100196 if( additional != NULL && len != 0 )
197 {
198 memcpy( seed + seedlen, additional, len );
199 seedlen += len;
200 }
201
202 /* 2. Update state */
TRodziewicz26371e42021-06-08 16:45:41 +0200203 if( ( ret = mbedtls_hmac_drbg_update( ctx, seed, seedlen ) ) != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200204 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100205
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100206 /* 3. Reset reseed_counter */
207 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200209exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200211 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200212 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100213}
214
215/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100216 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
217 */
218int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
219 const unsigned char *additional, size_t len )
220{
221 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
222}
223
224/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100225 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100226 *
227 * The nonce is not passed as a separate parameter but extracted
228 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100229 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200230int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100232 int (*f_entropy)(void *, unsigned char *, size_t),
233 void *p_entropy,
234 const unsigned char *custom,
235 size_t len )
236{
Janos Follath24eed8d2019-11-22 13:21:35 +0000237 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100238 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100241 return( ret );
242
Gilles Peskinee39b2192021-02-09 18:43:33 +0100243 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100244#if defined(MBEDTLS_THREADING_C)
245 mbedtls_mutex_init( &ctx->mutex );
246#endif
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100249
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100250 /*
251 * Set initial working state.
252 * Use the V memory location, which is currently all 0, to initialize the
253 * MD context with an all-zero key. Then set V to its initial value.
254 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200255 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
256 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100257 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100258
259 ctx->f_entropy = f_entropy;
260 ctx->p_entropy = p_entropy;
261
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200262 if( ctx->entropy_len == 0 )
263 {
264 /*
265 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
266 * each hash function, then according to SP800-90A rev1 10.1 table 2,
267 * min_entropy_len (in bits) is security_strength.
268 *
269 * (This also matches the sizes used in the NIST test vectors.)
270 */
271 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
272 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
273 32; /* better (256+) -> 256 bits */
274 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100275
Hanno Beckera823d4c2019-08-27 06:47:18 +0100276 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
277 1 /* add nonce */ ) ) != 0 )
278 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100279 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100280 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100281
282 return( 0 );
283}
284
285/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100286 * Set prediction resistance
287 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100289 int resistance )
290{
291 ctx->prediction_resistance = resistance;
292}
293
294/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200295 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100298{
299 ctx->entropy_len = len;
300}
301
302/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100303 * Set reseed interval
304 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100306{
307 ctx->reseed_interval = interval;
308}
309
310/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100311 * HMAC_DRBG random function with optional additional data:
312 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100315 unsigned char *output, size_t out_len,
316 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100317{
Janos Follath24eed8d2019-11-22 13:21:35 +0000318 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
320 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100321 size_t left = out_len;
322 unsigned char *out = output;
323
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
326 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100327
328 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
330 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100331
332 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100333 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100335 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100336 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100338 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100339
340 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100341 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100342
343 /* 2. Use additional data if any */
344 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200345 {
TRodziewicz26371e42021-06-08 16:45:41 +0200346 if( ( ret = mbedtls_hmac_drbg_update( ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200347 additional, add_len ) ) != 0 )
348 goto exit;
349 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100350
351 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100352 while( left != 0 )
353 {
354 size_t use_len = left > md_len ? md_len : left;
355
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200356 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
357 goto exit;
358 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
359 ctx->V, md_len ) ) != 0 )
360 goto exit;
361 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
362 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100363
364 memcpy( out, ctx->V, use_len );
365 out += use_len;
366 left -= use_len;
367 }
368
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100369 /* 6. Update */
TRodziewicz26371e42021-06-08 16:45:41 +0200370 if( ( ret = mbedtls_hmac_drbg_update( ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200371 additional, add_len ) ) != 0 )
372 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100373
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100374 /* 7. Update reseed counter */
375 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100376
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200377exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100378 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200379 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100380}
381
382/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383 * HMAC_DRBG random function
384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100386{
Janos Follath24eed8d2019-11-22 13:21:35 +0000387 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100388 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
389
390#if defined(MBEDTLS_THREADING_C)
391 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
392 return( ret );
393#endif
394
395 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
396
397#if defined(MBEDTLS_THREADING_C)
398 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
399 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
400#endif
401
402 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100403}
404
405/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800406 * This function resets HMAC_DRBG context to the state immediately
407 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100408 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100410{
411 if( ctx == NULL )
412 return;
413
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100414#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100415 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100416 if( ctx->md_ctx.md_info != NULL )
417 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100418#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 ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800421 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422}
423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424#if defined(MBEDTLS_FS_IO)
425int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100426{
Janos Follath24eed8d2019-11-22 13:21:35 +0000427 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100428 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100430
431 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100433
Gilles Peskineda0913b2022-06-30 17:03:40 +0200434 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
435 mbedtls_setbuf( f, NULL );
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438 goto exit;
439
440 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
441 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100443 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444 }
445
446 ret = 0;
447
448exit:
449 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500450 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100451
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452 return( ret );
453}
454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100456{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100457 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200458 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100459 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200461 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100462
463 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465
Gilles Peskineda0913b2022-06-30 17:03:40 +0200466 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
467 mbedtls_setbuf( f, NULL );
468
Gilles Peskine82204662018-09-11 18:43:09 +0200469 n = fread( buf, 1, sizeof( buf ), f );
470 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100471 {
Gilles Peskine82204662018-09-11 18:43:09 +0200472 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
473 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474 }
Gilles Peskine82204662018-09-11 18:43:09 +0200475 if( n == 0 || ferror( f ) )
476 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100477 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200478 goto exit;
479 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100480 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200481 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100482
TRodziewicz26371e42021-06-08 16:45:41 +0200483 ret = mbedtls_hmac_drbg_update( ctx, buf, n );
Gilles Peskine82204662018-09-11 18:43:09 +0200484
485exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500486 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200487 if( f != NULL )
488 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100489 if( ret != 0 )
490 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100499/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100501{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200502 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100503 return( 0 );
504}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100505#else
506
507#define OUTPUT_LEN 80
508
509/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000510static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100511 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
512 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
513 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
514 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
515 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
516static const unsigned char result_pr[OUTPUT_LEN] = {
517 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
518 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
519 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
520 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
521 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
522 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
523 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
524
525/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000526static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100527 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
528 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
529 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
530 0xe9, 0x9d, 0xfe, 0xdf };
531static const unsigned char result_nopr[OUTPUT_LEN] = {
532 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
533 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
534 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
535 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
536 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
537 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
538 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
539
540/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100541static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100542static int hmac_drbg_self_test_entropy( void *data,
543 unsigned char *buf, size_t len )
544{
545 const unsigned char *p = data;
546 memcpy( buf, p + test_offset, len );
547 test_offset += len;
548 return( 0 );
549}
550
Paul Bakker7dc4c442014-02-01 22:50:26 +0100551#define CHK( c ) if( (c) != 0 ) \
552 { \
553 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100555 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100556 }
557
558/*
559 * Checkup routine for HMAC_DRBG with SHA-1
560 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100562{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200567 mbedtls_hmac_drbg_init( &ctx );
568
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569 /*
570 * PR = True
571 */
572 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100574
575 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200576 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000577 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100578 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
580 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
581 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100584
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100585 mbedtls_hmac_drbg_free( &ctx );
586
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100587 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100589
590 /*
591 * PR = False
592 */
593 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100596 mbedtls_hmac_drbg_init( &ctx );
597
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200599 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000600 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
603 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
604 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100608 mbedtls_hmac_drbg_free( &ctx );
609
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612
613 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100615
616 return( 0 );
617}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618#endif /* MBEDTLS_SHA1_C */
619#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621#endif /* MBEDTLS_HMAC_DRBG_C */