blob: 886f44a80a5e7997e5d7fc1e098961d41af8edcf [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"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010041#include <stdio.h>
42#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST)
45#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#else
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_SELF_TEST */
51#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Paul Bakker34617722014-06-13 17:20:13 +020053/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020055 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020059 * HMAC_DRBG context initialization
60 */
61void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
62{
63 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010064
65#if defined(MBEDTLS_THREADING_C)
66 mbedtls_mutex_init( &ctx->mutex );
67#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020068}
69
70/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010071 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010072 */
Gilles Peskine4d237572018-09-13 22:19:57 +020073int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
74 const unsigned char *additional,
75 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010076{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010078 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
79 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine4d237572018-09-13 22:19:57 +020081 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010082
83 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
84 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010085 /* Step 1 or 4 */
Gilles Peskine4d237572018-09-13 22:19:57 +020086 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
87 goto exit;
88 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
89 ctx->V, md_len ) ) != 0 )
90 goto exit;
91 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
92 sep, 1 ) ) != 0 )
93 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010094 if( rounds == 2 )
Gilles Peskine4d237572018-09-13 22:19:57 +020095 {
96 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
97 additional, add_len ) ) != 0 )
98 goto exit;
99 }
100 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
101 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100102
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100103 /* Step 2 or 5 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200104 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
105 goto exit;
106 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
107 ctx->V, md_len ) ) != 0 )
108 goto exit;
109 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
110 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100111 }
Gilles Peskine1da77762018-09-11 15:35:41 +0200112
Gilles Peskine4d237572018-09-13 22:19:57 +0200113exit:
Gilles Peskine1da77762018-09-11 15:35:41 +0200114 mbedtls_zeroize( K, sizeof( K ) );
Gilles Peskine4d237572018-09-13 22:19:57 +0200115 return( ret );
116}
117
118void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
119 const unsigned char *additional,
120 size_t add_len )
121{
122 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100123}
124
125/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100126 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100127 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200128int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100130 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100131{
132 int ret;
133
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100135 return( ret );
136
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100137 /*
138 * Set initial working state.
139 * Use the V memory location, which is currently all 0, to initialize the
140 * MD context with an all-zero key. Then set V to its initial value.
141 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200142 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
143 mbedtls_md_get_size( md_info ) ) ) != 0 )
144 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100146
Gilles Peskine4d237572018-09-13 22:19:57 +0200147 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
148 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100149
150 return( 0 );
151}
152
153/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100154 * Internal function used both for seeding and reseeding the DRBG.
155 * Comments starting with arabic numbers refer to section 10.1.2.4
156 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100157 */
Hanno Beckerb98e3262019-08-27 06:47:18 +0100158static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
159 const unsigned char *additional, size_t len,
160 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerb98e3262019-08-27 06:47:18 +0100163 size_t seedlen = 0;
Gilles Peskine4d237572018-09-13 22:19:57 +0200164 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100165
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100166 {
Hanno Beckerb98e3262019-08-27 06:47:18 +0100167 size_t total_entropy_len;
168
169 if( use_nonce == 0 )
170 total_entropy_len = ctx->entropy_len;
171 else
172 total_entropy_len = ctx->entropy_len * 3 / 2;
173
174 /* III. Check input length */
175 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
176 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
177 {
178 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
179 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100180 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100183
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100184 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200185 if( ( ret = ctx->f_entropy( ctx->p_entropy,
186 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerb98e3262019-08-27 06:47:18 +0100187 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100189 }
190 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100191
Hanno Beckerb98e3262019-08-27 06:47:18 +0100192 /* For initial seeding, allow adding of nonce generated
193 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
194 if( use_nonce )
195 {
196 /* Note: We don't merge the two calls to f_entropy() in order
197 * to avoid requesting too much entropy from f_entropy()
198 * at once. Specifically, if the underlying digest is not
199 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
200 * is larger than the maximum of 32 Bytes that our own
201 * entropy source implementation can emit in a single
202 * call in configurations disabling SHA-512. */
203 if( ( ret = ctx->f_entropy( ctx->p_entropy,
204 seed + seedlen,
205 ctx->entropy_len / 2 ) ) != 0 )
206 {
207 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
208 }
209
210 seedlen += ctx->entropy_len / 2;
211 }
212
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100213
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100214 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100215 if( additional != NULL && len != 0 )
216 {
217 memcpy( seed + seedlen, additional, len );
218 seedlen += len;
219 }
220
221 /* 2. Update state */
Gilles Peskine4d237572018-09-13 22:19:57 +0200222 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
223 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100224
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100225 /* 3. Reset reseed_counter */
226 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100227
Gilles Peskine4d237572018-09-13 22:19:57 +0200228exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100229 /* 4. Done */
Gilles Peskine1da77762018-09-11 15:35:41 +0200230 mbedtls_zeroize( seed, seedlen );
Gilles Peskine4d237572018-09-13 22:19:57 +0200231 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100232}
233
234/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100235 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
236 */
237int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
238 const unsigned char *additional, size_t len )
239{
240 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
241}
242
243/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100244 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerb98e3262019-08-27 06:47:18 +0100245 *
246 * The nonce is not passed as a separate parameter but extracted
247 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100248 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200249int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100251 int (*f_entropy)(void *, unsigned char *, size_t),
252 void *p_entropy,
253 const unsigned char *custom,
254 size_t len )
255{
256 int ret;
Hanno Beckerb98e3262019-08-27 06:47:18 +0100257 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100260 return( ret );
261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100263
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100264 /*
265 * Set initial working state.
266 * Use the V memory location, which is currently all 0, to initialize the
267 * MD context with an all-zero key. Then set V to its initial value.
268 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200269 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
270 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100271 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100272
273 ctx->f_entropy = f_entropy;
274 ctx->p_entropy = p_entropy;
275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100277
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100278 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100279 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
280 * each hash function, then according to SP800-90A rev1 10.1 table 2,
281 * min_entropy_len (in bits) is security_strength.
282 *
283 * (This also matches the sizes used in the NIST test vectors.)
284 */
Hanno Beckerb98e3262019-08-27 06:47:18 +0100285 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
286 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
287 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100288
Hanno Beckerb98e3262019-08-27 06:47:18 +0100289 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
290 1 /* add nonce */ ) ) != 0 )
291 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100292 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100293 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100294
295 return( 0 );
296}
297
298/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100299 * Set prediction resistance
300 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100302 int resistance )
303{
304 ctx->prediction_resistance = resistance;
305}
306
307/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100308 * Set entropy length grabbed for reseeds
309 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100311{
312 ctx->entropy_len = len;
313}
314
315/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100316 * Set reseed interval
317 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100319{
320 ctx->reseed_interval = interval;
321}
322
323/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324 * HMAC_DRBG random function with optional additional data:
325 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100326 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100328 unsigned char *output, size_t out_len,
329 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100330{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100331 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
333 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100334 size_t left = out_len;
335 unsigned char *out = output;
336
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100337 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
339 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100340
341 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
343 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100344
345 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100346 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100348 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100349 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100351 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100352
353 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100354 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100355
356 /* 2. Use additional data if any */
357 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200358 {
359 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
360 additional, add_len ) ) != 0 )
361 goto exit;
362 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100363
364 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100365 while( left != 0 )
366 {
367 size_t use_len = left > md_len ? md_len : left;
368
Gilles Peskineaadc8182018-09-11 16:54:57 +0200369 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
370 goto exit;
371 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
372 ctx->V, md_len ) ) != 0 )
373 goto exit;
374 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
375 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100376
377 memcpy( out, ctx->V, use_len );
378 out += use_len;
379 left -= use_len;
380 }
381
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100382 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200383 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
384 additional, add_len ) ) != 0 )
385 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100386
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100387 /* 7. Update reseed counter */
388 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100389
Gilles Peskine4d237572018-09-13 22:19:57 +0200390exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100391 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200392 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100393}
394
395/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100396 * HMAC_DRBG random function
397 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100399{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100400 int ret;
401 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
402
403#if defined(MBEDTLS_THREADING_C)
404 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
405 return( ret );
406#endif
407
408 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
409
410#if defined(MBEDTLS_THREADING_C)
411 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
412 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
413#endif
414
415 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100416}
417
418/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419 * Free an HMAC_DRBG context
420 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422{
423 if( ctx == NULL )
424 return;
425
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100426#if defined(MBEDTLS_THREADING_C)
427 mbedtls_mutex_free( &ctx->mutex );
428#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100431}
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433#if defined(MBEDTLS_FS_IO)
434int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100436 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100437 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100439
440 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444 goto exit;
445
446 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
447 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100449 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100450 }
451
452 ret = 0;
453
454exit:
455 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100456 mbedtls_zeroize( buf, sizeof( buf ) );
457
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458 return( ret );
459}
460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100462{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100463 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464 FILE *f;
465 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467
468 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470
471 fseek( f, 0, SEEK_END );
472 n = (size_t) ftell( f );
473 fseek( f, 0, SEEK_SET );
474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476 {
477 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 }
480
481 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100482 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
483 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200484 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200485
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486 fclose( f );
487
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100488 mbedtls_zeroize( buf, sizeof( buf ) );
489
490 if( ret != 0 )
491 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100496
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100501/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100503{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200504 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100505 return( 0 );
506}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100507#else
508
509#define OUTPUT_LEN 80
510
511/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000512static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100513 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
514 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
515 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
516 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
517 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
518static const unsigned char result_pr[OUTPUT_LEN] = {
519 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
520 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
521 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
522 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
523 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
524 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
525 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
526
527/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000528static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100529 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
530 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
531 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
532 0xe9, 0x9d, 0xfe, 0xdf };
533static const unsigned char result_nopr[OUTPUT_LEN] = {
534 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
535 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
536 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
537 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
538 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
539 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
540 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
541
542/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100543static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544static int hmac_drbg_self_test_entropy( void *data,
545 unsigned char *buf, size_t len )
546{
547 const unsigned char *p = data;
548 memcpy( buf, p + test_offset, len );
549 test_offset += len;
550 return( 0 );
551}
552
Paul Bakker7dc4c442014-02-01 22:50:26 +0100553#define CHK( c ) if( (c) != 0 ) \
554 { \
555 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100557 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100558 }
559
560/*
561 * Checkup routine for HMAC_DRBG with SHA-1
562 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200569 mbedtls_hmac_drbg_init( &ctx );
570
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571 /*
572 * PR = True
573 */
574 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576
577 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200578 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000579 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100580 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
582 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
583 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100584 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100587 mbedtls_hmac_drbg_free( &ctx );
588
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100589 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591
592 /*
593 * PR = False
594 */
595 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100598 mbedtls_hmac_drbg_init( &ctx );
599
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200601 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000602 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
605 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
606 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100609
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100610 mbedtls_hmac_drbg_free( &ctx );
611
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614
615 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617
618 return( 0 );
619}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#endif /* MBEDTLS_SHA1_C */
621#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100622
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#endif /* MBEDTLS_HMAC_DRBG_C */