blob: 10cbd462ba902d568253549f24d9e3d7f8e9f343 [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útia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010045 */
46
47/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010048 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010050 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010051 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050062#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010063
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <string.h>
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010067#include <stdio.h>
68#endif
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#if defined(MBEDTLS_SELF_TEST)
71#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000072#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010073#else
Rich Evans00ab4702015-02-06 13:43:58 +000074#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#define mbedtls_printf printf
76#endif /* MBEDTLS_SELF_TEST */
77#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010078
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010079/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020080 * HMAC_DRBG context initialization
81 */
82void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
83{
84 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010085
Gavin Acquroff77cb30c2020-03-01 17:06:11 -080086 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
87
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010088#if defined(MBEDTLS_THREADING_C)
89 mbedtls_mutex_init( &ctx->mutex );
90#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020091}
92
93/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010094 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020096int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
97 const unsigned char *additional,
98 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100101 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
102 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200104 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100105
106 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
107 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100108 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200109 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
110 goto exit;
111 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
112 ctx->V, md_len ) ) != 0 )
113 goto exit;
114 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
115 sep, 1 ) ) != 0 )
116 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100117 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200118 {
119 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
120 additional, add_len ) ) != 0 )
121 goto exit;
122 }
123 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
124 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100125
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100126 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200127 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
128 goto exit;
129 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
130 ctx->V, md_len ) ) != 0 )
131 goto exit;
132 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
133 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100134 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200135
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200136exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200137 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200138 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100139}
140
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200141#if !defined(MBEDTLS_DEPRECATED_REMOVED)
142void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
143 const unsigned char *additional,
144 size_t add_len )
145{
146 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
147}
148#endif /* MBEDTLS_DEPRECATED_REMOVED */
149
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100150/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100151 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100152 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200153int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100155 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100156{
157 int ret;
158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100160 return( ret );
161
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100162 /*
163 * Set initial working state.
164 * Use the V memory location, which is currently all 0, to initialize the
165 * MD context with an all-zero key. Then set V to its initial value.
166 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200167 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
168 mbedtls_md_get_size( md_info ) ) ) != 0 )
169 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100171
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200172 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
173 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100174
175 return( 0 );
176}
177
178/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100179 * Internal function used both for seeding and reseeding the DRBG.
180 * Comments starting with arabic numbers refer to section 10.1.2.4
181 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100182 */
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100183static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
184 const unsigned char *additional, size_t len,
185 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100188 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200189 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100191 {
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100192 size_t total_entropy_len;
193
194 if( use_nonce == 0 )
195 total_entropy_len = ctx->entropy_len;
196 else
197 total_entropy_len = ctx->entropy_len * 3 / 2;
198
199 /* III. Check input length */
200 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
201 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
202 {
203 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
204 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100205 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100209 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200210 if( ( ret = ctx->f_entropy( ctx->p_entropy,
211 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100212 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100214 }
215 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100216
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100217 /* For initial seeding, allow adding of nonce generated
218 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
219 if( use_nonce )
220 {
221 /* Note: We don't merge the two calls to f_entropy() in order
222 * to avoid requesting too much entropy from f_entropy()
223 * at once. Specifically, if the underlying digest is not
224 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
225 * is larger than the maximum of 32 Bytes that our own
226 * entropy source implementation can emit in a single
227 * call in configurations disabling SHA-512. */
228 if( ( ret = ctx->f_entropy( ctx->p_entropy,
229 seed + seedlen,
230 ctx->entropy_len / 2 ) ) != 0 )
231 {
232 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
233 }
234
235 seedlen += ctx->entropy_len / 2;
236 }
237
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100238
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100239 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100240 if( additional != NULL && len != 0 )
241 {
242 memcpy( seed + seedlen, additional, len );
243 seedlen += len;
244 }
245
246 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200247 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
248 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100249
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100250 /* 3. Reset reseed_counter */
251 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100252
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200253exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100254 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200255 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200256 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100257}
258
259/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100260 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
261 */
262int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
263 const unsigned char *additional, size_t len )
264{
265 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
266}
267
268/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100269 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100270 *
271 * The nonce is not passed as a separate parameter but extracted
272 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100273 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200274int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100276 int (*f_entropy)(void *, unsigned char *, size_t),
277 void *p_entropy,
278 const unsigned char *custom,
279 size_t len )
280{
281 int ret;
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100282 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285 return( ret );
286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100288
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100289 /*
290 * Set initial working state.
291 * Use the V memory location, which is currently all 0, to initialize the
292 * MD context with an all-zero key. Then set V to its initial value.
293 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200294 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
295 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100296 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100297
298 ctx->f_entropy = f_entropy;
299 ctx->p_entropy = p_entropy;
300
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200301 if( ctx->entropy_len == 0 )
302 {
303 /*
304 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
305 * each hash function, then according to SP800-90A rev1 10.1 table 2,
306 * min_entropy_len (in bits) is security_strength.
307 *
308 * (This also matches the sizes used in the NIST test vectors.)
309 */
310 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
311 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
312 32; /* better (256+) -> 256 bits */
313 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100314
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100315 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
316 1 /* add nonce */ ) ) != 0 )
317 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100318 return( ret );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100319 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100320
321 return( 0 );
322}
323
324/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100325 * Set prediction resistance
326 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100328 int resistance )
329{
330 ctx->prediction_resistance = resistance;
331}
332
333/*
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200334 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100335 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100337{
338 ctx->entropy_len = len;
339}
340
341/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100342 * Set reseed interval
343 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100345{
346 ctx->reseed_interval = interval;
347}
348
349/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100350 * HMAC_DRBG random function with optional additional data:
351 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100354 unsigned char *output, size_t out_len,
355 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100357 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
359 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100360 size_t left = out_len;
361 unsigned char *out = output;
362
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100363 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
365 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100366
367 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
369 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100370
371 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100372 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100374 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100375 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100377 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100378
379 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100380 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100381
382 /* 2. Use additional data if any */
383 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200384 {
385 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
386 additional, add_len ) ) != 0 )
387 goto exit;
388 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100389
390 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100391 while( left != 0 )
392 {
393 size_t use_len = left > md_len ? md_len : left;
394
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200395 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
396 goto exit;
397 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
398 ctx->V, md_len ) ) != 0 )
399 goto exit;
400 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
401 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100402
403 memcpy( out, ctx->V, use_len );
404 out += use_len;
405 left -= use_len;
406 }
407
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100408 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200409 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
410 additional, add_len ) ) != 0 )
411 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100412
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100413 /* 7. Update reseed counter */
414 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100415
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200416exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200418 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419}
420
421/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100422 * HMAC_DRBG random function
423 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100425{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100426 int ret;
427 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
428
429#if defined(MBEDTLS_THREADING_C)
430 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
431 return( ret );
432#endif
433
434 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
435
436#if defined(MBEDTLS_THREADING_C)
437 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
438 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
439#endif
440
441 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100442}
443
444/*
Gavin Acquroff77cb30c2020-03-01 17:06:11 -0800445 * This function resets HMAC_DRBG context to the state immediately
446 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100447 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100449{
450 if( ctx == NULL )
451 return;
452
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100453#if defined(MBEDTLS_THREADING_C)
454 mbedtls_mutex_free( &ctx->mutex );
455#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500457 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff77cb30c2020-03-01 17:06:11 -0800458 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
459#if defined(MBEDTLS_THREADING_C)
460 mbedtls_mutex_init( &ctx->mutex );
461#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100462}
463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464#if defined(MBEDTLS_FS_IO)
465int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100466{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100467 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470
471 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475 goto exit;
476
477 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
478 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100480 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100481 }
482
483 ret = 0;
484
485exit:
486 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500487 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100488
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100489 return( ret );
490}
491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100493{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100494 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200495 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100496 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200498 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100499
500 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100502
Gilles Peskine82204662018-09-11 18:43:09 +0200503 n = fread( buf, 1, sizeof( buf ), f );
504 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100505 {
Gilles Peskine82204662018-09-11 18:43:09 +0200506 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
507 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100508 }
Gilles Peskine82204662018-09-11 18:43:09 +0200509 if( n == 0 || ferror( f ) )
510 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100511 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200512 goto exit;
513 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100514 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200515 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100516
Gilles Peskine82204662018-09-11 18:43:09 +0200517 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
518
519exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500520 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200521 if( f != NULL )
522 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100523 if( ret != 0 )
524 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100526}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100528
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100533/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100535{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200536 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100537 return( 0 );
538}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100539#else
540
541#define OUTPUT_LEN 80
542
543/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000544static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100545 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
546 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
547 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
548 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
549 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
550static const unsigned char result_pr[OUTPUT_LEN] = {
551 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
552 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
553 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
554 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
555 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
556 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
557 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
558
559/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000560static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100561 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
562 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
563 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
564 0xe9, 0x9d, 0xfe, 0xdf };
565static const unsigned char result_nopr[OUTPUT_LEN] = {
566 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
567 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
568 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
569 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
570 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
571 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
572 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
573
574/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100575static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576static int hmac_drbg_self_test_entropy( void *data,
577 unsigned char *buf, size_t len )
578{
579 const unsigned char *p = data;
580 memcpy( buf, p + test_offset, len );
581 test_offset += len;
582 return( 0 );
583}
584
Paul Bakker7dc4c442014-02-01 22:50:26 +0100585#define CHK( c ) if( (c) != 0 ) \
586 { \
587 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100589 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100590 }
591
592/*
593 * Checkup routine for HMAC_DRBG with SHA-1
594 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200601 mbedtls_hmac_drbg_init( &ctx );
602
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 /*
604 * PR = True
605 */
606 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608
609 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200610 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000611 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
614 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
615 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100618
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100619 mbedtls_hmac_drbg_free( &ctx );
620
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100621 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623
624 /*
625 * PR = False
626 */
627 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100629
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100630 mbedtls_hmac_drbg_init( &ctx );
631
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100632 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200633 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000634 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100635 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
637 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
638 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100639 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100641
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100642 mbedtls_hmac_drbg_free( &ctx );
643
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100646
647 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100649
650 return( 0 );
651}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652#endif /* MBEDTLS_SHA1_C */
653#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#endif /* MBEDTLS_HMAC_DRBG_C */