blob: ee8f8e3325389ee8a1956facbd7a2f517aa078e3 [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 Rodgman7ff79652023-11-03 12:04:52 +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 Peskine1b6c09a2023-01-11 14:52:35 +010033void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020034{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010043int mbedtls_hmac_drbg_update_ret(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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010055 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020056 goto exit;
57 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010090 mbedtls_platform_zeroize(K, sizeof(K));
91 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010092}
93
Gilles Peskinee0e9c572018-09-11 16:47:16 +020094#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095void mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
96 const unsigned char *additional,
97 size_t add_len)
Gilles Peskinee0e9c572018-09-11 16:47:16 +020098{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010099 (void) mbedtls_hmac_drbg_update_ret(ctx, additional, add_len);
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200100}
101#endif /* MBEDTLS_DEPRECATED_REMOVED */
102
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100103/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100104 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100105 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
107 const mbedtls_md_info_t *md_info,
108 const unsigned char *data, 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
113 return ret;
114 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100115
Gilles Peskineb791dc62021-01-31 00:06:51 +0100116#if defined(MBEDTLS_THREADING_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100118#endif
119
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100120 /*
121 * Set initial working state.
122 * Use the V memory location, which is currently all 0, to initialize the
123 * MD context with an all-zero key. Then set V to its initial value.
124 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
126 mbedtls_md_get_size(md_info))) != 0) {
127 return ret;
128 }
129 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100131 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, data, data_len)) != 0) {
132 return ret;
133 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100134
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100136}
137
138/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100139 * Internal function used both for seeding and reseeding the DRBG.
140 * Comments starting with arabic numbers refer to section 10.1.2.4
141 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100142 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
144 const unsigned char *additional, size_t len,
145 int use_nonce)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100146{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100148 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000149 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100150
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100151 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100152 size_t total_entropy_len;
153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100154 if (use_nonce == 0) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100155 total_entropy_len = ctx->entropy_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100156 } else {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100157 total_entropy_len = ctx->entropy_len * 3 / 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100158 }
Hanno Beckera823d4c2019-08-27 06:47:18 +0100159
160 /* III. Check input length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100161 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
162 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
163 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100164 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100165 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100168
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100169 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100170 if ((ret = ctx->f_entropy(ctx->p_entropy,
171 seed, ctx->entropy_len)) != 0) {
172 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100173 }
174 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100175
Hanno Beckera823d4c2019-08-27 06:47:18 +0100176 /* For initial seeding, allow adding of nonce generated
177 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178 if (use_nonce) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100179 /* Note: We don't merge the two calls to f_entropy() in order
180 * to avoid requesting too much entropy from f_entropy()
181 * at once. Specifically, if the underlying digest is not
182 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
183 * is larger than the maximum of 32 Bytes that our own
184 * entropy source implementation can emit in a single
185 * call in configurations disabling SHA-512. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100186 if ((ret = ctx->f_entropy(ctx->p_entropy,
187 seed + seedlen,
188 ctx->entropy_len / 2)) != 0) {
189 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100190 }
191
192 seedlen += ctx->entropy_len / 2;
193 }
194
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100195
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100196 /* 1. Concatenate entropy and additional data if any */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100197 if (additional != NULL && len != 0) {
198 memcpy(seed + seedlen, additional, len);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100199 seedlen += len;
200 }
201
202 /* 2. Update state */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100203 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, seed, seedlen)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200204 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100205 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100206
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100207 /* 3. Reset reseed_counter */
208 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100209
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200210exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100211 /* 4. Done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100212 mbedtls_platform_zeroize(seed, seedlen);
213 return ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214}
215
216/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100217 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
218 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100219int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
220 const unsigned char *additional, size_t len)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100221{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100222 return hmac_drbg_reseed_core(ctx, additional, len, 0);
Hanno Beckera823d4c2019-08-27 06:47:18 +0100223}
224
225/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100226 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100227 *
228 * The nonce is not passed as a separate parameter but extracted
229 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100230 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100231int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
232 const mbedtls_md_info_t *md_info,
233 int (*f_entropy)(void *, unsigned char *, size_t),
234 void *p_entropy,
235 const unsigned char *custom,
236 size_t len)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100237{
Janos Follath24eed8d2019-11-22 13:21:35 +0000238 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100239 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100240
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100241 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
242 return ret;
243 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100244
Gilles Peskinee39b2192021-02-09 18:43:33 +0100245 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100246#if defined(MBEDTLS_THREADING_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100248#endif
249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 md_size = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100251
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100252 /*
253 * Set initial working state.
254 * Use the V memory location, which is currently all 0, to initialize the
255 * MD context with an all-zero key. Then set V to its initial value.
256 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) {
258 return ret;
259 }
260 memset(ctx->V, 0x01, md_size);
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100261
262 ctx->f_entropy = f_entropy;
263 ctx->p_entropy = p_entropy;
264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 if (ctx->entropy_len == 0) {
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200266 /*
267 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
268 * each hash function, then according to SP800-90A rev1 10.1 table 2,
269 * min_entropy_len (in bits) is security_strength.
270 *
271 * (This also matches the sizes used in the NIST test vectors.)
272 */
273 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
274 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
275 32; /* better (256+) -> 256 bits */
276 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100277
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
279 1 /* add nonce */)) != 0) {
280 return ret;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100281 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100282
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100283 return 0;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100284}
285
286/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100287 * Set prediction resistance
288 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
290 int resistance)
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100291{
292 ctx->prediction_resistance = resistance;
293}
294
295/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200296 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100297 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len)
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100299{
300 ctx->entropy_len = len;
301}
302
303/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100304 * Set reseed interval
305 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval)
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100307{
308 ctx->reseed_interval = interval;
309}
310
311/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100312 * HMAC_DRBG random function with optional additional data:
313 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100314 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315int mbedtls_hmac_drbg_random_with_add(void *p_rng,
316 unsigned char *output, size_t out_len,
317 const unsigned char *additional, size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100318{
Janos Follath24eed8d2019-11-22 13:21:35 +0000319 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100322 size_t left = out_len;
323 unsigned char *out = output;
324
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100325 /* II. Check request length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100326 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) {
327 return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
328 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100329
330 /* III. Check input length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) {
332 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
333 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100334
335 /* 1. (aka VII and IX) Check reseed counter and PR */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100336 if (ctx->f_entropy != NULL && /* For no-reseeding instances */
337 (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
338 ctx->reseed_counter > ctx->reseed_interval)) {
339 if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) {
340 return ret;
341 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100342
343 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100344 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100345
346 /* 2. Use additional data if any */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 if (additional != NULL && add_len != 0) {
348 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
349 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200350 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100351 }
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200352 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100353
354 /* 3, 4, 5. Generate bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100356 size_t use_len = left > md_len ? md_len : left;
357
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200359 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100360 }
361 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
362 ctx->V, md_len)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200363 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100364 }
365 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200366 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369 memcpy(out, ctx->V, use_len);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100370 out += use_len;
371 left -= use_len;
372 }
373
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100374 /* 6. Update */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100375 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
376 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200377 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100379
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100380 /* 7. Update reseed counter */
381 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100382
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200383exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100384 /* 8. Done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100386}
387
388/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100389 * HMAC_DRBG random function
390 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392{
Janos Follath24eed8d2019-11-22 13:21:35 +0000393 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100394 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
395
396#if defined(MBEDTLS_THREADING_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
398 return ret;
399 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100400#endif
401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100403
404#if defined(MBEDTLS_THREADING_C)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
406 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
407 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100408#endif
409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100410 return ret;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100411}
412
413/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800414 * This function resets HMAC_DRBG context to the state immediately
415 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100416 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100418{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 if (ctx == NULL) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100420 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100421 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100422
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100423#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100424 /* The mutex is initialized iff the md context is set up. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 if (ctx->md_ctx.md_info != NULL) {
426 mbedtls_mutex_free(&ctx->mutex);
427 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100428#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 mbedtls_md_free(&ctx->md_ctx);
430 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800431 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100432}
433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434#if defined(MBEDTLS_FS_IO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100436{
Janos Follath24eed8d2019-11-22 13:21:35 +0000437 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100438 FILE *f;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100441 if ((f = fopen(path, "wb")) == NULL) {
442 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
443 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100444
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100446 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100448
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100449 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100451 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452 }
453
454 ret = 0;
455
456exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457 fclose(f);
458 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100459
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100461}
462
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100465 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200466 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467 size_t n;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100468 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Gilles Peskine82204662018-09-11 18:43:09 +0200469 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100471 if ((f = fopen(path, "rb")) == NULL) {
472 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
473 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100474
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100475 n = fread(buf, 1, sizeof(buf), f);
476 if (fread(&c, 1, 1, f) != 0) {
Gilles Peskine82204662018-09-11 18:43:09 +0200477 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
478 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 if (n == 0 || ferror(f)) {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100481 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200482 goto exit;
483 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100484 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200485 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 ret = mbedtls_hmac_drbg_update_ret(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200488
489exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 mbedtls_platform_zeroize(buf, sizeof(buf));
491 if (f != NULL) {
492 fclose(f);
493 }
494 if (ret != 0) {
495 return ret;
496 }
497 return mbedtls_hmac_drbg_write_seed_file(ctx, path);
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100500
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100505/* Dummy checkup routine */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100507{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200508 (void) verbose;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100510}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100511#else
512
513#define OUTPUT_LEN 80
514
515/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000516static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100517 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
518 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
519 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
520 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
522};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100523static const unsigned char result_pr[OUTPUT_LEN] = {
524 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
525 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
526 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
527 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
528 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
529 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
531};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100532
533/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000534static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
536 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
537 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100538 0xe9, 0x9d, 0xfe, 0xdf
539};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100540static const unsigned char result_nopr[OUTPUT_LEN] = {
541 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
542 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
543 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
544 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
545 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
546 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100547 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
548};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100549
550/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100551static size_t test_offset;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100552static int hmac_drbg_self_test_entropy(void *data,
553 unsigned char *buf, size_t len)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100554{
555 const unsigned char *p = data;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100556 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100557 test_offset += len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100558 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100559}
560
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561#define CHK(c) if ((c) != 0) \
562 { \
563 if (verbose != 0) \
564 mbedtls_printf("failed\n"); \
565 return 1; \
566 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100567
568/*
569 * Checkup routine for HMAC_DRBG with SHA-1
570 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100572{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100574 unsigned char buf[OUTPUT_LEN];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200578
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579 /*
580 * PR = True
581 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100582 if (verbose != 0) {
583 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
584 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585
586 test_offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100587 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
588 hmac_drbg_self_test_entropy, (void *) entropy_pr,
589 NULL, 0));
590 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
591 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
592 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
593 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
594 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100595
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100596 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100598 if (verbose != 0) {
599 mbedtls_printf("passed\n");
600 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100601
602 /*
603 * PR = False
604 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 if (verbose != 0) {
606 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
607 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100610
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100611 test_offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
613 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
614 NULL, 0));
615 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
616 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
617 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
618 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
619 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100622
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100623 if (verbose != 0) {
624 mbedtls_printf("passed\n");
625 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100626
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 if (verbose != 0) {
628 mbedtls_printf("\n");
629 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100630
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100631 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100632}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633#endif /* MBEDTLS_SHA1_C */
634#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636#endif /* MBEDTLS_HMAC_DRBG_C */