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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010045void mbedtls_hmac_drbg_init(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnardf9e94812015-04-28 22:07:14 +020046{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010055int 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +010067 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +020068 goto exit;
69 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +0100102 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107void 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100111 (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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100118int 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100137 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155static 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100166 if (use_nonce == 0) {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100167 total_entropy_len = ctx->entropy_len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100168 } else {
Hanno Beckera823d4c2019-08-27 06:47:18 +0100169 total_entropy_len = ctx->entropy_len * 3 / 2;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100170 }
Hanno Beckera823d4c2019-08-27 06:47:18 +0100171
172 /* III. Check input length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100173 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182 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. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100190 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. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100198 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100215 if ((ret = mbedtls_hmac_drbg_update_ret(ctx, seed, seedlen)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200216 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100217 }
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100224 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100231int 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{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243int 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 mbedtls_mutex_init(&ctx->mutex);
Gilles Peskineb791dc62021-01-31 00:06:51 +0100260#endif
261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100269 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100277 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100290 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301void 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310void 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318void 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100327int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100333 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100348 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100359 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100363 }
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200364 }
Manuel Pégourié-Gonnard8208d162014-01-30 12:19:26 +0100365
366 /* 3, 4, 5. Generate bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 while (left != 0) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100368 size_t use_len = left > md_len ? md_len : left;
369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100370 if ((ret = mbedtls_md_hmac_reset(&ctx->md_ctx)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200371 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 }
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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100376 }
377 if ((ret = mbedtls_md_hmac_finish(&ctx->md_ctx, ctx->V)) != 0) {
Gilles Peskineb7f71c82018-09-11 16:54:57 +0200378 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 }
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100380
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 if ((ret = mbedtls_hmac_drbg_update_ret(ctx,
388 additional, add_len)) != 0) {
Gilles Peskinee0e9c572018-09-11 16:47:16 +0200389 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 }
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403int 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
410 return ret;
411 }
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100412#endif
413
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429void mbedtls_hmac_drbg_free(mbedtls_hmac_drbg_context *ctx)
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100430{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 if (ctx == NULL) {
Manuel Pégourié-Gonnard490bdf32014-01-27 14:03:10 +0100432 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 }
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. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100437 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100441 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)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100451 unsigned char buf[MBEDTLS_HMAC_DRBG_MAX_INPUT];
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100452
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100453 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457 if ((ret = mbedtls_hmac_drbg_random(ctx, buf, sizeof(buf))) != 0) {
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100458 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100459 }
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100460
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100461 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:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469 fclose(f);
470 mbedtls_platform_zeroize(buf, sizeof(buf));
Andres Amaya Garcia3fee7592017-06-26 10:22:24 +0100471
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 return ret;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100473}
474
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100475int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 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 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492 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 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 fclose(f);
Gilles Peskine82204662018-09-11 18:43:09 +0200497 f = NULL;
Manuel Pégourié-Gonnard48bc3e82014-01-30 21:11:16 +0100498
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 ret = mbedtls_hmac_drbg_update_ret(ctx, buf, n);
Gilles Peskine82204662018-09-11 18:43:09 +0200500
501exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518int 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100521 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100533 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100542 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100550 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,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100564static 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100568 memcpy(buf, p + test_offset, len);
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100569 test_offset += len;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100570 return 0;
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100571}
572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573#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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100583int 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];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100587 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589 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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100599 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100609
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100610 if (verbose != 0) {
611 mbedtls_printf("passed\n");
612 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100613
614 /*
615 * PR = False
616 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 if (verbose != 0) {
618 mbedtls_printf(" HMAC_DRBG (PR = False) : ");
619 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100620
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621 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;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 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
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100633 mbedtls_hmac_drbg_free(&ctx);
Manuel Pégourié-Gonnard0a4fb092015-05-07 12:50:31 +0100634
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635 if (verbose != 0) {
636 mbedtls_printf("passed\n");
637 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100639 if (verbose != 0) {
640 mbedtls_printf("\n");
641 }
Manuel Pégourié-Gonnard79afaa02014-01-31 11:12:09 +0100642
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100643 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 */