iPXE
Functions
drbg.c File Reference

DRBG mechanism. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/entropy.h>
#include <ipxe/drbg.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
int drbg_instantiate (struct drbg_state *state, const void *personal, size_t personal_len)
 Instantiate DRBG. More...
 
int drbg_reseed (struct drbg_state *state, const void *additional, size_t additional_len)
 Reseed DRBG. More...
 
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. More...
 
void drbg_uninstantiate (struct drbg_state *state)
 Uninstantiate DRBG. More...
 

Detailed Description

DRBG mechanism.

This mechanism is designed to comply with ANS X9.82 Part 3-2007 Section 9. This standard is not freely available, but most of the text appears to be shared with NIST SP 800-90, which can be downloaded from

http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf

Where possible, references are given to both documents. In the case of any disagreement, ANS X9.82 takes priority over NIST SP 800-90. (In particular, note that some algorithms that are Approved by NIST SP 800-90 are not Approved by ANS X9.82.)

Definition in file drbg.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ drbg_instantiate()

int drbg_instantiate ( struct drbg_state state,
const void *  personal,
size_t  personal_len 
)

Instantiate DRBG.

Parameters
stateAlgorithm state to be initialised
personalPersonalisation string
personal_lenLength of personalisation string
Return values
rcReturn status code

This is the Instantiate_function defined in ANS X9.82 Part 3-2007 Section 9.2 (NIST SP 800-90 Section 9.1).

Only a single security strength is supported, and prediction resistance is always enabled. The nonce is accounted for by increasing the entropy input, as per ANS X9.82 Part 3-2007 Section 8.4.2 (NIST SP 800-90 Section 8.6.7).

Definition at line 78 of file drbg.c.

79  {
80  unsigned int entropy_bits = ( ( 3 * DRBG_SECURITY_STRENGTH + 1 ) / 2 );
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DRBG_MAX_ENTROPY_LEN_BYTES
Maximum entropy input length.
Definition: drbg.h:37
uint8_t state
State.
Definition: eth_slow.h:47
static void size_t size_t max_len
Definition: entropy.h:153
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
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void size_t min_len
Definition: entropy.h:152
#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
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DRBG_SECURITY_STRENGTH
Security strength.
Definition: drbg.h:30
#define DRBG_MIN_ENTROPY_LEN_BYTES
Minimum entropy input length.
Definition: drbg.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define DRBG_MAX_PERSONAL_LEN_BYTES
Maximum personalisation string length.
Definition: drbg.h:40

References assert(), data, DBGC, drbg_instantiate_algorithm(), DRBG_MAX_ENTROPY_LEN_BYTES, DRBG_MAX_PERSONAL_LEN_BYTES, DRBG_MAX_SECURITY_STRENGTH, DRBG_MIN_ENTROPY_LEN_BYTES, DRBG_SECURITY_STRENGTH, ENOTSUP, ERANGE, len, max_len, min_len, NULL, rc, state, and strerror().

Referenced by rbg_startup().

◆ drbg_reseed()

int drbg_reseed ( struct drbg_state state,
const void *  additional,
size_t  additional_len 
)

Reseed DRBG.

Parameters
stateAlgorithm state
additionalAdditional input
additional_lenLength of additional input
Return values
rcReturn status code

This is the Reseed_function defined in ANS X9.82 Part 3-2007 Section 9.3 (NIST SP 800-90 Section 9.2).

Prediction resistance is always enabled.

Definition at line 190 of file drbg.c.

191  {
192  unsigned int entropy_bits = DRBG_SECURITY_STRENGTH;
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 }
#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
uint8_t state
State.
Definition: eth_slow.h:47
static void size_t size_t max_len
Definition: entropy.h:153
#define DBGC(...)
Definition: compiler.h:505
#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
uint16_t additional
Additional sense code and qualifier.
Definition: scsi.h:28
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void size_t min_len
Definition: entropy.h:152
#define ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DRBG_SECURITY_STRENGTH
Security strength.
Definition: drbg.h:30
#define DRBG_MIN_ENTROPY_LEN_BYTES
Minimum entropy input length.
Definition: drbg.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References additional, assert(), data, DBGC, DRBG_MAX_ADDITIONAL_LEN_BYTES, DRBG_MAX_ENTROPY_LEN_BYTES, DRBG_MIN_ENTROPY_LEN_BYTES, drbg_reseed_algorithm(), DRBG_SECURITY_STRENGTH, EINVAL, ERANGE, len, max_len, min_len, NULL, rc, state, and strerror().

Referenced by drbg_generate().

◆ drbg_generate()

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.

Parameters
stateAlgorithm state
additionalAdditional input
additional_lenLength of additional input
prediction_resistPrediction resistance is required
dataOutput buffer
lenLength of output buffer
Return values
rcReturn status code

This is the Generate_function defined in ANS X9.82 Part 3-2007 Section 9.4 (NIST SP 800-90 Section 9.3).

Requests must be for an integral number of bytes. Only a single security strength is supported. Prediction resistance is supported if requested.

Definition at line 283 of file drbg.c.

285  {
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 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t state
State.
Definition: eth_slow.h:47
int drbg_reseed(struct drbg_state *state, const void *additional, size_t additional_len)
Reseed DRBG.
Definition: drbg.c:190
#define DBGC(...)
Definition: compiler.h:505
#define DRBG_MAX_ADDITIONAL_LEN_BYTES
Maximum additional input length.
Definition: drbg.h:43
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 ERANGE
Result too large.
Definition: errno.h:639
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DRBG_MAX_GENERATED_LEN_BYTES
Maximum length of generated pseudorandom data per request.
Definition: drbg.h:46
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References additional, assert(), data, DBGC, drbg_generate_algorithm(), DRBG_MAX_ADDITIONAL_LEN_BYTES, DRBG_MAX_GENERATED_LEN_BYTES, drbg_reseed(), EINVAL, ERANGE, len, NULL, rc, state, and strerror().

Referenced by rbg_generate().

◆ drbg_uninstantiate()

void drbg_uninstantiate ( struct drbg_state state)

Uninstantiate DRBG.

Parameters
stateAlgorithm state

This is the Uninstantiate_function defined in ANS X9.82 Part 3-2007 Section 9.5 (NIST SP 800-90 Section 9.4).

Definition at line 423 of file drbg.c.

423  {
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 }
uint8_t state
State.
Definition: eth_slow.h:47
#define DBGC(...)
Definition: compiler.h:505
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), DBGC, memset(), NULL, and state.

Referenced by rbg_shutdown().