blob: d0de5de0045b458c7222a995061dfc3a2e436be7 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010020 */
21
22/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010025 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010026 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010042#include <stdio.h>
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_SELF_TEST */
52#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010054/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020055 * HMAC_DRBG context initialization
56 */
57void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
58{
59 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010060
61#if defined(MBEDTLS_THREADING_C)
62 mbedtls_mutex_init( &ctx->mutex );
63#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020064}
65
66/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010067 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010068 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020069int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
70 const unsigned char *additional,
71 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010072{
Hanno Beckerd3827c72019-09-03 12:56:37 +010073 size_t md_len = mbedtls_md_get_size(
74 mbedtls_md_get_handle( &ctx->md_ctx ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
76 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +020078 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010079
80 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
81 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010082 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020083 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
84 goto exit;
85 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
86 ctx->V, md_len ) ) != 0 )
87 goto exit;
88 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
89 sep, 1 ) ) != 0 )
90 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010091 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092 {
93 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
94 additional, add_len ) ) != 0 )
95 goto exit;
96 }
97 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
98 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100100 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200101 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
102 goto exit;
103 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
104 ctx->V, md_len ) ) != 0 )
105 goto exit;
106 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
107 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100108 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200109
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200110exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200111 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200112 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113}
114
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200115#if !defined(MBEDTLS_DEPRECATED_REMOVED)
116void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
117 const unsigned char *additional,
118 size_t add_len )
119{
120 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
121}
122#endif /* MBEDTLS_DEPRECATED_REMOVED */
123
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100124/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100125 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200127int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100128 mbedtls_md_handle_t md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100129 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130{
131 int ret;
132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100134 return( ret );
135
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100136 /*
137 * Set initial working state.
138 * Use the V memory location, which is currently all 0, to initialize the
139 * MD context with an all-zero key. Then set V to its initial value.
140 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200141 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
142 mbedtls_md_get_size( md_info ) ) ) != 0 )
143 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100145
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200146 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
147 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148
149 return( 0 );
150}
151
Hanno Becker31c95e12019-08-27 09:22:09 +0100152/*
153 * Internal function used both for seeding and reseeding the DRBG.
154 * Comments starting with arabic numbers refer to section 10.1.2.4
155 * of SP800-90A, while roman numbers refer to section 9.2.
156 */
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100157static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
158 const unsigned char *additional, size_t len,
159 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckereab304c2019-08-26 15:29:14 +0100162 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200163 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100164
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100165 {
Hanno Beckereab304c2019-08-26 15:29:14 +0100166 size_t total_entropy_len;
167
168 if( use_nonce == 0 )
169 total_entropy_len = ctx->entropy_len;
170 else
171 total_entropy_len = ctx->entropy_len * 3 / 2;
172
173 /* III. Check input length */
174 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
175 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
176 {
177 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
178 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100179 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100182
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100183 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200184 if( ( ret = ctx->f_entropy( ctx->p_entropy,
185 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100186 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckereab304c2019-08-26 15:29:14 +0100188 }
189 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190
Hanno Becker31c95e12019-08-27 09:22:09 +0100191 /* For initial seeding, allow adding of nonce generated
192 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Hanno Beckereab304c2019-08-26 15:29:14 +0100193 if( use_nonce )
194 {
195 /* Note: We don't merge the two calls to f_entropy() in order
196 * to avoid requesting too much entropy from f_entropy()
197 * at once. Specifically, if the underlying digest is not
198 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
199 * is larger than the maximum of 32 Bytes that our own
200 * entropy source implementation can emit in a single
201 * call in configurations disabling SHA-512. */
202 if( ( ret = ctx->f_entropy( ctx->p_entropy,
203 seed + seedlen,
204 ctx->entropy_len / 2 ) ) != 0 )
205 {
206 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
207 }
208
209 seedlen += ctx->entropy_len / 2;
210 }
211
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100212
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100213 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214 if( additional != NULL && len != 0 )
215 {
Teppo Järvelin91d79382019-10-02 09:09:31 +0300216 mbedtls_platform_memcpy( seed + seedlen, additional, len );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217 seedlen += len;
218 }
219
220 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200221 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
222 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100223
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100224 /* 3. Reset reseed_counter */
225 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100226
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200227exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100228 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200229 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200230 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100231}
232
233/*
Hanno Becker31c95e12019-08-27 09:22:09 +0100234 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
Hanno Beckereab304c2019-08-26 15:29:14 +0100235 */
236int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
237 const unsigned char *additional, size_t len )
238{
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100239 return( hmac_drbg_reseed_core( ctx, additional, len,
240 0 /* no nonce */ ) );
Hanno Beckereab304c2019-08-26 15:29:14 +0100241}
242
243/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100244 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Becker31c95e12019-08-27 09:22:09 +0100245 *
246 * The nonce is not passed as a separate parameter but extracted
247 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100248 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200249int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100250 mbedtls_md_handle_t md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100251 int (*f_entropy)(void *, unsigned char *, size_t),
252 void *p_entropy,
253 const unsigned char *custom,
254 size_t len )
255{
256 int ret;
Hanno Beckereab304c2019-08-26 15:29:14 +0100257 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100260 return( ret );
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100263
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100264 /*
265 * Set initial working state.
266 * Use the V memory location, which is currently all 0, to initialize the
267 * MD context with an all-zero key. Then set V to its initial value.
268 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200269 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
270 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100271 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100272
273 ctx->f_entropy = f_entropy;
274 ctx->p_entropy = p_entropy;
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100277
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100278 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100279 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
280 * each hash function, then according to SP800-90A rev1 10.1 table 2,
281 * min_entropy_len (in bits) is security_strength.
282 *
283 * (This also matches the sizes used in the NIST test vectors.)
284 */
Hanno Beckereab304c2019-08-26 15:29:14 +0100285 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
286 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
287 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100288
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100289 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
290 1 /* add nonce */ ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100291 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100292 return( ret );
Hanno Beckereab304c2019-08-26 15:29:14 +0100293 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100294
295 return( 0 );
296}
297
298/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100299 * Set prediction resistance
300 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100302 int resistance )
303{
304 ctx->prediction_resistance = resistance;
305}
306
307/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100308 * Set entropy length grabbed for reseeds
309 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100311{
312 ctx->entropy_len = len;
313}
314
315/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100316 * Set reseed interval
317 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100319{
320 ctx->reseed_interval = interval;
321}
322
323/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324 * HMAC_DRBG random function with optional additional data:
325 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100326 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100328 unsigned char *output, size_t out_len,
329 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100330{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100331 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
Hanno Beckerd3827c72019-09-03 12:56:37 +0100333 size_t md_len = mbedtls_md_get_size(
334 mbedtls_md_get_handle( &ctx->md_ctx ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100335 size_t left = out_len;
336 unsigned char *out = output;
337
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100338 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
340 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100341
342 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
344 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100345
346 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100347 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100349 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100350 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100352 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100353
354 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100355 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100356
357 /* 2. Use additional data if any */
358 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200359 {
360 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
361 additional, add_len ) ) != 0 )
362 goto exit;
363 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100364
365 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100366 while( left != 0 )
367 {
368 size_t use_len = left > md_len ? md_len : left;
369
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200370 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
371 goto exit;
372 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
373 ctx->V, md_len ) ) != 0 )
374 goto exit;
375 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
376 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100377
Teppo Järvelin91d79382019-10-02 09:09:31 +0300378 mbedtls_platform_memcpy( out, ctx->V, use_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100379 out += use_len;
380 left -= use_len;
381 }
382
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200384 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
385 additional, add_len ) ) != 0 )
386 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100387
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100388 /* 7. Update reseed counter */
389 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100390
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200391exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200393 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100394}
395
396/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100397 * HMAC_DRBG random function
398 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100400{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100401 int ret;
402 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
403
404#if defined(MBEDTLS_THREADING_C)
405 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
406 return( ret );
407#endif
408
409 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
410
411#if defined(MBEDTLS_THREADING_C)
412 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
413 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
414#endif
415
416 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417}
418
419/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100420 * Free an HMAC_DRBG context
421 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423{
424 if( ctx == NULL )
425 return;
426
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100427#if defined(MBEDTLS_THREADING_C)
428 mbedtls_mutex_free( &ctx->mutex );
429#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500431 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100432}
433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434#if defined(MBEDTLS_FS_IO)
435int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100436{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100437 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440
441 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100445 goto exit;
446
447 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
448 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100450 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100451 }
452
453 ret = 0;
454
455exit:
456 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500457 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100458
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100459 return( ret );
460}
461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100464 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200465 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100466 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200468 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100469
470 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472
Gilles Peskine82204662018-09-11 18:43:09 +0200473 n = fread( buf, 1, sizeof( buf ), f );
474 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475 {
Gilles Peskine82204662018-09-11 18:43:09 +0200476 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
477 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100478 }
Gilles Peskine82204662018-09-11 18:43:09 +0200479 if( n == 0 || ferror( f ) )
480 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100481 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200482 goto exit;
483 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100484 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200485 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486
Gilles Peskine82204662018-09-11 18:43:09 +0200487 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
488
489exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500490 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200491 if( f != NULL )
492 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100493 if( ret != 0 )
494 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100496}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100503/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100505{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200506 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100507 return( 0 );
508}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100509#else
510
511#define OUTPUT_LEN 80
512
513/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000514static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100515 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
516 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
517 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
518 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
519 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
520static const unsigned char result_pr[OUTPUT_LEN] = {
521 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
522 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
523 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
524 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
525 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
526 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
527 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
528
529/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000530static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100531 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
532 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
533 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
534 0xe9, 0x9d, 0xfe, 0xdf };
535static const unsigned char result_nopr[OUTPUT_LEN] = {
536 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
537 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
538 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
539 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
540 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
541 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
542 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
543
544/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100545static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100546static int hmac_drbg_self_test_entropy( void *data,
547 unsigned char *buf, size_t len )
548{
549 const unsigned char *p = data;
Teppo Järvelinb5c46712019-10-04 13:35:55 +0300550 memcpy( buf, p + test_offset, len );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100551 test_offset += len;
552 return( 0 );
553}
554
Paul Bakker7dc4c442014-02-01 22:50:26 +0100555#define CHK( c ) if( (c) != 0 ) \
556 { \
557 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100559 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100560 }
561
562/*
563 * Checkup routine for HMAC_DRBG with SHA-1
564 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568 unsigned char buf[OUTPUT_LEN];
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100569 mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100570
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200571 mbedtls_hmac_drbg_init( &ctx );
572
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100573 /*
574 * PR = True
575 */
576 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100578
579 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200580 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000581 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
584 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
585 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100589 mbedtls_hmac_drbg_free( &ctx );
590
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593
594 /*
595 * PR = False
596 */
597 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100600 mbedtls_hmac_drbg_init( &ctx );
601
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100602 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200603 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000604 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
607 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
608 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100612 mbedtls_hmac_drbg_free( &ctx );
613
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616
617 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100619
620 return( 0 );
621}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622#endif /* MBEDTLS_SHA1_C */
623#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625#endif /* MBEDTLS_HMAC_DRBG_C */