blob: 9fbfc30660672897d28acc56d509be818e06b302 [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
86#if defined(MBEDTLS_THREADING_C)
87 mbedtls_mutex_init( &ctx->mutex );
88#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020089}
90
91/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010092 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010093 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020094int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
95 const unsigned char *additional,
96 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010097{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
100 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200102 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100103
104 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
105 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100106 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200107 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
108 goto exit;
109 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
110 ctx->V, md_len ) ) != 0 )
111 goto exit;
112 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
113 sep, 1 ) ) != 0 )
114 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100115 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200116 {
117 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
118 additional, add_len ) ) != 0 )
119 goto exit;
120 }
121 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
122 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100123
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100124 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200125 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
126 goto exit;
127 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
128 ctx->V, md_len ) ) != 0 )
129 goto exit;
130 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
131 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100132 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200133
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200134exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200135 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200136 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100137}
138
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200139#if !defined(MBEDTLS_DEPRECATED_REMOVED)
140void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
141 const unsigned char *additional,
142 size_t add_len )
143{
144 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
145}
146#endif /* MBEDTLS_DEPRECATED_REMOVED */
147
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148/*
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
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100160 /*
161 * Set initial working state.
162 * Use the V memory location, which is currently all 0, to initialize the
163 * MD context with an all-zero key. Then set V to its initial value.
164 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200165 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
166 mbedtls_md_get_size( md_info ) ) ) != 0 )
167 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100169
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200170 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
171 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100172
173 return( 0 );
174}
175
176/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100177 * Internal function used both for seeding and reseeding the DRBG.
178 * Comments starting with arabic numbers refer to section 10.1.2.4
179 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100180 */
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100181static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
182 const unsigned char *additional, size_t len,
183 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100186 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200187 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100188
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100189 {
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100190 size_t total_entropy_len;
191
192 if( use_nonce == 0 )
193 total_entropy_len = ctx->entropy_len;
194 else
195 total_entropy_len = ctx->entropy_len * 3 / 2;
196
197 /* III. Check input length */
198 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
199 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
200 {
201 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
202 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100203 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100207 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200208 if( ( ret = ctx->f_entropy( ctx->p_entropy,
209 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100210 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100212 }
213 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100215 /* For initial seeding, allow adding of nonce generated
216 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
217 if( use_nonce )
218 {
219 /* Note: We don't merge the two calls to f_entropy() in order
220 * to avoid requesting too much entropy from f_entropy()
221 * at once. Specifically, if the underlying digest is not
222 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
223 * is larger than the maximum of 32 Bytes that our own
224 * entropy source implementation can emit in a single
225 * call in configurations disabling SHA-512. */
226 if( ( ret = ctx->f_entropy( ctx->p_entropy,
227 seed + seedlen,
228 ctx->entropy_len / 2 ) ) != 0 )
229 {
230 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
231 }
232
233 seedlen += ctx->entropy_len / 2;
234 }
235
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100236
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100237 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100238 if( additional != NULL && len != 0 )
239 {
240 memcpy( seed + seedlen, additional, len );
241 seedlen += len;
242 }
243
244 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200245 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
246 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100247
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100248 /* 3. Reset reseed_counter */
249 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100250
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200251exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100252 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200253 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200254 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100255}
256
257/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100258 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
259 */
260int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
261 const unsigned char *additional, size_t len )
262{
263 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
264}
265
266/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100267 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100268 *
269 * The nonce is not passed as a separate parameter but extracted
270 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100271 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200272int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100274 int (*f_entropy)(void *, unsigned char *, size_t),
275 void *p_entropy,
276 const unsigned char *custom,
277 size_t len )
278{
279 int ret;
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100280 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100283 return( ret );
284
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100286
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100287 /*
288 * Set initial working state.
289 * Use the V memory location, which is currently all 0, to initialize the
290 * MD context with an all-zero key. Then set V to its initial value.
291 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200292 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
293 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100294 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100295
296 ctx->f_entropy = f_entropy;
297 ctx->p_entropy = p_entropy;
298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100300
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200301 if( ctx->entropy_len == 0 )
302 {
303 /*
304 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
305 * each hash function, then according to SP800-90A rev1 10.1 table 2,
306 * min_entropy_len (in bits) is security_strength.
307 *
308 * (This also matches the sizes used in the NIST test vectors.)
309 */
310 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
311 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
312 32; /* better (256+) -> 256 bits */
313 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100314
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100315 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
316 1 /* add nonce */ ) ) != 0 )
317 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100318 return( ret );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100319 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100320
321 return( 0 );
322}
323
324/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100325 * Set prediction resistance
326 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100328 int resistance )
329{
330 ctx->prediction_resistance = resistance;
331}
332
333/*
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200334 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100335 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100337{
338 ctx->entropy_len = len;
339}
340
341/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100342 * Set reseed interval
343 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100345{
346 ctx->reseed_interval = interval;
347}
348
349/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100350 * HMAC_DRBG random function with optional additional data:
351 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100354 unsigned char *output, size_t out_len,
355 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100357 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
359 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100360 size_t left = out_len;
361 unsigned char *out = output;
362
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100363 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
365 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100366
367 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
369 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100370
371 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100372 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100374 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100375 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100377 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100378
379 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100380 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100381
382 /* 2. Use additional data if any */
383 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200384 {
385 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
386 additional, add_len ) ) != 0 )
387 goto exit;
388 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100389
390 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100391 while( left != 0 )
392 {
393 size_t use_len = left > md_len ? md_len : left;
394
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200395 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
396 goto exit;
397 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
398 ctx->V, md_len ) ) != 0 )
399 goto exit;
400 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
401 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100402
403 memcpy( out, ctx->V, use_len );
404 out += use_len;
405 left -= use_len;
406 }
407
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100408 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200409 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
410 additional, add_len ) ) != 0 )
411 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100412
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100413 /* 7. Update reseed counter */
414 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100415
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200416exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200418 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419}
420
421/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100422 * HMAC_DRBG random function
423 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100425{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100426 int ret;
427 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
428
429#if defined(MBEDTLS_THREADING_C)
430 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
431 return( ret );
432#endif
433
434 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
435
436#if defined(MBEDTLS_THREADING_C)
437 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
438 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
439#endif
440
441 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100442}
443
444/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100445 * Free an HMAC_DRBG context
446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100448{
449 if( ctx == NULL )
450 return;
451
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100452#if defined(MBEDTLS_THREADING_C)
453 mbedtls_mutex_free( &ctx->mutex );
454#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500456 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100457}
458
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459#if defined(MBEDTLS_FS_IO)
460int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100462 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465
466 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470 goto exit;
471
472 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
473 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100475 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476 }
477
478 ret = 0;
479
480exit:
481 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500482 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100483
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100484 return( ret );
485}
486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100488{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100489 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200490 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100491 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200493 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494
495 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497
Gilles Peskine82204662018-09-11 18:43:09 +0200498 n = fread( buf, 1, sizeof( buf ), f );
499 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500 {
Gilles Peskine82204662018-09-11 18:43:09 +0200501 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
502 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100503 }
Gilles Peskine82204662018-09-11 18:43:09 +0200504 if( n == 0 || ferror( f ) )
505 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100506 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200507 goto exit;
508 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100509 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200510 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100511
Gilles Peskine82204662018-09-11 18:43:09 +0200512 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
513
514exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500515 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200516 if( f != NULL )
517 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100518 if( ret != 0 )
519 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100521}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100523
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100528/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100530{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200531 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100532 return( 0 );
533}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100534#else
535
536#define OUTPUT_LEN 80
537
538/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000539static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100540 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
541 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
542 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
543 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
544 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
545static const unsigned char result_pr[OUTPUT_LEN] = {
546 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
547 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
548 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
549 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
550 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
551 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
552 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
553
554/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000555static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100556 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
557 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
558 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
559 0xe9, 0x9d, 0xfe, 0xdf };
560static const unsigned char result_nopr[OUTPUT_LEN] = {
561 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
562 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
563 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
564 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
565 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
566 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
567 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
568
569/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100570static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571static int hmac_drbg_self_test_entropy( void *data,
572 unsigned char *buf, size_t len )
573{
574 const unsigned char *p = data;
575 memcpy( buf, p + test_offset, len );
576 test_offset += len;
577 return( 0 );
578}
579
Paul Bakker7dc4c442014-02-01 22:50:26 +0100580#define CHK( c ) if( (c) != 0 ) \
581 { \
582 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100584 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585 }
586
587/*
588 * Checkup routine for HMAC_DRBG with SHA-1
589 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200596 mbedtls_hmac_drbg_init( &ctx );
597
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598 /*
599 * PR = True
600 */
601 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603
604 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200605 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000606 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
609 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
610 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100614 mbedtls_hmac_drbg_free( &ctx );
615
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100618
619 /*
620 * PR = False
621 */
622 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100624
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100625 mbedtls_hmac_drbg_init( &ctx );
626
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100627 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200628 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000629 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100630 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
632 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
633 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100634 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100636
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100637 mbedtls_hmac_drbg_free( &ctx );
638
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100639 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100641
642 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644
645 return( 0 );
646}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#endif /* MBEDTLS_SHA1_C */
648#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_HMAC_DRBG_C */