blob: 69272fa73d333b2695d45625a0731c6174837eed [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 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020055int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
56 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
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100#if !defined(MBEDTLS_DEPRECATED_REMOVED)
101void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
102 const unsigned char *additional,
103 size_t add_len )
104{
105 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
106}
107#endif /* MBEDTLS_DEPRECATED_REMOVED */
108
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100110 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100111 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200112int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100114 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100115{
Janos Follath24eed8d2019-11-22 13:21:35 +0000116 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100119 return( ret );
120
Gilles Peskineb791dc62021-01-31 00:06:51 +0100121#if defined(MBEDTLS_THREADING_C)
122 mbedtls_mutex_init( &ctx->mutex );
123#endif
124
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100125 /*
126 * Set initial working state.
127 * Use the V memory location, which is currently all 0, to initialize the
128 * MD context with an all-zero key. Then set V to its initial value.
129 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200130 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
131 mbedtls_md_get_size( md_info ) ) ) != 0 )
132 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100134
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200135 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
136 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100137
138 return( 0 );
139}
140
141/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100142 * Internal function used both for seeding and reseeding the DRBG.
143 * Comments starting with arabic numbers refer to section 10.1.2.4
144 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100145 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100146static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
147 const unsigned char *additional, size_t len,
148 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100149{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100151 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000152 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100153
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100154 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100155 size_t total_entropy_len;
156
157 if( use_nonce == 0 )
158 total_entropy_len = ctx->entropy_len;
159 else
160 total_entropy_len = ctx->entropy_len * 3 / 2;
161
162 /* III. Check input length */
163 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
164 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
165 {
166 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
167 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100168 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100171
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100172 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200173 if( ( ret = ctx->f_entropy( ctx->p_entropy,
174 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100175 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100177 }
178 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100179
Hanno Beckera823d4c2019-08-27 06:47:18 +0100180 /* For initial seeding, allow adding of nonce generated
181 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
182 if( use_nonce )
183 {
184 /* Note: We don't merge the two calls to f_entropy() in order
185 * to avoid requesting too much entropy from f_entropy()
186 * at once. Specifically, if the underlying digest is not
187 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
188 * is larger than the maximum of 32 Bytes that our own
189 * entropy source implementation can emit in a single
190 * call in configurations disabling SHA-512. */
191 if( ( ret = ctx->f_entropy( ctx->p_entropy,
192 seed + seedlen,
193 ctx->entropy_len / 2 ) ) != 0 )
194 {
195 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
196 }
197
198 seedlen += ctx->entropy_len / 2;
199 }
200
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100201
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100202 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100203 if( additional != NULL && len != 0 )
204 {
205 memcpy( seed + seedlen, additional, len );
206 seedlen += len;
207 }
208
209 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200210 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
211 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100212
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100213 /* 3. Reset reseed_counter */
214 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100215
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200216exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200218 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200219 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100220}
221
222/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100223 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
224 */
225int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
226 const unsigned char *additional, size_t len )
227{
228 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
229}
230
231/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100232 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100233 *
234 * The nonce is not passed as a separate parameter but extracted
235 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100236 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200237int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100239 int (*f_entropy)(void *, unsigned char *, size_t),
240 void *p_entropy,
241 const unsigned char *custom,
242 size_t len )
243{
Janos Follath24eed8d2019-11-22 13:21:35 +0000244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100245 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100248 return( ret );
249
Gilles Peskinee39b2192021-02-09 18:43:33 +0100250 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100251#if defined(MBEDTLS_THREADING_C)
252 mbedtls_mutex_init( &ctx->mutex );
253#endif
254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100256
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100257 /*
258 * Set initial working state.
259 * Use the V memory location, which is currently all 0, to initialize the
260 * MD context with an all-zero key. Then set V to its initial value.
261 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200262 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
263 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100264 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100265
266 ctx->f_entropy = f_entropy;
267 ctx->p_entropy = p_entropy;
268
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200269 if( ctx->entropy_len == 0 )
270 {
271 /*
272 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
273 * each hash function, then according to SP800-90A rev1 10.1 table 2,
274 * min_entropy_len (in bits) is security_strength.
275 *
276 * (This also matches the sizes used in the NIST test vectors.)
277 */
278 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
279 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
280 32; /* better (256+) -> 256 bits */
281 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100282
Hanno Beckera823d4c2019-08-27 06:47:18 +0100283 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
284 1 /* add nonce */ ) ) != 0 )
285 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100286 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100287 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100288
289 return( 0 );
290}
291
292/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100293 * Set prediction resistance
294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100296 int resistance )
297{
298 ctx->prediction_resistance = resistance;
299}
300
301/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200302 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100305{
306 ctx->entropy_len = len;
307}
308
309/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100310 * Set reseed interval
311 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100313{
314 ctx->reseed_interval = interval;
315}
316
317/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100318 * HMAC_DRBG random function with optional additional data:
319 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100320 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100322 unsigned char *output, size_t out_len,
323 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100324{
Janos Follath24eed8d2019-11-22 13:21:35 +0000325 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
327 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100328 size_t left = out_len;
329 unsigned char *out = output;
330
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100331 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
333 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100334
335 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
337 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100338
339 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100340 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100342 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100343 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100345 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100346
347 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100348 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100349
350 /* 2. Use additional data if any */
351 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200352 {
353 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
354 additional, add_len ) ) != 0 )
355 goto exit;
356 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100357
358 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100359 while( left != 0 )
360 {
361 size_t use_len = left > md_len ? md_len : left;
362
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200363 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
364 goto exit;
365 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
366 ctx->V, md_len ) ) != 0 )
367 goto exit;
368 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
369 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100370
371 memcpy( out, ctx->V, use_len );
372 out += use_len;
373 left -= use_len;
374 }
375
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100376 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200377 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
378 additional, add_len ) ) != 0 )
379 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100380
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100381 /* 7. Update reseed counter */
382 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200384exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200386 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100387}
388
389/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100390 * HMAC_DRBG random function
391 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100393{
Janos Follath24eed8d2019-11-22 13:21:35 +0000394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100395 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
396
397#if defined(MBEDTLS_THREADING_C)
398 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
399 return( ret );
400#endif
401
402 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
403
404#if defined(MBEDTLS_THREADING_C)
405 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
406 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
407#endif
408
409 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100410}
411
412/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800413 * This function resets HMAC_DRBG context to the state immediately
414 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100415 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100417{
418 if( ctx == NULL )
419 return;
420
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100421#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100422 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100423 if( ctx->md_ctx.md_info != NULL )
424 mbedtls_mutex_free( &ctx->mutex );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100425#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500427 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800428 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100429}
430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431#if defined(MBEDTLS_FS_IO)
432int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100433{
Janos Follath24eed8d2019-11-22 13:21:35 +0000434 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100437
438 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442 goto exit;
443
444 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
445 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100447 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100448 }
449
450 ret = 0;
451
452exit:
453 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500454 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100455
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100456 return( ret );
457}
458
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100461 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200462 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200465 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100466
467 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100469
Gilles Peskine82204662018-09-11 18:43:09 +0200470 n = fread( buf, 1, sizeof( buf ), f );
471 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472 {
Gilles Peskine82204662018-09-11 18:43:09 +0200473 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
474 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475 }
Gilles Peskine82204662018-09-11 18:43:09 +0200476 if( n == 0 || ferror( f ) )
477 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100478 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200479 goto exit;
480 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100481 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200482 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100483
Gilles Peskine82204662018-09-11 18:43:09 +0200484 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
485
486exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500487 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200488 if( f != NULL )
489 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100490 if( ret != 0 )
491 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100493}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100500/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100502{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200503 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100504 return( 0 );
505}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100506#else
507
508#define OUTPUT_LEN 80
509
510/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000511static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100512 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
513 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
514 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
515 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
516 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
517static const unsigned char result_pr[OUTPUT_LEN] = {
518 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
519 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
520 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
521 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
522 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
523 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
524 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
525
526/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000527static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100528 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
529 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
530 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
531 0xe9, 0x9d, 0xfe, 0xdf };
532static const unsigned char result_nopr[OUTPUT_LEN] = {
533 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
534 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
535 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
536 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
537 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
538 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
539 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
540
541/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100542static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100543static int hmac_drbg_self_test_entropy( void *data,
544 unsigned char *buf, size_t len )
545{
546 const unsigned char *p = data;
547 memcpy( buf, p + test_offset, len );
548 test_offset += len;
549 return( 0 );
550}
551
Paul Bakker7dc4c442014-02-01 22:50:26 +0100552#define CHK( c ) if( (c) != 0 ) \
553 { \
554 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100556 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557 }
558
559/*
560 * Checkup routine for HMAC_DRBG with SHA-1
561 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100565 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200568 mbedtls_hmac_drbg_init( &ctx );
569
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100570 /*
571 * PR = True
572 */
573 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100575
576 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200577 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000578 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
581 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
582 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100583 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100586 mbedtls_hmac_drbg_free( &ctx );
587
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100590
591 /*
592 * PR = False
593 */
594 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100597 mbedtls_hmac_drbg_init( &ctx );
598
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200600 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000601 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100602 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
604 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
605 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100609 mbedtls_hmac_drbg_free( &ctx );
610
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
614 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616
617 return( 0 );
618}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619#endif /* MBEDTLS_SHA1_C */
620#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622#endif /* MBEDTLS_HMAC_DRBG_C */