blob: 824b009e16eb96564ca22da59b3c49a30143887c [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"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010042#include <stdio.h>
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_SELF_TEST)
46#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#define mbedtls_printf printf
51#endif /* MBEDTLS_SELF_TEST */
52#endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Arto Kinnunen5b366932019-11-20 16:13:13 +020054#define HMAC_NONCE_YES 0x4AAAAAAA
55#define HMAC_NONCE_NO 0x75555555
56
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010057/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020058 * HMAC_DRBG context initialization
59 */
60void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx )
61{
62 memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010063
64#if defined(MBEDTLS_THREADING_C)
65 mbedtls_mutex_init( &ctx->mutex );
66#endif
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020067}
68
69/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010070 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071 */
Gilles Peskinee0e9c572018-09-11 16:47:16 +020072int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
73 const unsigned char *additional,
74 size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075{
Hanno Beckerd3827c72019-09-03 12:56:37 +010076 size_t md_len = mbedtls_md_get_size(
77 mbedtls_md_get_handle( &ctx->md_ctx ) );
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];
Arto Kinnunen5b366932019-11-20 16:13:13 +020080 volatile unsigned char flow_counter = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Arto Kinnunen5b366932019-11-20 16:13:13 +020082 int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010083
84 for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
85 {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010086 /* Step 1 or 4 */
Arto Kinnunen5b366932019-11-20 16:13:13 +020087 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +020088 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
89 goto exit;
Arto Kinnunen5b366932019-11-20 16:13:13 +020090
91 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
93 ctx->V, md_len ) ) != 0 )
94 goto exit;
Arto Kinnunen5b366932019-11-20 16:13:13 +020095
96 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
98 sep, 1 ) ) != 0 )
99 goto exit;
Arto Kinnunen5b366932019-11-20 16:13:13 +0200100
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100101 if( rounds == 2 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200102 {
Arto Kinnunen5b366932019-11-20 16:13:13 +0200103 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200104 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
105 additional, add_len ) ) != 0 )
106 goto exit;
107 }
Arto Kinnunen5b366932019-11-20 16:13:13 +0200108
109 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200110 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, K ) ) != 0 )
111 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100112
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100113 /* Step 2 or 5 */
Arto Kinnunen5b366932019-11-20 16:13:13 +0200114 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200115 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ) ) != 0 )
116 goto exit;
Arto Kinnunen5b366932019-11-20 16:13:13 +0200117
118 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200119 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
120 ctx->V, md_len ) ) != 0 )
121 goto exit;
Arto Kinnunen5b366932019-11-20 16:13:13 +0200122
123 flow_counter++;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200124 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
125 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100126 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200127
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200128exit:
Arto Kinnunen5b366932019-11-20 16:13:13 +0200129
130 if( ret == 0 )
131 {
132 ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
133 /* Check for possible attack.
134 * Counters needs to have correct values when returning success
135 */
136 if ( ( ( flow_counter == 7 ) && ( sep[0] == 1 ) ) ||
137 ( ( flow_counter == 16 ) && ( sep[0] == 2 ) ) )
138 {
139 flow_counter = flow_counter - sep[0];
140 // Double check flow_counter
141 if ( ( flow_counter == 6 ) || ( flow_counter == 14 ) )
142 {
143 ret = 0;
144 }
145 }
146 }
147
Gilles Peskineafa80372018-09-11 15:35:41 +0200148 mbedtls_platform_zeroize( K, sizeof( K ) );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200149 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100150}
151
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200152#if !defined(MBEDTLS_DEPRECATED_REMOVED)
153void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx,
154 const unsigned char *additional,
155 size_t add_len )
156{
157 (void) mbedtls_hmac_drbg_update_ret( ctx, additional, add_len );
158}
159#endif /* MBEDTLS_DEPRECATED_REMOVED */
160
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100161/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100162 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100163 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200164int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
Arto Kinnunen5b366932019-11-20 16:13:13 +0200165 mbedtls_md_handle_t md_info,
166 const unsigned char *data, size_t data_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100167{
Arto Kinnunen5b366932019-11-20 16:13:13 +0200168 int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100171 return( ret );
172
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100173 /*
174 * Set initial working state.
175 * Use the V memory location, which is currently all 0, to initialize the
176 * MD context with an all-zero key. Then set V to its initial value.
177 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200178 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V,
179 mbedtls_md_get_size( md_info ) ) ) != 0 )
180 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100182
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200183 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, data, data_len ) ) != 0 )
184 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100185
Arto Kinnunen5b366932019-11-20 16:13:13 +0200186 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100187}
188
Hanno Becker31c95e12019-08-27 09:22:09 +0100189/*
190 * Internal function used both for seeding and reseeding the DRBG.
191 * Comments starting with arabic numbers refer to section 10.1.2.4
192 * of SP800-90A, while roman numbers refer to section 9.2.
193 */
Hanno Beckerb3a06e62019-08-27 09:21:44 +0100194static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
195 const unsigned char *additional, size_t len,
196 int use_nonce )
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100197{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckereab304c2019-08-26 15:29:14 +0100199 size_t seedlen = 0;
Arto Kinnunen5b366932019-11-20 16:13:13 +0200200 size_t total_entropy_len;
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200201 int ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100202
Arto Kinnunen5b366932019-11-20 16:13:13 +0200203 if( use_nonce == HMAC_NONCE_NO )
204 total_entropy_len = ctx->entropy_len;
205 else
206 total_entropy_len = ctx->entropy_len * 3 / 2;
207
208 /* III. Check input length */
209 if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
210 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT )
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100211 {
Arto Kinnunen5b366932019-11-20 16:13:13 +0200212 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100213 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100216
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100217 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200218 if( ( ret = ctx->f_entropy( ctx->p_entropy,
219 seed, ctx->entropy_len ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100220 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200221 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
Hanno Beckereab304c2019-08-26 15:29:14 +0100222 }
223 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100224
Hanno Becker31c95e12019-08-27 09:22:09 +0100225 /* For initial seeding, allow adding of nonce generated
226 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Arto Kinnunen5b366932019-11-20 16:13:13 +0200227 if( use_nonce == HMAC_NONCE_YES )
Hanno Beckereab304c2019-08-26 15:29:14 +0100228 {
229 /* Note: We don't merge the two calls to f_entropy() in order
230 * to avoid requesting too much entropy from f_entropy()
231 * at once. Specifically, if the underlying digest is not
232 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
233 * is larger than the maximum of 32 Bytes that our own
234 * entropy source implementation can emit in a single
235 * call in configurations disabling SHA-512. */
236 if( ( ret = ctx->f_entropy( ctx->p_entropy,
237 seed + seedlen,
238 ctx->entropy_len / 2 ) ) != 0 )
239 {
240 return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED );
241 }
242
243 seedlen += ctx->entropy_len / 2;
244 }
245
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100246
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100247 /* 1. Concatenate entropy and additional data if any */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100248 if( additional != NULL && len != 0 )
249 {
Teppo Järvelin91d79382019-10-02 09:09:31 +0300250 mbedtls_platform_memcpy( seed + seedlen, additional, len );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100251 seedlen += len;
252 }
253
254 /* 2. Update state */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200255 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx, seed, seedlen ) ) != 0 )
256 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100257
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100258 /* 3. Reset reseed_counter */
259 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100260
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200261exit:
Arto Kinnunen5b366932019-11-20 16:13:13 +0200262 if (ret == 0 && ctx->reseed_counter != 1)
263 {
264 /* Illegal condition, possible attack detected */
265 ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
266 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100267 /* 4. Done */
Gilles Peskineafa80372018-09-11 15:35:41 +0200268 mbedtls_platform_zeroize( seed, seedlen );
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200269 return( ret );
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100270}
271
272/*
Hanno Becker31c95e12019-08-27 09:22:09 +0100273 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
Hanno Beckereab304c2019-08-26 15:29:14 +0100274 */
275int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx,
276 const unsigned char *additional, size_t len )
277{
Arto Kinnunen5b366932019-11-20 16:13:13 +0200278 return( hmac_drbg_reseed_core( ctx, additional, len, HMAC_NONCE_NO ) );
Hanno Beckereab304c2019-08-26 15:29:14 +0100279}
280
281/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100282 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Becker31c95e12019-08-27 09:22:09 +0100283 *
284 * The nonce is not passed as a separate parameter but extracted
285 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100286 */
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200287int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100288 mbedtls_md_handle_t md_info,
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100289 int (*f_entropy)(void *, unsigned char *, size_t),
290 void *p_entropy,
291 const unsigned char *custom,
292 size_t len )
293{
294 int ret;
Hanno Beckereab304c2019-08-26 15:29:14 +0100295 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100298 return( ret );
299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 md_size = mbedtls_md_get_size( md_info );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100301
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100302 /*
303 * Set initial working state.
304 * Use the V memory location, which is currently all 0, to initialize the
305 * MD context with an all-zero key. Then set V to its initial value.
306 */
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200307 if( ( ret = mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ) ) != 0 )
308 return( ret );
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100309 memset( ctx->V, 0x01, md_size );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100310
311 ctx->f_entropy = f_entropy;
312 ctx->p_entropy = p_entropy;
313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100315
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100316 /*
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100317 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
318 * each hash function, then according to SP800-90A rev1 10.1 table 2,
319 * min_entropy_len (in bits) is security_strength.
320 *
321 * (This also matches the sizes used in the NIST test vectors.)
322 */
Hanno Beckereab304c2019-08-26 15:29:14 +0100323 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
324 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
325 32; /* better (256+) -> 256 bits */
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100326
Arto Kinnunen5b366932019-11-20 16:13:13 +0200327 if( ( ret = hmac_drbg_reseed_core( ctx, custom, len, HMAC_NONCE_YES ) ) != 0 )
Hanno Beckereab304c2019-08-26 15:29:14 +0100328 {
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100329 return( ret );
Hanno Beckereab304c2019-08-26 15:29:14 +0100330 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100331
Arto Kinnunen5b366932019-11-20 16:13:13 +0200332 return( ret );
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100333}
334
335/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100336 * Set prediction resistance
337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx,
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100339 int resistance )
340{
341 ctx->prediction_resistance = resistance;
342}
343
344/*
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100345 * Set entropy length grabbed for reseeds
346 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len )
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100348{
349 ctx->entropy_len = len;
350}
351
352/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100353 * Set reseed interval
354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval )
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100356{
357 ctx->reseed_interval = interval;
358}
359
360/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100361 * HMAC_DRBG random function with optional additional data:
362 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100363 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364int mbedtls_hmac_drbg_random_with_add( void *p_rng,
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100365 unsigned char *output, size_t out_len,
366 const unsigned char *additional, size_t add_len )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100367{
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100368 int ret;
Arto Kinnunen5b366932019-11-20 16:13:13 +0200369 volatile unsigned char *output_fi = output;
370 volatile size_t out_len_fi = out_len;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
Hanno Beckerd3827c72019-09-03 12:56:37 +0100372 size_t md_len = mbedtls_md_get_size(
373 mbedtls_md_get_handle( &ctx->md_ctx ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100374 size_t left = out_len;
375 unsigned char *out = output;
376
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100377 /* II. Check request length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST )
379 return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100380
381 /* III. Check input length */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200382 if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT )
383 return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100384
385 /* 1. (aka VII and IX) Check reseed counter and PR */
Manuel Pégourié-Gonnardefc8d802014-01-30 19:36:22 +0100386 if( ctx->f_entropy != NULL && /* For no-reseeding instances */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100388 ctx->reseed_counter > ctx->reseed_interval ) )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100389 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 )
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100391 return( ret );
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100392
393 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100394 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395
396 /* 2. Use additional data if any */
397 if( additional != NULL && add_len != 0 )
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200398 {
399 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
400 additional, add_len ) ) != 0 )
401 goto exit;
402 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100403
404 /* 3, 4, 5. Generate bytes */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100405 while( left != 0 )
406 {
407 size_t use_len = left > md_len ? md_len : left;
408
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200409 if( ( ret = mbedtls_md_hmac_reset( &ctx->md_ctx ) ) != 0 )
410 goto exit;
411 if( ( ret = mbedtls_md_hmac_update( &ctx->md_ctx,
412 ctx->V, md_len ) ) != 0 )
413 goto exit;
414 if( ( ret = mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ) ) != 0 )
415 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100416
Teppo Järvelin91d79382019-10-02 09:09:31 +0300417 mbedtls_platform_memcpy( out, ctx->V, use_len );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100418 out += use_len;
419 left -= use_len;
420 }
421
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100422 /* 6. Update */
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200423 if( ( ret = mbedtls_hmac_drbg_update_ret( ctx,
424 additional, add_len ) ) != 0 )
425 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100426
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100427 /* 7. Update reseed counter */
428 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100429
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200430exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100431 /* 8. Done */
Arto Kinnunen5b366932019-11-20 16:13:13 +0200432
433 if (ret == 0)
434 {
435 /*
436 * Check doubled variables and illegal conditions in case of possible
437 * attack.
438 */
439 ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
440 if ( ( out_len_fi == out_len ) && ( output_fi == output) &&
441 ( left == 0 ) )
442 {
443 ret = 0;
444 }
445 }
446
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200447 return( ret );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100448}
449
450/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100451 * HMAC_DRBG random function
452 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100454{
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100455 int ret;
456 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
457
458#if defined(MBEDTLS_THREADING_C)
459 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
460 return( ret );
461#endif
462
463 ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 );
464
465#if defined(MBEDTLS_THREADING_C)
466 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
467 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
468#endif
469
470 return( ret );
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100471}
472
473/*
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100474 * Free an HMAC_DRBG context
475 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100477{
478 if( ctx == NULL )
479 return;
480
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100481#if defined(MBEDTLS_THREADING_C)
482 mbedtls_mutex_free( &ctx->mutex );
483#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_md_free( &ctx->md_ctx );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500485 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) );
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100486}
487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_FS_IO)
489int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100490{
Manuel Pégourié-Gonnard446ee662014-02-01 10:02:32 +0100491 int ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100492 FILE *f;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100494
495 if( ( f = fopen( path, "wb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100499 goto exit;
500
501 if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) )
502 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100504 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100505 }
506
507 ret = 0;
508
509exit:
510 fclose( f );
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500511 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100512
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100513 return( ret );
514}
515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100517{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100518 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200519 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100520 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
Gilles Peskine82204662018-09-11 18:43:09 +0200522 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100523
524 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100526
Gilles Peskine82204662018-09-11 18:43:09 +0200527 n = fread( buf, 1, sizeof( buf ), f );
528 if( fread( &c, 1, 1, f ) != 0 )
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100529 {
Gilles Peskine82204662018-09-11 18:43:09 +0200530 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
531 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100532 }
Gilles Peskine82204662018-09-11 18:43:09 +0200533 if( n == 0 || ferror( f ) )
534 {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100535 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200536 goto exit;
537 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100538 fclose( f );
Gilles Peskine82204662018-09-11 18:43:09 +0200539 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100540
Gilles Peskine82204662018-09-11 18:43:09 +0200541 ret = mbedtls_hmac_drbg_update_ret( ctx, buf, n );
542
543exit:
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500544 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Gilles Peskine82204662018-09-11 18:43:09 +0200545 if( f != NULL )
546 fclose( f );
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100547 if( ret != 0 )
548 return( ret );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549 return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) );
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100550}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100552
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200554#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557/* Dummy checkup routine */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100559{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200560 (void) verbose;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100561 return( 0 );
562}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563#else
564
565#define OUTPUT_LEN 80
566
567/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000568static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
570 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
571 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
572 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
573 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 };
574static const unsigned char result_pr[OUTPUT_LEN] = {
575 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
576 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
577 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
578 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
579 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
580 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
581 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 };
582
583/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000584static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
586 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
587 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
588 0xe9, 0x9d, 0xfe, 0xdf };
589static const unsigned char result_nopr[OUTPUT_LEN] = {
590 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
591 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
592 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
593 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
594 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
595 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
596 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 };
597
598/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100599static size_t test_offset;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100600static int hmac_drbg_self_test_entropy( void *data,
601 unsigned char *buf, size_t len )
602{
603 const unsigned char *p = data;
Teppo Järvelinb5c46712019-10-04 13:35:55 +0300604 memcpy( buf, p + test_offset, len );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605 test_offset += len;
606 return( 0 );
607}
608
Paul Bakker7dc4c442014-02-01 22:50:26 +0100609#define CHK( c ) if( (c) != 0 ) \
610 { \
611 if( verbose != 0 ) \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_printf( "failed\n" ); \
Paul Bakker7dc4c442014-02-01 22:50:26 +0100613 return( 1 ); \
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100614 }
615
616/*
617 * Checkup routine for HMAC_DRBG with SHA-1
618 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200619int mbedtls_hmac_drbg_self_test( int verbose )
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100622 unsigned char buf[OUTPUT_LEN];
Hanno Beckera5cedbc2019-07-17 11:21:02 +0100623 mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100624
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200625 mbedtls_hmac_drbg_init( &ctx );
626
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100627 /*
628 * PR = True
629 */
630 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_printf( " HMAC_DRBG (PR = True) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100632
633 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200634 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000635 hmac_drbg_self_test_entropy, (void *) entropy_pr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100636 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
638 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
639 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100640 CHK( memcmp( buf, result_pr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100643 mbedtls_hmac_drbg_free( &ctx );
644
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100645 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100647
648 /*
649 * PR = False
650 */
651 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652 mbedtls_printf( " HMAC_DRBG (PR = False) : " );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100653
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100654 mbedtls_hmac_drbg_init( &ctx );
655
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100656 test_offset = 0;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200657 CHK( mbedtls_hmac_drbg_seed( &ctx, md_info,
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000658 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100659 NULL, 0 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) );
661 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
662 CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100663 CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 mbedtls_hmac_drbg_free( &ctx );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100665
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100666 mbedtls_hmac_drbg_free( &ctx );
667
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100668 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_printf( "passed\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100670
671 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 mbedtls_printf( "\n" );
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100673
674 return( 0 );
675}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676#endif /* MBEDTLS_SHA1_C */
677#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679#endif /* MBEDTLS_HMAC_DRBG_C */