blob: b45d61616f222cd2b4636f3638d56fb39bdbbde3 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010045 */
46
47/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010048 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010050 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010051 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050062#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010063
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <string.h>
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010067#include <stdio.h>
68#endif
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#if defined(MBEDTLS_SELF_TEST)
71#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000072#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010073#else
Rich Evans00ab4702015-02-06 13:43:58 +000074#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#define mbedtls_printf printf
76#endif /* MBEDTLS_SELF_TEST */
77#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010078
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010079/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020080 * HMAC_DRBG context initialization
81 */
82void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
83{
84 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010085
Gavin Acquroff77cb30c2020-03-01 17:06:11 -080086 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020087}
88
89/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010090 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010091 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
93 const unsigned char *additional,
94 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010097 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
98 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100101
102 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
103 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100104 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200105 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
106 goto exit;
107 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
108 ctx->V, md_len ) ) != 0 )
109 goto exit;
110 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
111 sep, 1 ) ) != 0 )
112 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200114 {
115 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
116 additional, add_len ) ) != 0 )
117 goto exit;
118 }
119 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
120 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100122 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200123 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
124 goto exit;
125 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
126 ctx->V, md_len ) ) != 0 )
127 goto exit;
128 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
129 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200131
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200132exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200133 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200134 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100135}
136
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200137#if !defined(MBEDTLS_DEPRECATED_REMOVED)
138void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
139 const unsigned char *additional,
140 size_t add_len )
141{
142 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
143}
144#endif /* MBEDTLS_DEPRECATED_REMOVED */
145
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100146/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100147 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200149int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100151 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100152{
153 int ret;
154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100156 return( ret );
157
Gilles Peskine05974892021-01-31 00:06:51 +0100158#if defined(MBEDTLS_THREADING_C)
159 mbedtls_mutex_init( &ctx->mutex );
160#endif
161
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100162 /*
163 * Set initial working state.
164 * Use the V memory location, which is currently all 0, to initialize the
165 * MD context with an all-zero key. Then set V to its initial value.
166 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200167 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
168 mbedtls_md_get_size( md_info ) ) ) != 0 )
169 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100171
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200172 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
173 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100174
175 return( 0 );
176}
177
178/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100179 * Internal function used both for seeding and reseeding the DRBG.
180 * Comments starting with arabic numbers refer to section 10.1.2.4
181 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100182 */
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100183static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
184 const unsigned char *additional, size_t len,
185 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100188 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200189 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100191 {
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100192 size_t total_entropy_len;
193
194 if( use_nonce == 0 )
195 total_entropy_len = ctx->entropy_len;
196 else
197 total_entropy_len = ctx->entropy_len * 3 / 2;
198
199 /* III. Check input length */
200 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
201 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
202 {
203 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
204 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100205 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100209 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200210 if( ( ret = ctx->f_entropy( ctx->p_entropy,
211 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100212 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100214 }
215 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100216
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100217 /* For initial seeding, allow adding of nonce generated
218 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
219 if( use_nonce )
220 {
221 /* Note: We don't merge the two calls to f_entropy() in order
222 * to avoid requesting too much entropy from f_entropy()
223 * at once. Specifically, if the underlying digest is not
224 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
225 * is larger than the maximum of 32 Bytes that our own
226 * entropy source implementation can emit in a single
227 * call in configurations disabling SHA-512. */
228 if( ( ret = ctx->f_entropy( ctx->p_entropy,
229 seed + seedlen,
230 ctx->entropy_len / 2 ) ) != 0 )
231 {
232 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
233 }
234
235 seedlen += ctx->entropy_len / 2;
236 }
237
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100238
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100239 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100240 if( additional != NULL && len != 0 )
241 {
242 memcpy( seed + seedlen, additional, len );
243 seedlen += len;
244 }
245
246 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200247 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
248 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100249
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100250 /* 3. Reset reseed_counter */
251 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100252
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200253exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100254 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200255 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200256 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100257}
258
259/*
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100260 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
261 */
262int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
263 const unsigned char *additional, size_t len )
264{
265 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
266}
267
268/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100269 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100270 *
271 * The nonce is not passed as a separate parameter but extracted
272 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100273 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200274int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100276 int (*f_entropy)(void *, unsigned char *, size_t),
277 void *p_entropy,
278 const unsigned char *custom,
279 size_t len )
280{
281 int ret;
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100282 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285 return( ret );
286
Gilles Peskineb5e295d2021-02-09 18:43:33 +0100287 /* The mutex is initialized iff the md context is set up. */
Gilles Peskine05974892021-01-31 00:06:51 +0100288#if defined(MBEDTLS_THREADING_C)
289 mbedtls_mutex_init( &ctx->mutex );
290#endif
291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100293
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100294 /*
295 * Set initial working state.
296 * Use the V memory location, which is currently all 0, to initialize the
297 * MD context with an all-zero key. Then set V to its initial value.
298 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200299 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
300 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100301 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100302
303 ctx->f_entropy = f_entropy;
304 ctx->p_entropy = p_entropy;
305
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200306 if( ctx->entropy_len == 0 )
307 {
308 /*
309 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
310 * each hash function, then according to SP800-90A rev1 10.1 table 2,
311 * min_entropy_len (in bits) is security_strength.
312 *
313 * (This also matches the sizes used in the NIST test vectors.)
314 */
315 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
316 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
317 32; /* better (256+) -> 256 bits */
318 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100319
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100320 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
321 1 /* add nonce */ ) ) != 0 )
322 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100323 return( ret );
Hanno Beckerfb1b7e12019-08-27 06:47:18 +0100324 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100325
326 return( 0 );
327}
328
329/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100330 * Set prediction resistance
331 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100333 int resistance )
334{
335 ctx->prediction_resistance = resistance;
336}
337
338/*
Gilles Peskinec68b70c2019-10-04 11:47:35 +0200339 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100340 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100342{
343 ctx->entropy_len = len;
344}
345
346/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100347 * Set reseed interval
348 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100350{
351 ctx->reseed_interval = interval;
352}
353
354/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100355 * HMAC_DRBG random function with optional additional data:
356 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100357 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100359 unsigned char *output, size_t out_len,
360 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100361{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100362 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
364 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100365 size_t left = out_len;
366 unsigned char *out = output;
367
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100368 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
370 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100371
372 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
374 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100375
376 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100377 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100379 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100380 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100382 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100383
384 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100385 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100386
387 /* 2. Use additional data if any */
388 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200389 {
390 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
391 additional, add_len ) ) != 0 )
392 goto exit;
393 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100394
395 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100396 while( left != 0 )
397 {
398 size_t use_len = left > md_len ? md_len : left;
399
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200400 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
401 goto exit;
402 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
403 ctx->V, md_len ) ) != 0 )
404 goto exit;
405 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
406 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100407
408 memcpy( out, ctx->V, use_len );
409 out += use_len;
410 left -= use_len;
411 }
412
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100413 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200414 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
415 additional, add_len ) ) != 0 )
416 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100417
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100418 /* 7. Update reseed counter */
419 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100420
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200421exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100422 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200423 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100424}
425
426/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100427 * HMAC_DRBG random function
428 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100430{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100431 int ret;
432 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
433
434#if defined(MBEDTLS_THREADING_C)
435 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
436 return( ret );
437#endif
438
439 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
440
441#if defined(MBEDTLS_THREADING_C)
442 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
443 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
444#endif
445
446 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100447}
448
449/*
Gavin Acquroff77cb30c2020-03-01 17:06:11 -0800450 * This function resets HMAC_DRBG context to the state immediately
451 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100452 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100454{
455 if( ctx == NULL )
456 return;
457
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100458#if defined(MBEDTLS_THREADING_C)
Gilles Peskineb5e295d2021-02-09 18:43:33 +0100459 /* The mutex is initialized iff the md context is set up. */
Gilles Peskine05974892021-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 );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500464 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff77cb30c2020-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 Garcia1f6301b2018-04-17 09:51:09 -0500491 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100492
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;
Gilles Peskine82204662018-09-11 18:43:09 +0200499 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200502 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100503
504 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100506
Gilles Peskine82204662018-09-11 18:43:09 +0200507 n = fread( buf, 1, sizeof( buf ), f );
508 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100509 {
Gilles Peskine82204662018-09-11 18:43:09 +0200510 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
511 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100512 }
Gilles Peskine82204662018-09-11 18:43:09 +0200513 if( n == 0 || ferror( f ) )
514 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100515 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200516 goto exit;
517 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100518 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200519 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100520
Gilles Peskine82204662018-09-11 18:43:09 +0200521 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
522
523exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500524 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200525 if( f != NULL )
526 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100527 if( ret != 0 )
528 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100530}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100532
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100535
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100537/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100539{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200540 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100541 return( 0 );
542}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100543#else
544
545#define OUTPUT_LEN 80
546
547/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000548static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100549 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
550 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
551 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
552 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
553 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
554static const unsigned char result_pr[OUTPUT_LEN] = {
555 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
556 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
557 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
558 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
559 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
560 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
561 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
562
563/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000564static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100565 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
566 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
567 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
568 0xe9, 0x9d, 0xfe, 0xdf };
569static const unsigned char result_nopr[OUTPUT_LEN] = {
570 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
571 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
572 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
573 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
574 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
575 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
576 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
577
578/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100579static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100580static int hmac_drbg_self_test_entropy( void *data,
581 unsigned char *buf, size_t len )
582{
583 const unsigned char *p = data;
584 memcpy( buf, p + test_offset, len );
585 test_offset += len;
586 return( 0 );
587}
588
Paul Bakker7dc4c442014-02-01 22:50:26 +0100589#define CHK( c ) if( (c) != 0 ) \
590 { \
591 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100593 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594 }
595
596/*
597 * Checkup routine for HMAC_DRBG with SHA-1
598 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100602 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200605 mbedtls_hmac_drbg_init( &ctx );
606
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607 /*
608 * PR = True
609 */
610 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612
613 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200614 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000615 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
618 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
619 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100622
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100623 mbedtls_hmac_drbg_free( &ctx );
624
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100625 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100627
628 /*
629 * PR = False
630 */
631 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100633
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100634 mbedtls_hmac_drbg_init( &ctx );
635
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100636 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200637 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000638 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100639 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
641 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
642 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100643 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100645
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100646 mbedtls_hmac_drbg_free( &ctx );
647
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100648 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100650
651 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100653
654 return( 0 );
655}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656#endif /* MBEDTLS_SHA1_C */
657#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#endif /* MBEDTLS_HMAC_DRBG_C */