blob: 6bc679dd25735f0e2f9b461bafe4e2179ec0d7c0 [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é-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010041
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010042/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020043 * HMAC_DRBG context initialization
44 */
45void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
46{
47 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010048
Gavin Acquroff6aceb512020-03-01 17:06:11 -080049 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050}
51
52/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010053 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010054 */
TRodziewicz26371e42021-06-08 16:45:41 +020055int mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +020056 const unsigned char *additional,
57 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
61 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020063 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010064
65 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
66 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010067 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020068 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
69 goto exit;
70 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
71 ctx->V, md_len ) ) != 0 )
72 goto exit;
73 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
74 sep, 1 ) ) != 0 )
75 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010076 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020077 {
78 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
79 additional, add_len ) ) != 0 )
80 goto exit;
81 }
82 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
83 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010084
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010085 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020086 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
87 goto exit;
88 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
89 ctx->V, md_len ) ) != 0 )
90 goto exit;
91 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
92 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010093 }
Gilles Peskineafa80372018-09-11 15:35:41 +020094
Gilles Peskinee0e9c572018-09-11 16:47:16 +020095exit:
Gilles Peskineafa80372018-09-11 15:35:41 +020096 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010098}
99
100/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100101 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100102 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200103int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100105 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100106{
Janos Follath24eed8d2019-11-22 13:21:35 +0000107 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100110 return( ret );
111
Gilles Peskineb791dc62021-01-31 00:06:51 +0100112#if defined(MBEDTLS_THREADING_C)
113 mbedtls_mutex_init( &ctx->mutex );
114#endif
115
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100116 /*
117 * Set initial working state.
118 * Use the V memory location, which is currently all 0, to initialize the
119 * MD context with an all-zero key. Then set V to its initial value.
120 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200121 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
122 mbedtls_md_get_size( md_info ) ) ) != 0 )
123 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100125
TRodziewicz26371e42021-06-08 16:45:41 +0200126 if( ( ret = mbedtls_hmac_drbg_update( ctx, data, data_len ) ) != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200127 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100128
129 return( 0 );
130}
131
132/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100133 * Internal function used both for seeding and reseeding the DRBG.
134 * Comments starting with arabic numbers refer to section 10.1.2.4
135 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100136 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100137static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
138 const unsigned char *additional, size_t len,
139 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100140{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100142 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100144
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100145 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100146 size_t total_entropy_len;
147
148 if( use_nonce == 0 )
149 total_entropy_len = ctx->entropy_len;
150 else
151 total_entropy_len = ctx->entropy_len * 3 / 2;
152
153 /* III. Check input length */
154 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
155 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
156 {
157 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
158 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100159 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100162
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100163 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200164 if( ( ret = ctx->f_entropy( ctx->p_entropy,
165 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100166 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100168 }
169 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100170
Hanno Beckera823d4c2019-08-27 06:47:18 +0100171 /* For initial seeding, allow adding of nonce generated
172 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
173 if( use_nonce )
174 {
175 /* Note: We don't merge the two calls to f_entropy() in order
176 * to avoid requesting too much entropy from f_entropy()
177 * at once. Specifically, if the underlying digest is not
178 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
179 * is larger than the maximum of 32 Bytes that our own
180 * entropy source implementation can emit in a single
181 * call in configurations disabling SHA-512. */
182 if( ( ret = ctx->f_entropy( ctx->p_entropy,
183 seed + seedlen,
184 ctx->entropy_len / 2 ) ) != 0 )
185 {
186 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
187 }
188
189 seedlen += ctx->entropy_len / 2;
190 }
191
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100192
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100193 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100194 if( additional != NULL && len != 0 )
195 {
196 memcpy( seed + seedlen, additional, len );
197 seedlen += len;
198 }
199
200 /* 2. Update state */
TRodziewicz26371e42021-06-08 16:45:41 +0200201 if( ( ret = mbedtls_hmac_drbg_update( ctx, seed, seedlen ) ) != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200202 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100203
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100204 /* 3. Reset reseed_counter */
205 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200207exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200209 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200210 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100211}
212
213/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100214 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
215 */
216int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
217 const unsigned char *additional, size_t len )
218{
219 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
220}
221
222/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100223 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100224 *
225 * The nonce is not passed as a separate parameter but extracted
226 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100227 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200228int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100230 int (*f_entropy)(void *, unsigned char *, size_t),
231 void *p_entropy,
232 const unsigned char *custom,
233 size_t len )
234{
Janos Follath24eed8d2019-11-22 13:21:35 +0000235 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100236 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100239 return( ret );
240
Gilles Peskinee39b2192021-02-09 18:43:33 +0100241 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100242#if defined(MBEDTLS_THREADING_C)
243 mbedtls_mutex_init( &ctx->mutex );
244#endif
245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100247
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100248 /*
249 * Set initial working state.
250 * Use the V memory location, which is currently all 0, to initialize the
251 * MD context with an all-zero key. Then set V to its initial value.
252 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200253 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
254 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100255 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100256
257 ctx->f_entropy = f_entropy;
258 ctx->p_entropy = p_entropy;
259
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200260 if( ctx->entropy_len == 0 )
261 {
262 /*
263 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
264 * each hash function, then according to SP800-90A rev1 10.1 table 2,
265 * min_entropy_len (in bits) is security_strength.
266 *
267 * (This also matches the sizes used in the NIST test vectors.)
268 */
269 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
270 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
271 32; /* better (256+) -> 256 bits */
272 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100273
Hanno Beckera823d4c2019-08-27 06:47:18 +0100274 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
275 1 /* add nonce */ ) ) != 0 )
276 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100277 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100278 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100279
280 return( 0 );
281}
282
283/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100284 * Set prediction resistance
285 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100287 int resistance )
288{
289 ctx->prediction_resistance = resistance;
290}
291
292/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200293 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100296{
297 ctx->entropy_len = len;
298}
299
300/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100301 * Set reseed interval
302 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100304{
305 ctx->reseed_interval = interval;
306}
307
308/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100309 * HMAC_DRBG random function with optional additional data:
310 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100311 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100313 unsigned char *output, size_t out_len,
314 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100315{
Janos Follath24eed8d2019-11-22 13:21:35 +0000316 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
318 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100319 size_t left = out_len;
320 unsigned char *out = output;
321
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100322 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
324 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100325
326 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
328 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100329
330 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100331 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100333 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100334 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100336 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100337
338 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100339 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100340
341 /* 2. Use additional data if any */
342 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200343 {
TRodziewicz26371e42021-06-08 16:45:41 +0200344 if( ( ret = mbedtls_hmac_drbg_update( ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200345 additional, add_len ) ) != 0 )
346 goto exit;
347 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100348
349 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100350 while( left != 0 )
351 {
352 size_t use_len = left > md_len ? md_len : left;
353
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200354 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
355 goto exit;
356 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
357 ctx->V, md_len ) ) != 0 )
358 goto exit;
359 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
360 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100361
362 memcpy( out, ctx->V, use_len );
363 out += use_len;
364 left -= use_len;
365 }
366
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100367 /* 6. Update */
TRodziewicz26371e42021-06-08 16:45:41 +0200368 if( ( ret = mbedtls_hmac_drbg_update( ctx,
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200369 additional, add_len ) ) != 0 )
370 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100371
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100372 /* 7. Update reseed counter */
373 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100374
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200375exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100376 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200377 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100378}
379
380/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100381 * HMAC_DRBG random function
382 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100384{
Janos Follath24eed8d2019-11-22 13:21:35 +0000385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100386 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
387
388#if defined(MBEDTLS_THREADING_C)
389 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
390 return( ret );
391#endif
392
393 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
394
395#if defined(MBEDTLS_THREADING_C)
396 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
397 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
398#endif
399
400 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100401}
402
403/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800404 * This function resets HMAC_DRBG context to the state immediately
405 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100406 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100408{
409 if( ctx == NULL )
410 return;
411
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100412#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100413 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100414 if( ctx->md_ctx.md_info != NULL )
415 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100416#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500418 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800419 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100420}
421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422#if defined(MBEDTLS_FS_IO)
423int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100424{
Janos Follath24eed8d2019-11-22 13:21:35 +0000425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100426 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100428
429 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100431
Gilles Peskineda0913b2022-06-30 17:03:40 +0200432 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
433 mbedtls_setbuf( f, NULL );
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100436 goto exit;
437
438 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
439 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100441 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442 }
443
444 ret = 0;
445
446exit:
447 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500448 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100449
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100450 return( ret );
451}
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100454{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100455 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200456 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100457 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200459 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460
461 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463
Gilles Peskineda0913b2022-06-30 17:03:40 +0200464 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
465 mbedtls_setbuf( f, NULL );
466
Gilles Peskine82204662018-09-11 18:43:09 +0200467 n = fread( buf, 1, sizeof( buf ), f );
468 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100469 {
Gilles Peskine82204662018-09-11 18:43:09 +0200470 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
471 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472 }
Gilles Peskine82204662018-09-11 18:43:09 +0200473 if( n == 0 || ferror( f ) )
474 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100475 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200476 goto exit;
477 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100478 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200479 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100480
TRodziewicz26371e42021-06-08 16:45:41 +0200481 ret = mbedtls_hmac_drbg_update( ctx, buf, n );
Gilles Peskine82204662018-09-11 18:43:09 +0200482
483exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500484 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200485 if( f != NULL )
486 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100487 if( ret != 0 )
488 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100490}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100497/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100499{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200500 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100501 return( 0 );
502}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100503#else
504
505#define OUTPUT_LEN 80
506
507/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000508static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100509 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
510 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
511 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
512 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
513 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
514static const unsigned char result_pr[OUTPUT_LEN] = {
515 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
516 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
517 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
518 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
519 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
520 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
521 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
522
523/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000524static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100525 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
526 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
527 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
528 0xe9, 0x9d, 0xfe, 0xdf };
529static const unsigned char result_nopr[OUTPUT_LEN] = {
530 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
531 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
532 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
533 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
534 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
535 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
536 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
537
538/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100539static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100540static int hmac_drbg_self_test_entropy( void *data,
541 unsigned char *buf, size_t len )
542{
543 const unsigned char *p = data;
544 memcpy( buf, p + test_offset, len );
545 test_offset += len;
546 return( 0 );
547}
548
Paul Bakker7dc4c442014-02-01 22:50:26 +0100549#define CHK( c ) if( (c) != 0 ) \
550 { \
551 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100553 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100554 }
555
556/*
557 * Checkup routine for HMAC_DRBG with SHA-1
558 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100560{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100562 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200565 mbedtls_hmac_drbg_init( &ctx );
566
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567 /*
568 * PR = True
569 */
570 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572
573 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200574 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000575 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
578 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
579 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100580 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100583 mbedtls_hmac_drbg_free( &ctx );
584
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100587
588 /*
589 * PR = False
590 */
591 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100594 mbedtls_hmac_drbg_init( &ctx );
595
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200597 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000598 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
601 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
602 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100606 mbedtls_hmac_drbg_free( &ctx );
607
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610
611 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
614 return( 0 );
615}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#endif /* MBEDTLS_SHA1_C */
617#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100618
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619#endif /* MBEDTLS_HMAC_DRBG_C */