blob: aa3e251040678f82011af9aaa8d3237316b24c32 [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
56#if defined(MBEDTLS_THREADING_C)
57 mbedtls_mutex_init( &ctx->mutex );
58#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020059}
60
61/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010062 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010063 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020064int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
65 const unsigned char *additional,
66 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010067{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010069 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
70 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020072 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010073
74 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
75 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010076 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020077 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
78 goto exit;
79 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
80 ctx->V, md_len ) ) != 0 )
81 goto exit;
82 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
83 sep, 1 ) ) != 0 )
84 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010085 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020086 {
87 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
88 additional, add_len ) ) != 0 )
89 goto exit;
90 }
91 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
92 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010093
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010094 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020095 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
96 goto exit;
97 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
98 ctx->V, md_len ) ) != 0 )
99 goto exit;
100 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
101 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100102 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200103
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200104exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200105 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200106 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100107}
108
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200109#if !defined(MBEDTLS_DEPRECATED_REMOVED)
110void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
111 const unsigned char *additional,
112 size_t add_len )
113{
114 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
115}
116#endif /* MBEDTLS_DEPRECATED_REMOVED */
117
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100118/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100119 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100120 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200121int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100123 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100124{
Janos Follath24eed8d2019-11-22 13:21:35 +0000125 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100128 return( ret );
129
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100130 /*
131 * Set initial working state.
132 * Use the V memory location, which is currently all 0, to initialize the
133 * MD context with an all-zero key. Then set V to its initial value.
134 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200135 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
136 mbedtls_md_get_size( md_info ) ) ) != 0 )
137 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100139
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200140 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
141 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100142
143 return( 0 );
144}
145
146/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100147 * Internal function used both for seeding and reseeding the DRBG.
148 * Comments starting with arabic numbers refer to section 10.1.2.4
149 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100150 */
Hanno Beckera823d4c2019-08-27 06:47:18 +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 Beckera823d4c2019-08-27 06:47:18 +0100156 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000157 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100158
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100159 {
Hanno Beckera823d4c2019-08-27 06:47:18 +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 Beckera823d4c2019-08-27 06:47:18 +0100180 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100182 }
183 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184
Hanno Beckera823d4c2019-08-27 06:47:18 +0100185 /* 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 Beckera823d4c2019-08-27 06:47:18 +0100228 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
229 */
230int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
231 const unsigned char *additional, size_t len )
232{
233 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
234}
235
236/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100237 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100238 *
239 * The nonce is not passed as a separate parameter but extracted
240 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100241 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200242int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100244 int (*f_entropy)(void *, unsigned char *, size_t),
245 void *p_entropy,
246 const unsigned char *custom,
247 size_t len )
248{
Janos Follath24eed8d2019-11-22 13:21:35 +0000249 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100250 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100253 return( ret );
254
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100256
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100257 /*
258 * Set initial working state.
259 * Use the V memory location, which is currently all 0, to initialize the
260 * MD context with an all-zero key. Then set V to its initial value.
261 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200262 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
263 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100264 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100265
266 ctx->f_entropy = f_entropy;
267 ctx->p_entropy = p_entropy;
268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100270
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200271 if( ctx->entropy_len == 0 )
272 {
273 /*
274 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
275 * each hash function, then according to SP800-90A rev1 10.1 table 2,
276 * min_entropy_len (in bits) is security_strength.
277 *
278 * (This also matches the sizes used in the NIST test vectors.)
279 */
280 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
281 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
282 32; /* better (256+) -> 256 bits */
283 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100284
Hanno Beckera823d4c2019-08-27 06:47:18 +0100285 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
286 1 /* add nonce */ ) ) != 0 )
287 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100288 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100289 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100290
291 return( 0 );
292}
293
294/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100295 * Set prediction resistance
296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100298 int resistance )
299{
300 ctx->prediction_resistance = resistance;
301}
302
303/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200304 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100305 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100307{
308 ctx->entropy_len = len;
309}
310
311/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100312 * Set reseed interval
313 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100315{
316 ctx->reseed_interval = interval;
317}
318
319/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100320 * HMAC_DRBG random function with optional additional data:
321 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100322 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100324 unsigned char *output, size_t out_len,
325 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100326{
Janos Follath24eed8d2019-11-22 13:21:35 +0000327 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
329 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100330 size_t left = out_len;
331 unsigned char *out = output;
332
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100333 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
335 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100336
337 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
339 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100340
341 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100342 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100344 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100345 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100347 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100348
349 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100350 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100351
352 /* 2. Use additional data if any */
353 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200354 {
355 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
356 additional, add_len ) ) != 0 )
357 goto exit;
358 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100359
360 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100361 while( left != 0 )
362 {
363 size_t use_len = left > md_len ? md_len : left;
364
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200365 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
366 goto exit;
367 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
368 ctx->V, md_len ) ) != 0 )
369 goto exit;
370 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
371 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100372
373 memcpy( out, ctx->V, use_len );
374 out += use_len;
375 left -= use_len;
376 }
377
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100378 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200379 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
380 additional, add_len ) ) != 0 )
381 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100382
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100383 /* 7. Update reseed counter */
384 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200386exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100387 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200388 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100389}
390
391/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392 * HMAC_DRBG random function
393 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395{
Janos Follath24eed8d2019-11-22 13:21:35 +0000396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100397 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
398
399#if defined(MBEDTLS_THREADING_C)
400 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
401 return( ret );
402#endif
403
404 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
405
406#if defined(MBEDTLS_THREADING_C)
407 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
408 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
409#endif
410
411 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100412}
413
414/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100415 * Free an HMAC_DRBG context
416 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100418{
419 if( ctx == NULL )
420 return;
421
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100422#if defined(MBEDTLS_THREADING_C)
423 mbedtls_mutex_free( &ctx->mutex );
424#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500426 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100427}
428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429#if defined(MBEDTLS_FS_IO)
430int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100431{
Janos Follath24eed8d2019-11-22 13:21:35 +0000432 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100433 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435
436 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440 goto exit;
441
442 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
443 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100445 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100446 }
447
448 ret = 0;
449
450exit:
451 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500452 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100453
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100454 return( ret );
455}
456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100459 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200460 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200463 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464
465 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467
Gilles Peskine82204662018-09-11 18:43:09 +0200468 n = fread( buf, 1, sizeof( buf ), f );
469 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470 {
Gilles Peskine82204662018-09-11 18:43:09 +0200471 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
472 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473 }
Gilles Peskine82204662018-09-11 18:43:09 +0200474 if( n == 0 || ferror( f ) )
475 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100476 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200477 goto exit;
478 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200480 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100481
Gilles Peskine82204662018-09-11 18:43:09 +0200482 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
483
484exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500485 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200486 if( f != NULL )
487 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100488 if( ret != 0 )
489 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100491}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100493
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100498/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100500{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200501 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100502 return( 0 );
503}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100504#else
505
506#define OUTPUT_LEN 80
507
508/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000509static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100510 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
511 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
512 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
513 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
514 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
515static const unsigned char result_pr[OUTPUT_LEN] = {
516 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
517 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
518 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
519 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
520 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
521 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
522 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
523
524/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000525static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100526 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
527 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
528 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
529 0xe9, 0x9d, 0xfe, 0xdf };
530static const unsigned char result_nopr[OUTPUT_LEN] = {
531 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
532 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
533 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
534 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
535 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
536 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
537 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
538
539/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100540static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100541static int hmac_drbg_self_test_entropy( void *data,
542 unsigned char *buf, size_t len )
543{
544 const unsigned char *p = data;
545 memcpy( buf, p + test_offset, len );
546 test_offset += len;
547 return( 0 );
548}
549
Paul Bakker7dc4c442014-02-01 22:50:26 +0100550#define CHK( c ) if( (c) != 0 ) \
551 { \
552 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100554 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100555 }
556
557/*
558 * Checkup routine for HMAC_DRBG with SHA-1
559 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100561{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100565
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200566 mbedtls_hmac_drbg_init( &ctx );
567
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568 /*
569 * PR = True
570 */
571 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100573
574 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200575 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000576 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100577 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
579 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
580 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100581 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100583
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100584 mbedtls_hmac_drbg_free( &ctx );
585
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588
589 /*
590 * PR = False
591 */
592 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100595 mbedtls_hmac_drbg_init( &ctx );
596
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200598 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000599 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
602 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
603 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100607 mbedtls_hmac_drbg_free( &ctx );
608
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611
612 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614
615 return( 0 );
616}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617#endif /* MBEDTLS_SHA1_C */
618#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100619
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#endif /* MBEDTLS_HMAC_DRBG_C */