blob: 25a02258350bd75ba1b70f3f808d041ec19eba96 [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úti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 */
19
20/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010021 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010022 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010037#include <stdio.h>
38#endif
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_SELF_TEST */
47#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050 * HMAC_DRBG context initialization
51 */
52void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
53{
54 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010055
Gavin Acquroff6aceb512020-03-01 17:06:11 -080056 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
57
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010058#if defined(MBEDTLS_THREADING_C)
59 mbedtls_mutex_init( &ctx->mutex );
60#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020061}
62
63/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010064 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010065 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020066int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
67 const unsigned char *additional,
68 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010069{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
72 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020074 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075
76 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
77 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010078 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020079 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
80 goto exit;
81 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
82 ctx->V, md_len ) ) != 0 )
83 goto exit;
84 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
85 sep, 1 ) ) != 0 )
86 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010087 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020088 {
89 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
90 additional, add_len ) ) != 0 )
91 goto exit;
92 }
93 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
94 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010096 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
98 goto exit;
99 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
100 ctx->V, md_len ) ) != 0 )
101 goto exit;
102 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
103 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200105
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200106exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200107 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200108 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109}
110
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200111#if !defined(MBEDTLS_DEPRECATED_REMOVED)
112void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
113 const unsigned char *additional,
114 size_t add_len )
115{
116 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
117}
118#endif /* MBEDTLS_DEPRECATED_REMOVED */
119
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100120/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100121 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100122 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200123int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100125 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126{
Janos Follath24eed8d2019-11-22 13:21:35 +0000127 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130 return( ret );
131
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100132 /*
133 * Set initial working state.
134 * Use the V memory location, which is currently all 0, to initialize the
135 * MD context with an all-zero key. Then set V to its initial value.
136 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200137 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
138 mbedtls_md_get_size( md_info ) ) ) != 0 )
139 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100141
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200142 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
143 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100144
145 return( 0 );
146}
147
148/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100149 * Internal function used both for seeding and reseeding the DRBG.
150 * Comments starting with arabic numbers refer to section 10.1.2.4
151 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100152 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
154 const unsigned char *additional, size_t len,
155 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100156{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100158 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000159 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100161 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100162 size_t total_entropy_len;
163
164 if( use_nonce == 0 )
165 total_entropy_len = ctx->entropy_len;
166 else
167 total_entropy_len = ctx->entropy_len * 3 / 2;
168
169 /* III. Check input length */
170 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
171 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
172 {
173 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
174 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100175 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100178
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100179 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200180 if( ( ret = ctx->f_entropy( ctx->p_entropy,
181 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100182 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100184 }
185 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186
Hanno Beckera823d4c2019-08-27 06:47:18 +0100187 /* For initial seeding, allow adding of nonce generated
188 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
189 if( use_nonce )
190 {
191 /* Note: We don't merge the two calls to f_entropy() in order
192 * to avoid requesting too much entropy from f_entropy()
193 * at once. Specifically, if the underlying digest is not
194 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
195 * is larger than the maximum of 32 Bytes that our own
196 * entropy source implementation can emit in a single
197 * call in configurations disabling SHA-512. */
198 if( ( ret = ctx->f_entropy( ctx->p_entropy,
199 seed + seedlen,
200 ctx->entropy_len / 2 ) ) != 0 )
201 {
202 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
203 }
204
205 seedlen += ctx->entropy_len / 2;
206 }
207
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100209 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210 if( additional != NULL && len != 0 )
211 {
212 memcpy( seed + seedlen, additional, len );
213 seedlen += len;
214 }
215
216 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200217 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
218 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100219
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100220 /* 3. Reset reseed_counter */
221 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200223exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100224 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200225 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200226 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100227}
228
229/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100230 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
231 */
232int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
233 const unsigned char *additional, size_t len )
234{
235 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
236}
237
238/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100239 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100240 *
241 * The nonce is not passed as a separate parameter but extracted
242 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100243 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200244int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100246 int (*f_entropy)(void *, unsigned char *, size_t),
247 void *p_entropy,
248 const unsigned char *custom,
249 size_t len )
250{
Janos Follath24eed8d2019-11-22 13:21:35 +0000251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100252 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100255 return( ret );
256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100258
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100259 /*
260 * Set initial working state.
261 * Use the V memory location, which is currently all 0, to initialize the
262 * MD context with an all-zero key. Then set V to its initial value.
263 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200264 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
265 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100266 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100267
268 ctx->f_entropy = f_entropy;
269 ctx->p_entropy = p_entropy;
270
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200271 if( ctx->entropy_len == 0 )
272 {
273 /*
274 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
275 * each hash function, then according to SP800-90A rev1 10.1 table 2,
276 * min_entropy_len (in bits) is security_strength.
277 *
278 * (This also matches the sizes used in the NIST test vectors.)
279 */
280 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
281 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
282 32; /* better (256+) -> 256 bits */
283 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100284
Hanno Beckera823d4c2019-08-27 06:47:18 +0100285 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
286 1 /* add nonce */ ) ) != 0 )
287 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100288 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100289 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100290
291 return( 0 );
292}
293
294/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100295 * Set prediction resistance
296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100298 int resistance )
299{
300 ctx->prediction_resistance = resistance;
301}
302
303/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200304 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100305 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100307{
308 ctx->entropy_len = len;
309}
310
311/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100312 * Set reseed interval
313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100315{
316 ctx->reseed_interval = interval;
317}
318
319/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100320 * HMAC_DRBG random function with optional additional data:
321 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100322 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100324 unsigned char *output, size_t out_len,
325 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100326{
Janos Follath24eed8d2019-11-22 13:21:35 +0000327 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
329 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100330 size_t left = out_len;
331 unsigned char *out = output;
332
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100333 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
335 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100336
337 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
339 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100340
341 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100342 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100344 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100345 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100347 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100348
349 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100350 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100351
352 /* 2. Use additional data if any */
353 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200354 {
355 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
356 additional, add_len ) ) != 0 )
357 goto exit;
358 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100359
360 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100361 while( left != 0 )
362 {
363 size_t use_len = left > md_len ? md_len : left;
364
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200365 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
366 goto exit;
367 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
368 ctx->V, md_len ) ) != 0 )
369 goto exit;
370 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
371 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100372
373 memcpy( out, ctx->V, use_len );
374 out += use_len;
375 left -= use_len;
376 }
377
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100378 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200379 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
380 additional, add_len ) ) != 0 )
381 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100382
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100383 /* 7. Update reseed counter */
384 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200386exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100387 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200388 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100389}
390
391/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392 * HMAC_DRBG random function
393 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395{
Janos Follath24eed8d2019-11-22 13:21:35 +0000396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100397 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
398
399#if defined(MBEDTLS_THREADING_C)
400 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
401 return( ret );
402#endif
403
404 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
405
406#if defined(MBEDTLS_THREADING_C)
407 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
408 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
409#endif
410
411 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100412}
413
414/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800415 * This function resets HMAC_DRBG context to the state immediately
416 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100417 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419{
420 if( ctx == NULL )
421 return;
422
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100423#if defined(MBEDTLS_THREADING_C)
424 mbedtls_mutex_free( &ctx->mutex );
425#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500427 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800428 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
429#if defined(MBEDTLS_THREADING_C)
430 mbedtls_mutex_init( &ctx->mutex );
431#endif
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{
Janos Follath24eed8d2019-11-22 13:21:35 +0000437 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
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;
550 memcpy( buf, p + test_offset, len );
551 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];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 const mbedtls_md_info_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 */