1 /*
2 * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 *
23 * Alternatively, you may distribute this code in source or binary
24 * form, with or without modification, provided that the following
25 * conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the above disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above
31 * copyright notice, this list of conditions and the above
32 * disclaimer in the documentation and/or other materials provided
33 * with the distribution.
34 */
35
36 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
37
38 /** @file
39 *
40 * DRBG mechanism
41 *
42 * This mechanism is designed to comply with ANS X9.82 Part 3-2007
43 * Section 9. This standard is not freely available, but most of the
44 * text appears to be shared with NIST SP 800-90, which can be
45 * downloaded from
46 *
47 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
48 *
49 * Where possible, references are given to both documents. In the
50 * case of any disagreement, ANS X9.82 takes priority over NIST SP
51 * 800-90. (In particular, note that some algorithms that are
52 * Approved by NIST SP 800-90 are not Approved by ANS X9.82.)
53 */
54
55 #include <stdint.h>
56 #include <string.h>
57 #include <errno.h>
58 #include <assert.h>
59 #include <ipxe/entropy.h>
60 #include <ipxe/drbg.h>
61
62 /**
63 * Instantiate DRBG
64 *
65 * @v state Algorithm state to be initialised
66 * @v personal Personalisation string
67 * @v personal_len Length of personalisation string
68 * @ret rc Return status code
69 *
70 * This is the Instantiate_function defined in ANS X9.82 Part 3-2007
71 * Section 9.2 (NIST SP 800-90 Section 9.1).
72 *
73 * Only a single security strength is supported, and prediction
74 * resistance is always enabled. The nonce is accounted for by
75 * increasing the entropy input, as per ANS X9.82 Part 3-2007 Section
76 * 8.4.2 (NIST SP 800-90 Section 8.6.7).
77 */
drbg_instantiate(struct drbg_state * state,const void * personal,size_t personal_len)78 int drbg_instantiate ( struct drbg_state *state, const void *personal,
79 size_t personal_len ) {
80 unsigned int entropy_bits = ( ( 3 * DRBG_SECURITY_STRENGTH + 1 ) / 2 );
81 size_t min_len = DRBG_MIN_ENTROPY_LEN_BYTES;
82 size_t max_len = DRBG_MAX_ENTROPY_LEN_BYTES;
83 uint8_t data[max_len];
84 int len;
85 int rc;
86
87 DBGC ( state, "DRBG %p instantiate\n", state );
88
89 /* Sanity checks */
90 assert ( state != NULL );
91
92 /* 1. If requested_instantiation_security_strength >
93 * highest_supported_security_strength, then return an
94 * ERROR_FLAG
95 */
96 if ( DRBG_SECURITY_STRENGTH > DRBG_MAX_SECURITY_STRENGTH ) {
97 DBGC ( state, "DRBG %p cannot support security strength %d\n",
98 state, DRBG_SECURITY_STRENGTH );
99 return -ENOTSUP;
100 }
101
102 /* 2. If prediction_resistance_flag is set, and prediction
103 * resistance is not supported, then return an ERROR_FLAG
104 *
105 * (Nothing to do since prediction resistance is always
106 * supported.)
107 */
108
109 /* 3. If the length of the personalization_string >
110 * max_personalization_string_length, return an ERROR_FLAG
111 */
112 if ( personal_len > DRBG_MAX_PERSONAL_LEN_BYTES ) {
113 DBGC ( state, "DRBG %p personalisation string too long (%zd "
114 "bytes)\n", state, personal_len );
115 return -ERANGE;
116 }
117
118 /* 4. Set security_strength to the nearest security strength
119 * greater than or equal to
120 * requested_instantiation_security_strength.
121 *
122 * (Nothing to do since we support only a single security
123 * strength.)
124 */
125
126 /* 5. Using the security_strength, select appropriate DRBG
127 * mechanism parameters.
128 *
129 * (Nothing to do since we support only a single security
130 * strength.)
131 */
132
133 /* 6. ( status, entropy_input ) = Get_entropy_input (
134 * security_strength, min_length, max_length,
135 * prediction_resistance_request )
136 * 7. If an ERROR is returned in step 6, return a
137 * CATASTROPHIC_ERROR_FLAG.
138 * 8. Obtain a nonce.
139 */
140 len = get_entropy_input ( entropy_bits, data, min_len,
141 sizeof ( data ) );
142 if ( len < 0 ) {
143 rc = len;
144 DBGC ( state, "DRBG %p could not get entropy input: %s\n",
145 state, strerror ( rc ) );
146 return rc;
147 }
148 assert ( len >= ( int ) min_len );
149 assert ( len <= ( int ) sizeof ( data ) );
150
151 /* 9. initial_working_state = Instantiate_algorithm (
152 * entropy_input, nonce, personalization_string ).
153 */
154 drbg_instantiate_algorithm ( state, data, len, personal, personal_len );
155
156 /* 10. Get a state_handle for a currently empty state. If an
157 * empty internal state cannot be found, return an
158 * ERROR_FLAG.
159 * 11. Set the internal state indicated by state_handle to
160 * the initial values for the internal state (i.e. set
161 * the working_state to the values returned as
162 * initial_working_state in step 9 and any other values
163 * required for the working_state, and set the
164 * administrative information to the appropriate values.
165 *
166 * (Almost nothing to do since the memory to hold the state
167 * was passed in by the caller and has already been updated
168 * in-situ.)
169 */
170 state->reseed_required = 0;
171 state->valid = 1;
172
173 /* 12. Return SUCCESS and state_handle. */
174 return 0;
175 }
176
177 /**
178 * Reseed DRBG
179 *
180 * @v state Algorithm state
181 * @v additional Additional input
182 * @v additional_len Length of additional input
183 * @ret rc Return status code
184 *
185 * This is the Reseed_function defined in ANS X9.82 Part 3-2007
186 * Section 9.3 (NIST SP 800-90 Section 9.2).
187 *
188 * Prediction resistance is always enabled.
189 */
drbg_reseed(struct drbg_state * state,const void * additional,size_t additional_len)190 int drbg_reseed ( struct drbg_state *state, const void *additional,
191 size_t additional_len ) {
192 unsigned int entropy_bits = DRBG_SECURITY_STRENGTH;
193 size_t min_len = DRBG_MIN_ENTROPY_LEN_BYTES;
194 size_t max_len = DRBG_MAX_ENTROPY_LEN_BYTES;
195 uint8_t data[max_len];
196 int len;
197 int rc;
198
199 DBGC ( state, "DRBG %p reseed\n", state );
200
201 /* Sanity checks */
202 assert ( state != NULL );
203
204 /* 1. Using state_handle, obtain the current internal state.
205 * If state_handle indicates an invalid or empty internal
206 * state, return an ERROR_FLAG.
207 *
208 * (Almost nothing to do since the memory holding the internal
209 * state was passed in by the caller.)
210 */
211 if ( ! state->valid ) {
212 DBGC ( state, "DRBG %p not valid\n", state );
213 return -EINVAL;
214 }
215
216 /* 2. If prediction_resistance_request is set, and
217 * prediction_resistance_flag is not set, then return an
218 * ERROR_FLAG.
219 *
220 * (Nothing to do since prediction resistance is always
221 * supported.)
222 */
223
224 /* 3. If the length of the additional_input >
225 * max_additional_input_length, return an ERROR_FLAG.
226 */
227 if ( additional_len > DRBG_MAX_ADDITIONAL_LEN_BYTES ) {
228 DBGC ( state, "DRBG %p additional input too long (%zd bytes)\n",
229 state, additional_len );
230 return -ERANGE;
231 }
232
233 /* 4. ( status, entropy_input ) = Get_entropy_input (
234 * security_strength, min_length, max_length,
235 * prediction_resistance_request ).
236 *
237 * 5. If an ERROR is returned in step 4, return a
238 * CATASTROPHIC_ERROR_FLAG.
239 */
240 len = get_entropy_input ( entropy_bits, data, min_len,
241 sizeof ( data ) );
242 if ( len < 0 ) {
243 rc = len;
244 DBGC ( state, "DRBG %p could not get entropy input: %s\n",
245 state, strerror ( rc ) );
246 return rc;
247 }
248
249 /* 6. new_working_state = Reseed_algorithm ( working_state,
250 * entropy_input, additional_input ).
251 */
252 drbg_reseed_algorithm ( state, data, len, additional, additional_len );
253
254 /* 7. Replace the working_state in the internal state
255 * indicated by state_handle with the values of
256 * new_working_state obtained in step 6.
257 *
258 * (Nothing to do since the state has already been updated in-situ.)
259 */
260
261 /* 8. Return SUCCESS. */
262 return 0;
263 }
264
265 /**
266 * Generate pseudorandom bits using DRBG
267 *
268 * @v state Algorithm state
269 * @v additional Additional input
270 * @v additional_len Length of additional input
271 * @v prediction_resist Prediction resistance is required
272 * @v data Output buffer
273 * @v len Length of output buffer
274 * @ret rc Return status code
275 *
276 * This is the Generate_function defined in ANS X9.82 Part 3-2007
277 * Section 9.4 (NIST SP 800-90 Section 9.3).
278 *
279 * Requests must be for an integral number of bytes. Only a single
280 * security strength is supported. Prediction resistance is supported
281 * if requested.
282 */
drbg_generate(struct drbg_state * state,const void * additional,size_t additional_len,int prediction_resist,void * data,size_t len)283 int drbg_generate ( struct drbg_state *state, const void *additional,
284 size_t additional_len, int prediction_resist,
285 void *data, size_t len ) {
286 int rc;
287
288 DBGC ( state, "DRBG %p generate\n", state );
289
290 /* Sanity checks */
291 assert ( state != NULL );
292 assert ( data != NULL );
293
294 /* 1. Using state_handle, obtain the current internal state
295 * for the instantiation. If state_handle indicates an
296 * invalid or empty internal state, then return an ERROR_FLAG.
297 *
298 * (Almost nothing to do since the memory holding the internal
299 * state was passed in by the caller.)
300 */
301 if ( ! state->valid ) {
302 DBGC ( state, "DRBG %p not valid\n", state );
303 return -EINVAL;
304 }
305
306 /* 2. If requested_number_of_bits >
307 * max_number_of_bits_per_request, then return an
308 * ERROR_FLAG.
309 */
310 if ( len > DRBG_MAX_GENERATED_LEN_BYTES ) {
311 DBGC ( state, "DRBG %p request too long (%zd bytes)\n",
312 state, len );
313 return -ERANGE;
314 }
315
316 /* 3. If requested_security_strength > the security_strength
317 * indicated in the internal state, then return an
318 * ERROR_FLAG.
319 *
320 * (Nothing to do since only a single security strength is
321 * supported.)
322 */
323
324 /* 4. If the length of the additional_input >
325 * max_additional_input_length, then return an ERROR_FLAG.
326 */
327 if ( additional_len > DRBG_MAX_ADDITIONAL_LEN_BYTES ) {
328 DBGC ( state, "DRBG %p additional input too long (%zd bytes)\n",
329 state, additional_len );
330 return -ERANGE;
331 }
332
333 /* 5. If prediction_resistance_request is set, and
334 * prediction_resistance_flag is not set, then return an
335 * ERROR_FLAG.
336 *
337 * (Nothing to do since prediction resistance is always
338 * supported.)
339 */
340
341 /* 6. Clear the reseed_required_flag. */
342 state->reseed_required = 0;
343
344 step_7:
345 /* 7. If reseed_required_flag is set, or if
346 * prediction_resistance_request is set, then
347 */
348 if ( state->reseed_required || prediction_resist ) {
349
350 /* 7.1 status = Reseed_function ( state_handle,
351 * prediction_resistance_request,
352 * additional_input )
353 * 7.2 If status indicates an ERROR, then return
354 * status.
355 */
356 if ( ( rc = drbg_reseed ( state, additional,
357 additional_len ) ) != 0 ) {
358 DBGC ( state, "DRBG %p could not reseed: %s\n",
359 state, strerror ( rc ) );
360 return rc;
361 }
362
363 /* 7.3 Using state_handle, obtain the new internal
364 * state.
365 *
366 * (Nothing to do since the internal state has been
367 * updated in-situ.)
368 */
369
370 /* 7.4 additional_input = the Null string. */
371 additional = NULL;
372 additional_len = 0;
373
374 /* 7.5 Clear the reseed_required_flag. */
375 state->reseed_required = 0;
376 }
377
378 /* 8. ( status, pseudorandom_bits, new_working_state ) =
379 * Generate_algorithm ( working_state,
380 * requested_number_of_bits, additional_input ).
381 */
382 rc = drbg_generate_algorithm ( state, additional, additional_len,
383 data, len );
384
385 /* 9. If status indicates that a reseed is required before
386 * the requested bits can be generated, then
387 */
388 if ( rc != 0 ) {
389
390 /* 9.1 Set the reseed_required_flag. */
391 state->reseed_required = 1;
392
393 /* 9.2 If the prediction_resistance_flag is set, then
394 * set the prediction_resistance_request
395 * indication.
396 */
397 prediction_resist = 1;
398
399 /* 9.3 Go to step 7. */
400 goto step_7;
401 }
402
403 /* 10. Replace the old working_state in the internal state
404 * indicated by state_handle with the values of
405 * new_working_state.
406 *
407 * (Nothing to do since the working state has already been
408 * updated in-situ.)
409 */
410
411 /* 11. Return SUCCESS and pseudorandom_bits. */
412 return 0;
413 }
414
415 /**
416 * Uninstantiate DRBG
417 *
418 * @v state Algorithm state
419 *
420 * This is the Uninstantiate_function defined in ANS X9.82 Part 3-2007
421 * Section 9.5 (NIST SP 800-90 Section 9.4).
422 */
drbg_uninstantiate(struct drbg_state * state)423 void drbg_uninstantiate ( struct drbg_state *state ) {
424
425 DBGC ( state, "DRBG %p uninstantiate\n", state );
426
427 /* Sanity checks */
428 assert ( state != NULL );
429
430 /* 1. If state_handle indicates an invalid state, then return
431 * an ERROR_FLAG.
432 *
433 * (Nothing to do since the memory holding the internal state
434 * was passed in by the caller.)
435 */
436
437 /* 2. Erase the contents of the internal state indicated by
438 * state_handle.
439 */
440 memset ( state, 0, sizeof ( *state ) );
441
442 /* 3. Return SUCCESS. */
443 }
444