cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
system.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib System Device Routines *
4 * Copyright Peter Gutmann 1995-2007 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "capabil.h"
11  #include "device.h"
12  #include "dev_mech.h"
13  #include "random.h"
14 #else
15  #include "crypt.h"
16  #include "device/capabil.h"
17  #include "device/device.h"
18  #include "mechs/dev_mech.h"
19  #include "random/random.h"
20 #endif /* Compiler-specific includes */
21 
22 /* Mechanisms supported by the system device. These are sorted in order of
23  frequency of use in order to make lookups a bit faster */
24 
25 static const MECHANISM_FUNCTION_INFO FAR_BSS mechanismFunctions[] = {
26 #ifdef USE_PKC
27  { MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) exportPKCS1 },
28  { MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) importPKCS1 },
29  { MESSAGE_DEV_SIGN, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) signPKCS1 },
30  { MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) sigcheckPKCS1 },
31  { MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) exportPKCS1 },
32  { MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) importPKCS1 },
33  #ifdef USE_OAEP
34  { MESSAGE_DEV_EXPORT, MECHANISM_ENC_OAEP, ( MECHANISM_FUNCTION ) exportOAEP },
35  { MESSAGE_DEV_IMPORT, MECHANISM_ENC_OAEP, ( MECHANISM_FUNCTION ) importOAEP },
36  #endif /* USE_OAEP */
37 #endif /* USE_PKC */
38 #ifdef USE_PGP
39  { MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) exportPKCS1PGP },
40  { MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) importPKCS1PGP },
41 #endif /* USE_PGP */
42  { MESSAGE_DEV_EXPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) exportCMS },
43  { MESSAGE_DEV_IMPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) importCMS },
44  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS5, ( MECHANISM_FUNCTION ) derivePKCS5 },
45 #ifdef USE_ENVELOPES
46  { MESSAGE_DEV_KDF, MECHANISM_DERIVE_PKCS5, ( MECHANISM_FUNCTION ) kdfPKCS5 },
47 #endif /* USE_ENVELOPES */
48 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
49  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PGP, ( MECHANISM_FUNCTION ) derivePGP },
50 #endif /* USE_PGP || USE_PGPKEYS */
51 #ifdef USE_SSL
52  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_SSL, ( MECHANISM_FUNCTION ) deriveSSL },
53  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_TLS, ( MECHANISM_FUNCTION ) deriveTLS },
54  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_TLS12, ( MECHANISM_FUNCTION ) deriveTLS12 },
55  { MESSAGE_DEV_SIGN, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) signSSL },
56  { MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) sigcheckSSL },
57 #endif /* USE_SSL */
58 #ifdef USE_CMP
59  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_CMP, ( MECHANISM_FUNCTION ) deriveCMP },
60 #endif /* USE_CMP */
61 #ifdef USE_PKCS12
62  { MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS12, ( MECHANISM_FUNCTION ) derivePKCS12 },
63 #endif /* USE_PKCS12 */
64 #ifdef USE_PKC
65  { MESSAGE_DEV_EXPORT, MECHANISM_PRIVATEKEYWRAP, ( MECHANISM_FUNCTION ) exportPrivateKey },
66  { MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP, ( MECHANISM_FUNCTION ) importPrivateKey },
67  { MESSAGE_DEV_EXPORT, MECHANISM_PRIVATEKEYWRAP_PKCS8, ( MECHANISM_FUNCTION ) exportPrivateKeyPKCS8 },
68  { MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP_PKCS8, ( MECHANISM_FUNCTION ) importPrivateKeyPKCS8 },
69 #endif /* USE_PKC */
70 #ifdef USE_PGPKEYS
71  { MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP_PGP2, ( MECHANISM_FUNCTION ) importPrivateKeyPGP2 },
72  { MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP_OPENPGP_OLD, ( MECHANISM_FUNCTION ) importPrivateKeyOpenPGPOld },
73  { MESSAGE_DEV_IMPORT, MECHANISM_PRIVATEKEYWRAP_OPENPGP, ( MECHANISM_FUNCTION ) importPrivateKeyOpenPGP },
74 #endif /* USE_PGPKEYS */
76  };
77 
78 /* Object creation functions supported by the system device. These are
79  sorted in order of frequency of use in order to make lookups a bit
80  faster */
81 
83 int createCertificate( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
84  STDC_UNUSED const void *auxDataPtr,
85  STDC_UNUSED const int auxValue );
87 int createEnvelope( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
88  STDC_UNUSED const void *auxDataPtr,
89  STDC_UNUSED const int auxValue );
91 int createSession( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
92  STDC_UNUSED const void *auxDataPtr,
93  STDC_UNUSED const int auxValue );
95 int createKeyset( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
96  STDC_UNUSED const void *auxDataPtr,
97  STDC_UNUSED const int auxValue );
99 int createDevice( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
100  STDC_UNUSED const void *auxDataPtr,
101  STDC_UNUSED const int auxValue );
103 int createUser( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
104  STDC_UNUSED const void *auxDataPtr,
105  STDC_UNUSED const int auxValue );
106 
107 static const CREATEOBJECT_FUNCTION_INFO FAR_BSS createObjectFunctions[] = {
108  { OBJECT_TYPE_CONTEXT, createContext },
109 #ifdef USE_CERTIFICATES
110  { OBJECT_TYPE_CERTIFICATE, createCertificate },
111 #endif /* USE_CERTIFICATES */
112 #ifdef USE_ENVELOPES
113  { OBJECT_TYPE_ENVELOPE, createEnvelope },
114 #endif /* USE_ENVELOPES */
115 #ifdef USE_SESSIONS
116  { OBJECT_TYPE_SESSION, createSession },
117 #endif /* USE_SESSIONS */
118 #ifdef USE_KEYSETS
119  { OBJECT_TYPE_KEYSET, createKeyset },
120 #endif /* USE_KEYSETS */
121  { OBJECT_TYPE_DEVICE, createDevice },
122  { OBJECT_TYPE_USER, createUser },
123  { OBJECT_TYPE_NONE, NULL }, { OBJECT_TYPE_NONE, NULL }
124  };
125 
126 /****************************************************************************
127 * *
128 * Utility Functions *
129 * *
130 ****************************************************************************/
131 
132 /* Get a random (but not necessarily cryptographically strong random) nonce.
133  Some nonces can simply be fresh (for which a monotonically increasing
134  sequence will do), some should be random (for which a hash of the
135  sequence is adequate), and some need to be unpredictable. In order to
136  avoid problems arising from the inadvertent use of a nonce with the wrong
137  properties we use unpredictable nonces in all cases, even where it isn't
138  strictly necessary.
139 
140  This simple generator divides the nonce state into a public section of
141  the same size as the hash output and a private section that contains 64
142  bits of data from the crypto RNG, which influences the public section.
143  The public and private sections are repeatedly hashed to produce the
144  required amount of output. Note that this leaks a small amount of
145  information about the crypto RNG output since an attacker knows that
146  public_state_n = hash( public_state_n - 1, private_state ) but this
147  isn't a major weakness */
148 
150 static int getNonce( INOUT SYSTEMDEV_INFO *systemInfo,
151  OUT_BUFFER_FIXED( dataLength ) void *data,
152  IN_LENGTH_SHORT const int dataLength )
153  {
154  BYTE *noncePtr = data;
155  int nonceLength, iterationCount;
156 
157  assert( isWritePtr( systemInfo, sizeof( SYSTEMDEV_INFO ) ) );
158  assert( isWritePtr( data, dataLength ) );
159 
160  REQUIRES( dataLength > 0 && dataLength < MAX_INTLENGTH_SHORT );
161 
162  /* If the nonce generator hasn't been initialised yet we set up the
163  hashing and get 64 bits of private nonce state. What to do if the
164  attempt to initialise the state fails is somewhat debatable. Since
165  nonces are only ever used in protocols alongside crypto keys and an
166  RNG failure will be detected when the key is generated we can
167  generally ignore a failure at this point. However nonces are
168  sometimes also used in non-crypto contexts (for example to generate
169  certificate serial numbers) where this detection in the RNG won't
170  happen. On the other hand we shouldn't really abort processing just
171  because we can't get some no-value nonce data so what we do is retry
172  the fetch of nonce data (in case the system object was busy and the
173  first attempt timed out) and if that fails too fall back to the
174  system time. This is no longer unpredictable, but the only location
175  where unpredictability matters is when used in combination with
176  crypto operations for which the absence of random data will be
177  detected during key generation */
178  if( !systemInfo->nonceDataInitialised )
179  {
181  int status;
182 
183  /* Get the 64-bit private portion of the nonce data */
184  getHashAtomicParameters( CRYPT_ALGO_SHA1, 0,
185  &systemInfo->hashFunctionAtomic,
186  &systemInfo->hashSize );
187  setMessageData( &msgData, systemInfo->nonceData + \
188  systemInfo->hashSize, 8 );
190  IMESSAGE_GETATTRIBUTE_S, &msgData,
191  CRYPT_IATTRIBUTE_RANDOM );
192  if( cryptStatusError( status ) )
194  IMESSAGE_GETATTRIBUTE_S, &msgData,
195  CRYPT_IATTRIBUTE_RANDOM );
196  if( cryptStatusError( status ) )
197  {
198  const time_t theTime = getTime();
199 
200  memcpy( systemInfo->nonceData + systemInfo->hashSize, &theTime,
201  sizeof( time_t ) );
202  }
203  systemInfo->nonceDataInitialised = TRUE;
204  }
205  ENSURES( systemInfo->hashFunctionAtomic != NULL );
206  ENSURES( systemInfo->hashSize >= 16 && \
207  systemInfo->hashSize <= CRYPT_MAX_HASHSIZE );
208 
209  /* Shuffle the public state and copy it to the output buffer until it's
210  full */
211  for( nonceLength = dataLength, iterationCount = 0;
212  nonceLength > 0 && iterationCount < FAILSAFE_ITERATIONS_LARGE;
213  iterationCount++ )
214  {
215  const int bytesToCopy = min( nonceLength, systemInfo->hashSize );
216 
217  /* Hash the state and copy the appropriate amount of data to the
218  output buffer */
219  systemInfo->hashFunctionAtomic( systemInfo->nonceData,
221  systemInfo->nonceData,
222  systemInfo->hashSize + 8 );
223  memcpy( noncePtr, systemInfo->nonceData, bytesToCopy );
224 
225  /* Move on to the next block of the output buffer */
226  noncePtr += bytesToCopy;
227  nonceLength -= bytesToCopy;
228  }
229  ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
230 
231  return( CRYPT_OK );
232  }
233 
234 #ifndef CONFIG_NO_SELFTEST
235 
236 /* Perform the algorithm self-test */
237 
239 static int algorithmSelfTest( INOUT \
240  CAPABILITY_INFO_LIST **capabilityInfoListPtrPtr )
241  {
242  CAPABILITY_INFO_LIST *capabilityInfoListPtr;
243  CAPABILITY_INFO_LIST *capabilityInfoListPrevPtr = NULL;
244  BOOLEAN algoTested = FALSE;
245  int iterationCount, status = CRYPT_OK;
246 
247  assert( isReadPtr( capabilityInfoListPtrPtr, \
248  sizeof( CAPABILITY_INFO_LIST * ) ) );
249 
250  /* Test each available capability */
251  for( capabilityInfoListPtr = *capabilityInfoListPtrPtr, iterationCount = 0;
252  capabilityInfoListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_MED;
253  capabilityInfoListPtr = capabilityInfoListPtr->next, iterationCount++ )
254  {
255  const CAPABILITY_INFO *capabilityInfoPtr = capabilityInfoListPtr->info;
256  int localStatus;
257 
258  REQUIRES( capabilityInfoPtr->selfTestFunction != NULL );
259 
260  /* Perform the self-test for this algorithm type */
261  localStatus = capabilityInfoPtr->selfTestFunction();
262  if( cryptStatusError( localStatus ) )
263  {
264  /* The self-test failed, remember the status if it's the first
265  failure and disable this algorithm */
266  if( cryptStatusOK( status ) )
267  status = localStatus;
268  deleteSingleListElement( capabilityInfoListPtrPtr,
269  capabilityInfoListPrevPtr,
270  capabilityInfoListPtr );
271 
272  /* Since the algorithm self-test is one of the first things that
273  gets called when cryptlib is built on a new system we make it
274  easy for developers by printing a diagnostic in the debug
275  build */
276  DEBUG_PRINT(( "Algorithm %s failed self-test.\n",
277  capabilityInfoPtr->algoName ));
278  }
279  else
280  {
281  algoTested = TRUE;
282 
283  /* Remember the last successfully-tested capability */
284  capabilityInfoListPrevPtr = capabilityInfoListPtr;
285  }
286  }
287  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
288 
289  return( algoTested ? status : CRYPT_ERROR_NOTFOUND );
290  }
291 
292 /* Perform the mechanism self-test. This is performed in addition to the
293  algorithm tests if the user requests a test of all algorithms. Currently
294  only key derivation mechanisms are tested since the others either produce
295  non-constant results that can't be checked against a fixed value or
296  require the creation of multiple contexts to hold keys */
297 
298 typedef struct {
302 
303 #define MECHANISM_OUTPUT_SIZE 32
304 #define MECHANISM_INPUT_SIZE 32
305 #define MECHANISM_SALT_SIZE 16
306 
307 #define MECHANISM_OUTPUT_SIZE_SSL 48
308 #define MECHANISM_INPUT_SIZE_SSL 48
309 #define MECHANISM_SALT_SIZE_SSL 64
310 
311 static const BYTE FAR_BSS inputValue[] = {
312  /* More than a single hash block size for SHA-1 */
313  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
314  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
315  0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
316  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
317  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
318  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
319  };
320 static const BYTE FAR_BSS saltValue[] = {
321  /* At least 64 bytes for SSL/TLS PRF */
322  0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
323  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
324  0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F,
325  0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
326  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
327  0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
328  0x80, 0x91, 0xA2, 0xB3, 0xC4, 0xD5, 0xE6, 0xF7,
329  0x08, 0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F
330  };
331 #ifdef USE_PKCS12
332 static const BYTE FAR_BSS pkcs12saltValue[] = {
333  /* PKCS #12 has a single-byte diversifier at the start of the salt */
334  0x01,
335  0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87,
336  0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
337  };
338 #endif /* USE_PKCS12 */
339 
340 static const MECHANISM_TEST_INFO FAR_BSS mechanismTestInfo[] = {
342  { "\x73\xF7\x8A\xBE\x3C\x9C\x65\x80\x97\x60\x56\xDE\x04\x2A\x0C\x97"
343  "\x99\xF5\x06\x0F\x43\x06\xA5\xD0\x74\xC9\xD5\xC5\xA5\x05\xB5\x7F", MECHANISM_OUTPUT_SIZE,
345  saltValue, MECHANISM_SALT_SIZE, 10 } },
346 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
348  { "\x4A\x4B\x90\x09\x27\xF8\xD0\x93\x56\x16\xEA\xC1\x45\xCD\xEE\x05"
349  "\x67\xE1\x09\x38\x66\xEB\xB2\xB2\xB9\x1F\xD3\xF7\x48\x2B\xDC\xCA", MECHANISM_OUTPUT_SIZE,
350  inputValue, MECHANISM_INPUT_SIZE, CRYPT_ALGO_SHA1, 0,
351  saltValue, 8, 10 } },
352 #endif /* USE_PGP || USE_PGPKEYS */
353 #ifdef USE_SSL
355  { "\x87\x46\xDD\x7D\xAD\x5F\x48\xB6\xFC\x8D\x92\xC4\xDB\x38\x79\x9A"
356  "\x3D\xEA\x22\xFA\xCD\x7E\x86\xD5\x23\x6E\x10\x4C\xBD\x84\x89\xDF"
357  "\x1C\x87\x60\xBF\xFA\x2B\xCA\xFE\xFE\x65\xC7\xA2\xCF\x04\xFF\xEB", MECHANISM_OUTPUT_SIZE_SSL,
359  saltValue, MECHANISM_SALT_SIZE_SSL, 1 } },
361  { "\xD3\xD4\x2F\xD6\xE3\x7D\xC0\x3C\xA6\x9F\x92\xDF\x3E\x40\x0A\x64"
362  "\x49\xB4\x0E\xC4\x14\x04\x2F\xC8\xDD\x27\xD5\x1C\x62\xD2\x2C\x97"
363  "\x90\xAE\x08\x4B\xEE\xF4\x8D\x22\xF0\x2A\x1E\x38\x2D\x31\xCB\x68", MECHANISM_OUTPUT_SIZE_SSL,
365  saltValue, MECHANISM_SALT_SIZE_SSL, 1 } },
366 #endif /* USE_SSL */
367 #ifdef USE_CMP
369  { "\x80\x0B\x95\x73\x74\x3B\xC1\x63\x6B\x28\x2B\x04\x47\xFD\xF0\x04"
370  "\x80\x40\x31\xB1", 20,
371  inputValue, MECHANISM_INPUT_SIZE, CRYPT_ALGO_SHA1, 0,
372  saltValue, MECHANISM_SALT_SIZE, 10 } },
373 #endif /* USE_CMP */
374 #ifdef USE_PKCS12
375  #if 0 /* Additional check value from OpenSSL, this only uses 1 iteration */
377  { "\x8A\xAA\xE6\x29\x7B\x6C\xB0\x46\x42\xAB\x5B\x07\x78\x51\x28\x4E"
378  "\xB7\x12\x8F\x1A\x2A\x7F\xBC\xA3", 24,
379  "smeg", 4, CRYPT_ALGO_SHA1, 0,
380  "\x01\x0A\x58\xCF\x64\x53\x0D\x82\x3F", 1 + 8, 1 } },
381  #endif /* 0 */
382  #if 0 /* Additional check value from OpenSSL, now with 1,000 iterations */
384  { "\xED\x20\x34\xE3\x63\x28\x83\x0F\xF0\x9D\xF1\xE1\xA0\x7D\xD3\x57"
385  "\x18\x5D\xAC\x0D\x4F\x9E\xB3\xD4", 24,
386  "queeg", 5, CRYPT_ALGO_SHA1, 0,
387  "\x01\x05\xDE\xC9\x59\xAC\xFF\x72\xF7", 1 + 8, 1000 } },
388  #endif /* 0 */
390  { "\x8B\xFB\x1D\x77\xFE\x78\xFF\xE8\xE9\x69\x76\xE0\xC5\x0A\xB6\xD2"
391  "\x64\xEC\xA3\x01\xE9\xD2\xE0\xC0\xBC\x60\x3D\x63\xB2\x4A\xB2\x63", MECHANISM_OUTPUT_SIZE,
392  inputValue, MECHANISM_INPUT_SIZE, CRYPT_ALGO_SHA1, 0,
393  pkcs12saltValue, 1 + MECHANISM_SALT_SIZE, 10 } },
394 #endif /* USE_PKCS12 */
396  };
397 
398 CHECK_RETVAL \
399 static int mechanismSelfTest( void )
400  {
402  int i, status;
403 
404  for( i = 0; mechanismTestInfo[ i ].mechanismType != MECHANISM_NONE && \
405  i < FAILSAFE_ARRAYSIZE( mechanismTestInfo, MECHANISM_TEST_INFO );
406  i++ )
407  {
408  const MECHANISM_TEST_INFO *mechanismTestInfoPtr = \
409  &mechanismTestInfo[ i ];
411 
412  memcpy( &mechanismInfo, &mechanismTestInfoPtr->mechanismInfo,
413  sizeof( MECHANISM_DERIVE_INFO ) );
414  mechanismInfo.dataOut = buffer;
416  IMESSAGE_DEV_DERIVE, &mechanismInfo,
417  mechanismTestInfoPtr->mechanismType );
418  if( cryptStatusError( status ) )
419  return( status );
420  if( memcmp( mechanismTestInfoPtr->mechanismInfo.dataOut, buffer,
421  mechanismTestInfoPtr->mechanismInfo.dataOutLength ) )
422  return( CRYPT_ERROR_FAILED );
423  }
424  ENSURES( i < FAILSAFE_ARRAYSIZE( mechanismTestInfo, MECHANISM_TEST_INFO ) );
425 
426  return( CRYPT_OK );
427  }
428 #endif /* CONFIG_NO_SELFTEST */
429 
430 /****************************************************************************
431 * *
432 * Device Init/Shutdown/Device Control Routines *
433 * *
434 ****************************************************************************/
435 
436 /* Initialise and shut down the system device */
437 
438 CHECK_RETVAL \
439 static int initCapabilities( void ); /* Fwd.dec for fn.*/
440 
442 static int initFunction( INOUT DEVICE_INFO *deviceInfo,
443  STDC_UNUSED const char *name,
444  STDC_UNUSED const int nameLength )
445  {
446  int status;
447 
448  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
449 
450  REQUIRES( name == NULL && nameLength == 0 );
451 
452  /* Set up the capability information for this device */
453  status = initCapabilities();
454  if( cryptStatusError( status ) )
455  return( status );
456 
457  /* Set up the randomness information */
458  status = initRandomInfo( &deviceInfo->randomInfo );
459  if( cryptStatusError( status ) )
460  return( status );
461 
462  /* Complete the initialisation and mark the device as active */
463  deviceInfo->label = "cryptlib system device";
464  deviceInfo->labelLen = strlen( deviceInfo->label );
465  deviceInfo->flags = DEVICE_ACTIVE | DEVICE_LOGGEDIN | DEVICE_TIME;
466  return( CRYPT_OK );
467  }
468 
469 STDC_NONNULL_ARG( ( 1 ) ) \
470 static void shutdownFunction( INOUT DEVICE_INFO *deviceInfo )
471  {
472  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
473 
474  endRandomInfo( &deviceInfo->randomInfo );
475  }
476 
477 #ifndef CONFIG_NO_SELFTEST
478 
479 /* Perform a self-test */
480 
481 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
482 static int selftestFunction( INOUT DEVICE_INFO *deviceInfo,
484  {
485  CAPABILITY_INFO_LIST **capabilityInfoListPtrPtr = \
486  ( CAPABILITY_INFO_LIST ** ) &deviceInfo->capabilityInfoList;
487  BYTE buffer[ 8 + 8 ];
488  int refCount, status;
489 
490  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
491  assert( isWritePtr( messageExtInfo, \
492  sizeof( MESSAGE_FUNCTION_EXTINFO ) ) );
493 
494  /* The self-tests need randomness for some of their operations, in order
495  to pre-empt a lack of this from causing a failure somewhere deep down
496  in the crypto code we perform a dummy read of first the randomness
497  source and then the nonce source to force a full initialisation of
498  the randomness subsystem */
499  status = deviceInfo->getRandomFunction( deviceInfo, buffer, 8, NULL );
500  if( cryptStatusError( status ) )
501  return( status );
502  zeroise( buffer, 8 );
503  status = getNonce( deviceInfo->deviceSystem, buffer, 8 );
504  if( cryptStatusError( status ) )
505  return( status );
506  zeroise( buffer, 8 );
507 
508  /* Perform an algorithm self-test */
509  status = algorithmSelfTest( capabilityInfoListPtrPtr );
510  if( cryptStatusError( status ) )
511  return( status );
512 
513  /* Perform the mechanism self-test. Since this can be quite lengthy and
514  requires recursive handling of messages by the system object (without
515  actually requiring access to system object state) we unlock it to
516  avoid it becoming a bottleneck */
517  status = krnlSuspendObject( deviceInfo->objectHandle, &refCount );
518  if( cryptStatusError( status ) )
519  return( status );
520  setMessageObjectUnlocked( messageExtInfo );
521  return( mechanismSelfTest() );
522  }
523 #endif /* !CONFIG_NO_SELFTEST */
524 
525 /* Get random data. We have to unlock the device around the randomness
526  fetch because background polling threads need to be able to send entropy
527  data to it:
528 
529  System Randomness
530  ------ ----------
531  getRand ------>| |
532  [Suspend] |
533  |--------------->|
534  | |
535  |<===============| Entropy
536  |<===============| Entropy
537  |<===============| Entropy Quality
538  | |
539  |<---------------|
540  [Resume] |
541 
542  If the caller has specified that it's unlockable and the reference count
543  is one or less (meaning that we've been sent the message directly), we
544  leave it unlocked. Otherwise we re-lock it afterwards.
545 
546  Note that there's a tiny chance of a race condition if the system object
547  is destroyed between the unlock and the acquisition of the randomness
548  mutex (which means that the randomInfo could be freed while we're getting
549  the random data), however there's no easy way around this short of using
550  a complex multiple-mutex interlock, and in any case there's only so much
551  that we can do to help a user who pulls data structures out from under
552  active threads */
553 
554 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
555 static int getRandomFunction( INOUT DEVICE_INFO *deviceInfo,
556  OUT_BUFFER_FIXED( length ) void *buffer,
557  IN_LENGTH_SHORT const int length,
558  INOUT_OPT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
559  {
560  int refCount, status;
561 
562  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
563  assert( isWritePtr( buffer, length ) );
564 
565  REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );
566 
567  /* Clear the return value and make sure that we fail the FIPS 140 tests
568  on the output if there's a problem */
569  zeroise( buffer, length );
570 
571  /* If the system device is already unlocked (which can happen if this
572  function is called in a loop, for example if multiple chunks of
573  randomness are read) just return the randomness directly */
574  if( messageExtInfo != NULL && isMessageObjectUnlocked( messageExtInfo ) )
575  return( getRandomData( deviceInfo->randomInfo, buffer, length ) );
576 
577  /* Unlock the system device, get the data, and re-lock it if necessary */
578  status = krnlSuspendObject( deviceInfo->objectHandle, &refCount );
579  if( cryptStatusError( status ) )
580  return( status );
581  status = getRandomData( deviceInfo->randomInfo, buffer, length );
582  if( messageExtInfo == NULL || refCount > 1 )
583  {
584  /* The object isn't unlockable or it's been locked recursively,
585  re-lock it */
586  status = krnlResumeObject( SYSTEM_OBJECT_HANDLE, refCount );
587  if( cryptStatusError( status ) )
588  {
589  /* We couldn't re-lock the system object, let the caller know.
590  Since this is a shouldn't-occur condition we also warn the
591  user in the debug version */
592  DEBUG_DIAG(( "Failed to re-lock system object" ));
593  assert( DEBUG_WARN );
594  if( messageExtInfo != NULL )
595  setMessageObjectUnlocked( messageExtInfo );
596  }
597  }
598  else
599  {
600  /* Tell the caller that we've left the object unlocked so they don't
601  have to do anything further with it */
602  setMessageObjectUnlocked( messageExtInfo );
603  }
604  return( status );
605  }
606 
607 /* Handle device control functions */
608 
610 static int controlFunction( INOUT DEVICE_INFO *deviceInfo,
612  IN_BUFFER_OPT( dataLength ) void *data,
613  IN_LENGTH_SHORT_Z const int dataLength,
614  INOUT_OPT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
615  {
616  int refCount, status;
617 
618  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
619  assert( data == NULL || isReadPtr( data, dataLength ) );
620 
621  REQUIRES( type == CRYPT_IATTRIBUTE_ENTROPY || \
622  type == CRYPT_IATTRIBUTE_ENTROPY_QUALITY || \
623  type == CRYPT_IATTRIBUTE_RANDOM_POLL || \
624  type == CRYPT_IATTRIBUTE_RANDOM_NONCE || \
625  type == CRYPT_IATTRIBUTE_TIME );
626  REQUIRES( ( ( type == CRYPT_IATTRIBUTE_ENTROPY || \
627  type == CRYPT_IATTRIBUTE_RANDOM_NONCE ) && \
628  ( data != NULL && \
629  dataLength > 0 && dataLength < MAX_INTLENGTH ) ) || \
630  ( type == CRYPT_IATTRIBUTE_TIME && \
631  data != NULL && dataLength == sizeof( time_t ) ) || \
632  ( ( type == CRYPT_IATTRIBUTE_ENTROPY_QUALITY || \
633  type == CRYPT_IATTRIBUTE_RANDOM_POLL ) && \
634  ( data == NULL && \
635  dataLength >= 0 && dataLength < MAX_INTLENGTH_SHORT ) ) );
636 
637  /* Handle entropy addition. Since this can take awhile, we do it with
638  the system object unlocked. See the comment in getRandomFunction()
639  about the possibility of a race condition */
640  if( type == CRYPT_IATTRIBUTE_ENTROPY )
641  {
642  status = krnlSuspendObject( deviceInfo->objectHandle, &refCount );
643  if( cryptStatusError( status ) )
644  return( status );
645  setMessageObjectUnlocked( messageExtInfo );
646  return( addEntropyData( deviceInfo->randomInfo, data, dataLength ) );
647  }
648  if( type == CRYPT_IATTRIBUTE_ENTROPY_QUALITY )
649  {
650  status = krnlSuspendObject( deviceInfo->objectHandle, &refCount );
651  if( cryptStatusError( status ) )
652  return( status );
653  setMessageObjectUnlocked( messageExtInfo );
654  return( addEntropyQuality( deviceInfo->randomInfo, dataLength ) );
655  }
656  if( type == CRYPT_IATTRIBUTE_RANDOM_POLL )
657  {
658  status = krnlSuspendObject( deviceInfo->objectHandle, &refCount );
659  if( cryptStatusError( status ) )
660  return( status );
661  setMessageObjectUnlocked( messageExtInfo );
662 
663  /* Perform a slow or fast poll as required */
664  if( dataLength == TRUE )
665  slowPoll();
666  else
667  fastPoll();
668 
669  return( CRYPT_OK );
670  }
671 
672  /* Handle nonces */
673  if( type == CRYPT_IATTRIBUTE_RANDOM_NONCE )
674  return( getNonce( deviceInfo->deviceSystem, data, dataLength ) );
675 
676  /* Handle high-reliability time */
677  if( type == CRYPT_IATTRIBUTE_TIME )
678  {
679  time_t *timePtr = ( time_t * ) data;
680 
681  *timePtr = getTime();
682  return( CRYPT_OK );
683  }
684 
685  retIntError();
686  }
687 
688 /****************************************************************************
689 * *
690 * Device Capability Routines *
691 * *
692 ****************************************************************************/
693 
694 /* The cryptlib intrinsic capability list */
695 
696 #define MAX_NO_CAPABILITIES 32
697 
698 static const GETCAPABILITY_FUNCTION FAR_BSS getCapabilityTable[] = {
700 #ifdef USE_AES
702 #endif /* USE_AES */
703 #ifdef USE_BLOWFISH
705 #endif /* USE_BLOWFISH */
707 #ifdef USE_IDEA
709 #endif /* USE_IDEA */
710 #ifdef USE_RC2
712 #endif /* USE_RC2 */
713 #ifdef USE_RC4
715 #endif /* USE_RC4 */
716 #ifdef USE_RC5
718 #endif /* USE_RC5 */
719 
720 #ifdef USE_MD5
722 #endif /* USE_MD5 */
723 #ifdef USE_RIPEMD160
725 #endif /* USE_RIPEMD160 */
727 #ifdef USE_SHA2
729 #endif /* USE_SHA2 */
730 
731 #ifdef USE_HMAC_MD5
733 #endif /* USE_HMAC_MD5 */
734 #ifdef USE_HMAC_RIPEMD160
736 #endif /* USE_HMAC_RIPEMD160 */
738 #ifdef USE_HMAC_SHA2
740 #endif /* USE_SHA2 */
741 
742 #ifdef USE_DH
744 #endif /* USE_DH */
745 #ifdef USE_DSA
747 #endif /* USE_DSA */
748 #ifdef USE_ELGAMAL
750 #endif /* USE_ELGAMAL */
751 #ifdef USE_RSA
753 #endif /* USE_RSA */
754 #ifdef USE_ECDSA
756 #endif /* USE_ECDSA */
757 #ifdef USE_ECDH
759 #endif /* USE_ECDH */
760 
762 
763  /* Vendors may want to use their own algorithms, which aren't part of the
764  general cryptlib suite. The following provides the ability to include
765  vendor-specific algorithm capabilities defined in the file
766  vendalgo.c */
767 #ifdef USE_VENDOR_ALGOS
768  #include "vendalgo.c"
769 #endif /* USE_VENDOR_ALGOS */
770 
771  /* End-of-list marker */
772  NULL, NULL
773  };
774 
775 static CAPABILITY_INFO_LIST FAR_BSS capabilityInfoList[ MAX_NO_CAPABILITIES ];
776 
777 /* Initialise the capability information */
778 
779 CHECK_RETVAL \
780 static int initCapabilities( void )
781  {
782  int i;
783 
784  /* Build the list of available capabilities */
785  memset( capabilityInfoList, 0,
787  for( i = 0;
788  getCapabilityTable[ i ] != NULL && \
789  i < FAILSAFE_ARRAYSIZE( getCapabilityTable, GETCAPABILITY_FUNCTION );
790  i++ )
791  {
792  const CAPABILITY_INFO *capabilityInfoPtr = getCapabilityTable[ i ]();
793 
794  REQUIRES( sanityCheckCapability( capabilityInfoPtr, FALSE ) );
795 
796  capabilityInfoList[ i ].info = capabilityInfoPtr;
797  capabilityInfoList[ i ].next = NULL;
798  if( i > 0 )
799  capabilityInfoList[ i - 1 ].next = &capabilityInfoList[ i ];
800  }
801  REQUIRES( i < FAILSAFE_ARRAYSIZE( getCapabilityTable, \
803 
804  return( CRYPT_OK );
805  }
806 
807 /****************************************************************************
808 * *
809 * Device Access Routines *
810 * *
811 ****************************************************************************/
812 
813 /* Set up the function pointers to the device methods */
814 
816 int setDeviceSystem( INOUT DEVICE_INFO *deviceInfo )
817  {
818  assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
819 
820  deviceInfo->initFunction = initFunction;
821  deviceInfo->shutdownFunction = shutdownFunction;
822  deviceInfo->controlFunction = controlFunction;
823 #ifndef CONFIG_NO_SELFTEST
824  deviceInfo->selftestFunction = selftestFunction;
825 #endif /* !CONFIG_NO_SELFTEST */
826  deviceInfo->getRandomFunction = getRandomFunction;
827  deviceInfo->capabilityInfoList = capabilityInfoList;
828  deviceInfo->createObjectFunctions = createObjectFunctions;
829  deviceInfo->createObjectFunctionCount = \
830  FAILSAFE_ARRAYSIZE( createObjectFunctions, CREATEOBJECT_FUNCTION_INFO );
831  deviceInfo->mechanismFunctions = mechanismFunctions;
832  deviceInfo->mechanismFunctionCount = \
833  FAILSAFE_ARRAYSIZE( mechanismFunctions, MECHANISM_FUNCTION_INFO );
834 
835  return( CRYPT_OK );
836  }