blob: f811885c9f87660ada000b6ac183f910921fb081 [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010020 */
21
22/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010025 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010026 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000038#include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010043#include <stdio.h>
44#endif
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_SELF_TEST)
47#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010049#else
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
52#endif /* MBEDTLS_SELF_TEST */
53#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010054
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010055/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020056 * HMAC_DRBG context initialization
57 */
58void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
59{
60 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010061
62#if defined(MBEDTLS_THREADING_C)
63 mbedtls_mutex_init( &ctx->mutex );
64#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020065}
66
67/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010068 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010069 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020070int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
71 const unsigned char *additional,
72 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010073{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
76 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020078 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010079
80 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
81 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010082 /* Step 1 or 4 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020083 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
84 goto exit;
85 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
86 ctx->V, md_len ) ) != 0 )
87 goto exit;
88 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
89 sep, 1 ) ) != 0 )
90 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010091 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092 {
93 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
94 additional, add_len ) ) != 0 )
95 goto exit;
96 }
97 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
98 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100100 /* Step 2 or 5 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200101 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
102 goto exit;
103 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
104 ctx->V, md_len ) ) != 0 )
105 goto exit;
106 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
107 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100108 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200109
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200110exit:
Gilles Peskineafa80372018-09-11 15:35:41 +0200111 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200112 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100113}
114
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200115#if !defined(MBEDTLS_DEPRECATED_REMOVED)
116void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
117 const unsigned char *additional,
118 size_t add_len )
119{
120 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
121}
122#endif /* MBEDTLS_DEPRECATED_REMOVED */
123
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100124/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100125 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200127int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100129 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130{
Janos Follath24eed8d2019-11-22 13:21:35 +0000131 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100134 return( ret );
135
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100136 /*
137 * Set initial working state.
138 * Use the V memory location, which is currently all 0, to initialize the
139 * MD context with an all-zero key. Then set V to its initial value.
140 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200141 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
142 mbedtls_md_get_size( md_info ) ) ) != 0 )
143 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100145
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200146 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
147 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148
149 return( 0 );
150}
151
152/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153 * Internal function used both for seeding and reseeding the DRBG.
154 * Comments starting with arabic numbers refer to section 10.1.2.4
155 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100156 */
Hanno Beckera823d4c2019-08-27 06:47:18 +0100157static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
158 const unsigned char *additional, size_t len,
159 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100160{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100162 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000163 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100164
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100165 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100166 size_t total_entropy_len;
167
168 if( use_nonce == 0 )
169 total_entropy_len = ctx->entropy_len;
170 else
171 total_entropy_len = ctx->entropy_len * 3 / 2;
172
173 /* III. Check input length */
174 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
175 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
176 {
177 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
178 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100179 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100182
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100183 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200184 if( ( ret = ctx->f_entropy( ctx->p_entropy,
185 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckera823d4c2019-08-27 06:47:18 +0100186 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100188 }
189 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190
Hanno Beckera823d4c2019-08-27 06:47:18 +0100191 /* For initial seeding, allow adding of nonce generated
192 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
193 if( use_nonce )
194 {
195 /* Note: We don't merge the two calls to f_entropy() in order
196 * to avoid requesting too much entropy from f_entropy()
197 * at once. Specifically, if the underlying digest is not
198 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
199 * is larger than the maximum of 32 Bytes that our own
200 * entropy source implementation can emit in a single
201 * call in configurations disabling SHA-512. */
202 if( ( ret = ctx->f_entropy( ctx->p_entropy,
203 seed + seedlen,
204 ctx->entropy_len / 2 ) ) != 0 )
205 {
206 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
207 }
208
209 seedlen += ctx->entropy_len / 2;
210 }
211
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100212
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100213 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214 if( additional != NULL && len != 0 )
215 {
216 memcpy( seed + seedlen, additional, len );
217 seedlen += len;
218 }
219
220 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200221 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
222 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100223
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100224 /* 3. Reset reseed_counter */
225 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100226
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200227exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100228 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200229 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200230 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100231}
232
233/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100234 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
235 */
236int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
237 const unsigned char *additional, size_t len )
238{
239 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
240}
241
242/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100243 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100244 *
245 * The nonce is not passed as a separate parameter but extracted
246 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100247 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200248int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100250 int (*f_entropy)(void *, unsigned char *, size_t),
251 void *p_entropy,
252 const unsigned char *custom,
253 size_t len )
254{
Janos Follath24eed8d2019-11-22 13:21:35 +0000255 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100256 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100257
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100259 return( ret );
260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100262
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100263 /*
264 * Set initial working state.
265 * Use the V memory location, which is currently all 0, to initialize the
266 * MD context with an all-zero key. Then set V to its initial value.
267 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200268 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
269 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100270 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100271
272 ctx->f_entropy = f_entropy;
273 ctx->p_entropy = p_entropy;
274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100276
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200277 if( ctx->entropy_len == 0 )
278 {
279 /*
280 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
281 * each hash function, then according to SP800-90A rev1 10.1 table 2,
282 * min_entropy_len (in bits) is security_strength.
283 *
284 * (This also matches the sizes used in the NIST test vectors.)
285 */
286 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
287 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
288 32; /* better (256+) -> 256 bits */
289 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100290
Hanno Beckera823d4c2019-08-27 06:47:18 +0100291 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
292 1 /* add nonce */ ) ) != 0 )
293 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100294 return( ret );
Hanno Beckera823d4c2019-08-27 06:47:18 +0100295 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100296
297 return( 0 );
298}
299
300/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100301 * Set prediction resistance
302 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100304 int resistance )
305{
306 ctx->prediction_resistance = resistance;
307}
308
309/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200310 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100311 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100313{
314 ctx->entropy_len = len;
315}
316
317/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100318 * Set reseed interval
319 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100321{
322 ctx->reseed_interval = interval;
323}
324
325/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100326 * HMAC_DRBG random function with optional additional data:
327 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100330 unsigned char *output, size_t out_len,
331 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100332{
Janos Follath24eed8d2019-11-22 13:21:35 +0000333 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
335 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100336 size_t left = out_len;
337 unsigned char *out = output;
338
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100339 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
341 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100342
343 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
345 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100346
347 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100348 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100350 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100351 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100353 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100354
355 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100356 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100357
358 /* 2. Use additional data if any */
359 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200360 {
361 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
362 additional, add_len ) ) != 0 )
363 goto exit;
364 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100365
366 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100367 while( left != 0 )
368 {
369 size_t use_len = left > md_len ? md_len : left;
370
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200371 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
372 goto exit;
373 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
374 ctx->V, md_len ) ) != 0 )
375 goto exit;
376 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
377 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100378
379 memcpy( out, ctx->V, use_len );
380 out += use_len;
381 left -= use_len;
382 }
383
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100384 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200385 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
386 additional, add_len ) ) != 0 )
387 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100388
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100389 /* 7. Update reseed counter */
390 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100391
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200392exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100393 /* 8. Done */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200394 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100395}
396
397/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100398 * HMAC_DRBG random function
399 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100401{
Janos Follath24eed8d2019-11-22 13:21:35 +0000402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100403 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
404
405#if defined(MBEDTLS_THREADING_C)
406 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
407 return( ret );
408#endif
409
410 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
411
412#if defined(MBEDTLS_THREADING_C)
413 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
414 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
415#endif
416
417 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100418}
419
420/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421 * Free an HMAC_DRBG context
422 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100424{
425 if( ctx == NULL )
426 return;
427
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100428#if defined(MBEDTLS_THREADING_C)
429 mbedtls_mutex_free( &ctx->mutex );
430#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500432 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100433}
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435#if defined(MBEDTLS_FS_IO)
436int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100437{
Janos Follath24eed8d2019-11-22 13:21:35 +0000438 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100439 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100441
442 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100446 goto exit;
447
448 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
449 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100451 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452 }
453
454 ret = 0;
455
456exit:
457 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500458 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100459
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460 return( ret );
461}
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100465 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200466 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200469 unsigned char c;
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
Gilles Peskine82204662018-09-11 18:43:09 +0200474 n = fread( buf, 1, sizeof( buf ), f );
475 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476 {
Gilles Peskine82204662018-09-11 18:43:09 +0200477 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
478 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 }
Gilles Peskine82204662018-09-11 18:43:09 +0200480 if( n == 0 || ferror( f ) )
481 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100482 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200483 goto exit;
484 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100485 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200486 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100487
Gilles Peskine82204662018-09-11 18:43:09 +0200488 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
489
490exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500491 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200492 if( f != NULL )
493 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100494 if( ret != 0 )
495 return( ret );
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 */