blob: 346c2632107d7fc12f6efd4712a5ea5b5d995fc9 [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
Gilles Peskine9c742242019-10-04 11:47:35 +0200278 if( ctx->entropy_len == 0 )
279 {
280 /*
281 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
282 * each hash function, then according to SP800-90A rev1 10.1 table 2,
283 * min_entropy_len (in bits) is security_strength.
284 *
285 * (This also matches the sizes used in the NIST test vectors.)
286 */
287 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
288 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
289 32; /* better (256+) -> 256 bits */
290 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100291
Hanno Beckerb98e3262019-08-27 06:47:18 +0100292 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
293 1 /* add nonce */ ) ) != 0 )
294 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100295 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100296 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100297
298 return( 0 );
299}
300
301/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100302 * Set prediction resistance
303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100305 int resistance )
306{
307 ctx->prediction_resistance = resistance;
308}
309
310/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200311 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100312 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100314{
315 ctx->entropy_len = len;
316}
317
318/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100319 * Set reseed interval
320 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100322{
323 ctx->reseed_interval = interval;
324}
325
326/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100327 * HMAC_DRBG random function with optional additional data:
328 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100329 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100331 unsigned char *output, size_t out_len,
332 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100333{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100334 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
336 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100337 size_t left = out_len;
338 unsigned char *out = output;
339
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100340 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
342 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100343
344 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
346 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100347
348 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100349 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100351 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100352 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100354 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100355
356 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100357 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100358
359 /* 2. Use additional data if any */
360 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200361 {
362 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
363 additional, add_len ) ) != 0 )
364 goto exit;
365 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100366
367 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100368 while( left != 0 )
369 {
370 size_t use_len = left > md_len ? md_len : left;
371
Gilles Peskineaadc8182018-09-11 16:54:57 +0200372 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
373 goto exit;
374 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
375 ctx->V, md_len ) ) != 0 )
376 goto exit;
377 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
378 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100379
380 memcpy( out, ctx->V, use_len );
381 out += use_len;
382 left -= use_len;
383 }
384
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200386 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
387 additional, add_len ) ) != 0 )
388 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100389
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100390 /* 7. Update reseed counter */
391 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392
Gilles Peskine4d237572018-09-13 22:19:57 +0200393exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100394 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200395 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100396}
397
398/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100399 * HMAC_DRBG random function
400 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100402{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100403 int ret;
404 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
405
406#if defined(MBEDTLS_THREADING_C)
407 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
408 return( ret );
409#endif
410
411 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
412
413#if defined(MBEDTLS_THREADING_C)
414 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
415 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
416#endif
417
418 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100419}
420
421/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422 * Free an HMAC_DRBG context
423 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100425{
426 if( ctx == NULL )
427 return;
428
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100429#if defined(MBEDTLS_THREADING_C)
430 mbedtls_mutex_free( &ctx->mutex );
431#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100434}
435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436#if defined(MBEDTLS_FS_IO)
437int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100439 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442
443 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100447 goto exit;
448
449 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
450 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100452 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100453 }
454
455 ret = 0;
456
457exit:
458 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100459 mbedtls_zeroize( buf, sizeof( buf ) );
460
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461 return( ret );
462}
463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100466 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467 FILE *f;
468 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470
471 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473
474 fseek( f, 0, SEEK_END );
475 n = (size_t) ftell( f );
476 fseek( f, 0, SEEK_SET );
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 {
480 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100482 }
483
484 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100485 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
486 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200487 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200488
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100489 fclose( f );
490
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100491 mbedtls_zeroize( buf, sizeof( buf ) );
492
493 if( ret != 0 )
494 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100499
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100504/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100506{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200507 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100508 return( 0 );
509}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100510#else
511
512#define OUTPUT_LEN 80
513
514/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000515static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100516 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
517 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
518 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
519 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
520 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
521static const unsigned char result_pr[OUTPUT_LEN] = {
522 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
523 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
524 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
525 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
526 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
527 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
528 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
529
530/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000531static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100532 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
533 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
534 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
535 0xe9, 0x9d, 0xfe, 0xdf };
536static const unsigned char result_nopr[OUTPUT_LEN] = {
537 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
538 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
539 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
540 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
541 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
542 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
543 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
544
545/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100546static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100547static int hmac_drbg_self_test_entropy( void *data,
548 unsigned char *buf, size_t len )
549{
550 const unsigned char *p = data;
551 memcpy( buf, p + test_offset, len );
552 test_offset += len;
553 return( 0 );
554}
555
Paul Bakker7dc4c442014-02-01 22:50:26 +0100556#define CHK( c ) if( (c) != 0 ) \
557 { \
558 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100560 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100561 }
562
563/*
564 * Checkup routine for HMAC_DRBG with SHA-1
565 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200572 mbedtls_hmac_drbg_init( &ctx );
573
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100574 /*
575 * PR = True
576 */
577 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579
580 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200581 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000582 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100583 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
585 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
586 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100587 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100589
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100590 mbedtls_hmac_drbg_free( &ctx );
591
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594
595 /*
596 * PR = False
597 */
598 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100601 mbedtls_hmac_drbg_init( &ctx );
602
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200604 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000605 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
608 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
609 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100612
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100613 mbedtls_hmac_drbg_free( &ctx );
614
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100615 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617
618 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
621 return( 0 );
622}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#endif /* MBEDTLS_SHA1_C */
624#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100625
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626#endif /* MBEDTLS_HMAC_DRBG_C */