blob: bd14b3cce3ef77abaa3a02477e5b1cb5f255a1c1 [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_SELF_TEST */
47#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050 * HMAC_DRBG context initialization
51 */
52void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
53{
54 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010055
Gavin Acquroff6aceb512020-03-01 17:06:11 -080056 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
57
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010058#if defined(MBEDTLS_THREADING_C)
59 mbedtls_mutex_init( &ctx->mutex );
60#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020061}
62
63/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010064 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010065 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020066int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
67 const unsigned char *additional,
68 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010069{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
72 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020074 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075
76 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
77 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010078 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020079 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
80 goto exit;
81 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
82 ctx->V, md_len ) ) != 0 )
83 goto exit;
84 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
85 sep, 1 ) ) != 0 )
86 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010087 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020088 {
89 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
90 additional, add_len ) ) != 0 )
91 goto exit;
92 }
93 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
94 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010096 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
98 goto exit;
99 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
100 ctx->V, md_len ) ) != 0 )
101 goto exit;
102 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
103 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200105
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200106exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200107 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200108 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109}
110
111/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100112 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200114int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100116 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100117{
Janos Follath24eed8d2019-11-22 13:21:35 +0000118 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121 return( ret );
122
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100123 /*
124 * Set initial working state.
125 * Use the V memory location, which is currently all 0, to initialize the
126 * MD context with an all-zero key. Then set V to its initial value.
127 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200128 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
129 mbedtls_md_get_size( md_info ) ) ) != 0 )
130 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100132
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200133 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
134 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100135
136 return( 0 );
137}
138
139/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100140 * Internal function used both for seeding and reseeding the DRBG.
141 * Comments starting with arabic numbers refer to section 10.1.2.4
142 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100143 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100144static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
145 const unsigned char *additional, size_t len,
146 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100147{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100149 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000150 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100151
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100152 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153 size_t total_entropy_len;
154
155 if( use_nonce == 0 )
156 total_entropy_len = ctx->entropy_len;
157 else
158 total_entropy_len = ctx->entropy_len * 3 / 2;
159
160 /* III. Check input length */
161 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
162 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
163 {
164 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
165 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100166 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100169
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100170 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200171 if( ( ret = ctx->f_entropy( ctx->p_entropy,
172 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100173 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100175 }
176 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100177
Hanno Beckera823d4c2019-08-27 06:47:18 +0100178 /* For initial seeding, allow adding of nonce generated
179 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
180 if( use_nonce )
181 {
182 /* Note: We don't merge the two calls to f_entropy() in order
183 * to avoid requesting too much entropy from f_entropy()
184 * at once. Specifically, if the underlying digest is not
185 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
186 * is larger than the maximum of 32 Bytes that our own
187 * entropy source implementation can emit in a single
188 * call in configurations disabling SHA-512. */
189 if( ( ret = ctx->f_entropy( ctx->p_entropy,
190 seed + seedlen,
191 ctx->entropy_len / 2 ) ) != 0 )
192 {
193 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
194 }
195
196 seedlen += ctx->entropy_len / 2;
197 }
198
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100199
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100200 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100201 if( additional != NULL && len != 0 )
202 {
203 memcpy( seed + seedlen, additional, len );
204 seedlen += len;
205 }
206
207 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200208 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
209 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100211 /* 3. Reset reseed_counter */
212 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100213
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200214exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100215 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200216 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200217 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100218}
219
220/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100221 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
222 */
223int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
224 const unsigned char *additional, size_t len )
225{
226 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
227}
228
229/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100230 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100231 *
232 * The nonce is not passed as a separate parameter but extracted
233 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100234 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200235int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100237 int (*f_entropy)(void *, unsigned char *, size_t),
238 void *p_entropy,
239 const unsigned char *custom,
240 size_t len )
241{
Janos Follath24eed8d2019-11-22 13:21:35 +0000242 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100243 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100246 return( ret );
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100249
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100250 /*
251 * Set initial working state.
252 * Use the V memory location, which is currently all 0, to initialize the
253 * MD context with an all-zero key. Then set V to its initial value.
254 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200255 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
256 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100257 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100258
259 ctx->f_entropy = f_entropy;
260 ctx->p_entropy = p_entropy;
261
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200262 if( ctx->entropy_len == 0 )
263 {
264 /*
265 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
266 * each hash function, then according to SP800-90A rev1 10.1 table 2,
267 * min_entropy_len (in bits) is security_strength.
268 *
269 * (This also matches the sizes used in the NIST test vectors.)
270 */
271 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
272 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
273 32; /* better (256+) -> 256 bits */
274 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100275
Hanno Beckera823d4c2019-08-27 06:47:18 +0100276 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
277 1 /* add nonce */ ) ) != 0 )
278 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100279 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100280 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100281
282 return( 0 );
283}
284
285/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100286 * Set prediction resistance
287 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100289 int resistance )
290{
291 ctx->prediction_resistance = resistance;
292}
293
294/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200295 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100298{
299 ctx->entropy_len = len;
300}
301
302/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100303 * Set reseed interval
304 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100306{
307 ctx->reseed_interval = interval;
308}
309
310/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100311 * HMAC_DRBG random function with optional additional data:
312 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100315 unsigned char *output, size_t out_len,
316 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100317{
Janos Follath24eed8d2019-11-22 13:21:35 +0000318 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
320 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100321 size_t left = out_len;
322 unsigned char *out = output;
323
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
326 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100327
328 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
330 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100331
332 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100333 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100335 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100336 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100338 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100339
340 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100341 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100342
343 /* 2. Use additional data if any */
344 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200345 {
346 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
347 additional, add_len ) ) != 0 )
348 goto exit;
349 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100350
351 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100352 while( left != 0 )
353 {
354 size_t use_len = left > md_len ? md_len : left;
355
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200356 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
357 goto exit;
358 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
359 ctx->V, md_len ) ) != 0 )
360 goto exit;
361 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
362 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100363
364 memcpy( out, ctx->V, use_len );
365 out += use_len;
366 left -= use_len;
367 }
368
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100369 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200370 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
371 additional, add_len ) ) != 0 )
372 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100373
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100374 /* 7. Update reseed counter */
375 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100376
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200377exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100378 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200379 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100380}
381
382/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383 * HMAC_DRBG random function
384 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100386{
Janos Follath24eed8d2019-11-22 13:21:35 +0000387 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100388 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
389
390#if defined(MBEDTLS_THREADING_C)
391 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
392 return( ret );
393#endif
394
395 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
396
397#if defined(MBEDTLS_THREADING_C)
398 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
399 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
400#endif
401
402 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100403}
404
405/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800406 * This function resets HMAC_DRBG context to the state immediately
407 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100408 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100410{
411 if( ctx == NULL )
412 return;
413
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100414#if defined(MBEDTLS_THREADING_C)
415 mbedtls_mutex_free( &ctx->mutex );
416#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500418 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800419 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
420#if defined(MBEDTLS_THREADING_C)
421 mbedtls_mutex_init( &ctx->mutex );
422#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#if defined(MBEDTLS_FS_IO)
426int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100427{
Janos Follath24eed8d2019-11-22 13:21:35 +0000428 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100429 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100431
432 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100436 goto exit;
437
438 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
439 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100441 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442 }
443
444 ret = 0;
445
446exit:
447 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500448 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100449
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100450 return( ret );
451}
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100454{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100455 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200456 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100457 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200459 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460
461 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100463
Gilles Peskine82204662018-09-11 18:43:09 +0200464 n = fread( buf, 1, sizeof( buf ), f );
465 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100466 {
Gilles Peskine82204662018-09-11 18:43:09 +0200467 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
468 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100469 }
Gilles Peskine82204662018-09-11 18:43:09 +0200470 if( n == 0 || ferror( f ) )
471 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100472 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200473 goto exit;
474 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100475 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200476 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100477
Gilles Peskine82204662018-09-11 18:43:09 +0200478 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
479
480exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500481 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200482 if( f != NULL )
483 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100484 if( ret != 0 )
485 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100487}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100489
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100494/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100496{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200497 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100498 return( 0 );
499}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100500#else
501
502#define OUTPUT_LEN 80
503
504/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000505static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100506 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
507 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
508 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
509 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
510 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
511static const unsigned char result_pr[OUTPUT_LEN] = {
512 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
513 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
514 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
515 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
516 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
517 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
518 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
519
520/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000521static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100522 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
523 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
524 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
525 0xe9, 0x9d, 0xfe, 0xdf };
526static const unsigned char result_nopr[OUTPUT_LEN] = {
527 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
528 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
529 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
530 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
531 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
532 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
533 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
534
535/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100536static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100537static int hmac_drbg_self_test_entropy( void *data,
538 unsigned char *buf, size_t len )
539{
540 const unsigned char *p = data;
541 memcpy( buf, p + test_offset, len );
542 test_offset += len;
543 return( 0 );
544}
545
Paul Bakker7dc4c442014-02-01 22:50:26 +0100546#define CHK( c ) if( (c) != 0 ) \
547 { \
548 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100550 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100551 }
552
553/*
554 * Checkup routine for HMAC_DRBG with SHA-1
555 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100559 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100561
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200562 mbedtls_hmac_drbg_init( &ctx );
563
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564 /*
565 * PR = True
566 */
567 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569
570 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200571 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000572 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100573 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
575 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
576 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100580 mbedtls_hmac_drbg_free( &ctx );
581
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100584
585 /*
586 * PR = False
587 */
588 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100590
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100591 mbedtls_hmac_drbg_init( &ctx );
592
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200594 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000595 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
598 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
599 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100602
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100603 mbedtls_hmac_drbg_free( &ctx );
604
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607
608 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610
611 return( 0 );
612}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613#endif /* MBEDTLS_SHA1_C */
614#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#endif /* MBEDTLS_HMAC_DRBG_C */