blob: 90174d5d17d56324ed14029b8f58431b98b99848 [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +01006 */
7
8/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +01009 * The NIST SP 800-90A DRBGs are described in the following publication.
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010010 * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010011 * References below are based on rev. 1 (January 2012).
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010012 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_HMAC_DRBG_C)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010017
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000018#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050019#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000020#include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010021
Rich Evans00ab4702015-02-06 13:43:58 +000022#include <string.h>
23
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010025#include <stdio.h>
26#endif
27
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010029
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010030/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020031 * HMAC_DRBG context initialization
32 */
Gilles Peskine449bd832023-01-11 14:50:10 +010033void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020034{
Gilles Peskine449bd832023-01-11 14:50:10 +010035 memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context));
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010036
Gavin Acquroff6aceb512020-03-01 17:06:11 -080037 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020038}
39
40/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010041 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010042 */
Gilles Peskine449bd832023-01-11 14:50:10 +010043int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
44 const unsigned char *additional,
45 size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010046{
Gilles Peskine449bd832023-01-11 14:50:10 +010047 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
48 unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010049 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020051 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010052
Gilles Peskine449bd832023-01-11 14:50:10 +010053 for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010054 /* Step 1 or 4 */
Gilles Peskine449bd832023-01-11 14:50:10 +010055 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020056 goto exit;
57 }
Gilles Peskine449bd832023-01-11 14:50:10 +010058 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
59 ctx->V, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020060 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010061 }
62 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
63 sep, 1)) != 0) {
64 goto exit;
65 }
66 if (rounds == 2) {
67 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
68 additional, add_len)) != 0) {
69 goto exit;
70 }
71 }
72 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0) {
73 goto exit;
74 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010075
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010076 /* Step 2 or 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +010077 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020078 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010079 }
80 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
81 ctx->V, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020082 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010083 }
84 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020085 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010086 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010087 }
Gilles Peskineafa80372018-09-11 15:35:41 +020088
Gilles Peskinee0e9c572018-09-11 16:47:16 +020089exit:
Gilles Peskine449bd832023-01-11 14:50:10 +010090 mbedtls_platform_zeroize(K, sizeof(K));
91 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010092}
93
94/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +010095 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010096 */
Gilles Peskine449bd832023-01-11 14:50:10 +010097int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
98 const mbedtls_md_info_t *md_info,
99 const unsigned char *data, size_t data_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100100{
Janos Follath24eed8d2019-11-22 13:21:35 +0000101 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
104 return ret;
105 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100106
Gilles Peskineb791dc62021-01-31 00:06:51 +0100107#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100109#endif
110
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100111 /*
112 * Set initial working state.
113 * Use the V memory location, which is currently all 0, to initialize the
114 * MD context with an all-zero key. Then set V to its initial value.
115 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
117 mbedtls_md_get_size(md_info))) != 0) {
118 return ret;
119 }
120 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 if ((ret = mbedtls_hmac_drbg_update(ctx, data, data_len)) != 0) {
123 return ret;
124 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100127}
128
129/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100130 * Internal function used both for seeding and reseeding the DRBG.
131 * Comments starting with arabic numbers refer to section 10.1.2.4
132 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100133 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100134static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
135 const unsigned char *additional, size_t len,
136 int use_nonce)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100137{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100139 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000140 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100141
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100142 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100143 size_t total_entropy_len;
144
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 if (use_nonce == 0) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100146 total_entropy_len = ctx->entropy_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 } else {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100148 total_entropy_len = ctx->entropy_len * 3 / 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 }
Hanno Beckera823d4c2019-08-27 06:47:18 +0100150
151 /* III. Check input length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
153 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
154 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100155 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100156 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100159
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100160 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 if ((ret = ctx->f_entropy(ctx->p_entropy,
162 seed, ctx->entropy_len)) != 0) {
163 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100164 }
165 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100166
Hanno Beckera823d4c2019-08-27 06:47:18 +0100167 /* For initial seeding, allow adding of nonce generated
168 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 if (use_nonce) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100170 /* Note: We don't merge the two calls to f_entropy() in order
171 * to avoid requesting too much entropy from f_entropy()
172 * at once. Specifically, if the underlying digest is not
173 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
174 * is larger than the maximum of 32 Bytes that our own
175 * entropy source implementation can emit in a single
176 * call in configurations disabling SHA-512. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 if ((ret = ctx->f_entropy(ctx->p_entropy,
178 seed + seedlen,
179 ctx->entropy_len / 2)) != 0) {
180 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100181 }
182
183 seedlen += ctx->entropy_len / 2;
184 }
185
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100186
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100187 /* 1. Concatenate entropy and additional data if any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 if (additional != NULL && len != 0) {
189 memcpy(seed + seedlen, additional, len);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100190 seedlen += len;
191 }
192
193 /* 2. Update state */
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 if ((ret = mbedtls_hmac_drbg_update(ctx, seed, seedlen)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200195 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100197
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100198 /* 3. Reset reseed_counter */
199 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100200
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200201exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100202 /* 4. Done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 mbedtls_platform_zeroize(seed, seedlen);
204 return ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100205}
206
207/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100208 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
209 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
211 const unsigned char *additional, size_t len)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100212{
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 return hmac_drbg_reseed_core(ctx, additional, len, 0);
Hanno Beckera823d4c2019-08-27 06:47:18 +0100214}
215
216/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100217 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100218 *
219 * The nonce is not passed as a separate parameter but extracted
220 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100221 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100222int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
223 const mbedtls_md_info_t *md_info,
224 int (*f_entropy)(void *, unsigned char *, size_t),
225 void *p_entropy,
226 const unsigned char *custom,
227 size_t len)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100228{
Janos Follath24eed8d2019-11-22 13:21:35 +0000229 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100230 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
233 return ret;
234 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100235
Gilles Peskinee39b2192021-02-09 18:43:33 +0100236 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100237#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100239#endif
240
Gilles Peskine449bd832023-01-11 14:50:10 +0100241 md_size = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100242
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100243 /*
244 * Set initial working state.
245 * Use the V memory location, which is currently all 0, to initialize the
246 * MD context with an all-zero key. Then set V to its initial value.
247 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) {
249 return ret;
250 }
251 memset(ctx->V, 0x01, md_size);
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100252
253 ctx->f_entropy = f_entropy;
254 ctx->p_entropy = p_entropy;
255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 if (ctx->entropy_len == 0) {
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200257 /*
258 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
259 * each hash function, then according to SP800-90A rev1 10.1 table 2,
260 * min_entropy_len (in bits) is security_strength.
261 *
262 * (This also matches the sizes used in the NIST test vectors.)
263 */
264 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
265 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
266 32; /* better (256+) -> 256 bits */
267 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
270 1 /* add nonce */)) != 0) {
271 return ret;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100272 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 return 0;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100275}
276
277/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100278 * Set prediction resistance
279 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100280void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
281 int resistance)
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100282{
283 ctx->prediction_resistance = resistance;
284}
285
286/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200287 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100288 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100289void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len)
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100290{
291 ctx->entropy_len = len;
292}
293
294/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100295 * Set reseed interval
296 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100297void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval)
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100298{
299 ctx->reseed_interval = interval;
300}
301
302/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100303 * HMAC_DRBG random function with optional additional data:
304 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100305 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100306int mbedtls_hmac_drbg_random_with_add(void *p_rng,
307 unsigned char *output, size_t out_len,
308 const unsigned char *additional, size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100309{
Janos Follath24eed8d2019-11-22 13:21:35 +0000310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100313 size_t left = out_len;
314 unsigned char *out = output;
315
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100316 /* II. Check request length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) {
318 return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
319 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100320
321 /* III. Check input length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) {
323 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
324 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100325
326 /* 1. (aka VII and IX) Check reseed counter and PR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 if (ctx->f_entropy != NULL && /* For no-reseeding instances */
328 (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
329 ctx->reseed_counter > ctx->reseed_interval)) {
330 if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) {
331 return ret;
332 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100333
334 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100335 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100336
337 /* 2. Use additional data if any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 if (additional != NULL && add_len != 0) {
339 if ((ret = mbedtls_hmac_drbg_update(ctx,
340 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200341 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 }
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200343 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100344
345 /* 3, 4, 5. Generate bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100347 size_t use_len = left > md_len ? md_len : left;
348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200350 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 }
352 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
353 ctx->V, md_len)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200354 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 }
356 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200357 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 memcpy(out, ctx->V, use_len);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100361 out += use_len;
362 left -= use_len;
363 }
364
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100365 /* 6. Update */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 if ((ret = mbedtls_hmac_drbg_update(ctx,
367 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200368 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100370
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100371 /* 7. Update reseed counter */
372 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100373
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200374exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100375 /* 8. Done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100377}
378
379/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100380 * HMAC_DRBG random function
381 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100383{
Janos Follath24eed8d2019-11-22 13:21:35 +0000384 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100385 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
386
387#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
389 return ret;
390 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100391#endif
392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100394
395#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
397 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
398 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100399#endif
400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 return ret;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100402}
403
404/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800405 * This function resets HMAC_DRBG context to the state immediately
406 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100407 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100409{
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if (ctx == NULL) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100411 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100413
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100414#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100415 /* The mutex is initialized iff the md context is set up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 if (ctx->md_ctx.md_info != NULL) {
417 mbedtls_mutex_free(&ctx->mutex);
418 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100419#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 mbedtls_md_free(&ctx->md_ctx);
421 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800422 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423}
424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#if defined(MBEDTLS_FS_IO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100426int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100427{
Janos Follath24eed8d2019-11-22 13:21:35 +0000428 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100429 FILE *f;
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 if ((f = fopen(path, "wb")) == NULL) {
433 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
434 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100435
Gilles Peskineda0913b2022-06-30 17:03:40 +0200436 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 mbedtls_setbuf(f, NULL);
Gilles Peskineda0913b2022-06-30 17:03:40 +0200438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100445 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100446 }
447
448 ret = 0;
449
450exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 fclose(f);
452 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100455}
456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100459 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200460 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Gilles Peskine82204662018-09-11 18:43:09 +0200463 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 if ((f = fopen(path, "rb")) == NULL) {
466 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
467 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100468
Gilles Peskineda0913b2022-06-30 17:03:40 +0200469 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 mbedtls_setbuf(f, NULL);
Gilles Peskineda0913b2022-06-30 17:03:40 +0200471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 n = fread(buf, 1, sizeof(buf), f);
473 if (fread(&c, 1, 1, f) != 0) {
Gilles Peskine82204662018-09-11 18:43:09 +0200474 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
475 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 if (n == 0 || ferror(f)) {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100478 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200479 goto exit;
480 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200482 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 ret = mbedtls_hmac_drbg_update(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200485
486exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_platform_zeroize(buf, sizeof(buf));
488 if (f != NULL) {
489 fclose(f);
490 }
491 if (ret != 0) {
492 return ret;
493 }
494 return mbedtls_hmac_drbg_write_seed_file(ctx, path);
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100497
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100500
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100501#if !defined(MBEDTLS_MD_CAN_SHA1)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100502/* Dummy checkup routine */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100504{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200505 (void) verbose;
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100507}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100508#else
509
510#define OUTPUT_LEN 80
511
512/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000513static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100514 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
515 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
516 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
517 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
519};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100520static const unsigned char result_pr[OUTPUT_LEN] = {
521 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
522 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
523 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
524 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
525 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
526 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
528};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100529
530/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000531static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100532 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
533 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
534 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 0xe9, 0x9d, 0xfe, 0xdf
536};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100537static const unsigned char result_nopr[OUTPUT_LEN] = {
538 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
539 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
540 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
541 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
542 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
543 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
545};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100546
547/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100548static size_t test_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100549static int hmac_drbg_self_test_entropy(void *data,
550 unsigned char *buf, size_t len)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100551{
552 const unsigned char *p = data;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100554 test_offset += len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100556}
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558#define CHK(c) if ((c) != 0) \
559 { \
560 if (verbose != 0) \
561 mbedtls_printf("failed\n"); \
562 return 1; \
563 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100564
565/*
566 * Checkup routine for HMAC_DRBG with SHA-1
567 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100568int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571 unsigned char buf[OUTPUT_LEN];
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100573
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200575
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576 /*
577 * PR = True
578 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (verbose != 0) {
580 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
581 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100582
583 test_offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
585 hmac_drbg_self_test_entropy, (void *) entropy_pr,
586 NULL, 0));
587 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
588 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
589 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
590 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
591 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100592
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 if (verbose != 0) {
596 mbedtls_printf("passed\n");
597 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100598
599 /*
600 * PR = False
601 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 if (verbose != 0) {
603 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
604 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100607
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608 test_offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
610 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
611 NULL, 0));
612 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
613 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
614 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
615 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
616 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 if (verbose != 0) {
621 mbedtls_printf("passed\n");
622 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 if (verbose != 0) {
625 mbedtls_printf("\n");
626 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100629}
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100630#endif /* MBEDTLS_MD_CAN_SHA1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#endif /* MBEDTLS_HMAC_DRBG_C */