blob: 02ce7f78a53e0d27e9592c7cb5449291c8e0a5b2 [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,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 const mbedtls_md_info_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 Beckerb3a06e62019-08-27 09:21:44 +0100151static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
152 const unsigned char *additional, size_t len,
153 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100154{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckereab304c2019-08-26 15:29:14 +0100156 size_t seedlen = 0;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200157 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100158
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100159 {
Hanno Beckereab304c2019-08-26 15:29:14 +0100160 size_t total_entropy_len;
161
162 if( use_nonce == 0 )
163 total_entropy_len = ctx->entropy_len;
164 else
165 total_entropy_len = ctx->entropy_len * 3 / 2;
166
167 /* III. Check input length */
168 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
169 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
170 {
171 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
172 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100173 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100176
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100177 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200178 if( ( ret = ctx->f_entropy( ctx->p_entropy,
179 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100180 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckereab304c2019-08-26 15:29:14 +0100182 }
183 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184
Hanno Beckereab304c2019-08-26 15:29:14 +0100185 /* IV'. For initial seeding, allow adding of nonce generated
186 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
187 if( use_nonce )
188 {
189 /* Note: We don't merge the two calls to f_entropy() in order
190 * to avoid requesting too much entropy from f_entropy()
191 * at once. Specifically, if the underlying digest is not
192 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
193 * is larger than the maximum of 32 Bytes that our own
194 * entropy source implementation can emit in a single
195 * call in configurations disabling SHA-512. */
196 if( ( ret = ctx->f_entropy( ctx->p_entropy,
197 seed + seedlen,
198 ctx->entropy_len / 2 ) ) != 0 )
199 {
200 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
201 }
202
203 seedlen += ctx->entropy_len / 2;
204 }
205
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100207 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208 if( additional != NULL && len != 0 )
209 {
210 memcpy( seed + seedlen, additional, len );
211 seedlen += len;
212 }
213
214 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200215 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
216 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100218 /* 3. Reset reseed_counter */
219 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100220
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200221exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100222 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200223 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200224 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100225}
226
227/*
Hanno Beckereab304c2019-08-26 15:29:14 +0100228 * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman)
229 */
230int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
231 const unsigned char *additional, size_t len )
232{
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100233 return( hmac_drbg_reseed_core( ctx, additional, len,
234 0 /* no nonce */ ) );
Hanno Beckereab304c2019-08-26 15:29:14 +0100235}
236
237/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100238 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100239 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200240int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100242 int (*f_entropy)(void *, unsigned char *, size_t),
243 void *p_entropy,
244 const unsigned char *custom,
245 size_t len )
246{
247 int ret;
Hanno Beckereab304c2019-08-26 15:29:14 +0100248 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100251 return( ret );
252
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100254
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100255 /*
256 * Set initial working state.
257 * Use the V memory location, which is currently all 0, to initialize the
258 * MD context with an all-zero key. Then set V to its initial value.
259 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200260 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
261 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100262 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100263
264 ctx->f_entropy = f_entropy;
265 ctx->p_entropy = p_entropy;
266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100268
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100269 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100270 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
271 * each hash function, then according to SP800-90A rev1 10.1 table 2,
272 * min_entropy_len (in bits) is security_strength.
273 *
274 * (This also matches the sizes used in the NIST test vectors.)
275 */
Hanno Beckereab304c2019-08-26 15:29:14 +0100276 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
277 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
278 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100279
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100280 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
281 1 /* add nonce */ ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100282 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100283 return( ret );
Hanno Beckereab304c2019-08-26 15:29:14 +0100284 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285
286 return( 0 );
287}
288
289/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100290 * Set prediction resistance
291 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100293 int resistance )
294{
295 ctx->prediction_resistance = resistance;
296}
297
298/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100299 * Set entropy length grabbed for reseeds
300 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100302{
303 ctx->entropy_len = len;
304}
305
306/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100307 * Set reseed interval
308 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100310{
311 ctx->reseed_interval = interval;
312}
313
314/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100315 * HMAC_DRBG random function with optional additional data:
316 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100317 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100319 unsigned char *output, size_t out_len,
320 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100321{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100322 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
324 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100325 size_t left = out_len;
326 unsigned char *out = output;
327
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100328 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
330 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100331
332 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
334 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100335
336 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100337 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100339 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100340 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100342 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100343
344 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100345 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100346
347 /* 2. Use additional data if any */
348 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200349 {
350 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
351 additional, add_len ) ) != 0 )
352 goto exit;
353 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100354
355 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356 while( left != 0 )
357 {
358 size_t use_len = left > md_len ? md_len : left;
359
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200360 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
361 goto exit;
362 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
363 ctx->V, md_len ) ) != 0 )
364 goto exit;
365 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
366 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100367
368 memcpy( out, ctx->V, use_len );
369 out += use_len;
370 left -= use_len;
371 }
372
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100373 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200374 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
375 additional, add_len ) ) != 0 )
376 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100377
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100378 /* 7. Update reseed counter */
379 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100380
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200381exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100382 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200383 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100384}
385
386/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100387 * HMAC_DRBG random function
388 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100390{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100391 int ret;
392 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
393
394#if defined(MBEDTLS_THREADING_C)
395 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
396 return( ret );
397#endif
398
399 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
400
401#if defined(MBEDTLS_THREADING_C)
402 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
403 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
404#endif
405
406 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100407}
408
409/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100410 * Free an HMAC_DRBG context
411 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100413{
414 if( ctx == NULL )
415 return;
416
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100417#if defined(MBEDTLS_THREADING_C)
418 mbedtls_mutex_free( &ctx->mutex );
419#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500421 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422}
423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424#if defined(MBEDTLS_FS_IO)
425int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100426{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100427 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100428 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100430
431 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435 goto exit;
436
437 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
438 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100440 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100441 }
442
443 ret = 0;
444
445exit:
446 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500447 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100448
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100449 return( ret );
450}
451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100453{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100454 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200455 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100456 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200458 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100459
460 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100462
Gilles Peskine82204662018-09-11 18:43:09 +0200463 n = fread( buf, 1, sizeof( buf ), f );
464 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465 {
Gilles Peskine82204662018-09-11 18:43:09 +0200466 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
467 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468 }
Gilles Peskine82204662018-09-11 18:43:09 +0200469 if( n == 0 || ferror( f ) )
470 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100471 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200472 goto exit;
473 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200475 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476
Gilles Peskine82204662018-09-11 18:43:09 +0200477 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
478
479exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500480 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200481 if( f != NULL )
482 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100483 if( ret != 0 )
484 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100488
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100493/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100495{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200496 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100497 return( 0 );
498}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100499#else
500
501#define OUTPUT_LEN 80
502
503/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000504static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100505 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
506 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
507 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
508 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
509 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
510static const unsigned char result_pr[OUTPUT_LEN] = {
511 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
512 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
513 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
514 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
515 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
516 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
517 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
518
519/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000520static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100521 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
522 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
523 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
524 0xe9, 0x9d, 0xfe, 0xdf };
525static const unsigned char result_nopr[OUTPUT_LEN] = {
526 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
527 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
528 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
529 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
530 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
531 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
532 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
533
534/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100535static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100536static int hmac_drbg_self_test_entropy( void *data,
537 unsigned char *buf, size_t len )
538{
539 const unsigned char *p = data;
540 memcpy( buf, p + test_offset, len );
541 test_offset += len;
542 return( 0 );
543}
544
Paul Bakker7dc4c442014-02-01 22:50:26 +0100545#define CHK( c ) if( (c) != 0 ) \
546 { \
547 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200548 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100549 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100550 }
551
552/*
553 * Checkup routine for HMAC_DRBG with SHA-1
554 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100556{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100558 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100560
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200561 mbedtls_hmac_drbg_init( &ctx );
562
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563 /*
564 * PR = True
565 */
566 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568
569 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200570 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000571 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
574 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
575 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100578
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100579 mbedtls_hmac_drbg_free( &ctx );
580
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100581 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100583
584 /*
585 * PR = False
586 */
587 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100589
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100590 mbedtls_hmac_drbg_init( &ctx );
591
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200593 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000594 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
597 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
598 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100599 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100602 mbedtls_hmac_drbg_free( &ctx );
603
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606
607 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609
610 return( 0 );
611}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612#endif /* MBEDTLS_SHA1_C */
613#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100614
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615#endif /* MBEDTLS_HMAC_DRBG_C */