blob: 26b15e95273395918ad60486a6da89294a98d305 [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;
91
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010092#if defined(MBEDTLS_THREADING_C)
93 mbedtls_mutex_init( &ctx->mutex );
94#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020095}
96
97/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010098 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200100int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
101 const unsigned char *additional,
102 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100103{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100105 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
106 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine4d237572018-09-13 22:19:57 +0200108 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109
110 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
111 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100112 /* Step 1 or 4 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200113 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
114 goto exit;
115 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
116 ctx->V, md_len ) ) != 0 )
117 goto exit;
118 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
119 sep, 1 ) ) != 0 )
120 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121 if( rounds == 2 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200122 {
123 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
124 additional, add_len ) ) != 0 )
125 goto exit;
126 }
127 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
128 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100129
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100130 /* Step 2 or 5 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200131 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
132 goto exit;
133 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
134 ctx->V, md_len ) ) != 0 )
135 goto exit;
136 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
137 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100138 }
Gilles Peskine1da77762018-09-11 15:35:41 +0200139
Gilles Peskine4d237572018-09-13 22:19:57 +0200140exit:
Gilles Peskine1da77762018-09-11 15:35:41 +0200141 mbedtls_zeroize( K, sizeof( K ) );
Gilles Peskine4d237572018-09-13 22:19:57 +0200142 return( ret );
143}
144
145void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
146 const unsigned char *additional,
147 size_t add_len )
148{
149 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100150}
151
152/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100153 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100154 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200155int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100157 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100158{
159 int ret;
160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100162 return( ret );
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100290
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100291 /*
292 * Set initial working state.
293 * Use the V memory location, which is currently all 0, to initialize the
294 * MD context with an all-zero key. Then set V to its initial value.
295 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200296 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
297 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100298 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100299
300 ctx->f_entropy = f_entropy;
301 ctx->p_entropy = p_entropy;
302
Gilles Peskine9c742242019-10-04 11:47:35 +0200303 if( ctx->entropy_len == 0 )
304 {
305 /*
306 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
307 * each hash function, then according to SP800-90A rev1 10.1 table 2,
308 * min_entropy_len (in bits) is security_strength.
309 *
310 * (This also matches the sizes used in the NIST test vectors.)
311 */
312 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
313 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
314 32; /* better (256+) -> 256 bits */
315 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100316
Hanno Beckerb98e3262019-08-27 06:47:18 +0100317 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
318 1 /* add nonce */ ) ) != 0 )
319 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100320 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100321 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100322
323 return( 0 );
324}
325
326/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100327 * Set prediction resistance
328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100330 int resistance )
331{
332 ctx->prediction_resistance = resistance;
333}
334
335/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200336 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100339{
340 ctx->entropy_len = len;
341}
342
343/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100344 * Set reseed interval
345 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100347{
348 ctx->reseed_interval = interval;
349}
350
351/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100352 * HMAC_DRBG random function with optional additional data:
353 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100356 unsigned char *output, size_t out_len,
357 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100358{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100359 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
361 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100362 size_t left = out_len;
363 unsigned char *out = output;
364
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100365 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
367 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100368
369 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
371 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100372
373 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100374 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100376 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100377 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100379 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100380
381 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100382 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383
384 /* 2. Use additional data if any */
385 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200386 {
387 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
388 additional, add_len ) ) != 0 )
389 goto exit;
390 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100391
392 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100393 while( left != 0 )
394 {
395 size_t use_len = left > md_len ? md_len : left;
396
Gilles Peskineaadc8182018-09-11 16:54:57 +0200397 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
398 goto exit;
399 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
400 ctx->V, md_len ) ) != 0 )
401 goto exit;
402 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
403 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100404
405 memcpy( out, ctx->V, use_len );
406 out += use_len;
407 left -= use_len;
408 }
409
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100410 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200411 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
412 additional, add_len ) ) != 0 )
413 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100414
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100415 /* 7. Update reseed counter */
416 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417
Gilles Peskine4d237572018-09-13 22:19:57 +0200418exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100419 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200420 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421}
422
423/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100424 * HMAC_DRBG random function
425 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100427{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100428 int ret;
429 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
430
431#if defined(MBEDTLS_THREADING_C)
432 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
433 return( ret );
434#endif
435
436 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
437
438#if defined(MBEDTLS_THREADING_C)
439 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
440 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
441#endif
442
443 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100444}
445
446/*
Gavin Acquroffceb99902020-03-01 17:06:11 -0800447 * This function resets HMAC_DRBG context to the state immediately
448 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100449 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100451{
452 if( ctx == NULL )
453 return;
454
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100455#if defined(MBEDTLS_THREADING_C)
456 mbedtls_mutex_free( &ctx->mutex );
457#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroffceb99902020-03-01 17:06:11 -0800460 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
461#if defined(MBEDTLS_THREADING_C)
462 mbedtls_mutex_init( &ctx->mutex );
463#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466#if defined(MBEDTLS_FS_IO)
467int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100469 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472
473 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100477 goto exit;
478
479 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
480 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100482 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100483 }
484
485 ret = 0;
486
487exit:
488 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100489 mbedtls_zeroize( buf, sizeof( buf ) );
490
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100491 return( ret );
492}
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100496 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497 FILE *f;
498 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500
501 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100503
504 fseek( f, 0, SEEK_END );
505 n = (size_t) ftell( f );
506 fseek( f, 0, SEEK_SET );
507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100509 {
510 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100512 }
513
514 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100515 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
516 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200517 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200518
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100519 fclose( f );
520
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100521 mbedtls_zeroize( buf, sizeof( buf ) );
522
523 if( ret != 0 )
524 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100527}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100529
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100534/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100536{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200537 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100538 return( 0 );
539}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100540#else
541
542#define OUTPUT_LEN 80
543
544/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000545static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100546 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
547 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
548 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
549 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
550 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
551static const unsigned char result_pr[OUTPUT_LEN] = {
552 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
553 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
554 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
555 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
556 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
557 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
558 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
559
560/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000561static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100562 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
563 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
564 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
565 0xe9, 0x9d, 0xfe, 0xdf };
566static const unsigned char result_nopr[OUTPUT_LEN] = {
567 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
568 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
569 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
570 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
571 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
572 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
573 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
574
575/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100576static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577static int hmac_drbg_self_test_entropy( void *data,
578 unsigned char *buf, size_t len )
579{
580 const unsigned char *p = data;
581 memcpy( buf, p + test_offset, len );
582 test_offset += len;
583 return( 0 );
584}
585
Paul Bakker7dc4c442014-02-01 22:50:26 +0100586#define CHK( c ) if( (c) != 0 ) \
587 { \
588 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100590 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591 }
592
593/*
594 * Checkup routine for HMAC_DRBG with SHA-1
595 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200602 mbedtls_hmac_drbg_init( &ctx );
603
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604 /*
605 * PR = True
606 */
607 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609
610 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200611 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000612 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
615 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
616 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100619
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100620 mbedtls_hmac_drbg_free( &ctx );
621
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100622 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100624
625 /*
626 * PR = False
627 */
628 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100630
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100631 mbedtls_hmac_drbg_init( &ctx );
632
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100633 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200634 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000635 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100636 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
638 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
639 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100640 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100643 mbedtls_hmac_drbg_free( &ctx );
644
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100645 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100647
648 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100650
651 return( 0 );
652}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#endif /* MBEDTLS_SHA1_C */
654#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100655
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656#endif /* MBEDTLS_HMAC_DRBG_C */