cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
rand_x917.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib X9.17 Generator Routines *
4 * Copyright Peter Gutmann 1995-2007 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "random_int.h"
11 #else
12  #include "crypt.h"
13  #include "random/random_int.h"
14 #endif /* Compiler-specific includes */
15 
16 /****************************************************************************
17 * *
18 * Utility Functions *
19 * *
20 ****************************************************************************/
21 
22 /* Sanity-check the X9.17 randomness state */
23 
25 static BOOLEAN sanityCheck( const RANDOM_INFO *randomInfo )
26  {
27  assert( isReadPtr( randomInfo, sizeof( RANDOM_INFO ) ) );
28 
29  /* Make sure that the X9.17 generator accounting information is within
30  bounds. See the comment in generateX917() for the high-range check */
31  if( randomInfo->x917Count < 0 || \
32  randomInfo->x917Count > X917_MAX_CYCLES + \
34  return( FALSE );
35 
36  return( TRUE );
37  }
38 
39 /****************************************************************************
40 * *
41 * ANSI X9.17 Generator *
42 * *
43 ****************************************************************************/
44 
45 /* The ANSI X9.17 Annex C generator has a number of problems (besides just
46  being slow) including a tiny internal state, use of fixed keys, no
47  entropy update, revealing the internal state to an attacker whenever it
48  generates output, and a horrible vulnerability to state compromise. For
49  FIPS 140 compliance however we need to use an approved generator (even
50  though Annex C is informative rather than normative and contains only "an
51  example of a pseudorandom key and IV generator" so that it could be argued
52  that any generator based on X9.17 3DES is permitted), which is why this
53  generator appears here.
54 
55  In order to minimise the potential for damage we employ it as a post-
56  processor for the pool (since X9.17 produces a 1-1 mapping it can never
57  make the output any worse), using as our timestamp input the main RNG
58  output. This is perfectly valid since X9.17 requires the use of DT, "a
59  date/time vector which is updated on each key generation", a requirement
60  which is met by the fastPoll() which is performed before the main pool is
61  mixed. The cryptlib representation of the date and time vector is as a
62  hash of assorted incidental data and the date and time. The fact that
63  99.9999% of the value of the generator is coming from the, uhh, timestamp
64  is as coincidental as the side effect of the engine cooling fan in the
65  Brabham ground effect cars.
66 
67  Some eval labs may not like this use of DT, in which case it's also
68  possible to inject the extra seed material into the generator by using
69  the X9.31 interpretation of X9.17, which makes the V value an externally-
70  modifiable value. In this interpretation the "generator" has degenerated
71  to little more than a 3DES encryption of V, which can hardly have been
72  the intent of the X9.17 designers. In other words the X9.17 operation:
73 
74  out = Enc( Enc( in ) ^ V(n) );
75  V(n+1) = Enc( Enc( in ) ^ out );
76 
77  degenerates to:
78 
79  out = Enc( Enc( DT ) ^ in );
80 
81  since V is overwritten on each iteration. If the eval lab requires this
82  interpretation rather than the more sensible DT one then this can be
83  enabled by supplying a dateTime value to setKeyX917(), although we don't
84  do it by default since it's so far removed from the real X9.17
85  generator */
86 
87 /* A macro to make what's being done by the generator easier to follow */
88 
89 #define tdesEncrypt( data, key ) \
90  des_ecb3_encrypt( ( C_Block * ) ( data ), ( C_Block * ) ( data ), \
91  ( key )->desKey1, ( key )->desKey2, \
92  ( key )->desKey3, DES_ENCRYPT )
93 
94 /* Set the X9.17 generator key */
95 
97 int setKeyX917( INOUT RANDOM_INFO *randomInfo,
98  IN_BUFFER_C( X917_KEYSIZE ) const BYTE *key,
99  IN_BUFFER_C( X917_POOLSIZE ) const BYTE *state,
100  IN_BUFFER_OPT_C( X917_POOLSIZE ) const BYTE *dateTime )
101  {
102  X917_3DES_KEY *des3Key = &randomInfo->x917Key;
103  int desStatus;
104 
105  assert( isWritePtr( randomInfo, sizeof( RANDOM_INFO ) ) );
106  assert( isReadPtr( key, X917_KEYSIZE ) );
107  assert( isReadPtr( state, X917_KEYSIZE ) );
108  assert( dateTime == NULL || isReadPtr( dateTime, X917_KEYSIZE ) );
109 
110  /* Precondition: the key and seed aren't being taken from the same
111  location */
112  REQUIRES( sanityCheck( randomInfo ) );
113  REQUIRES( memcmp( key, state, X917_POOLSIZE ) );
114 
115  /* Remember that we're about to reset the generator state */
116  randomInfo->x917Inited = FALSE;
117 
118  /* Schedule the DES keys. Rather than performing the third key schedule
119  we just copy the first scheduled key into the third one, since it's
120  the same key in EDE mode */
121  des_set_odd_parity( ( C_Block * ) key );
122  des_set_odd_parity( ( C_Block * ) ( key + bitsToBytes( 64 ) ) );
123  desStatus = des_key_sched( ( des_cblock * ) key, des3Key->desKey1 );
124  if( desStatus == 0 )
125  {
126  desStatus = des_key_sched( ( des_cblock * ) \
127  ( key + bitsToBytes( 64 ) ),
128  des3Key->desKey2 );
129  }
130  memcpy( des3Key->desKey3, des3Key->desKey1, DES_KEYSIZE );
131  if( desStatus )
132  {
133  /* There was a problem initialising the keys, don't try and go any
134  further */
135  ENSURES( randomInfo->x917Inited == FALSE );
136  return( CRYPT_ERROR_RANDOM );
137  }
138 
139  /* Set up the generator state value V(0) and DT if we're using the X9.31
140  interpretation */
141  memcpy( randomInfo->x917Pool, state, X917_POOLSIZE );
142  if( dateTime != NULL )
143  {
144  memcpy( randomInfo->x917DT, dateTime, X917_POOLSIZE );
145  randomInfo->useX931 = TRUE;
146  }
147 
148  /* We've initialised the generator and reset the cryptovariables, we're
149  ready to go */
150  randomInfo->x917Inited = TRUE;
151  randomInfo->x917Count = 0;
152 
153  ENSURES( sanityCheck( randomInfo ) );
154 
155  return( CRYPT_OK );
156  }
157 
158 /* Run the X9.17 generator over a block of data */
159 
161 int generateX917( INOUT RANDOM_INFO *randomInfo,
163  IN_RANGE( 1, MAX_RANDOM_BYTES ) const int length )
164  {
165  BYTE encTime[ X917_POOLSIZE + 8 ], *dataPtr = data;
166  int dataBlockPos;
167 
168  assert( isWritePtr( randomInfo, sizeof( RANDOM_INFO ) ) );
169  assert( isReadPtr( data, length ) );
170 
171  /* Precondition: The generator has been initialised, we're not asking
172  for more data than the maximum that should be needed, and the
173  cryptovariables aren't past their use-by date */
174  REQUIRES( sanityCheck( randomInfo ) );
175  REQUIRES( randomInfo->x917Inited == TRUE );
176  REQUIRES( length > 0 && length <= MAX_RANDOM_BYTES );
177  REQUIRES( randomInfo->x917Count >= 0 && \
178  randomInfo->x917Count < X917_MAX_CYCLES );
179 
180  /* Process as many blocks of output as needed. We can't check the
181  return value of the encryption call because there isn't one, however
182  the 3DES code has gone through a self-test when the randomness
183  subsystem was initialised. This can run the generator for slightly
184  more than X917_MAX_CYCLES if we're already close to the limit before
185  we start, but this isn't a big problem, it's only an approximate
186  reset-count measure anyway */
187  for( dataBlockPos = 0; dataBlockPos < length;
188  dataBlockPos += X917_POOLSIZE )
189  {
190  const int bytesToCopy = min( length - dataBlockPos, X917_POOLSIZE );
191  int i;
192  ORIGINAL_INT_VAR( x917Count, randomInfo->x917Count );
193 
194  /* Precondition: We're processing from 1...X917_POOLSIZE bytes of
195  data */
196  REQUIRES( bytesToCopy >= 1 && bytesToCopy <= X917_POOLSIZE );
197 
198  /* Set the seed from the user-supplied data. This varies depending
199  on whether we're using the X9.17 or X9.31 interpretation of
200  seeding */
201  if( randomInfo->useX931 )
202  {
203  /* It's the X9.31 interpretation, there's no further user seed
204  input apart from the V and DT that we set initially */
205  memcpy( encTime, randomInfo->x917DT, X917_POOLSIZE );
206  }
207  else
208  {
209  /* It's the X9.17 seed-via-DT interpretation, the user input is
210  DT. Copy in as much timestamp (+ other assorted data) as we
211  can into the DT value */
212  memcpy( encTime, dataPtr, bytesToCopy );
213 
214  /* Inner precondition: The DT buffer contains the input data */
215  FORALL( k, 0, bytesToCopy,
216  encTime[ k ] == data[ dataBlockPos + k ] );
217  }
218 
219  /* out = Enc( Enc( DT ) ^ V(n) ); */
220  tdesEncrypt( encTime, &randomInfo->x917Key );
221  for( i = 0; i < X917_POOLSIZE; i++ )
222  randomInfo->x917Pool[ i ] ^= encTime[ i ];
223  tdesEncrypt( randomInfo->x917Pool, &randomInfo->x917Key );
224  memcpy( dataPtr, randomInfo->x917Pool, bytesToCopy );
225 
226  /* Postcondition: The internal state has been copied to the output
227  (ick) */
228  FORALL( k, 0, bytesToCopy, \
229  data[ dataBlockPos + k ] == randomInfo->x917Pool[ k ] );
230 
231  /* V(n+1) = Enc( Enc( DT ) ^ out ); */
232  for( i = 0; i < X917_POOLSIZE; i++ )
233  randomInfo->x917Pool[ i ] ^= encTime[ i ];
234  tdesEncrypt( randomInfo->x917Pool, &randomInfo->x917Key );
235 
236  /* If we're using the X9.31 interpretation, update DT to meet the
237  monotonically increasing time value requirement. Although the
238  spec doesn't explicitly state this, the published test vectors
239  increment the rightmost byte so the value is treated as big-
240  endian */
241  if( randomInfo->useX931 )
242  {
243  ORIGINAL_INT_VAR( lsb1, randomInfo->x917DT[ X917_POOLSIZE - 1 ] );
244  ORIGINAL_INT_VAR( lsb2, randomInfo->x917DT[ X917_POOLSIZE - 2 ] );
245  ORIGINAL_INT_VAR( lsb3, randomInfo->x917DT[ X917_POOLSIZE - 3 ] );
246 
247  for( i = X917_POOLSIZE - 1; i >= 0; i-- )
248  {
249  randomInfo->x917DT[ i ]++;
250  if( randomInfo->x917DT[ i ] != 0 )
251  break;
252  }
253 
254  /* Postcondition: The value has been incremented by one */
255  ENSURES( ( randomInfo->x917DT[ X917_POOLSIZE - 1 ] == \
256  ORIGINAL_VALUE( lsb1 ) + 1 ) || \
257  ( randomInfo->x917DT[ X917_POOLSIZE - 1 ] == 0 && \
258  randomInfo->x917DT[ X917_POOLSIZE - 2 ] == \
259  ORIGINAL_VALUE( lsb2 ) + 1 ) || \
260  ( randomInfo->x917DT[ X917_POOLSIZE - 1 ] == 0 && \
261  randomInfo->x917DT[ X917_POOLSIZE - 2 ] == 0 && \
262  randomInfo->x917DT[ X917_POOLSIZE - 3 ] == \
263  ORIGINAL_VALUE( lsb3 ) + 1 ) );
264  }
265 
266  /* Move on to the next block */
267  dataPtr += bytesToCopy;
268  randomInfo->x917Count++;
269 
270  /* Postcondition: We've processed one more block of data */
271  ENSURES( dataPtr == data + dataBlockPos + bytesToCopy );
272  ENSURES( randomInfo->x917Count == ORIGINAL_VALUE( x917Count ) + 1 );
273  }
274 
275  /* Postcondition: We processed all of the data */
276  ENSURES( dataPtr == data + length );
277 
278  zeroise( encTime, X917_POOLSIZE );
279 
280  /* Postcondition: Nulla vestigia retrorsum */
281  FORALL( i, 0, X917_POOLSIZE,
282  encTime[ i ] == 0 );
283 
284  ENSURES( sanityCheck( randomInfo ) );
285 
286  return( CRYPT_OK );
287  }
288 
289 /****************************************************************************
290 * *
291 * X9.17 Generator Self-test Routines *
292 * *
293 ****************************************************************************/
294 
295 /* X9.17/X9.31 generator test vectors. The first set of values used are
296  from the NIST publication "The Random Number Generator Validation System
297  (RNGVS)" (unfortunately the MCT values for this are wrong so they can't
298  be used), the second set are from test data used by an eval lab, and the
299  third set are the values used for cryptlib's FIPS evaluation */
300 
301 #define RNG_TEST_NIST 0
302 #define RNG_TEST_INFOGARD 1
303 #define RNG_TEST_FIPSEVAL 2
304 
305 #define RNG_TEST_VALUES RNG_TEST_INFOGARD
306 
307 #if ( RNG_TEST_VALUES == RNG_TEST_NIST )
308  #define VST_ITERATIONS 5
309 #elif ( RNG_TEST_VALUES == RNG_TEST_INFOGARD )
310  #define VST_ITERATIONS 64
311 #elif ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
312  #define VST_ITERATIONS 64
313 #endif /* VST iterations */
314 
315 typedef struct {
316  /* The values are declared with an extra byte of storage since they're
317  initialised from strings, which have an implicit '\0' at the end */
318  const BYTE key[ X917_KEYSIZE + 1 ];
319  const BYTE DT[ X917_BLOCKSIZE + 1 ], V[ X917_BLOCKSIZE + 1 ];
320  const BYTE R[ X917_BLOCKSIZE + 1 ];
322 
323 typedef struct {
324  const BYTE key[ X917_KEYSIZE + 1 ];
325  const BYTE initDT[ X917_BLOCKSIZE + 1 ], initV[ X917_BLOCKSIZE + 1 ];
326  const BYTE R[ VST_ITERATIONS ][ X917_BLOCKSIZE + 1 ];
328 
329 static const X917_MCT_TESTDATA FAR_BSS x917MCTdata = { /* Monte Carlo Test */
330 #if ( RNG_TEST_VALUES == RNG_TEST_NIST ) /* These values are wrong */
331  /* Key1 = 75C71AE5A11A232C
332  Key2 = 40256DCD94F767B0
333  DT = C89A1D888ED12F3C
334  V = D5538F9CF450F53C
335  R = 77C695C33E51C8C0 */
336  "\x75\xC7\x1A\xE5\xA1\x1A\x23\x2C\x40\x25\x6D\xCD\x94\xF7\x67\xB0",
337  "\xC8\x9A\x1D\x88\x8E\xD1\x2F\x3C",
338  "\xD5\x53\x8F\x9C\xF4\x50\xF5\x3C",
339  "\x77\xC6\x95\xC3\x3E\x51\xC8\xC0"
340 #elif ( RNG_TEST_VALUES == RNG_TEST_INFOGARD )
341  /* Key1 = 625BB5131A45F492
342  Key2 = 70971C9E0D4C9792
343  DT = 5F328264B787B098
344  V = A24F6E0EE43204CD
345  R = C7AC1E8F100CC30A */
346  "\x62\x5B\xB5\x13\x1A\x45\xF4\x92\x70\x97\x1C\x9E\x0D\x4C\x97\x92",
347  "\x5F\x32\x82\x64\xB7\x87\xB0\x98",
348  "\xA2\x4F\x6E\x0E\xE4\x32\x04\xCD",
349  "\xC7\xAC\x1E\x8F\x10\x0C\xC3\x0A"
350 #elif ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
351  /* Key1 = A45BF2E50D153710
352  Key2 = 79832F38A89B2AB0
353  DT = 8219E01B2A6958BB
354  V = 283176BA23FA3181
355  R = ? */
356  "\xA4\x5B\xF2\xE5\x0D\x15\x37\x10\x79\x83\x2F\x38\xA8\x9B\x2A\xB0",
357  "\x82\x19\xE0\x1B\x2A\x69\x58\xBB",
358  "\x28\x31\x76\xBA\x23\xFA\x31\x81",
359  0
360 #endif /* Different test vectors */
361  };
362 
363 static const X917_VST_TESTDATA FAR_BSS x917VSTdata = { /* Variable Seed Test (VST) */
364 #if ( RNG_TEST_VALUES == RNG_TEST_NIST )
365  /* Count = 0
366  Key1 = 75C71AE5A11A232C
367  Key2 = 40256DCD94F767B0
368  DT = C89A1D888ED12F3C
369  V = 80000000000000000 */
370  "\x75\xC7\x1A\xE5\xA1\x1A\x23\x2C\x40\x25\x6D\xCD\x94\xF7\x67\xB0",
371  "\xC8\x9A\x1D\x88\x8E\xD1\x2F\x3C",
372  "\x80\x00\x00\x00\x00\x00\x00\x00",
373  /* Count = 0, V = 8000000000000000, R = 944DC7210D6D7FD7 */
374  { "\x94\x4D\xC7\x21\x0D\x6D\x7F\xD7",
375  /* Count = 1, V = C000000000000000, R = AF1A648591BB7C2C */
376  "\xAF\x1A\x64\x85\x91\xBB\x7C\x2C",
377  /* Count = 2, V = E000000000000000, R = 221839B07451E423 */
378  "\x22\x18\x39\xB0\x74\x51\xE4\x23",
379  /* Count = 3, V = F000000000000000, R = EBA9271E04043712 */
380  "\xEB\xA9\x27\x1E\x04\x04\x37\x12",
381  /* Count = 4, V = F800000000000000, R = 02433C9417A3326F */
382  "\x02\x43\x3C\x94\x17\xA3\x32\x6F" }
383 #elif ( RNG_TEST_VALUES == RNG_TEST_INFOGARD )
384  /* Count = 0
385  Key1 = 3164916EA2C87AAE
386  Key2 = 2ABC323EFB9802E3
387  DT = 65B9108277AC0582
388  V = 80000000000000000 */
389  "\x31\x64\x91\x6E\xA2\xC8\x7A\xAE\x2A\xBC\x32\x3E\xFB\x98\x02\xE3",
390  "\x65\xB9\x10\x82\x77\xAC\x05\x82",
391  "\x80\x00\x00\x00\x00\x00\x00\x00",
392  /* Count = 0, V = 8000000000000000, R = D8015B966ADE69BA */
393  { "\xD8\x01\x5B\x96\x6A\xDE\x69\xBA",
394  /* Count = 1, V = C000000000000000, R = E737E18734365F43 */
395  "\xE7\x37\xE1\x87\x34\x36\x5F\x43",
396  /* Count = 2, V = E000000000000000, R = CA8F00C1DF28FCFF */
397  "\xCA\x8F\x00\xC1\xDF\x28\xFC\xFF",
398  /* Count = 3, V = F000000000000000, R = 9FF307027622FA2A */
399  "\x9F\xF3\x07\x02\x76\x22\xFA\x2A",
400  /* Count = 4, V = F800000000000000, R = 0A4BB2E54842648E */
401  "\x0A\x4B\xB2\xE5\x48\x42\x64\x8E",
402  /* Count = 5, V = FC00000000000000, R = FFAD84A57EE0DE37 */
403  "\xFF\xAD\x84\xA5\x7E\xE0\xDE\x37",
404  /* Count = 6, V = FE00000000000000, R = 0CF064313A7889FD */
405  "\x0C\xF0\x64\x31\x3A\x78\x89\xFD",
406  /* Count = 7, V = FF00000000000000, R = 97B6854447D95A01 */
407  "\x97\xB6\x85\x44\x47\xD9\x5A\x01",
408  /* Count = 8, V = ff80000000000000, R = 55272f900ae13948 */
409  "\x55\x27\x2F\x90\x0A\xE1\x39\x48",
410  /* Count = 9, V = ffc0000000000000, R = dbd731bdf9875a04 */
411  "\xDB\xD7\x31\xBD\xF9\x87\x5A\x04",
412  /* Count = 10, V = ffe0000000000000, R = b19589a371d4942d */
413  "\xB1\x95\x89\xA3\x71\xD4\x94\x2D",
414  /* Count = 11, V = fff0000000000000, R = 8da8f8e8c59fc497 */
415  "\x8D\xA8\xF8\xE8\xC5\x9F\xC4\x97",
416  /* Count = 12, V = fff8000000000000, R = ddfbf3f319bcda42 */
417  "\xDD\xFB\xF3\xF3\x19\xBC\xDA\x42",
418  /* Count = 13, V = fffc000000000000, R = a72ddd98d1744844 */
419  "\xA7\x2D\xDD\x98\xD1\x74\x48\x44",
420  /* Count = 14, V = fffe000000000000, R = de0835034456629e */
421  "\xDE\x08\x35\x03\x44\x56\x62\x9E",
422  /* Count = 15, V = ffff000000000000, R = e977daafef7aa5e0 */
423  "\xE9\x77\xDA\xAF\xEF\x7A\xA5\xE0",
424  /* Count = 16, V = ffff800000000000, R = 019c3edc5ae93ab8 */
425  "\x01\x9C\x3E\xDC\x5A\xE9\x3A\xB8",
426  /* Count = 17, V = ffffc00000000000, R = 163c3dbe31ffd91b */
427  "\x16\x3C\x3D\xBE\x31\xFF\xD9\x1B",
428  /* Count = 18, V = ffffe00000000000, R = f2045893945b4774 */
429  "\xF2\x04\x58\x93\x94\x5B\x47\x74",
430  /* Count = 19, V = fffff00000000000, R = 50c88799fc1ec55d */
431  "\x50\xC8\x87\x99\xFC\x1E\xC5\x5D",
432  /* Count = 20, V = fffff80000000000, R = 1545f463986e1511 */
433  "\x15\x45\xF4\x63\x98\x6E\x15\x11",
434  /* Count = 21, V = fffffc0000000000, R = 55f999624fe045a6 */
435  "\x55\xF9\x99\x62\x4F\xE0\x45\xA6",
436  /* Count = 22, V = fffffe0000000000, R = e3e0db844bca7505 */
437  "\xE3\xE0\xDB\x84\x4B\xCA\x75\x05",
438  /* Count = 23, V = ffffff0000000000, R = 8fb4b76d808562d7 */
439  "\x8F\xB4\xB7\x6D\x80\x85\x62\xD7",
440  /* Count = 24, V = ffffff8000000000, R = 9d5457baaeb496e4 */
441  "\x9D\x54\x57\xBA\xAE\xB4\x96\xE4",
442  /* Count = 25, V = ffffffc000000000, R = 2b8abff2bdc82366 */
443  "\x2B\x8A\xBF\xF2\xBD\xC8\x23\x66",
444  /* Count = 26, V = ffffffe000000000, R = 3936c324d09465af */
445  "\x39\x36\xC3\x24\xD0\x94\x65\xAF",
446  /* Count = 27, V = fffffff000000000, R = 1983dd227e55240e */
447  "\x19\x83\xDD\x22\x7E\x55\x24\x0E",
448  /* Count = 28, V = fffffff800000000, R = 866cf6e6dc3d03fb */
449  "\x86\x6C\xF6\xE6\xDC\x3D\x03\xFB",
450  /* Count = 29, V = fffffffc00000000, R = 03d10b0f17b04b59 */
451  "\x03\xD1\x0B\x0F\x17\xB0\x4B\x59",
452  /* Count = 30, V = fffffffe00000000, R = 3eeb1cd0248e25a6 */
453  "\x3E\xEB\x1C\xD0\x24\x8E\x25\xA6",
454  /* Count = 31, V = ffffffff00000000, R = 9d8bd4b8c3e425dc */
455  "\x9D\x8B\xD4\xB8\xC3\xE4\x25\xDC",
456  /* Count = 32, V = ffffffff80000000, R = bc515d3a0a719be1 */
457  "\xBC\x51\x5D\x3A\x0A\x71\x9B\xE1",
458  /* Count = 33, V = ffffffffc0000000, R = 1b35fb4aca4ac47c */
459  "\x1B\x35\xFB\x4A\xCA\x4A\xC4\x7C",
460  /* Count = 34, V = ffffffffe0000000, R = f8338668b6ead493 */
461  "\xF8\x33\x86\x68\xB6\xEA\xD4\x93",
462  /* Count = 35, V = fffffffff0000000, R = cdfa8e5ffa2deb17 */
463  "\xCD\xFA\x8E\x5F\xFA\x2D\xEB\x17",
464  /* Count = 36, V = fffffffff8000000, R = c965a35109044ca3 */
465  "\xC9\x65\xA3\x51\x09\x04\x4C\xA3",
466  /* Count = 37, V = fffffffffc000000, R = 8da70c88167b2746 */
467  "\x8D\xA7\x0C\x88\x16\x7B\x27\x46",
468  /* Count = 38, V = fffffffffe000000, R = 22ba92a21a74eb5b */
469  "\x22\xBA\x92\xA2\x1A\x74\xEB\x5B",
470  /* Count = 39, V = ffffffffff000000, R = 1fba0fab823a85e7 */
471  "\x1F\xBA\x0F\xAB\x82\x3A\x85\xE7",
472  /* Count = 40, V = ffffffffff800000, R = 656f4fc91245073d */
473  "\x65\x6F\x4F\xC9\x12\x45\x07\x3D",
474  /* Count = 41, V = ffffffffffc00000, R = a803441fb939f09c */
475  "\xA8\x03\x44\x1F\xB9\x39\xF0\x9C",
476  /* Count = 42, V = ffffffffffe00000, R = e3f30bb6aed64331 */
477  "\xE3\xF3\x0B\xB6\xAE\xD6\x43\x31",
478  /* Count = 43, V = fffffffffff00000, R = 6a75588b5e6f5ea4 */
479  "\x6A\x75\x58\x8B\x5E\x6F\x5E\xA4",
480  /* Count = 44, V = fffffffffff80000, R = ec95ad55ac684e93 */
481  "\xEC\x95\xAD\x55\xAC\x68\x4E\x93",
482  /* Count = 45, V = fffffffffffc0000, R = b2a79a0ebfb96c4e */
483  "\xB2\xA7\x9A\x0E\xBF\xB9\x6C\x4E",
484  /* Count = 46, V = fffffffffffe0000, R = 480263bb6146006f */
485  "\x48\x02\x63\xBB\x61\x46\x00\x6F",
486  /* Count = 47, V = ffffffffffff0000, R = c0d8b711395b290f */
487  "\xC0\xD8\xB7\x11\x39\x5B\x29\x0F",
488  /* Count = 48, V = ffffffffffff8000, R = a3f39193fe3d526d */
489  "\xA3\xF3\x91\x93\xFE\x3D\x52\x6D",
490  /* Count = 49, V = ffffffffffffc000, R = 6f50ba964d94d153 */
491  "\x6F\x50\xBA\x96\x4D\x94\xD1\x53",
492  /* Count = 50, V = ffffffffffffe000, R = ff8240a77c67bb8d */
493  "\xFF\x82\x40\xA7\x7C\x67\xBB\x8D",
494  /* Count = 51, V = fffffffffffff000, R = 7f95c72fd9b38ff6 */
495  "\x7F\x95\xC7\x2F\xD9\xB3\x8F\xF6",
496  /* Count = 52, V = fffffffffffff800, R = 7fbdf1428f44aac1 */
497  "\x7F\xBD\xF1\x42\x8F\x44\xAA\xC1",
498  /* Count = 53, V = fffffffffffffc00, R = 04cec286480ab97b */
499  "\x04\xCE\xC2\x86\x48\x0A\xB9\x7B",
500  /* Count = 54, V = fffffffffffffe00, R = 86562948c1cf8ec0 */
501  "\x86\x56\x29\x48\xC1\xCF\x8E\xC0",
502  /* Count = 55, V = ffffffffffffff00, R = b1a1c0f20c71b267 */
503  "\xB1\xA1\xC0\xF2\x0C\x71\xB2\x67",
504  /* Count = 56, V = ffffffffffffff80, R = f357a25c7dacbca8 */
505  "\xF3\x57\xA2\x5C\x7D\xAC\xBC\xA8",
506  /* Count = 57, V = ffffffffffffffc0, R = 8f8f4e0e348bf185 */
507  "\x8F\x8F\x4E\x0E\x34\x8B\xF1\x85",
508  /* Count = 58, V = ffffffffffffffe0, R = 52a21df35fa70190 */
509  "\x52\xA2\x1D\xF3\x5F\xA7\x01\x90",
510  /* Count = 59, V = fffffffffffffff0, R = 8be78733594af616 */
511  "\x8B\xE7\x87\x33\x59\x4A\xF6\x16",
512  /* Count = 60, V = fffffffffffffff8, R = e03a051b4ca826e5 */
513  "\xE0\x3A\x05\x1B\x4C\xA8\x26\xE5",
514  /* Count = 61, V = fffffffffffffffc, R = 5c4b73bb5901c3cf */
515  "\x5C\x4B\x73\xBB\x59\x01\xC3\xCF",
516  /* Count = 62, V = fffffffffffffffe, R = e5d7fc8415bfb0f0 */
517  "\xE5\xD7\xFC\x84\x15\xBF\xB0\xF0",
518  /* Count = 63, V = ffffffffffffffff, R = 9417d7247eaa5159 */
519  "\x94\x17\xD7\x24\x7E\xAA\x51\x59" }
520 #elif ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
521  /* COUNT = 0
522  Key1 = 3D3D0289DAEC867A
523  Key2 = 29B3F2C7F12C40E5
524  DT = 6FC8AE5CA678E042
525  V = 80000000000000000 */
526  "\x3D\x3D\x02\x89\xDA\xEC\x86\x7A\x29\xB3\xF2\xC7\xF1\x2C\x40\xE5",
527  "\x6F\xC8\xAE\x5C\xA6\x78\xE0\x42",
528  "\x80\x00\x00\x00\x00\x00\x00\x00",
529  { 0 }
530 #endif /* Different test vectors */
531  };
532 
533 /* Helper functions to output the test data in the format required for the
534  FIPS eval */
535 
536 #if ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
537 
538 static void printVector( const char *description, const BYTE *data )
539  {
540  int i;
541 
542  printf( "%s = ", description );
543  for( i = 0; i < 8; i++ )
544  printf( "%02x", data[ i ] );
545  putchar( '\n' );
546  }
547 
548 static void printVectors( const BYTE *key, const BYTE *dt, const BYTE *v,
549  const BYTE *r, const int count )
550  {
551  printf( "COUNT = %d\n", count );
552  printVector( "Key1", key );
553  printVector( "Key2", key + 8 );
554  printVector( "DT", dt );
555  printVector( "V", v );
556  printVector( "R", r );
557  }
558 #endif /* FIPS eval data output */
559 
560 /* Self-test code for the two crypto algorithms that are used for random
561  number generation. The self-test of these two algorithms is performed
562  every time the randomness subsystem is initialised. Note that the same
563  tests have already been performed as part of the startup self-test but
564  we perform them again here for the benefit of the randomness subsystem,
565  which doesn't necessarily trust (or even know about) the startup self-
566  test */
567 
568 #if defined( INC_ALL )
569  #include "capabil.h"
570 #else
571  #include "device/capabil.h"
572 #endif /* Compiler-specific includes */
573 
574 CHECK_RETVAL \
576  {
577  const CAPABILITY_INFO *capabilityInfo;
578  int status;
579 
580  /* Test the SHA-1 functionality */
581  capabilityInfo = getSHA1Capability();
582  status = capabilityInfo->selfTestFunction();
583  if( cryptStatusError( status ) )
584  return( status );
585 
586  /* Test the 3DES (and DES) functionality */
587  capabilityInfo = get3DESCapability();
588  status = capabilityInfo->selfTestFunction();
589  if( cryptStatusError( status ) )
590  return( status );
591 
592  return( CRYPT_OK );
593  }
594 
595 /* Test the X9.17 generator */
596 
597 CHECK_RETVAL \
598 int selfTestX917( INOUT RANDOM_INFO *testRandomInfo,
599  IN_BUFFER_C( X917_KEYSIZE ) const BYTE *key )
600  {
601  BYTE buffer[ X917_BLOCKSIZE + 8 ];
602  int status;
603 
604  assert( isWritePtr( testRandomInfo, sizeof( RANDOM_INFO ) ) );
605  assert( isReadPtr( key, X917_KEYSIZE ) );
606 
607  /* Check that the ANSI X9.17 PRNG is working correctly */
608  memset( buffer, 0, 16 );
609  status = setKeyX917( testRandomInfo, key, key + X917_KEYSIZE, NULL );
610  if( cryptStatusError( status ) )
611  return( status );
612  status = generateX917( testRandomInfo, buffer, X917_BLOCKSIZE );
613  if( cryptStatusOK( status ) && \
614  memcmp( buffer, "\xF0\x8D\xD4\xDE\xFA\x2C\x80\x11", X917_BLOCKSIZE ) )
615  status = CRYPT_ERROR_FAILED;
616  if( cryptStatusOK( status ) )
617  status = generateX917( testRandomInfo, buffer, X917_BLOCKSIZE );
618  if( cryptStatusOK( status ) && \
619  memcmp( buffer, "\xA0\xA9\x4E\xEC\xCD\xD9\x28\x7F", X917_BLOCKSIZE ) )
620  status = CRYPT_ERROR_FAILED;
621  if( cryptStatusOK( status ) )
622  status = generateX917( testRandomInfo, buffer, X917_BLOCKSIZE );
623  if( cryptStatusOK( status ) && \
624  memcmp( buffer, "\x70\x82\x64\xED\x83\x88\x40\xE4", X917_BLOCKSIZE ) )
625  status = CRYPT_ERROR_FAILED;
626 
627  return( status );
628  }
629 
630 CHECK_RETVAL \
631 int fipsTestX917( INOUT RANDOM_INFO *testRandomInfo )
632  {
633  /* The following tests can take quite some time on slower CPUs because
634  they're iterated tests so we only run them if we can assume that
635  there's a reasonably fast CPU present */
636 #if !defined( CONFIG_SLOW_CPU )
637  BYTE keyBuffer[ X917_KEYSIZE + 8 ];
638  BYTE buffer[ X917_BLOCKSIZE + 8 ];
639  int i, isX931, status;
640 
641  assert( isWritePtr( testRandomInfo, sizeof( RANDOM_INFO ) ) );
642 
643  /* Check the ANSI X9.17 PRNG again, this time using X9.31 test vectors.
644  These aren't test vectors from X9.31 but vectors used to certify an
645  X9.17 generator when run in X9.31 mode (we actually run the test
646  twice, once in X9.17 seed-via-DT mode and once in X9.31 seed-via-V
647  mode). We have to do this after the above test since they're run as
648  a linked series of tests going from the lowest-level cryptlib and
649  ANSI PRNGs to the top-level overall random number generation system.
650  Inserting this test in the middle would upset the final result
651  values */
652  initRandomPool( testRandomInfo );
653  memcpy( keyBuffer, x917MCTdata.key, X917_KEYSIZE );
654  status = setKeyX917( testRandomInfo, keyBuffer, x917MCTdata.V,
655  x917MCTdata.DT );
656  if( cryptStatusOK( status ) )
657  {
658  for( i = 0; cryptStatusOK( status ) && i < 10000; i++ )
659  {
660  testRandomInfo->x917Count = 0;
661  status = generateX917( testRandomInfo, buffer, X917_BLOCKSIZE );
662  }
663  }
664 #if ( RNG_TEST_VALUES != RNG_TEST_FIPSEVAL )
665  if( cryptStatusOK( status ) && \
666  memcmp( buffer, x917MCTdata.R, X917_BLOCKSIZE ) )
667  status = CRYPT_ERROR_FAILED;
668 #endif /* FIPS eval data output */
669  if( cryptStatusError( status ) )
670  retIntError();
671  endRandomPool( testRandomInfo );
672 #if ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
673  printf( "[X9.31]\n[2-Key TDES]\n\n" );
674  printVectors( x917MCTdata.key, x917MCTdata.DT, x917MCTdata.V, buffer, 0 );
675  printf( "\n\n[X9.31]\n[2-Key TDES]\n\n" );
676 #endif /* FIPS eval data output */
677  for( isX931 = FALSE; isX931 <= TRUE; isX931++ )
678  {
679  BYTE V[ X917_BLOCKSIZE + 8 ], DT[ X917_BLOCKSIZE + 8 ];
680 
681  /* Run through the tests twice, once using the X9.17 interpretation
682  and a second time using the X9.31 interpretation */
683  memcpy( V, x917VSTdata.initV, X917_BLOCKSIZE );
684  memcpy( DT, x917VSTdata.initDT, X917_BLOCKSIZE );
685  for( i = 0; i < VST_ITERATIONS; i++ )
686  {
687  int j;
688 
689  initRandomPool( testRandomInfo );
690  memcpy( keyBuffer, x917VSTdata.key, X917_KEYSIZE );
691  memcpy( buffer, DT, X917_BLOCKSIZE );
692  status = setKeyX917( testRandomInfo, keyBuffer, V, \
693  isX931 ? DT : NULL );
694  if( cryptStatusOK( status ) )
695  status = generateX917( testRandomInfo, buffer, X917_BLOCKSIZE );
696 #if ( RNG_TEST_VALUES != RNG_TEST_FIPSEVAL )
697  if( cryptStatusOK( status ) && \
698  memcmp( buffer, x917VSTdata.R[ i ], X917_BLOCKSIZE ) )
699  status = CRYPT_ERROR_FAILED;
700 #endif /* FIPS eval data output */
701  endRandomPool( testRandomInfo );
702  if( cryptStatusError( status ) )
703  retIntError();
704 #if ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
705  if( isX931 )
706  {
707  printVectors( x917VSTdata.key, DT, V, buffer, i );
708  putchar( '\n' );
709  }
710 #endif /* FIPS eval data output */
711 
712  /* V = V >> 1, shifting in 1 bits;
713  DT = DT + 1 */
714  for( j = X917_BLOCKSIZE - 1; j > 0; j-- )
715  {
716  if( V[ j - 1 ] & 1 )
717  V[ j ] = ( V[ j ] >> 1 ) | 0x80;
718  }
719  V[ 0 ] = ( V[ 0 ] >> 1 ) | 0x80;
720  for( j = X917_BLOCKSIZE - 1; j >= 0; j-- )
721  {
722  DT[ j ]++;
723  if( DT[ j ] != 0 )
724  break;
725  }
726  }
727  }
728 #if ( RNG_TEST_VALUES == RNG_TEST_FIPSEVAL )
729  /* Since this is run as a background thread we need to flush the output
730  before the thread terminates, otherwise it'll be discarded */
731  fflush( stdout );
732 #endif /* FIPS eval data output */
733 #endif /* Slower CPUs */
734 
735  return( CRYPT_OK );
736  }