blob: f24a66c852f9d6d91f220dc2d9ceb482ee0a4b55 [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úti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010045 */
46
47/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010048 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010050 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010051 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/hmac_drbg.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010066#include <stdio.h>
67#endif
68
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_SELF_TEST)
70#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010072#else
Rich Evans00ab4702015-02-06 13:43:58 +000073#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#define mbedtls_printf printf
75#endif /* MBEDTLS_SELF_TEST */
76#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Paul Bakker34617722014-06-13 17:20:13 +020078/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020080 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
81}
82
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010083/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020084 * HMAC_DRBG context initialization
85 */
86void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
87{
88 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010089
90#if defined(MBEDTLS_THREADING_C)
91 mbedtls_mutex_init( &ctx->mutex );
92#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020093}
94
95/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010096 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010097 */
Gilles Peskine4d237572018-09-13 22:19:57 +020098int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
99 const unsigned char *additional,
100 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100101{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100103 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
104 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine4d237572018-09-13 22:19:57 +0200106 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100107
108 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
109 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100110 /* Step 1 or 4 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200111 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
112 goto exit;
113 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
114 ctx->V, md_len ) ) != 0 )
115 goto exit;
116 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
117 sep, 1 ) ) != 0 )
118 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100119 if( rounds == 2 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200120 {
121 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
122 additional, add_len ) ) != 0 )
123 goto exit;
124 }
125 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
126 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100127
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100128 /* Step 2 or 5 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200129 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
130 goto exit;
131 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
132 ctx->V, md_len ) ) != 0 )
133 goto exit;
134 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
135 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100136 }
Gilles Peskine1da77762018-09-11 15:35:41 +0200137
Gilles Peskine4d237572018-09-13 22:19:57 +0200138exit:
Gilles Peskine1da77762018-09-11 15:35:41 +0200139 mbedtls_zeroize( K, sizeof( K ) );
Gilles Peskine4d237572018-09-13 22:19:57 +0200140 return( ret );
141}
142
143void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
144 const unsigned char *additional,
145 size_t add_len )
146{
147 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148}
149
150/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100151 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100152 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200153int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100155 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100156{
157 int ret;
158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100160 return( ret );
161
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100162 /*
163 * Set initial working state.
164 * Use the V memory location, which is currently all 0, to initialize the
165 * MD context with an all-zero key. Then set V to its initial value.
166 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200167 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
168 mbedtls_md_get_size( md_info ) ) ) != 0 )
169 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100171
Gilles Peskine4d237572018-09-13 22:19:57 +0200172 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
173 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100174
175 return( 0 );
176}
177
178/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100179 * Internal function used both for seeding and reseeding the DRBG.
180 * Comments starting with arabic numbers refer to section 10.1.2.4
181 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100182 */
Hanno Beckerb98e3262019-08-27 06:47:18 +0100183static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
184 const unsigned char *additional, size_t len,
185 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerb98e3262019-08-27 06:47:18 +0100188 size_t seedlen = 0;
Gilles Peskine4d237572018-09-13 22:19:57 +0200189 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100191 {
Hanno Beckerb98e3262019-08-27 06:47:18 +0100192 size_t total_entropy_len;
193
194 if( use_nonce == 0 )
195 total_entropy_len = ctx->entropy_len;
196 else
197 total_entropy_len = ctx->entropy_len * 3 / 2;
198
199 /* III. Check input length */
200 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
201 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
202 {
203 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
204 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100205 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100209 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200210 if( ( ret = ctx->f_entropy( ctx->p_entropy,
211 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerb98e3262019-08-27 06:47:18 +0100212 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100214 }
215 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100216
Hanno Beckerb98e3262019-08-27 06:47:18 +0100217 /* For initial seeding, allow adding of nonce generated
218 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
219 if( use_nonce )
220 {
221 /* Note: We don't merge the two calls to f_entropy() in order
222 * to avoid requesting too much entropy from f_entropy()
223 * at once. Specifically, if the underlying digest is not
224 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
225 * is larger than the maximum of 32 Bytes that our own
226 * entropy source implementation can emit in a single
227 * call in configurations disabling SHA-512. */
228 if( ( ret = ctx->f_entropy( ctx->p_entropy,
229 seed + seedlen,
230 ctx->entropy_len / 2 ) ) != 0 )
231 {
232 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
233 }
234
235 seedlen += ctx->entropy_len / 2;
236 }
237
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100238
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100239 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100240 if( additional != NULL && len != 0 )
241 {
242 memcpy( seed + seedlen, additional, len );
243 seedlen += len;
244 }
245
246 /* 2. Update state */
Gilles Peskine4d237572018-09-13 22:19:57 +0200247 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
248 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100249
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100250 /* 3. Reset reseed_counter */
251 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100252
Gilles Peskine4d237572018-09-13 22:19:57 +0200253exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100254 /* 4. Done */
Gilles Peskine1da77762018-09-11 15:35:41 +0200255 mbedtls_zeroize( seed, seedlen );
Gilles Peskine4d237572018-09-13 22:19:57 +0200256 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100257}
258
259/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100260 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
261 */
262int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
263 const unsigned char *additional, size_t len )
264{
265 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
266}
267
268/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100269 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerb98e3262019-08-27 06:47:18 +0100270 *
271 * The nonce is not passed as a separate parameter but extracted
272 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100273 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200274int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100276 int (*f_entropy)(void *, unsigned char *, size_t),
277 void *p_entropy,
278 const unsigned char *custom,
279 size_t len )
280{
281 int ret;
Hanno Beckerb98e3262019-08-27 06:47:18 +0100282 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285 return( ret );
286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100288
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100289 /*
290 * Set initial working state.
291 * Use the V memory location, which is currently all 0, to initialize the
292 * MD context with an all-zero key. Then set V to its initial value.
293 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200294 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
295 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100296 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100297
298 ctx->f_entropy = f_entropy;
299 ctx->p_entropy = p_entropy;
300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100302
Gilles Peskine9c742242019-10-04 11:47:35 +0200303 if( ctx->entropy_len == 0 )
304 {
305 /*
306 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
307 * each hash function, then according to SP800-90A rev1 10.1 table 2,
308 * min_entropy_len (in bits) is security_strength.
309 *
310 * (This also matches the sizes used in the NIST test vectors.)
311 */
312 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
313 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
314 32; /* better (256+) -> 256 bits */
315 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100316
Hanno Beckerb98e3262019-08-27 06:47:18 +0100317 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
318 1 /* add nonce */ ) ) != 0 )
319 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100320 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100321 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100322
323 return( 0 );
324}
325
326/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100327 * Set prediction resistance
328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100330 int resistance )
331{
332 ctx->prediction_resistance = resistance;
333}
334
335/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200336 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100339{
340 ctx->entropy_len = len;
341}
342
343/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100344 * Set reseed interval
345 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100347{
348 ctx->reseed_interval = interval;
349}
350
351/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100352 * HMAC_DRBG random function with optional additional data:
353 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100356 unsigned char *output, size_t out_len,
357 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100358{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100359 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
361 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100362 size_t left = out_len;
363 unsigned char *out = output;
364
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100365 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
367 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100368
369 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
371 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100372
373 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100374 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100376 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100377 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100379 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100380
381 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100382 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383
384 /* 2. Use additional data if any */
385 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200386 {
387 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
388 additional, add_len ) ) != 0 )
389 goto exit;
390 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100391
392 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100393 while( left != 0 )
394 {
395 size_t use_len = left > md_len ? md_len : left;
396
Gilles Peskineaadc8182018-09-11 16:54:57 +0200397 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
398 goto exit;
399 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
400 ctx->V, md_len ) ) != 0 )
401 goto exit;
402 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
403 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100404
405 memcpy( out, ctx->V, use_len );
406 out += use_len;
407 left -= use_len;
408 }
409
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100410 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200411 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
412 additional, add_len ) ) != 0 )
413 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100414
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100415 /* 7. Update reseed counter */
416 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100417
Gilles Peskine4d237572018-09-13 22:19:57 +0200418exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100419 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200420 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421}
422
423/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100424 * HMAC_DRBG random function
425 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100427{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100428 int ret;
429 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
430
431#if defined(MBEDTLS_THREADING_C)
432 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
433 return( ret );
434#endif
435
436 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
437
438#if defined(MBEDTLS_THREADING_C)
439 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
440 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
441#endif
442
443 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100444}
445
446/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100447 * Free an HMAC_DRBG context
448 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100450{
451 if( ctx == NULL )
452 return;
453
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100454#if defined(MBEDTLS_THREADING_C)
455 mbedtls_mutex_free( &ctx->mutex );
456#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100459}
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461#if defined(MBEDTLS_FS_IO)
462int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100464 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467
468 if( ( f = fopen( path, "wb" ) ) == 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472 goto exit;
473
474 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
475 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100477 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100478 }
479
480 ret = 0;
481
482exit:
483 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100484 mbedtls_zeroize( buf, sizeof( buf ) );
485
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486 return( ret );
487}
488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100490{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100491 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492 FILE *f;
493 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495
496 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498
499 fseek( f, 0, SEEK_END );
500 n = (size_t) ftell( f );
501 fseek( f, 0, SEEK_SET );
502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100504 {
505 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100507 }
508
509 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100510 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
511 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200512 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200513
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100514 fclose( f );
515
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100516 mbedtls_zeroize( buf, sizeof( buf ) );
517
518 if( ret != 0 )
519 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100522}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100524
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100529/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100531{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200532 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100533 return( 0 );
534}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535#else
536
537#define OUTPUT_LEN 80
538
539/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000540static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100541 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
542 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
543 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
544 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
545 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
546static const unsigned char result_pr[OUTPUT_LEN] = {
547 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
548 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
549 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
550 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
551 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
552 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
553 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
554
555/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000556static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
558 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
559 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
560 0xe9, 0x9d, 0xfe, 0xdf };
561static const unsigned char result_nopr[OUTPUT_LEN] = {
562 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
563 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
564 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
565 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
566 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
567 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
568 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
569
570/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100571static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572static int hmac_drbg_self_test_entropy( void *data,
573 unsigned char *buf, size_t len )
574{
575 const unsigned char *p = data;
576 memcpy( buf, p + test_offset, len );
577 test_offset += len;
578 return( 0 );
579}
580
Paul Bakker7dc4c442014-02-01 22:50:26 +0100581#define CHK( c ) if( (c) != 0 ) \
582 { \
583 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100585 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586 }
587
588/*
589 * Checkup routine for HMAC_DRBG with SHA-1
590 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200597 mbedtls_hmac_drbg_init( &ctx );
598
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599 /*
600 * PR = True
601 */
602 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604
605 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200606 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000607 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
610 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
611 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100615 mbedtls_hmac_drbg_free( &ctx );
616
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100619
620 /*
621 * PR = False
622 */
623 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100625
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100626 mbedtls_hmac_drbg_init( &ctx );
627
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100628 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200629 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000630 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100631 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
633 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
634 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100635 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100637
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100638 mbedtls_hmac_drbg_free( &ctx );
639
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100640 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642
643 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100645
646 return( 0 );
647}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648#endif /* MBEDTLS_SHA1_C */
649#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#endif /* MBEDTLS_HMAC_DRBG_C */