blob: af205aacb64d349ff884ce66d642a3276e7b0a02 [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
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/hmac_drbg.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +010037#include <stdio.h>
38#endif
39
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010041
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010042/*
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020043 * HMAC_DRBG context initialization
44 */
Gilles Peskine449bd832023-01-11 14:50:10 +010045void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020046{
Gilles Peskine449bd832023-01-11 14:50:10 +010047 memset(ctx, 0, sizeof(mbedtls_hmac_drbg_context));
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +010048
Gavin Acquroff6aceb512020-03-01 17:06:11 -080049 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020050}
51
52/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010053 * HMAC_DRBG update, using optional additional data (10.1.2.2)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010054 */
Gilles Peskine449bd832023-01-11 14:50:10 +010055int mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
56 const unsigned char *additional,
57 size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010058{
Gilles Peskine449bd832023-01-11 14:50:10 +010059 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
60 unsigned char rounds = (additional != NULL && add_len != 0) ? 2 : 1;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010061 unsigned char sep[1];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062 unsigned char K[MBEDTLS_MD_MAX_SIZE];
Gilles Peskine006c1b52019-09-30 17:29:54 +020063 int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010064
Gilles Peskine449bd832023-01-11 14:50:10 +010065 for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010066 /* Step 1 or 4 */
Gilles Peskine449bd832023-01-11 14:50:10 +010067 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020068 goto exit;
69 }
Gilles Peskine449bd832023-01-11 14:50:10 +010070 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
71 ctx->V, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020072 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010073 }
74 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
75 sep, 1)) != 0) {
76 goto exit;
77 }
78 if (rounds == 2) {
79 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
80 additional, add_len)) != 0) {
81 goto exit;
82 }
83 }
84 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, K)) != 0) {
85 goto exit;
86 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010087
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010088 /* Step 2 or 5 */
Gilles Peskine449bd832023-01-11 14:50:10 +010089 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020090 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010091 }
92 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
93 ctx->V, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020094 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010095 }
96 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +010098 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +010099 }
Gilles Peskineafa80372018-09-11 15:35:41 +0200100
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200101exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 mbedtls_platform_zeroize(K, sizeof(K));
103 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104}
105
106/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100107 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100108 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100109int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
110 const mbedtls_md_info_t *md_info,
111 const unsigned char *data, size_t data_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100112{
Janos Follath24eed8d2019-11-22 13:21:35 +0000113 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
116 return ret;
117 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100118
Gilles Peskineb791dc62021-01-31 00:06:51 +0100119#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100121#endif
122
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100123 /*
124 * Set initial working state.
125 * Use the V memory location, which is currently all 0, to initialize the
126 * MD context with an all-zero key. Then set V to its initial value.
127 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
129 mbedtls_md_get_size(md_info))) != 0) {
130 return ret;
131 }
132 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 if ((ret = mbedtls_hmac_drbg_update(ctx, data, data_len)) != 0) {
135 return ret;
136 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100139}
140
141/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100142 * Internal function used both for seeding and reseeding the DRBG.
143 * Comments starting with arabic numbers refer to section 10.1.2.4
144 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100145 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100146static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
147 const unsigned char *additional, size_t len,
148 int use_nonce)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100149{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100151 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000152 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100153
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100154 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100155 size_t total_entropy_len;
156
Gilles Peskine449bd832023-01-11 14:50:10 +0100157 if (use_nonce == 0) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100158 total_entropy_len = ctx->entropy_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100159 } else {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100160 total_entropy_len = ctx->entropy_len * 3 / 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 }
Hanno Beckera823d4c2019-08-27 06:47:18 +0100162
163 /* III. Check input length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
165 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
166 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100167 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100168 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100171
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100172 /* IV. Gather entropy_len bytes of entropy for the seed */
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 if ((ret = ctx->f_entropy(ctx->p_entropy,
174 seed, ctx->entropy_len)) != 0) {
175 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100176 }
177 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100178
Hanno Beckera823d4c2019-08-27 06:47:18 +0100179 /* For initial seeding, allow adding of nonce generated
180 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 if (use_nonce) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100182 /* Note: We don't merge the two calls to f_entropy() in order
183 * to avoid requesting too much entropy from f_entropy()
184 * at once. Specifically, if the underlying digest is not
185 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
186 * is larger than the maximum of 32 Bytes that our own
187 * entropy source implementation can emit in a single
188 * call in configurations disabling SHA-512. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if ((ret = ctx->f_entropy(ctx->p_entropy,
190 seed + seedlen,
191 ctx->entropy_len / 2)) != 0) {
192 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100193 }
194
195 seedlen += ctx->entropy_len / 2;
196 }
197
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100198
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100199 /* 1. Concatenate entropy and additional data if any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 if (additional != NULL && len != 0) {
201 memcpy(seed + seedlen, additional, len);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100202 seedlen += len;
203 }
204
205 /* 2. Update state */
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 if ((ret = mbedtls_hmac_drbg_update(ctx, seed, seedlen)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200207 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100209
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100210 /* 3. Reset reseed_counter */
211 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100212
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200213exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100214 /* 4. Done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 mbedtls_platform_zeroize(seed, seedlen);
216 return ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100217}
218
219/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100220 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
221 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100222int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
223 const unsigned char *additional, size_t len)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100224{
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 return hmac_drbg_reseed_core(ctx, additional, len, 0);
Hanno Beckera823d4c2019-08-27 06:47:18 +0100226}
227
228/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100229 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100230 *
231 * The nonce is not passed as a separate parameter but extracted
232 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100233 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100234int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
235 const mbedtls_md_info_t *md_info,
236 int (*f_entropy)(void *, unsigned char *, size_t),
237 void *p_entropy,
238 const unsigned char *custom,
239 size_t len)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100240{
Janos Follath24eed8d2019-11-22 13:21:35 +0000241 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100242 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
245 return ret;
246 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100247
Gilles Peskinee39b2192021-02-09 18:43:33 +0100248 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100249#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100251#endif
252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 md_size = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100254
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100255 /*
256 * Set initial working state.
257 * Use the V memory location, which is currently all 0, to initialize the
258 * MD context with an all-zero key. Then set V to its initial value.
259 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) {
261 return ret;
262 }
263 memset(ctx->V, 0x01, md_size);
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100264
265 ctx->f_entropy = f_entropy;
266 ctx->p_entropy = p_entropy;
267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 if (ctx->entropy_len == 0) {
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200269 /*
270 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
271 * each hash function, then according to SP800-90A rev1 10.1 table 2,
272 * min_entropy_len (in bits) is security_strength.
273 *
274 * (This also matches the sizes used in the NIST test vectors.)
275 */
276 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
277 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
278 32; /* better (256+) -> 256 bits */
279 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
282 1 /* add nonce */)) != 0) {
283 return ret;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100284 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 return 0;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100287}
288
289/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100290 * Set prediction resistance
291 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100292void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
293 int resistance)
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100294{
295 ctx->prediction_resistance = resistance;
296}
297
298/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200299 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100300 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100301void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len)
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100302{
303 ctx->entropy_len = len;
304}
305
306/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100307 * Set reseed interval
308 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100309void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval)
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100310{
311 ctx->reseed_interval = interval;
312}
313
314/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100315 * HMAC_DRBG random function with optional additional data:
316 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100317 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100318int mbedtls_hmac_drbg_random_with_add(void *p_rng,
319 unsigned char *output, size_t out_len,
320 const unsigned char *additional, size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100321{
Janos Follath24eed8d2019-11-22 13:21:35 +0000322 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100325 size_t left = out_len;
326 unsigned char *out = output;
327
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100328 /* II. Check request length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) {
330 return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
331 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100332
333 /* III. Check input length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) {
335 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
336 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100337
338 /* 1. (aka VII and IX) Check reseed counter and PR */
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 if (ctx->f_entropy != NULL && /* For no-reseeding instances */
340 (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
341 ctx->reseed_counter > ctx->reseed_interval)) {
342 if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) {
343 return ret;
344 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100345
346 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100347 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100348
349 /* 2. Use additional data if any */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 if (additional != NULL && add_len != 0) {
351 if ((ret = mbedtls_hmac_drbg_update(ctx,
352 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200353 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 }
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200355 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100356
357 /* 3, 4, 5. Generate bytes */
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100359 size_t use_len = left > md_len ? md_len : left;
360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200362 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 }
364 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
365 ctx->V, md_len)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200366 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 }
368 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200369 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 memcpy(out, ctx->V, use_len);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100373 out += use_len;
374 left -= use_len;
375 }
376
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100377 /* 6. Update */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 if ((ret = mbedtls_hmac_drbg_update(ctx,
379 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200380 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100382
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100383 /* 7. Update reseed counter */
384 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100385
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200386exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100387 /* 8. Done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100389}
390
391/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100392 * HMAC_DRBG random function
393 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100395{
Janos Follath24eed8d2019-11-22 13:21:35 +0000396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100397 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
398
399#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
401 return ret;
402 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100403#endif
404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100406
407#if defined(MBEDTLS_THREADING_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
409 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
410 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100411#endif
412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 return ret;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100414}
415
416/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800417 * This function resets HMAC_DRBG context to the state immediately
418 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100419 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100420void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100421{
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 if (ctx == NULL) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100423 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100425
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100426#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100427 /* The mutex is initialized iff the md context is set up. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 if (ctx->md_ctx.md_info != NULL) {
429 mbedtls_mutex_free(&ctx->mutex);
430 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100431#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 mbedtls_md_free(&ctx->md_ctx);
433 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800434 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100435}
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437#if defined(MBEDTLS_FS_IO)
Gilles Peskine449bd832023-01-11 14:50:10 +0100438int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100439{
Janos Follath24eed8d2019-11-22 13:21:35 +0000440 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100441 FILE *f;
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 if ((f = fopen(path, "wb")) == NULL) {
445 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
446 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100447
Gilles Peskineda0913b2022-06-30 17:03:40 +0200448 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 mbedtls_setbuf(f, NULL);
Gilles Peskineda0913b2022-06-30 17:03:40 +0200450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100457 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458 }
459
460 ret = 0;
461
462exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 fclose(f);
464 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100467}
468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100470{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100471 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200472 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473 size_t n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Gilles Peskine82204662018-09-11 18:43:09 +0200475 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 if ((f = fopen(path, "rb")) == NULL) {
478 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
479 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100480
Gilles Peskineda0913b2022-06-30 17:03:40 +0200481 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 mbedtls_setbuf(f, NULL);
Gilles Peskineda0913b2022-06-30 17:03:40 +0200483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 n = fread(buf, 1, sizeof(buf), f);
485 if (fread(&c, 1, 1, f) != 0) {
Gilles Peskine82204662018-09-11 18:43:09 +0200486 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
487 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100488 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 if (n == 0 || ferror(f)) {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100490 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200491 goto exit;
492 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200494 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 ret = mbedtls_hmac_drbg_update(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200497
498exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 mbedtls_platform_zeroize(buf, sizeof(buf));
500 if (f != NULL) {
501 fclose(f);
502 }
503 if (ret != 0) {
504 return ret;
505 }
506 return mbedtls_hmac_drbg_write_seed_file(ctx, path);
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100507}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100509
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100512
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100513#if !defined(MBEDTLS_MD_CAN_SHA1)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100514/* Dummy checkup routine */
Gilles Peskine449bd832023-01-11 14:50:10 +0100515int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100516{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200517 (void) verbose;
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100519}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100520#else
521
522#define OUTPUT_LEN 80
523
524/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000525static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100526 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
527 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
528 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
529 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
531};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100532static const unsigned char result_pr[OUTPUT_LEN] = {
533 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
534 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
535 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
536 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
537 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
538 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
540};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100541
542/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000543static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
545 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
546 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 0xe9, 0x9d, 0xfe, 0xdf
548};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100549static const unsigned char result_nopr[OUTPUT_LEN] = {
550 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
551 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
552 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
553 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
554 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
555 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
557};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100558
559/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100560static size_t test_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100561static int hmac_drbg_self_test_entropy(void *data,
562 unsigned char *buf, size_t len)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100563{
564 const unsigned char *p = data;
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566 test_offset += len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100568}
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570#define CHK(c) if ((c) != 0) \
571 { \
572 if (verbose != 0) \
573 mbedtls_printf("failed\n"); \
574 return 1; \
575 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100576
577/*
578 * Checkup routine for HMAC_DRBG with SHA-1
579 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100580int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100581{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100583 unsigned char buf[OUTPUT_LEN];
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200587
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588 /*
589 * PR = True
590 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 if (verbose != 0) {
592 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
593 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100594
595 test_offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
597 hmac_drbg_self_test_entropy, (void *) entropy_pr,
598 NULL, 0));
599 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
600 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
601 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
602 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
603 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 if (verbose != 0) {
608 mbedtls_printf("passed\n");
609 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100610
611 /*
612 * PR = False
613 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 if (verbose != 0) {
615 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
616 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100619
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620 test_offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
622 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
623 NULL, 0));
624 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
625 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
626 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
627 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
628 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 if (verbose != 0) {
633 mbedtls_printf("passed\n");
634 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (verbose != 0) {
637 mbedtls_printf("\n");
638 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100639
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100641}
Manuel Pégourié-Gonnard93302422023-03-21 17:23:08 +0100642#endif /* MBEDTLS_MD_CAN_SHA1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100644
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645#endif /* MBEDTLS_HMAC_DRBG_C */