1 | /* |
2 | * DRBG based on NIST SP800-90A |
3 | * |
4 | * Copyright Stephan Mueller <smueller@chronox.de>, 2014 |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions |
8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, and the entire permission notice in its entirety, |
11 | * including the disclaimer of warranties. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. The name of the author may not be used to endorse or promote |
16 | * products derived from this software without specific prior |
17 | * written permission. |
18 | * |
19 | * ALTERNATIVELY, this product may be distributed under the terms of |
20 | * the GNU General Public License, in which case the provisions of the GPL are |
21 | * required INSTEAD OF the above restrictions. (This clause is |
22 | * necessary due to a potential bad interaction between the GPL and |
23 | * the restrictions contained in a BSD-style copyright.) |
24 | * |
25 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
26 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF |
28 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE |
29 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
31 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
32 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
35 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH |
36 | * DAMAGE. |
37 | */ |
38 | |
39 | #ifndef _DRBG_H |
40 | #define _DRBG_H |
41 | |
42 | |
43 | #include <linux/random.h> |
44 | #include <linux/scatterlist.h> |
45 | #include <crypto/hash.h> |
46 | #include <crypto/skcipher.h> |
47 | #include <linux/module.h> |
48 | #include <linux/crypto.h> |
49 | #include <linux/slab.h> |
50 | #include <crypto/internal/rng.h> |
51 | #include <crypto/rng.h> |
52 | #include <linux/fips.h> |
53 | #include <linux/mutex.h> |
54 | #include <linux/list.h> |
55 | #include <linux/workqueue.h> |
56 | |
57 | /* |
58 | * Concatenation Helper and string operation helper |
59 | * |
60 | * SP800-90A requires the concatenation of different data. To avoid copying |
61 | * buffers around or allocate additional memory, the following data structure |
62 | * is used to point to the original memory with its size. In addition, it |
63 | * is used to build a linked list. The linked list defines the concatenation |
64 | * of individual buffers. The order of memory block referenced in that |
65 | * linked list determines the order of concatenation. |
66 | */ |
67 | struct drbg_string { |
68 | const unsigned char *buf; |
69 | size_t len; |
70 | struct list_head list; |
71 | }; |
72 | |
73 | static inline void drbg_string_fill(struct drbg_string *string, |
74 | const unsigned char *buf, size_t len) |
75 | { |
76 | string->buf = buf; |
77 | string->len = len; |
78 | INIT_LIST_HEAD(list: &string->list); |
79 | } |
80 | |
81 | struct drbg_state; |
82 | typedef uint32_t drbg_flag_t; |
83 | |
84 | struct drbg_core { |
85 | drbg_flag_t flags; /* flags for the cipher */ |
86 | __u8 statelen; /* maximum state length */ |
87 | __u8 blocklen_bytes; /* block size of output in bytes */ |
88 | char cra_name[CRYPTO_MAX_ALG_NAME]; /* mapping to kernel crypto API */ |
89 | /* kernel crypto API backend cipher name */ |
90 | char backend_cra_name[CRYPTO_MAX_ALG_NAME]; |
91 | }; |
92 | |
93 | struct drbg_state_ops { |
94 | int (*update)(struct drbg_state *drbg, struct list_head *seed, |
95 | int reseed); |
96 | int (*generate)(struct drbg_state *drbg, |
97 | unsigned char *buf, unsigned int buflen, |
98 | struct list_head *addtl); |
99 | int (*crypto_init)(struct drbg_state *drbg); |
100 | int (*crypto_fini)(struct drbg_state *drbg); |
101 | |
102 | }; |
103 | |
104 | struct drbg_test_data { |
105 | struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */ |
106 | }; |
107 | |
108 | enum drbg_seed_state { |
109 | DRBG_SEED_STATE_UNSEEDED, |
110 | DRBG_SEED_STATE_PARTIAL, /* Seeded with !rng_is_initialized() */ |
111 | DRBG_SEED_STATE_FULL, |
112 | }; |
113 | |
114 | struct drbg_state { |
115 | struct mutex drbg_mutex; /* lock around DRBG */ |
116 | unsigned char *V; /* internal state 10.1.1.1 1a) */ |
117 | unsigned char *Vbuf; |
118 | /* hash: static value 10.1.1.1 1b) hmac / ctr: key */ |
119 | unsigned char *C; |
120 | unsigned char *Cbuf; |
121 | /* Number of RNG requests since last reseed -- 10.1.1.1 1c) */ |
122 | size_t reseed_ctr; |
123 | size_t reseed_threshold; |
124 | /* some memory the DRBG can use for its operation */ |
125 | unsigned char *scratchpad; |
126 | unsigned char *scratchpadbuf; |
127 | void *priv_data; /* Cipher handle */ |
128 | |
129 | struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */ |
130 | struct skcipher_request *ctr_req; /* CTR mode request handle */ |
131 | __u8 *outscratchpadbuf; /* CTR mode output scratchpad */ |
132 | __u8 *outscratchpad; /* CTR mode aligned outbuf */ |
133 | struct crypto_wait ctr_wait; /* CTR mode async wait obj */ |
134 | struct scatterlist sg_in, sg_out; /* CTR mode SGLs */ |
135 | |
136 | enum drbg_seed_state seeded; /* DRBG fully seeded? */ |
137 | unsigned long last_seed_time; |
138 | bool pr; /* Prediction resistance enabled? */ |
139 | bool fips_primed; /* Continuous test primed? */ |
140 | unsigned char *prev; /* FIPS 140-2 continuous test value */ |
141 | struct crypto_rng *jent; |
142 | const struct drbg_state_ops *d_ops; |
143 | const struct drbg_core *core; |
144 | struct drbg_string test_data; |
145 | }; |
146 | |
147 | static inline __u8 drbg_statelen(struct drbg_state *drbg) |
148 | { |
149 | if (drbg && drbg->core) |
150 | return drbg->core->statelen; |
151 | return 0; |
152 | } |
153 | |
154 | static inline __u8 drbg_blocklen(struct drbg_state *drbg) |
155 | { |
156 | if (drbg && drbg->core) |
157 | return drbg->core->blocklen_bytes; |
158 | return 0; |
159 | } |
160 | |
161 | static inline __u8 drbg_keylen(struct drbg_state *drbg) |
162 | { |
163 | if (drbg && drbg->core) |
164 | return (drbg->core->statelen - drbg->core->blocklen_bytes); |
165 | return 0; |
166 | } |
167 | |
168 | static inline size_t drbg_max_request_bytes(struct drbg_state *drbg) |
169 | { |
170 | /* SP800-90A requires the limit 2**19 bits, but we return bytes */ |
171 | return (1 << 16); |
172 | } |
173 | |
174 | static inline size_t drbg_max_addtl(struct drbg_state *drbg) |
175 | { |
176 | /* SP800-90A requires 2**35 bytes additional info str / pers str */ |
177 | #if (__BITS_PER_LONG == 32) |
178 | /* |
179 | * SP800-90A allows smaller maximum numbers to be returned -- we |
180 | * return SIZE_MAX - 1 to allow the verification of the enforcement |
181 | * of this value in drbg_healthcheck_sanity. |
182 | */ |
183 | return (SIZE_MAX - 1); |
184 | #else |
185 | return (1UL<<35); |
186 | #endif |
187 | } |
188 | |
189 | static inline size_t drbg_max_requests(struct drbg_state *drbg) |
190 | { |
191 | /* SP800-90A requires 2**48 maximum requests before reseeding */ |
192 | return (1<<20); |
193 | } |
194 | |
195 | /* |
196 | * This is a wrapper to the kernel crypto API function of |
197 | * crypto_rng_generate() to allow the caller to provide additional data. |
198 | * |
199 | * @drng DRBG handle -- see crypto_rng_get_bytes |
200 | * @outbuf output buffer -- see crypto_rng_get_bytes |
201 | * @outlen length of output buffer -- see crypto_rng_get_bytes |
202 | * @addtl_input additional information string input buffer |
203 | * @addtllen length of additional information string buffer |
204 | * |
205 | * return |
206 | * see crypto_rng_get_bytes |
207 | */ |
208 | static inline int crypto_drbg_get_bytes_addtl(struct crypto_rng *drng, |
209 | unsigned char *outbuf, unsigned int outlen, |
210 | struct drbg_string *addtl) |
211 | { |
212 | return crypto_rng_generate(tfm: drng, src: addtl->buf, slen: addtl->len, |
213 | dst: outbuf, dlen: outlen); |
214 | } |
215 | |
216 | /* |
217 | * TEST code |
218 | * |
219 | * This is a wrapper to the kernel crypto API function of |
220 | * crypto_rng_generate() to allow the caller to provide additional data and |
221 | * allow furnishing of test_data |
222 | * |
223 | * @drng DRBG handle -- see crypto_rng_get_bytes |
224 | * @outbuf output buffer -- see crypto_rng_get_bytes |
225 | * @outlen length of output buffer -- see crypto_rng_get_bytes |
226 | * @addtl_input additional information string input buffer |
227 | * @addtllen length of additional information string buffer |
228 | * @test_data filled test data |
229 | * |
230 | * return |
231 | * see crypto_rng_get_bytes |
232 | */ |
233 | static inline int crypto_drbg_get_bytes_addtl_test(struct crypto_rng *drng, |
234 | unsigned char *outbuf, unsigned int outlen, |
235 | struct drbg_string *addtl, |
236 | struct drbg_test_data *test_data) |
237 | { |
238 | crypto_rng_set_entropy(tfm: drng, data: test_data->testentropy->buf, |
239 | len: test_data->testentropy->len); |
240 | return crypto_rng_generate(tfm: drng, src: addtl->buf, slen: addtl->len, |
241 | dst: outbuf, dlen: outlen); |
242 | } |
243 | |
244 | /* |
245 | * TEST code |
246 | * |
247 | * This is a wrapper to the kernel crypto API function of |
248 | * crypto_rng_reset() to allow the caller to provide test_data |
249 | * |
250 | * @drng DRBG handle -- see crypto_rng_reset |
251 | * @pers personalization string input buffer |
252 | * @perslen length of additional information string buffer |
253 | * @test_data filled test data |
254 | * |
255 | * return |
256 | * see crypto_rng_reset |
257 | */ |
258 | static inline int crypto_drbg_reset_test(struct crypto_rng *drng, |
259 | struct drbg_string *pers, |
260 | struct drbg_test_data *test_data) |
261 | { |
262 | crypto_rng_set_entropy(tfm: drng, data: test_data->testentropy->buf, |
263 | len: test_data->testentropy->len); |
264 | return crypto_rng_reset(tfm: drng, seed: pers->buf, slen: pers->len); |
265 | } |
266 | |
267 | /* DRBG type flags */ |
268 | #define DRBG_CTR ((drbg_flag_t)1<<0) |
269 | #define DRBG_HMAC ((drbg_flag_t)1<<1) |
270 | #define DRBG_HASH ((drbg_flag_t)1<<2) |
271 | #define DRBG_TYPE_MASK (DRBG_CTR | DRBG_HMAC | DRBG_HASH) |
272 | /* DRBG strength flags */ |
273 | #define DRBG_STRENGTH128 ((drbg_flag_t)1<<3) |
274 | #define DRBG_STRENGTH192 ((drbg_flag_t)1<<4) |
275 | #define DRBG_STRENGTH256 ((drbg_flag_t)1<<5) |
276 | #define DRBG_STRENGTH_MASK (DRBG_STRENGTH128 | DRBG_STRENGTH192 | \ |
277 | DRBG_STRENGTH256) |
278 | |
279 | enum drbg_prefixes { |
280 | DRBG_PREFIX0 = 0x00, |
281 | DRBG_PREFIX1, |
282 | DRBG_PREFIX2, |
283 | DRBG_PREFIX3 |
284 | }; |
285 | |
286 | #endif /* _DRBG_H */ |
287 | |