blob: 876fa574a84bdaca31c17aa1dd5c2c296b63cbd2 [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úti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-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úti4e9f7122020-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"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010066#include <stdio.h>
67#endif
68
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_SELF_TEST)
70#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010072#else
Rich Evans00ab4702015-02-06 13:43:58 +000073#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#define mbedtls_printf printf
75#endif /* MBEDTLS_SELF_TEST */
76#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Paul Bakker34617722014-06-13 17:20:13 +020078/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020080 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
81}
82
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010083/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020084 * HMAC_DRBG context initialization
85 */
86void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
87{
88 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010089
Gavin Acquroffceb99902020-03-01 17:06:11 -080090 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
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 Peskine4d237572018-09-13 22:19:57 +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 Peskine4d237572018-09-13 22:19:57 +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 Peskine4d237572018-09-13 22:19:57 +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 Peskine4d237572018-09-13 22:19:57 +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 Peskine4d237572018-09-13 22:19:57 +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 Peskine1da77762018-09-11 15:35:41 +0200135
Gilles Peskine4d237572018-09-13 22:19:57 +0200136exit:
Gilles Peskine1da77762018-09-11 15:35:41 +0200137 mbedtls_zeroize( K, sizeof( K ) );
Gilles Peskine4d237572018-09-13 22:19:57 +0200138 return( ret );
139}
140
141void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
142 const unsigned char *additional,
143 size_t add_len )
144{
145 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100146}
147
148/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100149 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100150 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200151int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100153 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100154{
155 int ret;
156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100158 return( ret );
159
Gilles Peskinea9857af2021-01-31 00:06:51 +0100160#if defined(MBEDTLS_THREADING_C)
161 mbedtls_mutex_init( &ctx->mutex );
162#endif
163
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100164 /*
165 * Set initial working state.
166 * Use the V memory location, which is currently all 0, to initialize the
167 * MD context with an all-zero key. Then set V to its initial value.
168 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200169 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
170 mbedtls_md_get_size( md_info ) ) ) != 0 )
171 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100173
Gilles Peskine4d237572018-09-13 22:19:57 +0200174 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
175 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100176
177 return( 0 );
178}
179
180/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100181 * Internal function used both for seeding and reseeding the DRBG.
182 * Comments starting with arabic numbers refer to section 10.1.2.4
183 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184 */
Hanno Beckerb98e3262019-08-27 06:47:18 +0100185static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
186 const unsigned char *additional, size_t len,
187 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100188{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerb98e3262019-08-27 06:47:18 +0100190 size_t seedlen = 0;
Gilles Peskine4d237572018-09-13 22:19:57 +0200191 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100192
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100193 {
Hanno Beckerb98e3262019-08-27 06:47:18 +0100194 size_t total_entropy_len;
195
196 if( use_nonce == 0 )
197 total_entropy_len = ctx->entropy_len;
198 else
199 total_entropy_len = ctx->entropy_len * 3 / 2;
200
201 /* III. Check input length */
202 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
203 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
204 {
205 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
206 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100207 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100211 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200212 if( ( ret = ctx->f_entropy( ctx->p_entropy,
213 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerb98e3262019-08-27 06:47:18 +0100214 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100216 }
217 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100218
Hanno Beckerb98e3262019-08-27 06:47:18 +0100219 /* For initial seeding, allow adding of nonce generated
220 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
221 if( use_nonce )
222 {
223 /* Note: We don't merge the two calls to f_entropy() in order
224 * to avoid requesting too much entropy from f_entropy()
225 * at once. Specifically, if the underlying digest is not
226 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
227 * is larger than the maximum of 32 Bytes that our own
228 * entropy source implementation can emit in a single
229 * call in configurations disabling SHA-512. */
230 if( ( ret = ctx->f_entropy( ctx->p_entropy,
231 seed + seedlen,
232 ctx->entropy_len / 2 ) ) != 0 )
233 {
234 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
235 }
236
237 seedlen += ctx->entropy_len / 2;
238 }
239
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100240
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100241 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100242 if( additional != NULL && len != 0 )
243 {
244 memcpy( seed + seedlen, additional, len );
245 seedlen += len;
246 }
247
248 /* 2. Update state */
Gilles Peskine4d237572018-09-13 22:19:57 +0200249 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
250 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100251
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100252 /* 3. Reset reseed_counter */
253 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100254
Gilles Peskine4d237572018-09-13 22:19:57 +0200255exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100256 /* 4. Done */
Gilles Peskine1da77762018-09-11 15:35:41 +0200257 mbedtls_zeroize( seed, seedlen );
Gilles Peskine4d237572018-09-13 22:19:57 +0200258 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100259}
260
261/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100262 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
263 */
264int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
265 const unsigned char *additional, size_t len )
266{
267 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
268}
269
270/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100271 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerb98e3262019-08-27 06:47:18 +0100272 *
273 * The nonce is not passed as a separate parameter but extracted
274 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100275 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200276int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100278 int (*f_entropy)(void *, unsigned char *, size_t),
279 void *p_entropy,
280 const unsigned char *custom,
281 size_t len )
282{
283 int ret;
Hanno Beckerb98e3262019-08-27 06:47:18 +0100284 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100287 return( ret );
288
Gilles Peskine3ec7f572021-02-09 18:43:33 +0100289 /* The mutex is initialized iff the md context is set up. */
Gilles Peskinea9857af2021-01-31 00:06:51 +0100290#if defined(MBEDTLS_THREADING_C)
291 mbedtls_mutex_init( &ctx->mutex );
292#endif
293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100295
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100296 /*
297 * Set initial working state.
298 * Use the V memory location, which is currently all 0, to initialize the
299 * MD context with an all-zero key. Then set V to its initial value.
300 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200301 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
302 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100303 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100304
305 ctx->f_entropy = f_entropy;
306 ctx->p_entropy = p_entropy;
307
Gilles Peskine9c742242019-10-04 11:47:35 +0200308 if( ctx->entropy_len == 0 )
309 {
310 /*
311 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
312 * each hash function, then according to SP800-90A rev1 10.1 table 2,
313 * min_entropy_len (in bits) is security_strength.
314 *
315 * (This also matches the sizes used in the NIST test vectors.)
316 */
317 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
318 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
319 32; /* better (256+) -> 256 bits */
320 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100321
Hanno Beckerb98e3262019-08-27 06:47:18 +0100322 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
323 1 /* add nonce */ ) ) != 0 )
324 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100325 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100326 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100327
328 return( 0 );
329}
330
331/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100332 * Set prediction resistance
333 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100335 int resistance )
336{
337 ctx->prediction_resistance = resistance;
338}
339
340/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200341 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100342 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100344{
345 ctx->entropy_len = len;
346}
347
348/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100349 * Set reseed interval
350 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100352{
353 ctx->reseed_interval = interval;
354}
355
356/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100357 * HMAC_DRBG random function with optional additional data:
358 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100359 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100361 unsigned char *output, size_t out_len,
362 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100363{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100364 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
366 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100367 size_t left = out_len;
368 unsigned char *out = output;
369
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100370 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
372 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100373
374 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
376 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100377
378 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100379 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100381 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100382 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100384 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100385
386 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100387 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100388
389 /* 2. Use additional data if any */
390 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200391 {
392 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
393 additional, add_len ) ) != 0 )
394 goto exit;
395 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100396
397 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100398 while( left != 0 )
399 {
400 size_t use_len = left > md_len ? md_len : left;
401
Gilles Peskineaadc8182018-09-11 16:54:57 +0200402 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
403 goto exit;
404 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
405 ctx->V, md_len ) ) != 0 )
406 goto exit;
407 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
408 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100409
410 memcpy( out, ctx->V, use_len );
411 out += use_len;
412 left -= use_len;
413 }
414
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100415 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200416 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
417 additional, add_len ) ) != 0 )
418 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100420 /* 7. Update reseed counter */
421 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100422
Gilles Peskine4d237572018-09-13 22:19:57 +0200423exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100424 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200425 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100426}
427
428/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100429 * HMAC_DRBG random function
430 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100432{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100433 int ret;
434 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
435
436#if defined(MBEDTLS_THREADING_C)
437 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
438 return( ret );
439#endif
440
441 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
442
443#if defined(MBEDTLS_THREADING_C)
444 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
445 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
446#endif
447
448 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100449}
450
451/*
Gavin Acquroffceb99902020-03-01 17:06:11 -0800452 * This function resets HMAC_DRBG context to the state immediately
453 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100454 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100456{
457 if( ctx == NULL )
458 return;
459
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100460#if defined(MBEDTLS_THREADING_C)
Gilles Peskine3ec7f572021-02-09 18:43:33 +0100461 /* The mutex is initialized iff the md context is set up. */
Gilles Peskinea9857af2021-01-31 00:06:51 +0100462 if( ctx->md_ctx.md_info != NULL )
463 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100464#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroffceb99902020-03-01 17:06:11 -0800467 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100468}
469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470#if defined(MBEDTLS_FS_IO)
471int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100473 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476
477 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100481 goto exit;
482
483 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
484 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100486 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100487 }
488
489 ret = 0;
490
491exit:
492 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100493 mbedtls_zeroize( buf, sizeof( buf ) );
494
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495 return( ret );
496}
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100499{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100500 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100501 FILE *f;
502 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100504
505 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100507
508 fseek( f, 0, SEEK_END );
509 n = (size_t) ftell( f );
510 fseek( f, 0, SEEK_SET );
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100513 {
514 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100516 }
517
518 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100519 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
520 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200521 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200522
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100523 fclose( f );
524
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100525 mbedtls_zeroize( buf, sizeof( buf ) );
526
527 if( ret != 0 )
528 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100531}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100533
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100534
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100538/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100540{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200541 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100542 return( 0 );
543}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544#else
545
546#define OUTPUT_LEN 80
547
548/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000549static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100550 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
551 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
552 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
553 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
554 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
555static const unsigned char result_pr[OUTPUT_LEN] = {
556 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
557 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
558 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
559 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
560 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
561 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
562 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
563
564/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000565static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
567 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
568 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
569 0xe9, 0x9d, 0xfe, 0xdf };
570static const unsigned char result_nopr[OUTPUT_LEN] = {
571 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
572 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
573 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
574 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
575 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
576 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
577 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
578
579/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100580static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100581static int hmac_drbg_self_test_entropy( void *data,
582 unsigned char *buf, size_t len )
583{
584 const unsigned char *p = data;
585 memcpy( buf, p + test_offset, len );
586 test_offset += len;
587 return( 0 );
588}
589
Paul Bakker7dc4c442014-02-01 22:50:26 +0100590#define CHK( c ) if( (c) != 0 ) \
591 { \
592 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100594 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595 }
596
597/*
598 * Checkup routine for HMAC_DRBG with SHA-1
599 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200606 mbedtls_hmac_drbg_init( &ctx );
607
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608 /*
609 * PR = True
610 */
611 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
614 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200615 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000616 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
619 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
620 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100621 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100624 mbedtls_hmac_drbg_free( &ctx );
625
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100626 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100628
629 /*
630 * PR = False
631 */
632 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100634
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100635 mbedtls_hmac_drbg_init( &ctx );
636
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100637 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200638 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000639 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100640 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
642 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
643 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100646
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100647 mbedtls_hmac_drbg_free( &ctx );
648
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100649 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100651
652 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100654
655 return( 0 );
656}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_SHA1_C */
658#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100659
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660#endif /* MBEDTLS_HMAC_DRBG_C */