Skip to content
This repository was archived by the owner on Mar 5, 2024. It is now read-only.

Commit 6e0eb53

Browse files
thoh-otmczraf
authored andcommitted
Fix HMAC-PRNG implementation
Use tests based on NIST SP 800-90A HMAC_DRBG testvectors. Signed-off-by: Thomas Ebert Hansen <[email protected]> Signed-off-by: Rafael Misoczki <[email protected]>
1 parent b7e3195 commit 6e0eb53

File tree

2 files changed

+7403
-86
lines changed

2 files changed

+7403
-86
lines changed

lib/source/hmac_prng.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,28 @@ static const unsigned int MAX_GENS = UINT32_MAX;
7373
static const unsigned int MAX_OUT = (1 << 19);
7474

7575
/*
76-
* Assumes: prng != NULL, e != NULL, len >= 0.
76+
* Assumes: prng != NULL
7777
*/
78-
static void update(TCHmacPrng_t prng, const uint8_t *e, unsigned int len)
78+
static void update(TCHmacPrng_t prng, const uint8_t *data, unsigned int datalen, const uint8_t *additional_data, unsigned int additional_datalen)
7979
{
8080
const uint8_t separator0 = 0x00;
8181
const uint8_t separator1 = 0x01;
8282

83+
/* configure the new prng key into the prng's instance of hmac */
84+
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
85+
8386
/* use current state, e and separator 0 to compute a new prng key: */
8487
(void)tc_hmac_init(&prng->h);
8588
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
8689
(void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0));
87-
(void)tc_hmac_update(&prng->h, e, len);
90+
91+
if (data && datalen)
92+
(void)tc_hmac_update(&prng->h, data, datalen);
93+
if (additional_data && additional_datalen)
94+
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
95+
8896
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
97+
8998
/* configure the new prng key into the prng's instance of hmac */
9099
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
91100

@@ -94,12 +103,21 @@ static void update(TCHmacPrng_t prng, const uint8_t *e, unsigned int len)
94103
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
95104
(void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h);
96105

106+
if (data == 0 || datalen == 0)
107+
return;
108+
109+
/* configure the new prng key into the prng's instance of hmac */
110+
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
111+
97112
/* use current state, e and separator 1 to compute a new prng key: */
98113
(void)tc_hmac_init(&prng->h);
99114
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
100115
(void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1));
101-
(void)tc_hmac_update(&prng->h, e, len);
116+
(void)tc_hmac_update(&prng->h, data, datalen);
117+
if (additional_data && additional_datalen)
118+
(void)tc_hmac_update(&prng->h, additional_data, additional_datalen);
102119
(void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h);
120+
103121
/* configure the new prng key into the prng's instance of hmac */
104122
(void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
105123

@@ -124,10 +142,8 @@ int tc_hmac_prng_init(TCHmacPrng_t prng,
124142
/* put the generator into a known state: */
125143
_set(prng->key, 0x00, sizeof(prng->key));
126144
_set(prng->v, 0x01, sizeof(prng->v));
127-
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
128-
/* update assumes SOME key has been configured into HMAC */
129145

130-
update(prng, personalization, plen);
146+
update(prng, personalization, plen, 0, 0);
131147

132148
/* force a reseed before allowing tc_hmac_prng_generate to succeed: */
133149
prng->countdown = 0;
@@ -159,13 +175,12 @@ int tc_hmac_prng_reseed(TCHmacPrng_t prng,
159175
additionallen > MAX_ALEN) {
160176
return TC_CRYPTO_FAIL;
161177
} else {
162-
/* call update for the seed and additional_input */
163-
update(prng, seed, seedlen);
164-
update(prng, additional_input, additionallen);
178+
/* call update for the seed and additional_input */
179+
update(prng, seed, seedlen, additional_input, additionallen);
165180
}
166181
} else {
167182
/* call update only for the seed */
168-
update(prng, seed, seedlen);
183+
update(prng, seed, seedlen, 0, 0);
169184
}
170185

171186
/* ... and enable hmac_prng_generate */
@@ -191,6 +206,9 @@ int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
191206
prng->countdown--;
192207

193208
while (outlen != 0) {
209+
/* configure the new prng key into the prng's instance of hmac */
210+
tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key));
211+
194212
/* operate HMAC in OFB mode to create "random" outputs */
195213
(void)tc_hmac_init(&prng->h);
196214
(void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v));
@@ -206,7 +224,7 @@ int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng)
206224
}
207225

208226
/* block future PRNG compromises from revealing past state */
209-
update(prng, prng->v, TC_SHA256_DIGEST_SIZE);
227+
update(prng, 0, 0, 0, 0);
210228

211229
return TC_CRYPTO_SUCCESS;
212230
}

0 commit comments

Comments
 (0)