blob: 330702101edef33db16665895ff52a831990dd9f [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;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020087}
88
89/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010090 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010091 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
93 const unsigned char *additional,
94 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010097 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
98 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100101
102 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
103 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100104 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200105 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
106 goto exit;
107 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
108 ctx->V, md_len ) ) != 0 )
109 goto exit;
110 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
111 sep, 1 ) ) != 0 )
112 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200114 {
115 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
116 additional, add_len ) ) != 0 )
117 goto exit;
118 }
119 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
120 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100122 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200123 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
124 goto exit;
125 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
126 ctx->V, md_len ) ) != 0 )
127 goto exit;
128 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
129 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200131
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200132exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200133 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200134 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100135}
136
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200137#if !defined(MBEDTLS_DEPRECATED_REMOVED)
138void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
139 const unsigned char *additional,
140 size_t add_len )
141{
142 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
143}
144#endif /* MBEDTLS_DEPRECATED_REMOVED */
145
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100146/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100147 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200149int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100151 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100152{
153 int ret;
154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100156 return( ret );
157
Gilles Peskine05974892021-01-31 00:06:51 +0100158#if defined(MBEDTLS_THREADING_C)
159 mbedtls_mutex_init( &ctx->mutex );
160#endif
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
Gilles Peskine05974892021-01-31 00:06:51 +0100287#if defined(MBEDTLS_THREADING_C)
288 mbedtls_mutex_init( &ctx->mutex );
289#endif
290
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100292
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100293 /*
294 * Set initial working state.
295 * Use the V memory location, which is currently all 0, to initialize the
296 * MD context with an all-zero key. Then set V to its initial value.
297 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200298 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
299 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100300 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100301
302 ctx->f_entropy = f_entropy;
303 ctx->p_entropy = p_entropy;
304
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200305 if( ctx->entropy_len == 0 )
306 {
307 /*
308 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
309 * each hash function, then according to SP800-90A rev1 10.1 table 2,
310 * min_entropy_len (in bits) is security_strength.
311 *
312 * (This also matches the sizes used in the NIST test vectors.)
313 */
314 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
315 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
316 32; /* better (256+) -> 256 bits */
317 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100318
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100319 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
320 1 /* add nonce */ ) ) != 0 )
321 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100322 return( ret );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100323 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100324
325 return( 0 );
326}
327
328/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100329 * Set prediction resistance
330 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100332 int resistance )
333{
334 ctx->prediction_resistance = resistance;
335}
336
337/*
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200338 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100339 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100341{
342 ctx->entropy_len = len;
343}
344
345/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100346 * Set reseed interval
347 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100349{
350 ctx->reseed_interval = interval;
351}
352
353/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100354 * HMAC_DRBG random function with optional additional data:
355 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100358 unsigned char *output, size_t out_len,
359 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100360{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100361 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
363 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100364 size_t left = out_len;
365 unsigned char *out = output;
366
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100367 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
369 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100370
371 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
373 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100374
375 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100376 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100378 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100379 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100381 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100382
383 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100384 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385
386 /* 2. Use additional data if any */
387 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200388 {
389 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
390 additional, add_len ) ) != 0 )
391 goto exit;
392 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100393
394 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100395 while( left != 0 )
396 {
397 size_t use_len = left > md_len ? md_len : left;
398
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200399 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
400 goto exit;
401 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
402 ctx->V, md_len ) ) != 0 )
403 goto exit;
404 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
405 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100406
407 memcpy( out, ctx->V, use_len );
408 out += use_len;
409 left -= use_len;
410 }
411
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100412 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200413 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
414 additional, add_len ) ) != 0 )
415 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100416
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100417 /* 7. Update reseed counter */
418 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100419
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200420exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100421 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200422 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423}
424
425/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100426 * HMAC_DRBG random function
427 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100429{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100430 int ret;
431 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
432
433#if defined(MBEDTLS_THREADING_C)
434 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
435 return( ret );
436#endif
437
438 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
439
440#if defined(MBEDTLS_THREADING_C)
441 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
442 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
443#endif
444
445 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100446}
447
448/*
Gavin Acquroff77cb30c2020-03-01 17:06:11 -0800449 * This function resets HMAC_DRBG context to the state immediately
450 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100451 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100453{
454 if( ctx == NULL )
455 return;
456
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100457#if defined(MBEDTLS_THREADING_C)
Gilles Peskine05974892021-01-31 00:06:51 +0100458 if( ctx->md_ctx.md_info != NULL )
459 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100460#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500462 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff77cb30c2020-03-01 17:06:11 -0800463 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466#if defined(MBEDTLS_FS_IO)
467int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100469 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472
473 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100477 goto exit;
478
479 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
480 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100482 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100483 }
484
485 ret = 0;
486
487exit:
488 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500489 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100490
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100491 return( ret );
492}
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100496 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200497 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200500 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100501
502 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100504
Gilles Peskine82204662018-09-11 18:43:09 +0200505 n = fread( buf, 1, sizeof( buf ), f );
506 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100507 {
Gilles Peskine82204662018-09-11 18:43:09 +0200508 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
509 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100510 }
Gilles Peskine82204662018-09-11 18:43:09 +0200511 if( n == 0 || ferror( f ) )
512 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100513 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200514 goto exit;
515 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100516 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200517 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100518
Gilles Peskine82204662018-09-11 18:43:09 +0200519 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
520
521exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500522 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200523 if( f != NULL )
524 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100525 if( ret != 0 )
526 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100528}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100530
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100537{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200538 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100539 return( 0 );
540}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100541#else
542
543#define OUTPUT_LEN 80
544
545/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000546static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100547 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
548 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
549 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
550 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
551 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
552static const unsigned char result_pr[OUTPUT_LEN] = {
553 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
554 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
555 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
556 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
557 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
558 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
559 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
560
561/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000562static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
564 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
565 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
566 0xe9, 0x9d, 0xfe, 0xdf };
567static const unsigned char result_nopr[OUTPUT_LEN] = {
568 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
569 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
570 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
571 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
572 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
573 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
574 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
575
576/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100577static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100578static int hmac_drbg_self_test_entropy( void *data,
579 unsigned char *buf, size_t len )
580{
581 const unsigned char *p = data;
582 memcpy( buf, p + test_offset, len );
583 test_offset += len;
584 return( 0 );
585}
586
Paul Bakker7dc4c442014-02-01 22:50:26 +0100587#define CHK( c ) if( (c) != 0 ) \
588 { \
589 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100591 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592 }
593
594/*
595 * Checkup routine for HMAC_DRBG with SHA-1
596 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100602
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200603 mbedtls_hmac_drbg_init( &ctx );
604
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605 /*
606 * PR = True
607 */
608 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610
611 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200612 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000613 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
616 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
617 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100618 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100621 mbedtls_hmac_drbg_free( &ctx );
622
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100625
626 /*
627 * PR = False
628 */
629 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100631
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100632 mbedtls_hmac_drbg_init( &ctx );
633
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100634 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200635 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000636 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100637 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
639 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
640 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100641 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100643
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100644 mbedtls_hmac_drbg_free( &ctx );
645
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100646 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100648
649 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100651
652 return( 0 );
653}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#endif /* MBEDTLS_SHA1_C */
655#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_HMAC_DRBG_C */