blob: fabe00252a57513232edb77b5c5cad3c14a61f2e [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 */
David Horstmannceeaeb92023-01-05 15:44:23 +000045void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020046{
David Horstmannceeaeb92023-01-05 15:44:23 +000047 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +000055int mbedtls_hmac_drbg_update_ret(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{
David Horstmannceeaeb92023-01-05 15:44:23 +000059 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
David Horstmannceeaeb92023-01-05 15:44:23 +000065 for (sep[0] = 0; sep[0] < rounds; sep[0]++) {
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +010066 /* Step 1 or 4 */
David Horstmannceeaeb92023-01-05 15:44:23 +000067 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020068 goto exit;
69 }
David Horstmannceeaeb92023-01-05 15:44:23 +000070 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;
David Horstmannceeaeb92023-01-05 15:44:23 +000073 }
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 */
David Horstmannceeaeb92023-01-05 15:44:23 +000089 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, K, md_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020090 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +000091 }
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;
David Horstmannceeaeb92023-01-05 15:44:23 +000095 }
96 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020097 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +000098 }
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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000102 mbedtls_platform_zeroize(K, sizeof(K));
103 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100104}
105
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200106#if !defined(MBEDTLS_DEPRECATED_REMOVED)
David Horstmannceeaeb92023-01-05 15:44:23 +0000107void mbedtls_hmac_drbg_update(mbedtls_hmac_drbg_context *ctx,
108 const unsigned char *additional,
109 size_t add_len)
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200110{
David Horstmannceeaeb92023-01-05 15:44:23 +0000111 (void) mbedtls_hmac_drbg_update_ret(ctx, additional, add_len);
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200112}
113#endif /* MBEDTLS_DEPRECATED_REMOVED */
114
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100115/*
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100116 * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100117 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000118int mbedtls_hmac_drbg_seed_buf(mbedtls_hmac_drbg_context *ctx,
119 const mbedtls_md_info_t *md_info,
120 const unsigned char *data, size_t data_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100121{
Janos Follath24eed8d2019-11-22 13:21:35 +0000122 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100123
David Horstmannceeaeb92023-01-05 15:44:23 +0000124 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
125 return ret;
126 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100127
Gilles Peskineb791dc62021-01-31 00:06:51 +0100128#if defined(MBEDTLS_THREADING_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000129 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100130#endif
131
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100132 /*
133 * Set initial working state.
134 * Use the V memory location, which is currently all 0, to initialize the
135 * MD context with an all-zero key. Then set V to its initial value.
136 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000137 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V,
138 mbedtls_md_get_size(md_info))) != 0) {
139 return ret;
140 }
141 memset(ctx->V, 0x01, mbedtls_md_get_size(md_info));
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100142
David Horstmannceeaeb92023-01-05 15:44:23 +0000143 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, data, data_len)) != 0) {
144 return ret;
145 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100146
David Horstmannceeaeb92023-01-05 15:44:23 +0000147 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100148}
149
150/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100151 * Internal function used both for seeding and reseeding the DRBG.
152 * Comments starting with arabic numbers refer to section 10.1.2.4
153 * of SP800-90A, while roman numbers refer to section 9.2.
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100154 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000155static int hmac_drbg_reseed_core(mbedtls_hmac_drbg_context *ctx,
156 const unsigned char *additional, size_t len,
157 int use_nonce)
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
Hanno Beckera823d4c2019-08-27 06:47:18 +0100160 size_t seedlen = 0;
Janos Follath24eed8d2019-11-22 13:21:35 +0000161 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100162
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100163 {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100164 size_t total_entropy_len;
165
David Horstmannceeaeb92023-01-05 15:44:23 +0000166 if (use_nonce == 0) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100167 total_entropy_len = ctx->entropy_len;
David Horstmannceeaeb92023-01-05 15:44:23 +0000168 } else {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100169 total_entropy_len = ctx->entropy_len * 3 / 2;
David Horstmannceeaeb92023-01-05 15:44:23 +0000170 }
Hanno Beckera823d4c2019-08-27 06:47:18 +0100171
172 /* III. Check input length */
David Horstmannceeaeb92023-01-05 15:44:23 +0000173 if (len > MBEDTLS_HMAC_DRBG_MAX_INPUT ||
174 total_entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT) {
175 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100176 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100177 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100178
David Horstmannceeaeb92023-01-05 15:44:23 +0000179 memset(seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100180
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100181 /* IV. Gather entropy_len bytes of entropy for the seed */
David Horstmannceeaeb92023-01-05 15:44:23 +0000182 if ((ret = ctx->f_entropy(ctx->p_entropy,
183 seed, ctx->entropy_len)) != 0) {
184 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100185 }
186 seedlen += ctx->entropy_len;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100187
Hanno Beckera823d4c2019-08-27 06:47:18 +0100188 /* For initial seeding, allow adding of nonce generated
189 * from the entropy source. See Sect 8.6.7 in SP800-90A. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000190 if (use_nonce) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100191 /* Note: We don't merge the two calls to f_entropy() in order
192 * to avoid requesting too much entropy from f_entropy()
193 * at once. Specifically, if the underlying digest is not
194 * SHA-1, 3 / 2 * entropy_len is at least 36 Bytes, which
195 * is larger than the maximum of 32 Bytes that our own
196 * entropy source implementation can emit in a single
197 * call in configurations disabling SHA-512. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000198 if ((ret = ctx->f_entropy(ctx->p_entropy,
199 seed + seedlen,
200 ctx->entropy_len / 2)) != 0) {
201 return MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100202 }
203
204 seedlen += ctx->entropy_len / 2;
205 }
206
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100207
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100208 /* 1. Concatenate entropy and additional data if any */
David Horstmannceeaeb92023-01-05 15:44:23 +0000209 if (additional != NULL && len != 0) {
210 memcpy(seed + seedlen, additional, len);
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100211 seedlen += len;
212 }
213
214 /* 2. Update state */
David Horstmannceeaeb92023-01-05 15:44:23 +0000215 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, seed, seedlen)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200216 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000217 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100218
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100219 /* 3. Reset reseed_counter */
220 ctx->reseed_counter = 1;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100221
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200222exit:
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100223 /* 4. Done */
David Horstmannceeaeb92023-01-05 15:44:23 +0000224 mbedtls_platform_zeroize(seed, seedlen);
225 return ret;
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100226}
227
228/*
Hanno Beckera823d4c2019-08-27 06:47:18 +0100229 * HMAC_DRBG reseeding: 10.1.2.4 + 9.2
230 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000231int mbedtls_hmac_drbg_reseed(mbedtls_hmac_drbg_context *ctx,
232 const unsigned char *additional, size_t len)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100233{
David Horstmannceeaeb92023-01-05 15:44:23 +0000234 return hmac_drbg_reseed_core(ctx, additional, len, 0);
Hanno Beckera823d4c2019-08-27 06:47:18 +0100235}
236
237/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100238 * HMAC_DRBG initialisation (10.1.2.3 + 9.1)
Hanno Beckera823d4c2019-08-27 06:47:18 +0100239 *
240 * The nonce is not passed as a separate parameter but extracted
241 * from the entropy source as suggested in 8.6.7.
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100242 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000243int mbedtls_hmac_drbg_seed(mbedtls_hmac_drbg_context *ctx,
244 const mbedtls_md_info_t *md_info,
245 int (*f_entropy)(void *, unsigned char *, size_t),
246 void *p_entropy,
247 const unsigned char *custom,
248 size_t len)
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100249{
Janos Follath24eed8d2019-11-22 13:21:35 +0000250 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100251 size_t md_size;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100252
David Horstmannceeaeb92023-01-05 15:44:23 +0000253 if ((ret = mbedtls_md_setup(&ctx->md_ctx, md_info, 1)) != 0) {
254 return ret;
255 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100256
Gilles Peskinee39b2192021-02-09 18:43:33 +0100257 /* The mutex is initialized iff the md context is set up. */
Gilles Peskineb791dc62021-01-31 00:06:51 +0100258#if defined(MBEDTLS_THREADING_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000259 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100260#endif
261
David Horstmannceeaeb92023-01-05 15:44:23 +0000262 md_size = mbedtls_md_get_size(md_info);
Manuel Pégourié-Gonnardca878db2015-03-24 12:13:30 +0100263
Manuel Pégourié-Gonnardb05db2a2014-02-01 11:38:05 +0100264 /*
265 * Set initial working state.
266 * Use the V memory location, which is currently all 0, to initialize the
267 * MD context with an all-zero key. Then set V to its initial value.
268 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000269 if ((ret = mbedtls_md_hmac_starts(&ctx->md_ctx, ctx->V, md_size)) != 0) {
270 return ret;
271 }
272 memset(ctx->V, 0x01, md_size);
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100273
274 ctx->f_entropy = f_entropy;
275 ctx->p_entropy = p_entropy;
276
David Horstmannceeaeb92023-01-05 15:44:23 +0000277 if (ctx->entropy_len == 0) {
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200278 /*
279 * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by
280 * each hash function, then according to SP800-90A rev1 10.1 table 2,
281 * min_entropy_len (in bits) is security_strength.
282 *
283 * (This also matches the sizes used in the NIST test vectors.)
284 */
285 ctx->entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */
286 md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */
287 32; /* better (256+) -> 256 bits */
288 }
Manuel Pégourié-Gonnard8fc484d2014-01-30 18:28:09 +0100289
David Horstmannceeaeb92023-01-05 15:44:23 +0000290 if ((ret = hmac_drbg_reseed_core(ctx, custom, len,
291 1 /* add nonce */)) != 0) {
292 return ret;
Hanno Beckera823d4c2019-08-27 06:47:18 +0100293 }
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100294
David Horstmannceeaeb92023-01-05 15:44:23 +0000295 return 0;
Manuel Pégourié-Gonnardfe34a5f2014-01-30 15:06:40 +0100296}
297
298/*
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100299 * Set prediction resistance
300 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000301void mbedtls_hmac_drbg_set_prediction_resistance(mbedtls_hmac_drbg_context *ctx,
302 int resistance)
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100303{
304 ctx->prediction_resistance = resistance;
305}
306
307/*
Gilles Peskine8f7921e2019-10-04 11:47:35 +0200308 * Set entropy length grabbed for seeding
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100309 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000310void mbedtls_hmac_drbg_set_entropy_len(mbedtls_hmac_drbg_context *ctx, size_t len)
Manuel Pégourié-Gonnard4e669c62014-01-30 18:06:08 +0100311{
312 ctx->entropy_len = len;
313}
314
315/*
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100316 * Set reseed interval
317 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000318void mbedtls_hmac_drbg_set_reseed_interval(mbedtls_hmac_drbg_context *ctx, int interval)
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100319{
320 ctx->reseed_interval = interval;
321}
322
323/*
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100324 * HMAC_DRBG random function with optional additional data:
325 * 10.1.2.5 (arabic) + 9.3 (Roman)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100326 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000327int mbedtls_hmac_drbg_random_with_add(void *p_rng,
328 unsigned char *output, size_t out_len,
329 const unsigned char *additional, size_t add_len)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100330{
Janos Follath24eed8d2019-11-22 13:21:35 +0000331 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
David Horstmannceeaeb92023-01-05 15:44:23 +0000333 size_t md_len = mbedtls_md_get_size(ctx->md_ctx.md_info);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100334 size_t left = out_len;
335 unsigned char *out = output;
336
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100337 /* II. Check request length */
David Horstmannceeaeb92023-01-05 15:44:23 +0000338 if (out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST) {
339 return MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG;
340 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100341
342 /* III. Check input length */
David Horstmannceeaeb92023-01-05 15:44:23 +0000343 if (add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT) {
344 return MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
345 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100346
347 /* 1. (aka VII and IX) Check reseed counter and PR */
David Horstmannceeaeb92023-01-05 15:44:23 +0000348 if (ctx->f_entropy != NULL && /* For no-reseeding instances */
349 (ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON ||
350 ctx->reseed_counter > ctx->reseed_interval)) {
351 if ((ret = mbedtls_hmac_drbg_reseed(ctx, additional, add_len)) != 0) {
352 return ret;
353 }
Manuel Pégourié-Gonnard6e897c22014-01-30 19:29:04 +0100354
355 add_len = 0; /* VII.4 */
Manuel Pégourié-Gonnardaf786ff2014-01-30 18:44:18 +0100356 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100357
358 /* 2. Use additional data if any */
David Horstmannceeaeb92023-01-05 15:44:23 +0000359 if (additional != NULL && add_len != 0) {
360 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
361 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200362 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000363 }
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200364 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100365
366 /* 3, 4, 5. Generate bytes */
David Horstmannceeaeb92023-01-05 15:44:23 +0000367 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100368 size_t use_len = left > md_len ? md_len : left;
369
David Horstmannceeaeb92023-01-05 15:44:23 +0000370 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200371 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000372 }
373 if ((ret = mbedtls_md_hmac_update(&ctx->md_ctx,
374 ctx->V, md_len)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200375 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000376 }
377 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200378 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000379 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100380
David Horstmannceeaeb92023-01-05 15:44:23 +0000381 memcpy(out, ctx->V, use_len);
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100382 out += use_len;
383 left -= use_len;
384 }
385
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100386 /* 6. Update */
David Horstmannceeaeb92023-01-05 15:44:23 +0000387 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
388 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200389 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000390 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100391
Manuel Pégourié-Gonnard658dbed2014-01-30 19:03:45 +0100392 /* 7. Update reseed counter */
393 ctx->reseed_counter++;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100394
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200395exit:
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100396 /* 8. Done */
David Horstmannceeaeb92023-01-05 15:44:23 +0000397 return ret;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100398}
399
400/*
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100401 * HMAC_DRBG random function
402 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000403int mbedtls_hmac_drbg_random(void *p_rng, unsigned char *output, size_t out_len)
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100404{
Janos Follath24eed8d2019-11-22 13:21:35 +0000405 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100406 mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
407
408#if defined(MBEDTLS_THREADING_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000409 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
410 return ret;
411 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100412#endif
413
David Horstmannceeaeb92023-01-05 15:44:23 +0000414 ret = mbedtls_hmac_drbg_random_with_add(ctx, output, out_len, NULL, 0);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100415
416#if defined(MBEDTLS_THREADING_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000417 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
418 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
419 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100420#endif
421
David Horstmannceeaeb92023-01-05 15:44:23 +0000422 return ret;
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100423}
424
425/*
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800426 * This function resets HMAC_DRBG context to the state immediately
427 * after initial call of mbedtls_hmac_drbg_init().
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100428 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000429void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100430{
David Horstmannceeaeb92023-01-05 15:44:23 +0000431 if (ctx == NULL) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100432 return;
David Horstmannceeaeb92023-01-05 15:44:23 +0000433 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100434
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100435#if defined(MBEDTLS_THREADING_C)
Gilles Peskinee39b2192021-02-09 18:43:33 +0100436 /* The mutex is initialized iff the md context is set up. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000437 if (ctx->md_ctx.md_info != NULL) {
438 mbedtls_mutex_free(&ctx->mutex);
439 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100440#endif
David Horstmannceeaeb92023-01-05 15:44:23 +0000441 mbedtls_md_free(&ctx->md_ctx);
442 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_hmac_drbg_context));
Gavin Acquroff6aceb512020-03-01 17:06:11 -0800443 ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100444}
445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446#if defined(MBEDTLS_FS_IO)
David Horstmannceeaeb92023-01-05 15:44:23 +0000447int mbedtls_hmac_drbg_write_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100448{
Janos Follath24eed8d2019-11-22 13:21:35 +0000449 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100450 FILE *f;
David Horstmannceeaeb92023-01-05 15:44:23 +0000451 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452
David Horstmannceeaeb92023-01-05 15:44:23 +0000453 if ((f = fopen(path, "wb")) == NULL) {
454 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
455 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100456
David Horstmannceeaeb92023-01-05 15:44:23 +0000457 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000459 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460
David Horstmannceeaeb92023-01-05 15:44:23 +0000461 if (fwrite(buf, 1, sizeof(buf), f) != sizeof(buf)) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Paul Bakker4c284c92014-03-26 15:33:05 +0100463 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100464 }
465
466 ret = 0;
467
468exit:
David Horstmannceeaeb92023-01-05 15:44:23 +0000469 fclose(f);
470 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100471
David Horstmannceeaeb92023-01-05 15:44:23 +0000472 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473}
474
David Horstmannceeaeb92023-01-05 15:44:23 +0000475int mbedtls_hmac_drbg_update_seed_file(mbedtls_hmac_drbg_context *ctx, const char *path)
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100476{
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100477 int ret = 0;
Gilles Peskine82204662018-09-11 18:43:09 +0200478 FILE *f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100479 size_t n;
David Horstmannceeaeb92023-01-05 15:44:23 +0000480 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Gilles Peskine82204662018-09-11 18:43:09 +0200481 unsigned char c;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100482
David Horstmannceeaeb92023-01-05 15:44:23 +0000483 if ((f = fopen(path, "rb")) == NULL) {
484 return MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
485 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100486
David Horstmannceeaeb92023-01-05 15:44:23 +0000487 n = fread(buf, 1, sizeof(buf), f);
488 if (fread(&c, 1, 1, f) != 0) {
Gilles Peskine82204662018-09-11 18:43:09 +0200489 ret = MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG;
490 goto exit;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100491 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000492 if (n == 0 || ferror(f)) {
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100493 ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR;
Gilles Peskine82204662018-09-11 18:43:09 +0200494 goto exit;
495 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000496 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200497 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498
David Horstmannceeaeb92023-01-05 15:44:23 +0000499 ret = mbedtls_hmac_drbg_update_ret(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200500
501exit:
David Horstmannceeaeb92023-01-05 15:44:23 +0000502 mbedtls_platform_zeroize(buf, sizeof(buf));
503 if (f != NULL) {
504 fclose(f);
505 }
506 if (ret != 0) {
507 return ret;
508 }
509 return mbedtls_hmac_drbg_write_seed_file(ctx, path);
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100510}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#endif /* MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100512
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516#if !defined(MBEDTLS_SHA1_C)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100517/* Dummy checkup routine */
David Horstmannceeaeb92023-01-05 15:44:23 +0000518int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100519{
Manuel Pégourié-Gonnardd1004f02015-08-07 10:46:54 +0200520 (void) verbose;
David Horstmannceeaeb92023-01-05 15:44:23 +0000521 return 0;
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100522}
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100523#else
524
525#define OUTPUT_LEN 80
526
527/* From a NIST PR=true test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000528static const unsigned char entropy_pr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100529 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f,
530 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11,
531 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42,
532 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3,
David Horstmannceeaeb92023-01-05 15:44:23 +0000533 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4
534};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100535static const unsigned char result_pr[OUTPUT_LEN] = {
536 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39,
537 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94,
538 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54,
539 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e,
540 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab,
541 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3,
David Horstmannceeaeb92023-01-05 15:44:23 +0000542 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44
543};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100544
545/* From a NIST PR=false test vector */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000546static const unsigned char entropy_nopr[] = {
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100547 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66,
548 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8,
549 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3,
David Horstmannceeaeb92023-01-05 15:44:23 +0000550 0xe9, 0x9d, 0xfe, 0xdf
551};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100552static const unsigned char result_nopr[OUTPUT_LEN] = {
553 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f,
554 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6,
555 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a,
556 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec,
557 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd,
558 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49,
David Horstmannceeaeb92023-01-05 15:44:23 +0000559 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7
560};
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100561
562/* "Entropy" from buffer */
Manuel Pégourié-Gonnard95924852014-03-21 10:54:55 +0100563static size_t test_offset;
David Horstmannceeaeb92023-01-05 15:44:23 +0000564static int hmac_drbg_self_test_entropy(void *data,
565 unsigned char *buf, size_t len)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100566{
567 const unsigned char *p = data;
David Horstmannceeaeb92023-01-05 15:44:23 +0000568 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569 test_offset += len;
David Horstmannceeaeb92023-01-05 15:44:23 +0000570 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571}
572
David Horstmannceeaeb92023-01-05 15:44:23 +0000573#define CHK(c) if ((c) != 0) \
574 { \
575 if (verbose != 0) \
576 mbedtls_printf("failed\n"); \
577 return 1; \
578 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100579
580/*
581 * Checkup routine for HMAC_DRBG with SHA-1
582 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000583int mbedtls_hmac_drbg_self_test(int verbose)
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100584{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_hmac_drbg_context ctx;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100586 unsigned char buf[OUTPUT_LEN];
David Horstmannceeaeb92023-01-05 15:44:23 +0000587 const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100588
David Horstmannceeaeb92023-01-05 15:44:23 +0000589 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +0200590
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100591 /*
592 * PR = True
593 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000594 if (verbose != 0) {
595 mbedtls_printf(" HMAC_DRBG (PR = True) : ");
596 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100597
598 test_offset = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +0000599 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
600 hmac_drbg_self_test_entropy, (void *) entropy_pr,
601 NULL, 0));
602 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON);
603 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
604 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
605 CHK(memcmp(buf, result_pr, OUTPUT_LEN));
606 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100607
David Horstmannceeaeb92023-01-05 15:44:23 +0000608 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100609
David Horstmannceeaeb92023-01-05 15:44:23 +0000610 if (verbose != 0) {
611 mbedtls_printf("passed\n");
612 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
614 /*
615 * PR = False
616 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000617 if (verbose != 0) {
618 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
619 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
David Horstmannceeaeb92023-01-05 15:44:23 +0000621 mbedtls_hmac_drbg_init(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100622
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100623 test_offset = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +0000624 CHK(mbedtls_hmac_drbg_seed(&ctx, md_info,
625 hmac_drbg_self_test_entropy, (void *) entropy_nopr,
626 NULL, 0));
627 CHK(mbedtls_hmac_drbg_reseed(&ctx, NULL, 0));
628 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
629 CHK(mbedtls_hmac_drbg_random(&ctx, buf, OUTPUT_LEN));
630 CHK(memcmp(buf, result_nopr, OUTPUT_LEN));
631 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100632
David Horstmannceeaeb92023-01-05 15:44:23 +0000633 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100634
David Horstmannceeaeb92023-01-05 15:44:23 +0000635 if (verbose != 0) {
636 mbedtls_printf("passed\n");
637 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100638
David Horstmannceeaeb92023-01-05 15:44:23 +0000639 if (verbose != 0) {
640 mbedtls_printf("\n");
641 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642
David Horstmannceeaeb92023-01-05 15:44:23 +0000643 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100644}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645#endif /* MBEDTLS_SHA1_C */
646#endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648#endif /* MBEDTLS_HMAC_DRBG_C */