blob: 9ac96275afd6b4d278737686ff5a9663bd597f9b [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010043
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010044/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020045 * HMAC_DRBG context initialization
46 */
47void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
48{
49 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010050
Gavin Acquroff6aceb512020-03-01 17:06:11 -080051 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020052}
53
54/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010055 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010056 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020057int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
58 const unsigned char *additional,
59 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010062 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
63 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020065 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010066
67 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
68 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010069 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020070 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
71 goto exit;
72 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
73 ctx->V, md_len ) ) != 0 )
74 goto exit;
75 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
76 sep, 1 ) ) != 0 )
77 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010078 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020079 {
80 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
81 additional, add_len ) ) != 0 )
82 goto exit;
83 }
84 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
85 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010086
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010087 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020088 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
89 goto exit;
90 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
91 ctx->V, md_len ) ) != 0 )
92 goto exit;
93 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
94 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095 }
Gilles Peskineafa80372018-09-11 15:35:41 +020096
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097exit:
Gilles Peskineafa80372018-09-11 15:35:41 +020098 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +020099 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100100}
101
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200102#if !defined(MBEDTLS_DEPRECATED_REMOVED)
103void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
104 const unsigned char *additional,
105 size_t add_len )
106{
107 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
108}
109#endif /* MBEDTLS_DEPRECATED_REMOVED */
110
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100111/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100112 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200114int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100116 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100117{
Janos Follath24eed8d2019-11-22 13:21:35 +0000118 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121 return( ret );
122
Gilles Peskineb791dc62021-01-31 00:06:51 +0100123#if defined(MBEDTLS_THREADING_C)
124 mbedtls_mutex_init( &ctx->mutex );
125#endif
126
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100127 /*
128 * Set initial working state.
129 * Use the V memory location, which is currently all 0, to initialize the
130 * MD context with an all-zero key. Then set V to its initial value.
131 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200132 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
133 mbedtls_md_get_size( md_info ) ) ) != 0 )
134 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100136
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200137 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
138 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100139
140 return( 0 );
141}
142
143/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100144 * Internal function used both for seeding and reseeding the DRBG.
145 * Comments starting with arabic numbers refer to section 10.1.2.4
146 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100147 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100148static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
149 const unsigned char *additional, size_t len,
150 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100151{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000154 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100155
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100156 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100157 size_t total_entropy_len;
158
159 if( use_nonce == 0 )
160 total_entropy_len = ctx->entropy_len;
161 else
162 total_entropy_len = ctx->entropy_len * 3 / 2;
163
164 /* III. Check input length */
165 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
166 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
167 {
168 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
169 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100170 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100173
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100174 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200175 if( ( ret = ctx->f_entropy( ctx->p_entropy,
176 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100177 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100179 }
180 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100181
Hanno Beckera823d4c2019-08-27 06:47:18 +0100182 /* For initial seeding, allow adding of nonce generated
183 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
184 if( use_nonce )
185 {
186 /* Note: We don't merge the two calls to f_entropy() in order
187 * to avoid requesting too much entropy from f_entropy()
188 * at once. Specifically, if the underlying digest is not
189 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
190 * is larger than the maximum of 32 Bytes that our own
191 * entropy source implementation can emit in a single
192 * call in configurations disabling SHA-512. */
193 if( ( ret = ctx->f_entropy( ctx->p_entropy,
194 seed + seedlen,
195 ctx->entropy_len / 2 ) ) != 0 )
196 {
197 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
198 }
199
200 seedlen += ctx->entropy_len / 2;
201 }
202
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100203
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100204 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100205 if( additional != NULL && len != 0 )
206 {
207 memcpy( seed + seedlen, additional, len );
208 seedlen += len;
209 }
210
211 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200212 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
213 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100215 /* 3. Reset reseed_counter */
216 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200218exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100219 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200220 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200221 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222}
223
224/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100225 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
226 */
227int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
228 const unsigned char *additional, size_t len )
229{
230 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
231}
232
233/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100234 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100235 *
236 * The nonce is not passed as a separate parameter but extracted
237 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100238 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200239int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200240 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100241 int (*f_entropy)(void *, unsigned char *, size_t),
242 void *p_entropy,
243 const unsigned char *custom,
244 size_t len )
245{
Janos Follath24eed8d2019-11-22 13:21:35 +0000246 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100247 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100250 return( ret );
251
Gilles Peskinee39b2192021-02-09 18:43:33 +0100252 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100253#if defined(MBEDTLS_THREADING_C)
254 mbedtls_mutex_init( &ctx->mutex );
255#endif
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)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100424 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100425 if( ctx->md_ctx.md_info != NULL )
426 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100427#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500429 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800430 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100431}
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433#if defined(MBEDTLS_FS_IO)
434int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435{
Janos Follath24eed8d2019-11-22 13:21:35 +0000436 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100437 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100439
440 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444 goto exit;
445
446 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
447 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100449 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100450 }
451
452 ret = 0;
453
454exit:
455 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500456 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100457
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458 return( ret );
459}
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100462{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100463 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200464 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200467 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468
469 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100471
Gilles Peskine82204662018-09-11 18:43:09 +0200472 n = fread( buf, 1, sizeof( buf ), f );
473 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474 {
Gilles Peskine82204662018-09-11 18:43:09 +0200475 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
476 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100477 }
Gilles Peskine82204662018-09-11 18:43:09 +0200478 if( n == 0 || ferror( f ) )
479 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100480 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200481 goto exit;
482 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100483 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200484 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100485
Gilles Peskine82204662018-09-11 18:43:09 +0200486 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
487
488exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500489 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200490 if( f != NULL )
491 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100492 if( ret != 0 )
493 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100502/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100504{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200505 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100506 return( 0 );
507}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100508#else
509
510#define OUTPUT_LEN 80
511
512/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000513static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100514 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
515 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
516 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
517 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
518 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
519static const unsigned char result_pr[OUTPUT_LEN] = {
520 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
521 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
522 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
523 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
524 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
525 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
526 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
527
528/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000529static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100530 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
531 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
532 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
533 0xe9, 0x9d, 0xfe, 0xdf };
534static const unsigned char result_nopr[OUTPUT_LEN] = {
535 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
536 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
537 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
538 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
539 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
540 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
541 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
542
543/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100544static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100545static int hmac_drbg_self_test_entropy( void *data,
546 unsigned char *buf, size_t len )
547{
548 const unsigned char *p = data;
549 memcpy( buf, p + test_offset, len );
550 test_offset += len;
551 return( 0 );
552}
553
Paul Bakker7dc4c442014-02-01 22:50:26 +0100554#define CHK( c ) if( (c) != 0 ) \
555 { \
556 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100558 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100559 }
560
561/*
562 * Checkup routine for HMAC_DRBG with SHA-1
563 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100565{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200570 mbedtls_hmac_drbg_init( &ctx );
571
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572 /*
573 * PR = True
574 */
575 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577
578 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200579 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000580 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100581 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
583 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
584 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100587
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100588 mbedtls_hmac_drbg_free( &ctx );
589
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100590 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592
593 /*
594 * PR = False
595 */
596 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100599 mbedtls_hmac_drbg_init( &ctx );
600
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200602 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000603 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
606 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
607 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100611 mbedtls_hmac_drbg_free( &ctx );
612
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100615
616 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100618
619 return( 0 );
620}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621#endif /* MBEDTLS_SHA1_C */
622#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100623
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624#endif /* MBEDTLS_HMAC_DRBG_C */