blob: 2ce20bc63b57f111fc2eb27c8d1b00183b7f236a [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
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010047 */
48
49/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010050 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010051 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010052 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010053 */
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000056#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#endif
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010062
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/hmac_drbg.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010068#include <stdio.h>
69#endif
70
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#if defined(MBEDTLS_SELF_TEST)
72#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010074#else
Rich Evans00ab4702015-02-06 13:43:58 +000075#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076#define mbedtls_printf printf
77#endif /* MBEDTLS_SELF_TEST */
78#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010079
Paul Bakker34617722014-06-13 17:20:13 +020080/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020082 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
83}
84
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010085/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020086 * HMAC_DRBG context initialization
87 */
88void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
89{
90 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010091
92#if defined(MBEDTLS_THREADING_C)
93 mbedtls_mutex_init( &ctx->mutex );
94#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020095}
96
97/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010098 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200100int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
101 const unsigned char *additional,
102 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100103{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100105 unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
106 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine4d237572018-09-13 22:19:57 +0200108 int ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109
110 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
111 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100112 /* Step 1 or 4 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200113 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
114 goto exit;
115 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
116 ctx->V, md_len ) ) != 0 )
117 goto exit;
118 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
119 sep, 1 ) ) != 0 )
120 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121 if( rounds == 2 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200122 {
123 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
124 additional, add_len ) ) != 0 )
125 goto exit;
126 }
127 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
128 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100129
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100130 /* Step 2 or 5 */
Gilles Peskine4d237572018-09-13 22:19:57 +0200131 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
132 goto exit;
133 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
134 ctx->V, md_len ) ) != 0 )
135 goto exit;
136 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
137 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100138 }
Gilles Peskine1da77762018-09-11 15:35:41 +0200139
Gilles Peskine4d237572018-09-13 22:19:57 +0200140exit:
Gilles Peskine1da77762018-09-11 15:35:41 +0200141 mbedtls_zeroize( K, sizeof( K ) );
Gilles Peskine4d237572018-09-13 22:19:57 +0200142 return( ret );
143}
144
145void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
146 const unsigned char *additional,
147 size_t add_len )
148{
149 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100150}
151
152/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100153 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100154 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200155int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100157 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100158{
159 int ret;
160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100162 return( ret );
163
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100164 /*
165 * Set initial working state.
166 * Use the V memory location, which is currently all 0, to initialize the
167 * MD context with an all-zero key. Then set V to its initial value.
168 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200169 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
170 mbedtls_md_get_size( md_info ) ) ) != 0 )
171 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100173
Gilles Peskine4d237572018-09-13 22:19:57 +0200174 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
175 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100176
177 return( 0 );
178}
179
180/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100181 * Internal function used both for seeding and reseeding the DRBG.
182 * Comments starting with arabic numbers refer to section 10.1.2.4
183 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100184 */
Hanno Beckerb98e3262019-08-27 06:47:18 +0100185static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
186 const unsigned char *additional, size_t len,
187 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100188{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckerb98e3262019-08-27 06:47:18 +0100190 size_t seedlen = 0;
Gilles Peskine4d237572018-09-13 22:19:57 +0200191 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100192
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100193 {
Hanno Beckerb98e3262019-08-27 06:47:18 +0100194 size_t total_entropy_len;
195
196 if( use_nonce == 0 )
197 total_entropy_len = ctx->entropy_len;
198 else
199 total_entropy_len = ctx->entropy_len * 3 / 2;
200
201 /* III. Check input length */
202 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
203 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
204 {
205 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
206 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100207 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100210
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100211 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200212 if( ( ret = ctx->f_entropy( ctx->p_entropy,
213 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckerb98e3262019-08-27 06:47:18 +0100214 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100216 }
217 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100218
Hanno Beckerb98e3262019-08-27 06:47:18 +0100219 /* For initial seeding, allow adding of nonce generated
220 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
221 if( use_nonce )
222 {
223 /* Note: We don't merge the two calls to f_entropy() in order
224 * to avoid requesting too much entropy from f_entropy()
225 * at once. Specifically, if the underlying digest is not
226 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
227 * is larger than the maximum of 32 Bytes that our own
228 * entropy source implementation can emit in a single
229 * call in configurations disabling SHA-512. */
230 if( ( ret = ctx->f_entropy( ctx->p_entropy,
231 seed + seedlen,
232 ctx->entropy_len / 2 ) ) != 0 )
233 {
234 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
235 }
236
237 seedlen += ctx->entropy_len / 2;
238 }
239
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100240
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100241 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100242 if( additional != NULL && len != 0 )
243 {
244 memcpy( seed + seedlen, additional, len );
245 seedlen += len;
246 }
247
248 /* 2. Update state */
Gilles Peskine4d237572018-09-13 22:19:57 +0200249 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
250 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100251
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100252 /* 3. Reset reseed_counter */
253 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100254
Gilles Peskine4d237572018-09-13 22:19:57 +0200255exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100256 /* 4. Done */
Gilles Peskine1da77762018-09-11 15:35:41 +0200257 mbedtls_zeroize( seed, seedlen );
Gilles Peskine4d237572018-09-13 22:19:57 +0200258 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100259}
260
261/*
Hanno Beckerb98e3262019-08-27 06:47:18 +0100262 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
263 */
264int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
265 const unsigned char *additional, size_t len )
266{
267 return( hmac_drbg_reseed_core( ctx, additional, len, 0 ) );
268}
269
270/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100271 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckerb98e3262019-08-27 06:47:18 +0100272 *
273 * The nonce is not passed as a separate parameter but extracted
274 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100275 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200276int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 const mbedtls_md_info_t * md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100278 int (*f_entropy)(void *, unsigned char *, size_t),
279 void *p_entropy,
280 const unsigned char *custom,
281 size_t len )
282{
283 int ret;
Hanno Beckerb98e3262019-08-27 06:47:18 +0100284 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100287 return( ret );
288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100290
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100291 /*
292 * Set initial working state.
293 * Use the V memory location, which is currently all 0, to initialize the
294 * MD context with an all-zero key. Then set V to its initial value.
295 */
Gilles Peskineaadc8182018-09-11 16:54:57 +0200296 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
297 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100298 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100299
300 ctx->f_entropy = f_entropy;
301 ctx->p_entropy = p_entropy;
302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100304
Gilles Peskine9c742242019-10-04 11:47:35 +0200305 if( ctx->entropy_len == 0 )
306 {
307 /*
308 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
309 * each hash function, then according to SP800-90A rev1 10.1 table 2,
310 * min_entropy_len (in bits) is security_strength.
311 *
312 * (This also matches the sizes used in the NIST test vectors.)
313 */
314 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
315 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
316 32; /* better (256+) -> 256 bits */
317 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100318
Hanno Beckerb98e3262019-08-27 06:47:18 +0100319 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len,
320 1 /* add nonce */ ) ) != 0 )
321 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100322 return( ret );
Hanno Beckerb98e3262019-08-27 06:47:18 +0100323 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100324
325 return( 0 );
326}
327
328/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100329 * Set prediction resistance
330 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100332 int resistance )
333{
334 ctx->prediction_resistance = resistance;
335}
336
337/*
Gilles Peskine9c742242019-10-04 11:47:35 +0200338 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100339 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100341{
342 ctx->entropy_len = len;
343}
344
345/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100346 * Set reseed interval
347 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100349{
350 ctx->reseed_interval = interval;
351}
352
353/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100354 * HMAC_DRBG random function with optional additional data:
355 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100358 unsigned char *output, size_t out_len,
359 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100360{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100361 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
363 size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100364 size_t left = out_len;
365 unsigned char *out = output;
366
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100367 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
369 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100370
371 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
373 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100374
375 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100376 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100378 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100379 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100381 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100382
383 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100384 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385
386 /* 2. Use additional data if any */
387 if( additional != NULL && add_len != 0 )
Gilles Peskine4d237572018-09-13 22:19:57 +0200388 {
389 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
390 additional, add_len ) ) != 0 )
391 goto exit;
392 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100393
394 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100395 while( left != 0 )
396 {
397 size_t use_len = left > md_len ? md_len : left;
398
Gilles Peskineaadc8182018-09-11 16:54:57 +0200399 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
400 goto exit;
401 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
402 ctx->V, md_len ) ) != 0 )
403 goto exit;
404 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
405 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100406
407 memcpy( out, ctx->V, use_len );
408 out += use_len;
409 left -= use_len;
410 }
411
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100412 /* 6. Update */
Gilles Peskine4d237572018-09-13 22:19:57 +0200413 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
414 additional, add_len ) ) != 0 )
415 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100416
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100417 /* 7. Update reseed counter */
418 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100419
Gilles Peskine4d237572018-09-13 22:19:57 +0200420exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100421 /* 8. Done */
Gilles Peskine4d237572018-09-13 22:19:57 +0200422 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423}
424
425/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100426 * HMAC_DRBG random function
427 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100429{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100430 int ret;
431 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
432
433#if defined(MBEDTLS_THREADING_C)
434 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
435 return( ret );
436#endif
437
438 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
439
440#if defined(MBEDTLS_THREADING_C)
441 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
442 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
443#endif
444
445 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100446}
447
448/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100449 * Free an HMAC_DRBG context
450 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100452{
453 if( ctx == NULL )
454 return;
455
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100456#if defined(MBEDTLS_THREADING_C)
457 mbedtls_mutex_free( &ctx->mutex );
458#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_md_free( &ctx->md_ctx );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100461}
462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200463#if defined(MBEDTLS_FS_IO)
464int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100465{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100466 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100469
470 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474 goto exit;
475
476 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
477 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100479 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100480 }
481
482 ret = 0;
483
484exit:
485 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100486 mbedtls_zeroize( buf, sizeof( buf ) );
487
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100488 return( ret );
489}
490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100493 int ret = 0;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494 FILE *f;
495 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497
498 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500
501 fseek( f, 0, SEEK_END );
502 n = (size_t) ftell( f );
503 fseek( f, 0, SEEK_SET );
504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100506 {
507 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100509 }
510
511 if( fread( buf, 1, n, f ) != n )
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100512 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
513 else
Gilles Peskine4d237572018-09-13 22:19:57 +0200514 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
Gilles Peskineaadc8182018-09-11 16:54:57 +0200515
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100516 fclose( f );
517
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100518 mbedtls_zeroize( buf, sizeof( buf ) );
519
520 if( ret != 0 )
521 return( ret );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100524}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100526
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100531/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100533{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200534 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100535 return( 0 );
536}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100537#else
538
539#define OUTPUT_LEN 80
540
541/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000542static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100543 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
544 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
545 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
546 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
547 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
548static const unsigned char result_pr[OUTPUT_LEN] = {
549 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
550 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
551 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
552 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
553 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
554 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
555 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
556
557/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000558static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100559 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
560 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
561 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
562 0xe9, 0x9d, 0xfe, 0xdf };
563static const unsigned char result_nopr[OUTPUT_LEN] = {
564 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
565 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
566 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
567 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
568 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
569 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
570 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
571
572/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100573static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100574static int hmac_drbg_self_test_entropy( void *data,
575 unsigned char *buf, size_t len )
576{
577 const unsigned char *p = data;
578 memcpy( buf, p + test_offset, len );
579 test_offset += len;
580 return( 0 );
581}
582
Paul Bakker7dc4c442014-02-01 22:50:26 +0100583#define CHK( c ) if( (c) != 0 ) \
584 { \
585 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100587 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588 }
589
590/*
591 * Checkup routine for HMAC_DRBG with SHA-1
592 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100596 unsigned char buf[OUTPUT_LEN];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200599 mbedtls_hmac_drbg_init( &ctx );
600
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601 /*
602 * PR = True
603 */
604 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100606
607 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200608 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000609 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
612 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
613 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100616
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100617 mbedtls_hmac_drbg_free( &ctx );
618
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100619 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100621
622 /*
623 * PR = False
624 */
625 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200626 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100627
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100628 mbedtls_hmac_drbg_init( &ctx );
629
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100630 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200631 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000632 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100633 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
635 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
636 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100637 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100639
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100640 mbedtls_hmac_drbg_free( &ctx );
641
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644
645 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100647
648 return( 0 );
649}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_SHA1_C */
651#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#endif /* MBEDTLS_HMAC_DRBG_C */