blob: aa5597fce2cccbf6f37cae68ed10ef56de38772f [file] [log] [blame]
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01001/*
2 * HMAC_DRBG implementation (NIST SP 800-90)
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 */
19
20/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010021 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010022 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010023 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010024 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010029
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020030# include "mbedtls/hmac_drbg.h"
31# include "mbedtls/platform_util.h"
32# include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020034# include <string.h>
Rich Evans00ab4702015-02-06 13:43:58 +000035
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020036# if defined(MBEDTLS_FS_IO)
37# include <stdio.h>
38# endif
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040# if defined(MBEDTLS_SELF_TEST)
41# if defined(MBEDTLS_PLATFORM_C)
42# include "mbedtls/platform.h"
43# else
44# include <stdio.h>
45# define mbedtls_printf printf
46# endif /* MBEDTLS_SELF_TEST */
47# endif /* MBEDTLS_PLATFORM_C */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050 * HMAC_DRBG context initialization
51 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020052void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020053{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020054 memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context));
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010055
Gavin Acquroff6aceb512020-03-01 17:06:11 -080056 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020057}
58
59/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010060 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010061 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020062int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
63 const unsigned char *additional,
64 size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010065{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020066 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
67 unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010068 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020070 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010071
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020072 for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010073 /* Step 1 or 4 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020074 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020075 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020076 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, ctx->V, md_len)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020077 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020078 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, sep, 1)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020079 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 if (rounds == 2) {
81 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, additional,
82 add_len)) != 0)
83 goto exit;
Gilles Peskinee0e9c572018-09-11 16:47:16 +020084 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020085 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020086 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010087
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010088 /* Step 2 or 5 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020089 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020090 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020091 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, ctx->V, md_len)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020092 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020093 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020094 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010095 }
Gilles Peskineafa80372018-09-11 15:35:41 +020096
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020098 mbedtls_platform_zeroize(K, sizeof(K));
99 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100100}
101
102/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100103 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
106 const mbedtls_md_info_t *md_info,
107 const unsigned char *data,
108 size_t data_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100109{
Janos Follath24eed8d2019-11-22 13:21:35 +0000110 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100111
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200112 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0)
113 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100114
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200115# if defined(MBEDTLS_THREADING_C)
116 mbedtls_mutex_init(&ctx->mutex);
117# endif
Gilles Peskineb791dc62021-01-31 00:06:51 +0100118
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100119 /*
120 * Set initial working state.
121 * Use the V memory location, which is currently all 0, to initialize the
122 * MD context with an all-zero key. Then set V to its initial value.
123 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200124 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
125 mbedtls_md_get_size(md_info))) != 0)
126 return ret;
127 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100128
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200129 if ((ret = mbedtls_hmac_drbg_update(ctx, data, data_len)) != 0)
130 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100131
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200132 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100133}
134
135/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100136 * Internal function used both for seeding and reseeding the DRBG.
137 * Comments starting with arabic numbers refer to section 10.1.2.4
138 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100139 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
141 const unsigned char *additional,
142 size_t len,
143 int use_nonce)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100144{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100146 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000147 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100148
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100149 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100150 size_t total_entropy_len;
151
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 if (use_nonce == 0)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100153 total_entropy_len = ctx->entropy_len;
154 else
155 total_entropy_len = ctx->entropy_len * 3 / 2;
156
157 /* III. Check input length */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200158 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
159 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
160 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100161 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100162 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100163
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200164 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100165
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100166 /* IV. Gather entropy_len bytes of entropy for the seed */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 if ((ret = ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) != 0) {
168 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100169 }
170 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100171
Hanno Beckera823d4c2019-08-27 06:47:18 +0100172 /* For initial seeding, allow adding of nonce generated
173 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200174 if (use_nonce) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100175 /* Note: We don't merge the two calls to f_entropy() in order
176 * to avoid requesting too much entropy from f_entropy()
177 * at once. Specifically, if the underlying digest is not
178 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
179 * is larger than the maximum of 32 Bytes that our own
180 * entropy source implementation can emit in a single
181 * call in configurations disabling SHA-512. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200182 if ((ret = ctx->f_entropy(ctx->p_entropy, seed + seedlen,
183 ctx->entropy_len / 2)) != 0) {
184 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100185 }
186
187 seedlen += ctx->entropy_len / 2;
188 }
189
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100190 /* 1. Concatenate entropy and additional data if any */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200191 if (additional != NULL && len != 0) {
192 memcpy(seed + seedlen, additional, len);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100193 seedlen += len;
194 }
195
196 /* 2. Update state */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200197 if ((ret = mbedtls_hmac_drbg_update(ctx, seed, seedlen)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200198 goto exit;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100199
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100200 /* 3. Reset reseed_counter */
201 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100202
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200203exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100204 /* 4. Done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200205 mbedtls_platform_zeroize(seed, seedlen);
206 return ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100207}
208
209/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100210 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
211 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200212int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
213 const unsigned char *additional,
214 size_t len)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100215{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216 return hmac_drbg_reseed_core(ctx, additional, len, 0);
Hanno Beckera823d4c2019-08-27 06:47:18 +0100217}
218
219/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100220 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100221 *
222 * The nonce is not passed as a separate parameter but extracted
223 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100224 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200225int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
226 const mbedtls_md_info_t *md_info,
227 int (*f_entropy)(void *, unsigned char *, size_t),
228 void *p_entropy,
229 const unsigned char *custom,
230 size_t len)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100231{
Janos Follath24eed8d2019-11-22 13:21:35 +0000232 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100233 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100234
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0)
236 return ret;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100237
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200238 /* The mutex is initialized iff the md context is set up. */
239# if defined(MBEDTLS_THREADING_C)
240 mbedtls_mutex_init(&ctx->mutex);
241# endif
Gilles Peskineb791dc62021-01-31 00:06:51 +0100242
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200243 md_size = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100244
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100245 /*
246 * Set initial working state.
247 * Use the V memory location, which is currently all 0, to initialize the
248 * MD context with an all-zero key. Then set V to its initial value.
249 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0)
251 return ret;
252 memset(ctx->V, 0x01, md_size);
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100253
254 ctx->f_entropy = f_entropy;
255 ctx->p_entropy = p_entropy;
256
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200257 if (ctx->entropy_len == 0) {
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200258 /*
259 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
260 * each hash function, then according to SP800-90A rev1 10.1 table 2,
261 * min_entropy_len (in bits) is security_strength.
262 *
263 * (This also matches the sizes used in the NIST test vectors.)
264 */
265 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
266 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
267 32; /* better (256+) -> 256 bits */
268 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100269
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200270 if ((ret = hmac_drbg_reseed_core(ctx, custom, len, 1 /* add nonce */)) !=
271 0) {
272 return ret;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100273 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275 return 0;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100276}
277
278/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100279 * Set prediction resistance
280 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
282 int resistance)
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100283{
284 ctx->prediction_resistance = resistance;
285}
286
287/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200288 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100289 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200290void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx,
291 size_t len)
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100292{
293 ctx->entropy_len = len;
294}
295
296/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100297 * Set reseed interval
298 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx,
300 int interval)
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100301{
302 ctx->reseed_interval = interval;
303}
304
305/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100306 * HMAC_DRBG random function with optional additional data:
307 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100308 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309int mbedtls_hmac_drbg_random_with_add(void *p_rng,
310 unsigned char *output,
311 size_t out_len,
312 const unsigned char *additional,
313 size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100314{
Janos Follath24eed8d2019-11-22 13:21:35 +0000315 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200316 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *)p_rng;
317 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100318 size_t left = out_len;
319 unsigned char *out = output;
320
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100321 /* II. Check request length */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200322 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST)
323 return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324
325 /* III. Check input length */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200326 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT)
327 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100328
329 /* 1. (aka VII and IX) Check reseed counter and PR */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200330 if (ctx->f_entropy != NULL && /* For no-reseeding instances */
331 (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
332 ctx->reseed_counter > ctx->reseed_interval)) {
333 if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0)
334 return ret;
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100335
336 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100337 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100338
339 /* 2. Use additional data if any */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 if (additional != NULL && add_len != 0) {
341 if ((ret = mbedtls_hmac_drbg_update(ctx, additional, add_len)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200342 goto exit;
343 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100344
345 /* 3, 4, 5. Generate bytes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200346 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100347 size_t use_len = left > md_len ? md_len : left;
348
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200349 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0)
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200350 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx, ctx->V, md_len)) != 0)
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200352 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200353 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0)
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200354 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100355
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200356 memcpy(out, ctx->V, use_len);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100357 out += use_len;
358 left -= use_len;
359 }
360
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100361 /* 6. Update */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 if ((ret = mbedtls_hmac_drbg_update(ctx, additional, add_len)) != 0)
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200363 goto exit;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100364
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100365 /* 7. Update reseed counter */
366 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100367
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200368exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100369 /* 8. Done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200370 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100371}
372
373/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100374 * HMAC_DRBG random function
375 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100377{
Janos Follath24eed8d2019-11-22 13:21:35 +0000378 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200379 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *)p_rng;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100380
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200381# if defined(MBEDTLS_THREADING_C)
382 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0)
383 return ret;
384# endif
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100385
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200386 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100387
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200388# if defined(MBEDTLS_THREADING_C)
389 if (mbedtls_mutex_unlock(&ctx->mutex) != 0)
390 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
391# endif
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100392
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393 return ret;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100394}
395
396/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800397 * This function resets HMAC_DRBG context to the state immediately
398 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100399 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100401{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200402 if (ctx == NULL)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100403 return;
404
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405# if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100406 /* The mutex is initialized iff the md context is set up. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200407 if (ctx->md_ctx.md_info != NULL)
408 mbedtls_mutex_free(&ctx->mutex);
409# endif
410 mbedtls_md_free(&ctx->md_ctx);
411 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800412 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100413}
414
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200415# if defined(MBEDTLS_FS_IO)
416int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx,
417 const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100418{
Janos Follath24eed8d2019-11-22 13:21:35 +0000419 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100420 FILE *f;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100422
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200423 if ((f = fopen(path, "wb")) == NULL)
424 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100425
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200426 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100427 goto exit;
428
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100431 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100432 }
433
434 ret = 0;
435
436exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200437 fclose(f);
438 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100439
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200440 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100441}
442
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200443int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx,
444 const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100445{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100446 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200447 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100448 size_t n;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200449 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Gilles Peskine82204662018-09-11 18:43:09 +0200450 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100451
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200452 if ((f = fopen(path, "rb")) == NULL)
453 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100454
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455 n = fread(buf, 1, sizeof(buf), f);
456 if (fread(&c, 1, 1, f) != 0) {
Gilles Peskine82204662018-09-11 18:43:09 +0200457 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
458 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100459 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200460 if (n == 0 || ferror(f)) {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100461 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200462 goto exit;
463 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200464 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200465 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100466
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200467 ret = mbedtls_hmac_drbg_update(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200468
469exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470 mbedtls_platform_zeroize(buf, sizeof(buf));
471 if (f != NULL)
472 fclose(f);
473 if (ret != 0)
474 return ret;
475 return mbedtls_hmac_drbg_write_seed_file(ctx, path);
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200477# endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100478
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200479# if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100480
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481# if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100482/* Dummy checkup routine */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200483int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100484{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485 (void)verbose;
486 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100487}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200488# else
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200490# define OUTPUT_LEN 80
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100491
492/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000493static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100494 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
495 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
496 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
497 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200498 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
499};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100500static const unsigned char result_pr[OUTPUT_LEN] = {
501 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
502 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
503 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
504 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
505 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
506 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200507 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
508};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100509
510/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000511static const unsigned char entropy_nopr[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200512 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57,
513 0x86, 0x66, 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a,
514 0xbf, 0x8c, 0x35, 0xc8, 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4,
515 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, 0xe9, 0x9d, 0xfe, 0xdf
516};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100517static const unsigned char result_nopr[OUTPUT_LEN] = {
518 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
519 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
520 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
521 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
522 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
523 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200524 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
525};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100526
527/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100528static size_t test_offset;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200529static int
530hmac_drbg_self_test_entropy(void *data, unsigned char *buf, size_t len)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100531{
532 const unsigned char *p = data;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200533 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100534 test_offset += len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200535 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100536}
537
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200538# define CHK(c) \
539 if ((c) != 0) { \
540 if (verbose != 0) \
541 mbedtls_printf("failed\n"); \
542 return 1; \
543 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544
545/*
546 * Checkup routine for HMAC_DRBG with SHA-1
547 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200548int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100549{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100551 unsigned char buf[OUTPUT_LEN];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200552 const mbedtls_md_info_t *md_info =
553 mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100554
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200555 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200556
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557 /*
558 * PR = True
559 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200560 if (verbose != 0)
561 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100562
563 test_offset = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200564 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info, hmac_drbg_self_test_entropy,
565 (void *)entropy_pr, NULL, 0));
566 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
567 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
568 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
569 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
570 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200572 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100573
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200574 if (verbose != 0)
575 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576
577 /*
578 * PR = False
579 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200580 if (verbose != 0)
581 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200583 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100584
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585 test_offset = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200586 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info, hmac_drbg_self_test_entropy,
587 (void *)entropy_nopr, NULL, 0));
588 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
589 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
590 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
591 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
592 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100593
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200594 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100595
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200596 if (verbose != 0)
597 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599 if (verbose != 0)
600 mbedtls_printf("\n");
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200602 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100603}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200604# endif /* MBEDTLS_SHA1_C */
605# endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100606
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607#endif /* MBEDTLS_HMAC_DRBG_C */