iPXE
drbg.c
Go to the documentation of this file.
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  */
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;
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  */
97  DBGC ( state, "DRBG %p cannot support security strength %d\n",
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  */
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;
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  */
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  */
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  */
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 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DRBG_MAX_ENTROPY_LEN_BYTES
Maximum entropy input length.
Definition: drbg.h:37
static int get_entropy_input(unsigned int min_entropy_bits, void *data, size_t min_len, size_t max_len)
Obtain entropy input.
Definition: entropy.h:231
DRBG mechanism.
uint8_t state
State.
Definition: eth_slow.h:47
Error codes.
int drbg_reseed(struct drbg_state *state, const void *additional, size_t additional_len)
Reseed DRBG.
Definition: drbg.c:190
uint16_t max_len
Maximum length (in bytes)
Definition: ntlm.h:18
static void drbg_instantiate_algorithm(struct drbg_state *state, const void *entropy, size_t entropy_len, const void *personal, size_t personal_len)
Instantiate DRBG algorithm.
Definition: drbg.h:70
#define DBGC(...)
Definition: compiler.h:505
A Deterministic Random Bit Generator.
Definition: drbg.h:49
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define DRBG_MAX_ADDITIONAL_LEN_BYTES
Maximum additional input length.
Definition: drbg.h:43
static void drbg_reseed_algorithm(struct drbg_state *state, const void *entropy, size_t entropy_len, const void *additional, size_t additional_len)
Reseed DRBG algorithm.
Definition: drbg.h:92
Assertions.
uint16_t additional
Additional sense code and qualifier.
Definition: scsi.h:28
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int drbg_generate_algorithm(struct drbg_state *state, const void *additional, size_t additional_len, void *data, size_t len)
Generate pseudorandom bits using DRBG algorithm.
Definition: drbg.h:117
#define DRBG_MAX_SECURITY_STRENGTH
Maximum security strength.
Definition: drbg.h:23
#define ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int drbg_instantiate(struct drbg_state *state, const void *personal, size_t personal_len)
Instantiate DRBG.
Definition: drbg.c:78
unsigned char uint8_t
Definition: stdint.h:10
#define DRBG_MAX_GENERATED_LEN_BYTES
Maximum length of generated pseudorandom data per request.
Definition: drbg.h:46
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
uint32_t len
Length.
Definition: ena.h:14
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define DRBG_SECURITY_STRENGTH
Security strength.
Definition: drbg.h:30
void drbg_uninstantiate(struct drbg_state *state)
Uninstantiate DRBG.
Definition: drbg.c:423
#define DRBG_MIN_ENTROPY_LEN_BYTES
Minimum entropy input length.
Definition: drbg.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
Entropy source.
#define DRBG_MAX_PERSONAL_LEN_BYTES
Maximum personalisation string length.
Definition: drbg.h:40
int drbg_generate(struct drbg_state *state, const void *additional, size_t additional_len, int prediction_resist, void *data, size_t len)
Generate pseudorandom bits using DRBG.
Definition: drbg.c:283
void * memset(void *dest, int character, size_t len) __nonnull