Added some comments.
[BearSSL] / inc / bearssl_rand.h
1 /*
2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 #ifndef BR_BEARSSL_RAND_H__
26 #define BR_BEARSSL_RAND_H__
27
28 #include <stddef.h>
29 #include <stdint.h>
30
31 /*
32 * Pseudo-Random Generators
33 * ------------------------
34 *
35 * A PRNG is a state-based engine that outputs pseudo-random bytes on
36 * demand. It is initialized with an initial seed, and additional seed
37 * bytes can be added afterwards. Bytes produced depend on the seeds
38 * and also on the exact sequence of calls (including sizes requested
39 * for each call).
40 *
41 * An object-oriented API is defined, with rules similar to that of
42 * hash functions. The context structure for a PRNG must start with
43 * a pointer to the vtable. The vtable contains the following fields:
44 *
45 * context_size size of the context structure for this PRNG
46 * init initialize context with an initial seed
47 * generate produce some pseudo-random bytes
48 * update insert some additional seed
49 *
50 * Note that the init() method may accept additional parameters, provided
51 * as a 'const void *' pointer at API level. These additional parameters
52 * depend on the implemented PRNG.
53 */
54
55 typedef struct br_prng_class_ br_prng_class;
56 struct br_prng_class_ {
57 size_t context_size;
58 void (*init)(const br_prng_class **ctx, const void *params,
59 const void *seed, size_t seed_len);
60 void (*generate)(const br_prng_class **ctx, void *out, size_t len);
61 void (*update)(const br_prng_class **ctx,
62 const void *seed, size_t seed_len);
63 };
64
65 /*
66 * HMAC_DRBG is a pseudo-random number generator based on HMAC (with
67 * an underlying hash function). HMAC_DRBG is specified in NIST Special
68 * Publication 800-90A. It works as a stateful machine:
69 * -- It has an internal state.
70 * -- The state can be updated with additional "entropy" (some bytes
71 * provided from the outside).
72 * -- Each request is for some bits (up to some limit). For each request,
73 * an internal "reseed counter" is incremented.
74 * -- When the reseed counter reaches a given threshold, a reseed is
75 * necessary.
76 *
77 * Standard limits are quite high: each request can produce up to 2^19
78 * bits (i.e. 64 kB of data), and the threshold for the reseed counter
79 * is 2^48. In practice, we cannot really reach that reseed counter, so
80 * the implementation simply omits the counter. Similarly, we consider
81 * that it is up to callers NOT to ask for more than 64 kB of randomness
82 * in one go. Under these conditions, this implementation cannot fail,
83 * and thus functions need not return any status code.
84 *
85 * (Asking for more than 64 kB of data in one generate() call won't make
86 * the implementation fail, and, as far as we know, it will not induce
87 * any actual weakness; this is "merely" out of the formal usage range
88 * defined for HMAC_DRBG.)
89 *
90 * A dedicated context structure (caller allocated, as usual) contains
91 * the current PRNG state.
92 *
93 * For the OOP interface, the "additional parameters" are a pointer to
94 * the class of the hash function to use.
95 */
96
97 typedef struct {
98 const br_prng_class *vtable;
99 unsigned char K[64];
100 unsigned char V[64];
101 const br_hash_class *digest_class;
102 } br_hmac_drbg_context;
103
104 extern const br_prng_class br_hmac_drbg_vtable;
105
106 /*
107 * Initialize a HMAC_DRBG instance, with the provided initial seed (of
108 * 'len' bytes). The 'seed' used here is what is called, in SP 800-90A
109 * terminology, the concatenation of the "seed", "nonce" and
110 * "personalization string", in that order.
111 *
112 * Formally, the underlying digest can only be SHA-1 or one of the SHA-2
113 * functions. This implementation also works with any other implemented
114 * hash function (e.g. MD5), but such usage is non-standard and not
115 * recommended.
116 */
117 void br_hmac_drbg_init(br_hmac_drbg_context *ctx,
118 const br_hash_class *digest_class, const void *seed, size_t len);
119
120 /*
121 * Obtain some pseudorandom bits from HMAC_DRBG. The provided context
122 * is updated. The output bits are written in 'out' ('len' bytes). The
123 * size of the requested chunk of pseudorandom bits MUST NOT exceed
124 * 64 kB (the function won't fail if more bytes are requested, but
125 * the usage will be outside of the HMAC_DRBG specification limits).
126 */
127 void br_hmac_drbg_generate(br_hmac_drbg_context *ctx, void *out, size_t len);
128
129 /*
130 * Update an HMAC_DRBG instance with some new entropy. The extra 'seed'
131 * complements the current state but does not completely replace any
132 * previous seed. The process is such that pushing new entropy, even of
133 * questionable quality, will not make the output "less random" in any
134 * practical way.
135 */
136 void br_hmac_drbg_update(br_hmac_drbg_context *ctx,
137 const void *seed, size_t len);
138
139 /*
140 * Get the hash function implementation used by a given instance of
141 * HMAC_DRBG.
142 */
143 static inline const br_hash_class *
144 br_hmac_drbg_get_hash(const br_hmac_drbg_context *ctx)
145 {
146 return ctx->digest_class;
147 }
148
149 #endif