2 * Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
13 #include <openssl/crypto.h>
14 #include <openssl/err.h>
15 #include <openssl/rand.h>
16 #include "internal/thread_once.h"
19 /* 440 bits from SP800-90Ar1 10.1 table 2 */
20 #define HASH_PRNG_SMALL_SEEDLEN (440/8)
21 /* Determine what seedlen to use based on the block length */
22 #define MAX_BLOCKLEN_USING_SMALL_SEEDLEN (256/8)
23 #define INBYTE_IGNORE ((unsigned char)0xFF)
27 * SP800-90Ar1 10.3.1 Derivation function using a Hash Function (Hash_df).
28 * The input string used is composed of:
29 * inbyte - An optional leading byte (ignore if equal to INBYTE_IGNORE)
30 * in - input string 1 (A Non NULL value).
31 * in2 - optional input string (Can be NULL).
32 * in3 - optional input string (Can be NULL).
33 * These are concatenated as part of the DigestUpdate process.
35 static int hash_df(RAND_DRBG
*drbg
, unsigned char *out
,
36 const unsigned char inbyte
,
37 const unsigned char *in
, size_t inlen
,
38 const unsigned char *in2
, size_t in2len
,
39 const unsigned char *in3
, size_t in3len
)
41 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
42 EVP_MD_CTX
*ctx
= hash
->ctx
;
43 unsigned char *vtmp
= hash
->vtmp
;
44 /* tmp = counter || num_bits_returned || [inbyte] */
45 unsigned char tmp
[1 + 4 + 1];
47 size_t outlen
= drbg
->seedlen
;
48 size_t num_bits_returned
= outlen
* 8;
50 * No need to check outlen size here, as the standard only ever needs
51 * seedlen bytes which is always less than the maximum permitted.
54 /* (Step 3) counter = 1 (tmp[0] is the 8 bit counter) */
56 /* tmp[1..4] is the fixed 32 bit no_of_bits_to_return */
57 tmp
[tmp_sz
++] = (unsigned char)((num_bits_returned
>> 24) & 0xff);
58 tmp
[tmp_sz
++] = (unsigned char)((num_bits_returned
>> 16) & 0xff);
59 tmp
[tmp_sz
++] = (unsigned char)((num_bits_returned
>> 8) & 0xff);
60 tmp
[tmp_sz
++] = (unsigned char)(num_bits_returned
& 0xff);
61 /* Tack the additional input byte onto the end of tmp if it exists */
62 if (inbyte
!= INBYTE_IGNORE
)
63 tmp
[tmp_sz
++] = inbyte
;
68 * (Step 4.1) out = out || Hash(tmp || in || [in2] || [in3])
69 * (where tmp = counter || num_bits_returned || [inbyte])
71 if (!(EVP_DigestInit_ex(ctx
, hash
->md
, NULL
)
72 && EVP_DigestUpdate(ctx
, tmp
, tmp_sz
)
73 && EVP_DigestUpdate(ctx
, in
, inlen
)
74 && (in2
== NULL
|| EVP_DigestUpdate(ctx
, in2
, in2len
))
75 && (in3
== NULL
|| EVP_DigestUpdate(ctx
, in3
, in3len
))))
78 if (outlen
< hash
->blocklen
) {
79 if (!EVP_DigestFinal(ctx
, vtmp
, NULL
))
81 memcpy(out
, vtmp
, outlen
);
82 OPENSSL_cleanse(vtmp
, hash
->blocklen
);
84 } else if(!EVP_DigestFinal(ctx
, out
, NULL
)) {
88 outlen
-= hash
->blocklen
;
91 /* (Step 4.2) counter++ */
93 out
+= hash
->blocklen
;
98 /* Helper function that just passes 2 input parameters to hash_df() */
99 static int hash_df1(RAND_DRBG
*drbg
, unsigned char *out
,
100 const unsigned char in_byte
,
101 const unsigned char *in1
, size_t in1len
)
103 return hash_df(drbg
, out
, in_byte
, in1
, in1len
, NULL
, 0, NULL
, 0);
107 * Add 2 byte buffers together. The first elements in each buffer are the top
108 * most bytes. The result is stored in the dst buffer.
109 * The final carry is ignored i.e: dst = (dst + in) mod (2^seedlen_bits).
110 * where dst size is drbg->seedlen, and inlen <= drbg->seedlen.
112 static int add_bytes(RAND_DRBG
*drbg
, unsigned char *dst
,
113 unsigned char *in
, size_t inlen
)
117 const unsigned char *add
;
118 unsigned char carry
= 0, *d
;
120 assert(drbg
->seedlen
>= 1 && inlen
>= 1 && inlen
<= drbg
->seedlen
);
122 d
= &dst
[drbg
->seedlen
- 1];
123 add
= &in
[inlen
- 1];
125 for (i
= inlen
; i
> 0; i
--, d
--, add
--) {
126 result
= *d
+ *add
+ carry
;
127 carry
= (unsigned char)(result
>> 8);
128 *d
= (unsigned char)(result
& 0xff);
132 /* Add the carry to the top of the dst if inlen is not the same size */
133 for (i
= drbg
->seedlen
- inlen
; i
> 0; --i
, d
--) {
134 *d
+= 1; /* Carry can only be 1 */
135 if (*d
!= 0) /* exit if carry doesnt propagate to the next byte */
142 /* V = (V + Hash(inbyte || V || [additional_input]) mod (2^seedlen) */
143 static int add_hash_to_v(RAND_DRBG
*drbg
, unsigned char inbyte
,
144 const unsigned char *adin
, size_t adinlen
)
146 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
147 EVP_MD_CTX
*ctx
= hash
->ctx
;
149 return EVP_DigestInit_ex(ctx
, hash
->md
, NULL
)
150 && EVP_DigestUpdate(ctx
, &inbyte
, 1)
151 && EVP_DigestUpdate(ctx
, hash
->V
, drbg
->seedlen
)
152 && (adin
== NULL
|| EVP_DigestUpdate(ctx
, adin
, adinlen
))
153 && EVP_DigestFinal(ctx
, hash
->vtmp
, NULL
)
154 && add_bytes(drbg
, hash
->V
, hash
->vtmp
, hash
->blocklen
);
158 * The Hashgen() as listed in SP800-90Ar1 10.1.1.4 Hash_DRBG_Generate_Process.
160 * drbg contains the current value of V.
161 * outlen is the requested number of bytes.
162 * out is a buffer to return the generated bits.
164 * The algorithm to generate the bits is:
168 * W = W || Hash(data)
169 * data = (data + 1) mod (2^seedlen)
171 * out = Leftmost(W, outlen)
173 * Returns zero if an error occurs otherwise it returns 1.
175 static int hash_gen(RAND_DRBG
*drbg
, unsigned char *out
, size_t outlen
)
177 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
178 unsigned char one
= 1;
182 memcpy(hash
->vtmp
, hash
->V
, drbg
->seedlen
);
184 if (!EVP_DigestInit_ex(hash
->ctx
, hash
->md
, NULL
)
185 || !EVP_DigestUpdate(hash
->ctx
, hash
->vtmp
, drbg
->seedlen
))
188 if (outlen
< hash
->blocklen
) {
189 if (!EVP_DigestFinal(hash
->ctx
, hash
->vtmp
, NULL
))
191 memcpy(out
, hash
->vtmp
, outlen
);
194 if (!EVP_DigestFinal(hash
->ctx
, out
, NULL
))
196 outlen
-= hash
->blocklen
;
199 out
+= hash
->blocklen
;
201 add_bytes(drbg
, hash
->vtmp
, &one
, 1);
207 * SP800-90Ar1 10.1.1.2 Hash_DRBG_Instantiate_Process:
209 * ent is entropy input obtained from a randomness source of length ent_len.
210 * nonce is a string of bytes of length nonce_len.
211 * pstr is a personalization string received from an application. May be NULL.
213 * Returns zero if an error occurs otherwise it returns 1.
215 static int drbg_hash_instantiate(RAND_DRBG
*drbg
,
216 const unsigned char *ent
, size_t ent_len
,
217 const unsigned char *nonce
, size_t nonce_len
,
218 const unsigned char *pstr
, size_t pstr_len
)
220 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
222 /* (Step 1-3) V = Hash_df(entropy||nonce||pers, seedlen) */
223 return hash_df(drbg
, hash
->V
, INBYTE_IGNORE
,
224 ent
, ent_len
, nonce
, nonce_len
, pstr
, pstr_len
)
225 /* (Step 4) C = Hash_df(0x00||V, seedlen) */
226 && hash_df1(drbg
, hash
->C
, 0x00, hash
->V
, drbg
->seedlen
);
230 * SP800-90Ar1 10.1.1.3 Hash_DRBG_Reseed_Process:
232 * ent is entropy input bytes obtained from a randomness source.
233 * addin is additional input received from an application. May be NULL.
235 * Returns zero if an error occurs otherwise it returns 1.
237 static int drbg_hash_reseed(RAND_DRBG
*drbg
,
238 const unsigned char *ent
, size_t ent_len
,
239 const unsigned char *adin
, size_t adin_len
)
241 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
243 /* (Step 1-2) V = Hash_df(0x01 || V || entropy_input || additional_input)*/
244 /* V about to be updated so use C as output instead */
245 if (!hash_df(drbg
, hash
->C
, 0x01, hash
->V
, drbg
->seedlen
, ent
, ent_len
,
248 memcpy(hash
->V
, hash
->C
, drbg
->seedlen
);
249 /* (Step 4) C = Hash_df(0x00||V, seedlen) */
250 return hash_df1(drbg
, hash
->C
, 0x00, hash
->V
, drbg
->seedlen
);
254 * SP800-90Ar1 10.1.1.4 Hash_DRBG_Generate_Process:
256 * Generates pseudo random bytes using the drbg.
257 * out is a buffer to fill with outlen bytes of pseudo random data.
258 * addin is additional input received from an application. May be NULL.
260 * Returns zero if an error occurs otherwise it returns 1.
262 static int drbg_hash_generate(RAND_DRBG
*drbg
,
263 unsigned char *out
, size_t outlen
,
264 const unsigned char *adin
, size_t adin_len
)
266 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
267 unsigned char counter
[4];
268 int reseed_counter
= drbg
->reseed_gen_counter
;
270 counter
[0] = (unsigned char)((reseed_counter
>> 24) & 0xff);
271 counter
[1] = (unsigned char)((reseed_counter
>> 16) & 0xff);
272 counter
[2] = (unsigned char)((reseed_counter
>> 8) & 0xff);
273 counter
[3] = (unsigned char)(reseed_counter
& 0xff);
276 /* (Step 2) if adin != NULL then V = V + Hash(0x02||V||adin) */
278 || add_hash_to_v(drbg
, 0x02, adin
, adin_len
))
279 /* (Step 3) Hashgen(outlen, V) */
280 && hash_gen(drbg
, out
, outlen
)
281 /* (Step 4/5) H = V = (V + Hash(0x03||V) mod (2^seedlen_bits) */
282 && add_hash_to_v(drbg
, 0x03, NULL
, 0)
283 /* (Step 5) V = (V + H + C + reseed_counter) mod (2^seedlen_bits) */
284 /* V = (V + C) mod (2^seedlen_bits) */
285 && add_bytes(drbg
, hash
->V
, hash
->C
, drbg
->seedlen
)
286 /* V = (V + reseed_counter) mod (2^seedlen_bits) */
287 && add_bytes(drbg
, hash
->V
, counter
, 4);
290 static int drbg_hash_uninstantiate(RAND_DRBG
*drbg
)
292 EVP_MD_meth_free(drbg
->data
.hash
.md
);
293 EVP_MD_CTX_free(drbg
->data
.hash
.ctx
);
294 OPENSSL_cleanse(&drbg
->data
.hash
, sizeof(drbg
->data
.hash
));
298 static RAND_DRBG_METHOD drbg_hash_meth
= {
299 drbg_hash_instantiate
,
302 drbg_hash_uninstantiate
305 int drbg_hash_init(RAND_DRBG
*drbg
)
308 RAND_DRBG_HASH
*hash
= &drbg
->data
.hash
;
311 /* Any approved digest is allowed */
312 md
= EVP_MD_meth_dup(EVP_get_digestbynid(drbg
->type
));
314 /* TODO(3.0): Fill this out with the complete list of allowed digests */
315 switch (drbg
->type
) {
319 md
= EVP_MD_fetch(drbg
->libctx
, "SHA256", "");
327 drbg
->meth
= &drbg_hash_meth
;
329 if (hash
->ctx
== NULL
) {
330 hash
->ctx
= EVP_MD_CTX_new();
331 if (hash
->ctx
== NULL
) {
332 EVP_MD_meth_free(md
);
337 EVP_MD_meth_free(hash
->md
);
340 /* These are taken from SP 800-90 10.1 Table 2 */
341 hash
->blocklen
= EVP_MD_size(md
);
342 /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
343 drbg
->strength
= 64 * (hash
->blocklen
>> 3);
344 if (drbg
->strength
> 256)
345 drbg
->strength
= 256;
346 if (hash
->blocklen
> MAX_BLOCKLEN_USING_SMALL_SEEDLEN
)
347 drbg
->seedlen
= HASH_PRNG_MAX_SEEDLEN
;
349 drbg
->seedlen
= HASH_PRNG_SMALL_SEEDLEN
;
351 drbg
->min_entropylen
= drbg
->strength
/ 8;
352 drbg
->max_entropylen
= DRBG_MAX_LENGTH
;
354 drbg
->min_noncelen
= drbg
->min_entropylen
/ 2;
355 drbg
->max_noncelen
= DRBG_MAX_LENGTH
;
357 drbg
->max_perslen
= DRBG_MAX_LENGTH
;
358 drbg
->max_adinlen
= DRBG_MAX_LENGTH
;
360 /* Maximum number of bits per request = 2^19 = 2^16 bytes */
361 drbg
->max_request
= 1 << 16;