blob: c9c541d8387decb29d13c6f0e99b99f68ca55d89 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010020 */
21
22/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010025 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010026 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010042#include <stdio.h>
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_SELF_TEST */
52#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010054/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020055 * HMAC_DRBG context initialization
56 */
57void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
58{
59 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010060
61#if defined(MBEDTLS_THREADING_C)
62 mbedtls_mutex_init( &ctx->mutex );
63#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020064}
65
66/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010067 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010068 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020069int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
70 const unsigned char *additional,
71 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010072{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010074 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
75 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskinee0e9c572018-09-11 16:47:16 +020077 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010078
79 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
80 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010081 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020082 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
83 goto exit;
84 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
85 ctx->V, md_len ) ) != 0 )
86 goto exit;
87 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
88 sep, 1 ) ) != 0 )
89 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010090 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020091 {
92 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
93 additional, add_len ) ) != 0 )
94 goto exit;
95 }
96 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
97 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010098
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010099 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
101 goto exit;
102 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
103 ctx->V, md_len ) ) != 0 )
104 goto exit;
105 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
106 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100107 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200108
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200109exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200110 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200111 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100112}
113
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200114#if !defined(MBEDTLS_DEPRECATED_REMOVED)
115void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
116 const unsigned char *additional,
117 size_t add_len )
118{
119 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
120}
121#endif /* MBEDTLS_DEPRECATED_REMOVED */
122
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100123/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100124 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100125 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200126int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100127 mbedtls_md_handle_t md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100128 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100129{
130 int ret;
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100133 return( ret );
134
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100135 /*
136 * Set initial working state.
137 * Use the V memory location, which is currently all 0, to initialize the
138 * MD context with an all-zero key. Then set V to its initial value.
139 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200140 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
141 mbedtls_md_get_size( md_info ) ) ) != 0 )
142 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100144
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200145 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
146 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100147
148 return( 0 );
149}
150
Hanno Becker31c95e12019-08-27 09:22:09 +0100151/*
152 * Internal function used both for seeding and reseeding the DRBG.
153 * Comments starting with arabic numbers refer to section 10.1.2.4
154 * of SP800-90A, while roman numbers refer to section 9.2.
155 */
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100156static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
157 const unsigned char *additional, size_t len,
158 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100159{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckereab304c2019-08-26 15:29:14 +0100161 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200162 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100163
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100164 {
Hanno Beckereab304c2019-08-26 15:29:14 +0100165 size_t total_entropy_len;
166
167 if( use_nonce == 0 )
168 total_entropy_len = ctx->entropy_len;
169 else
170 total_entropy_len = ctx->entropy_len * 3 / 2;
171
172 /* III. Check input length */
173 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
174 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
175 {
176 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
177 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100178 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100181
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100182 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200183 if( ( ret = ctx->f_entropy( ctx->p_entropy,
184 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100185 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckereab304c2019-08-26 15:29:14 +0100187 }
188 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100189
Hanno Becker31c95e12019-08-27 09:22:09 +0100190 /* For initial seeding, allow adding of nonce generated
191 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Hanno Beckereab304c2019-08-26 15:29:14 +0100192 if( use_nonce )
193 {
194 /* Note: We don't merge the two calls to f_entropy() in order
195 * to avoid requesting too much entropy from f_entropy()
196 * at once. Specifically, if the underlying digest is not
197 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
198 * is larger than the maximum of 32 Bytes that our own
199 * entropy source implementation can emit in a single
200 * call in configurations disabling SHA-512. */
201 if( ( ret = ctx->f_entropy( ctx->p_entropy,
202 seed + seedlen,
203 ctx->entropy_len / 2 ) ) != 0 )
204 {
205 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
206 }
207
208 seedlen += ctx->entropy_len / 2;
209 }
210
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100211
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100212 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100213 if( additional != NULL && len != 0 )
214 {
215 memcpy( seed + seedlen, additional, len );
216 seedlen += len;
217 }
218
219 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200220 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
221 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100223 /* 3. Reset reseed_counter */
224 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100225
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200226exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100227 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200228 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200229 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100230}
231
232/*
Hanno Becker31c95e12019-08-27 09:22:09 +0100233 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
Hanno Beckereab304c2019-08-26 15:29:14 +0100234 */
235int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
236 const unsigned char *additional, size_t len )
237{
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100238 return( hmac_drbg_reseed_core( ctx, additional, len,
239 0 /* no nonce */ ) );
Hanno Beckereab304c2019-08-26 15:29:14 +0100240}
241
242/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100243 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Becker31c95e12019-08-27 09:22:09 +0100244 *
245 * The nonce is not passed as a separate parameter but extracted
246 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100247 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200248int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100249 mbedtls_md_handle_t md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100250 int (*f_entropy)(void *, unsigned char *, size_t),
251 void *p_entropy,
252 const unsigned char *custom,
253 size_t len )
254{
255 int ret;
Hanno Beckereab304c2019-08-26 15:29:14 +0100256 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100257
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100259 return( ret );
260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100262
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100263 /*
264 * Set initial working state.
265 * Use the V memory location, which is currently all 0, to initialize the
266 * MD context with an all-zero key. Then set V to its initial value.
267 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200268 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
269 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100270 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100271
272 ctx->f_entropy = f_entropy;
273 ctx->p_entropy = p_entropy;
274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100276
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100277 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100278 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
279 * each hash function, then according to SP800-90A rev1 10.1 table 2,
280 * min_entropy_len (in bits) is security_strength.
281 *
282 * (This also matches the sizes used in the NIST test vectors.)
283 */
Hanno Beckereab304c2019-08-26 15:29:14 +0100284 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
285 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
286 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100287
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100288 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
289 1 /* add nonce */ ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100290 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100291 return( ret );
Hanno Beckereab304c2019-08-26 15:29:14 +0100292 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100293
294 return( 0 );
295}
296
297/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100298 * Set prediction resistance
299 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100301 int resistance )
302{
303 ctx->prediction_resistance = resistance;
304}
305
306/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100307 * Set entropy length grabbed for reseeds
308 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100310{
311 ctx->entropy_len = len;
312}
313
314/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100315 * Set reseed interval
316 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100318{
319 ctx->reseed_interval = interval;
320}
321
322/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100323 * HMAC_DRBG random function with optional additional data:
324 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100325 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100327 unsigned char *output, size_t out_len,
328 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100329{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100330 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
332 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100333 size_t left = out_len;
334 unsigned char *out = output;
335
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100336 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
338 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100339
340 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
342 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100343
344 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100345 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100347 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100348 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100350 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100351
352 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100353 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100354
355 /* 2. Use additional data if any */
356 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200357 {
358 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
359 additional, add_len ) ) != 0 )
360 goto exit;
361 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100362
363 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100364 while( left != 0 )
365 {
366 size_t use_len = left > md_len ? md_len : left;
367
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200368 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
369 goto exit;
370 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
371 ctx->V, md_len ) ) != 0 )
372 goto exit;
373 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
374 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100375
376 memcpy( out, ctx->V, use_len );
377 out += use_len;
378 left -= use_len;
379 }
380
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100381 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200382 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
383 additional, add_len ) ) != 0 )
384 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100385
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100386 /* 7. Update reseed counter */
387 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100388
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200389exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100390 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200391 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100392}
393
394/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395 * HMAC_DRBG random function
396 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100398{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100399 int ret;
400 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
401
402#if defined(MBEDTLS_THREADING_C)
403 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
404 return( ret );
405#endif
406
407 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
408
409#if defined(MBEDTLS_THREADING_C)
410 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
411 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
412#endif
413
414 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100415}
416
417/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100418 * Free an HMAC_DRBG context
419 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421{
422 if( ctx == NULL )
423 return;
424
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100425#if defined(MBEDTLS_THREADING_C)
426 mbedtls_mutex_free( &ctx->mutex );
427#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 ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100430}
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432#if defined(MBEDTLS_FS_IO)
433int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100434{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100435 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100436 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438
439 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100443 goto exit;
444
445 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
446 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100448 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100449 }
450
451 ret = 0;
452
453exit:
454 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500455 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100456
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100457 return( ret );
458}
459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100462 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200463 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200466 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467
468 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470
Gilles Peskine82204662018-09-11 18:43:09 +0200471 n = fread( buf, 1, sizeof( buf ), f );
472 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473 {
Gilles Peskine82204662018-09-11 18:43:09 +0200474 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
475 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476 }
Gilles Peskine82204662018-09-11 18:43:09 +0200477 if( n == 0 || ferror( f ) )
478 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100479 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200480 goto exit;
481 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100482 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200483 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100484
Gilles Peskine82204662018-09-11 18:43:09 +0200485 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
486
487exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500488 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200489 if( f != NULL )
490 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100491 if( ret != 0 )
492 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100496
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100501/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100503{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200504 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100505 return( 0 );
506}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100507#else
508
509#define OUTPUT_LEN 80
510
511/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000512static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100513 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
514 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
515 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
516 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
517 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
518static const unsigned char result_pr[OUTPUT_LEN] = {
519 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
520 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
521 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
522 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
523 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
524 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
525 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
526
527/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000528static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100529 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
530 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
531 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
532 0xe9, 0x9d, 0xfe, 0xdf };
533static const unsigned char result_nopr[OUTPUT_LEN] = {
534 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
535 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
536 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
537 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
538 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
539 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
540 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
541
542/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100543static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544static int hmac_drbg_self_test_entropy( void *data,
545 unsigned char *buf, size_t len )
546{
547 const unsigned char *p = data;
548 memcpy( buf, p + test_offset, len );
549 test_offset += len;
550 return( 0 );
551}
552
Paul Bakker7dc4c442014-02-01 22:50:26 +0100553#define CHK( c ) if( (c) != 0 ) \
554 { \
555 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100557 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100558 }
559
560/*
561 * Checkup routine for HMAC_DRBG with SHA-1
562 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566 unsigned char buf[OUTPUT_LEN];
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100567 mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200569 mbedtls_hmac_drbg_init( &ctx );
570
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571 /*
572 * PR = True
573 */
574 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576
577 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200578 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000579 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100580 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
582 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
583 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100584 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100587 mbedtls_hmac_drbg_free( &ctx );
588
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100589 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591
592 /*
593 * PR = False
594 */
595 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100598 mbedtls_hmac_drbg_init( &ctx );
599
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200601 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000602 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
605 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
606 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100610 mbedtls_hmac_drbg_free( &ctx );
611
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614
615 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617
618 return( 0 );
619}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#endif /* MBEDTLS_SHA1_C */
621#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100622
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#endif /* MBEDTLS_HMAC_DRBG_C */