blob: 8bd8a05d5e60d491c669f025a4c45649ee99cf59 [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 Peskinea9857af2021-01-31 00:06:51 +0100289#if defined(MBEDTLS_THREADING_C)
290 mbedtls_mutex_init( &ctx->mutex );
291#endif
292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100294
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100295 /*
296 * Set initial working state.
297 * Use the V memory location, which is currently all 0, to initialize the
298 * MD context with an all-zero key. Then set V to its initial value.
299 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200300 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
301 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100302 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100303
304 ctx->f_entropy = f_entropy;
305 ctx->p_entropy = p_entropy;
306
Gilles Peskine9c742242019-10-04 11:47:35 +0200307 if( ctx->entropy_len == 0 )
308 {
309 /*
310 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
311 * each hash function, then according to SP800-90A rev1 10.1 table 2,
312 * min_entropy_len (in bits) is security_strength.
313 *
314 * (This also matches the sizes used in the NIST test vectors.)
315 */
316 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
317 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
318 32; /* better (256+) -> 256 bits */
319 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100320
Hanno Beckerb98e3262019-08-27 06:47:18 +0100321 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
322 1 /* add nonce */ ) ) != 0 )
323 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100324 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100325 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100326
327 return( 0 );
328}
329
330/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100331 * Set prediction resistance
332 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100334 int resistance )
335{
336 ctx->prediction_resistance = resistance;
337}
338
339/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200340 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100341 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100343{
344 ctx->entropy_len = len;
345}
346
347/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100348 * Set reseed interval
349 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100351{
352 ctx->reseed_interval = interval;
353}
354
355/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100356 * HMAC_DRBG random function with optional additional data:
357 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100358 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100360 unsigned char *output, size_t out_len,
361 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100362{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100363 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
365 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100366 size_t left = out_len;
367 unsigned char *out = output;
368
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100369 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
371 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100372
373 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
375 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100376
377 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100378 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100380 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100381 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100383 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100384
385 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100386 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100387
388 /* 2. Use additional data if any */
389 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200390 {
391 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
392 additional, add_len ) ) != 0 )
393 goto exit;
394 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395
396 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100397 while( left != 0 )
398 {
399 size_t use_len = left > md_len ? md_len : left;
400
Gilles Peskineaadc8182018-09-11 16:54:57 +0200401 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
402 goto exit;
403 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
404 ctx->V, md_len ) ) != 0 )
405 goto exit;
406 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
407 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100408
409 memcpy( out, ctx->V, use_len );
410 out += use_len;
411 left -= use_len;
412 }
413
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100414 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200415 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
416 additional, add_len ) ) != 0 )
417 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100418
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100419 /* 7. Update reseed counter */
420 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100421
Gilles Peskine4d237572018-09-13 22:19:57 +0200422exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100423 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200424 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100425}
426
427/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100428 * HMAC_DRBG random function
429 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100431{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100432 int ret;
433 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
434
435#if defined(MBEDTLS_THREADING_C)
436 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
437 return( ret );
438#endif
439
440 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
441
442#if defined(MBEDTLS_THREADING_C)
443 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
444 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
445#endif
446
447 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100448}
449
450/*
Gavin Acquroffceb99902020-03-01 17:06:11 -0800451 * This function resets HMAC_DRBG context to the state immediately
452 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100453 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100455{
456 if( ctx == NULL )
457 return;
458
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100459#if defined(MBEDTLS_THREADING_C)
Gilles Peskinea9857af2021-01-31 00:06:51 +0100460 if( ctx->md_ctx.md_info != NULL )
461 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100462#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroffceb99902020-03-01 17:06:11 -0800465 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100466}
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468#if defined(MBEDTLS_FS_IO)
469int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100471 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474
475 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 goto exit;
480
481 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
482 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100484 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100485 }
486
487 ret = 0;
488
489exit:
490 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100491 mbedtls_zeroize( buf, sizeof( buf ) );
492
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100493 return( ret );
494}
495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100498 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100499 FILE *f;
500 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100502
503 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100505
506 fseek( f, 0, SEEK_END );
507 n = (size_t) ftell( f );
508 fseek( f, 0, SEEK_SET );
509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100511 {
512 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100514 }
515
516 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100517 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
518 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200519 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200520
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100521 fclose( f );
522
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100523 mbedtls_zeroize( buf, sizeof( buf ) );
524
525 if( ret != 0 )
526 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100529}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100531
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100534
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100536/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100538{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200539 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100540 return( 0 );
541}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100542#else
543
544#define OUTPUT_LEN 80
545
546/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000547static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100548 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
549 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
550 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
551 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
552 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
553static const unsigned char result_pr[OUTPUT_LEN] = {
554 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
555 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
556 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
557 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
558 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
559 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
560 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
561
562/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000563static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
565 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
566 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
567 0xe9, 0x9d, 0xfe, 0xdf };
568static const unsigned char result_nopr[OUTPUT_LEN] = {
569 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
570 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
571 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
572 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
573 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
574 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
575 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
576
577/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100578static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579static int hmac_drbg_self_test_entropy( void *data,
580 unsigned char *buf, size_t len )
581{
582 const unsigned char *p = data;
583 memcpy( buf, p + test_offset, len );
584 test_offset += len;
585 return( 0 );
586}
587
Paul Bakker7dc4c442014-02-01 22:50:26 +0100588#define CHK( c ) if( (c) != 0 ) \
589 { \
590 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100592 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593 }
594
595/*
596 * Checkup routine for HMAC_DRBG with SHA-1
597 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200604 mbedtls_hmac_drbg_init( &ctx );
605
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606 /*
607 * PR = True
608 */
609 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611
612 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200613 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000614 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100615 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
617 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
618 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100619 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100621
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100622 mbedtls_hmac_drbg_free( &ctx );
623
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100624 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100626
627 /*
628 * PR = False
629 */
630 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100632
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100633 mbedtls_hmac_drbg_init( &ctx );
634
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100635 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200636 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000637 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100638 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
640 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
641 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100645 mbedtls_hmac_drbg_free( &ctx );
646
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100647 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100649
650 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100652
653 return( 0 );
654}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#endif /* MBEDTLS_SHA1_C */
656#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658#endif /* MBEDTLS_HMAC_DRBG_C */