cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
hw_dummy.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Dummy Crypto HAL Routines *
4 * Copyright Peter Gutmann 1998-2009 *
5 * *
6 ****************************************************************************/
7 
8 /* This module is a template for use when adding support for custom
9  cryptographic hardware to cryptlib. It implements dummy versions of the
10  cryptographic operations that are provided by the custom hardware. See
11  the inline comments for what's needed at each stage */
12 
13 #if defined( INC_ALL )
14  #include "crypt.h"
15  #include "context.h"
16  #include "hardware.h"
17 #else
18  #include "crypt.h"
19  #include "context/context.h"
20  #include "device/hardware.h"
21 #endif /* Compiler-specific includes */
22 
23 #ifdef USE_HARDWARE
24 
25 /****************************************************************************
26 * *
27 * Personality Storage *
28 * *
29 ****************************************************************************/
30 
31 /* Each key, along with its associated identifiers, certificates, and other
32  metadata, constitutes a personality. cryptlib manages most of this
33  information externally, the only data that's stored here is the keying
34  information in whatever format the cryptographic hardware uses and a
35  short binary unique-ID value, the storageID, that cryptlib uses to look
36  up a personality.
37 
38  Externally, cryptlib maintains a 160-bit value as a storageID but this
39  module only needs to use as much of it as required to avoid a false
40  positive match. In this case we use 64 bits of the storageID to look up
41  a personality */
42 
43 #define STORAGEID_SIZE 8
44 
45 /* Private key data will generally be stored in a hardware-specific internal
46  format. For demonstration purposes we assume that this consists of
47  32-bit big-endian words (chosen because the most widely-deployed
48  architectures are little-endian, so this guarantees that if there's a
49  problem it'll be caught by the different endianness), which we need to
50  convert to and from the generic CRYPT_PKCINFO_RSA/CRYPT_PKCINFO_DLP
51  format on import and export. The following structure is used to store
52  data in the dummy hardware-internal format. The layout of the data is
53  as follows:
54 
55  Index RSA value DLP value ECC value
56  ----- --------- --------- ---------
57  0 n p p
58  1 e q a
59  2 d q b
60  3 p y gx
61  4 q x gy
62  5 u r
63  6 e1 h
64  7 e2 [...] */
65 
66 typedef struct {
67  LONG data[ CRYPT_MAX_PKCSIZE / sizeof( LONG ) ];
68  int dataSize;
69  } BIGNUM_STORAGE;
70 
71 #define NO_BIGNUMS 8
72 
73 /* Each personality contains (at least) the storageID used to reference it
74  and whatever keying information is needed by the underlying cryptographic
75  hardware. The following structure contains the information stored for
76  each personality. The inUse flag is a convenience feature, it can also
77  be indicated through a convention such as an all-zero storageID */
78 
79 typedef struct {
80  /* General management information */
81  BOOLEAN inUse; /* Whether this personality is in use */
82  BYTE storageID[ STORAGEID_SIZE ];/* ID used to look up this personality */
83 
84  /* Key data storage */
85  union {
86  BYTE convKeyInfo[ CRYPT_MAX_KEYSIZE ];
87  BIGNUM_STORAGE pkcKeyInfo[ NO_BIGNUMS ];
88  } keyInfo;
89  } PERSONALITY_INFO;
90 
91 /* Storage for each personality. This would typically be held either in
92  internal protected memory (for example battery-backed device-internal
93  SRAM) or encrypted external memory that's transparently accessed as
94  standard memory. The memory doesn't explicitly have to be zeroed since
95  cryptlib does this on device initialisation, it's done here merely as
96  a convenience during debugging */
97 
98 #define NO_PERSONALITIES 8
99 
100 static PERSONALITY_INFO personalityInfo[ NO_PERSONALITIES ] = { 0 };
101 
102 /****************************************************************************
103 * *
104 * Personality Management Routines *
105 * *
106 ****************************************************************************/
107 
108 /* The following routines manage access to the personality storage and
109  represent an example implementation matching the sample PERSONALITY_INFO
110  structure defined earlier. The routines look up a personality given its
111  storageID, find a free personality slot to use when instantiating a new
112  personality (or in more high-level terms when loading or generating a
113  key for an encryption context), and delete a personality */
114 
115 /* Look up a personality given a key ID */
116 
117 static int lookupPersonality( const void *keyID, const int keyIDlength,
118  int *keyHandle )
119  {
120  const int storageIDlength = min( keyIDlength, STORAGEID_SIZE );
121  int i;
122 
123  assert( isReadPtr( keyID, keyIDlength ) );
124  assert( isWritePtr( keyHandle, sizeof( int ) ) );
125 
126  REQUIRES( keyIDlength >= 4 && keyIDlength <= KEYID_SIZE );
127 
128  /* Clear return value */
129  *keyHandle = CRYPT_ERROR;
130 
131  /* Scan the personality table looking for one matching the given
132  storageID */
133  for( i = 0; i < NO_PERSONALITIES; i++ )
134  {
135  PERSONALITY_INFO *personalityInfoPtr = &personalityInfo[ i ];
136 
137  if( !personalityInfoPtr->inUse )
138  continue;
139  if( !memcmp( personalityInfoPtr->storageID, keyID, storageIDlength ) )
140  {
141  *keyHandle = i;
142  return( CRYPT_OK );
143  }
144  }
145  return( CRYPT_ERROR_NOTFOUND );
146  }
147 
148 /* Find a free personality */
149 
150 static int findFreePersonality( int *keyHandle )
151  {
152  int i;
153 
154  assert( isWritePtr( keyHandle, sizeof( int ) ) );
155 
156  /* Clear return value */
157  *keyHandle = CRYPT_ERROR;
158 
159  /* Scan the personality table looking for a free slot */
160  for( i = 0; i < NO_PERSONALITIES; i++ )
161  {
162  PERSONALITY_INFO *personalityInfoPtr = &personalityInfo[ i ];
163 
164  if( !personalityInfoPtr->inUse )
165  {
166  zeroise( personalityInfoPtr, sizeof( PERSONALITY_INFO ) );
167  *keyHandle = i;
168  return( CRYPT_OK );
169  }
170  }
171  return( CRYPT_ERROR_OVERFLOW );
172  }
173 
174 /* Delete a personality */
175 
176 static void deletePersonality( const int keyHandle )
177  {
178  PERSONALITY_INFO *personalityInfoPtr;
179 
180  REQUIRES_V( keyHandle >= 0 && keyHandle < NO_PERSONALITIES );
181 
182  if( keyHandle < 0 || keyHandle >= NO_PERSONALITIES )
183  return;
184  personalityInfoPtr = &personalityInfo[ keyHandle ];
185  zeroise( personalityInfoPtr, sizeof( PERSONALITY_INFO ) );
186  }
187 
188 /****************************************************************************
189 * *
190 * Utility Routines *
191 * *
192 ****************************************************************************/
193 
194 /* Functions used to convert from the dummy hardware-internal bignum format
195  (big-endian 32-bit words) to the generic external format */
196 
197 static void bignumToInternal( LONG *outData, int *outDataLength,
198  const BYTE *inData, const int inDataLength )
199  {
200  int inIndex, outIndex = 0, i;
201 
202  assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) );
203  assert( isWritePtr( outDataLength, sizeof( int ) ) );
204  assert( isReadPtr( inData, inDataLength ) );
205 
206  REQUIRES_V( inDataLength > 0 && inDataLength <= CRYPT_MAX_PKCSIZE );
207 
208  for( i = 0; i < CRYPT_MAX_PKCSIZE / sizeof( LONG ); i++ )
209  outData[ i ] = 0L;
210  for( inIndex = 0; inIndex < inDataLength; inIndex += sizeof( LONG ) )
211  {
212  outData[ outIndex++ ] = mgetLong( inData );
213  }
214  *outDataLength = outIndex;
215  }
216 
217 static void bignumToExternal( BYTE *outData, int *outDataLength,
218  const LONG *inData, const int inDataLength )
219  {
220  int inIndex = 0, outIndex;
221 
222  assert( isWritePtr( outData, CRYPT_MAX_PKCSIZE ) );
223  assert( isWritePtr( outDataLength, sizeof( int ) ) );
224  assert( isReadPtr( inData, inDataLength * sizeof( LONG ) ) );
225 
226  REQUIRES_V( inDataLength > 0 && \
227  inDataLength <= CRYPT_MAX_PKCSIZE / sizeof( LONG ) );
228 
229  memset( outData, 0, CRYPT_MAX_PKCSIZE );
230  for( outIndex = 0; outIndex < inDataLength; outIndex++ )
231  {
232  const LONG value = inData[ inIndex++ ];
233 
234  mputLong( outData, value );
235  }
236  *outDataLength = outIndex * sizeof( LONG );
237  }
238 
239 /* Dummy functions used to "encrypt" data and generate "random" data in the
240  absence of any actual hardware functionality */
241 
242 static void dummyEncrypt( const PERSONALITY_INFO *personalityInfoPtr,
243  BYTE *data, const int length,
245  const CRYPT_MODE_TYPE cryptMode )
246  {
247  int i;
248 
249  assert( isReadPtr( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ) );
250  assert( isWritePtr( data, length ) );
251 
252  REQUIRES_V( cryptAlgo > CRYPT_ALGO_NONE && \
253  cryptAlgo < CRYPT_ALGO_LAST_EXTERNAL );
254  REQUIRES_V( cryptMode >= CRYPT_MODE_NONE && \
255  cryptMode < CRYPT_MODE_LAST );
256 
257  if( isPkcAlgo( cryptAlgo ) )
258  {
259  BYTE bignumData[ CRYPT_MAX_PKCSIZE + 8 ];
260  int bignumDataLength;
261 
262  bignumToExternal( bignumData, &bignumDataLength,
263  personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].data,
264  personalityInfoPtr->keyInfo.pkcKeyInfo[ 0 ].dataSize );
265  for( i = 0; i < length; i++ )
266  data[ i ] ^= bignumData[ i ];
267 
268  return;
269  }
270 
271  /* We have to be a bit careful with the conventional encryption because
272  the self-tests encrypt data in variable-length quantities to check
273  for things like chaining problems, which means that for stream
274  ciphers we really can't do anything more than repeatedly XOR with a
275  fixed key byte */
276  if( cryptMode == CRYPT_MODE_CFB || cryptMode == CRYPT_MODE_OFB )
277  {
278  const int keyDataOffset = CRYPT_MODE_CFB ? 0 : 1;
279 
280  for( i = 0; i < length; i++ )
281  data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ keyDataOffset ];
282  }
283  else
284  {
285  /* It's a block mode, we can at least use ECB, although we still
286  can't chain because we don't know where we are in the data
287  stream */
288  for( i = 0; i < length; i++ )
289  data[ i ] ^= personalityInfoPtr->keyInfo.convKeyInfo[ i % 16 ];
290  }
291  }
292 
293 static void dummyGenRandom( void *buffer, const int length )
294  {
295  HASHFUNCTION_ATOMIC hashFunctionAtomic;
296  BYTE hashBuffer[ CRYPT_MAX_HASHSIZE ], *bufPtr = buffer;
297  static int counter = 0;
298  int hashSize, i;
299 
300  assert( isWritePtr( buffer, length ) );
301 
302  REQUIRES_V( length >= 1 && length < MAX_INTLENGTH );
303 
304  /* Fill the buffer with random-ish data. This gets a bit tricky because
305  we need to fool the entropy tests so we can't just fill it with a
306  fixed (or even semi-random) pattern but have to set up a somewhat
307  kludgy PRNG */
308  getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic,
309  &hashSize );
310  memset( hashBuffer, counter, hashSize );
311  counter++;
312  for( i = 0; i < length; i++ )
313  {
314  if( i % hashSize == 0 )
315  {
317  hashBuffer, hashSize );
318  }
319  bufPtr[ i ] = hashBuffer[ i % hashSize ];
320  }
321  }
322 
323 /****************************************************************************
324 * *
325 * Symmetric Capability Interface Routines *
326 * *
327 ****************************************************************************/
328 
329 /* Perform a self-test */
330 
331 static int aesSelfTest( void )
332  {
333  /* Perform the self-test */
334  /* ... */
335 
336  return( CRYPT_OK );
337  }
338 
339 /* Load a key */
340 
341 static int completeInitKeyAES( CONTEXT_INFO *contextInfoPtr,
342  PERSONALITY_INFO *personalityInfoPtr,
343  const int keyHandle, const int keySize )
344  {
345  int status;
346 
347  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
348  assert( isWritePtr( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ) );
349 
350  REQUIRES( keyHandle >= 0 && keyHandle < NO_PERSONALITIES );
351  REQUIRES( keySize >= MIN_KEYSIZE && keySize <= CRYPT_MAX_KEYSIZE );
352 
353  /* This personality is now active and in use, initialise the metadata
354  and set up the mapping from the crypto hardware personality to the
355  context using the helper function in hardware.c */
356  status = setConvInfo( contextInfoPtr->objectHandle, keySize );
357  if( cryptStatusOK( status ) )
358  {
359  status = setPersonalityMapping( contextInfoPtr, keyHandle,
360  personalityInfoPtr->storageID,
361  STORAGEID_SIZE );
362  }
363  if( cryptStatusError( status ) )
364  {
365  deletePersonality( keyHandle );
366  return( status );
367  }
368  personalityInfoPtr->inUse = TRUE;
369 
370  return( CRYPT_OK );
371  }
372 
373 static int aesInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
374  const int keyLength )
375  {
376  PERSONALITY_INFO *personalityInfoPtr;
377  int keyHandle, status;
378 
379  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
380  assert( isReadPtr( key, keyLength ) );
381 
382  REQUIRES( keyLength >= 1 && keyLength <= CRYPT_MAX_KEYSIZE );
383 
384  /* Find a free personality slot to store the key */
385  status = findFreePersonality( &keyHandle );
386  if( cryptStatusError( status ) )
387  return( status );
388  personalityInfoPtr = &personalityInfo[ keyHandle ];
389 
390  /* Load the key into the personality */
391  memcpy( personalityInfoPtr->keyInfo.convKeyInfo, key, keyLength );
392  return( completeInitKeyAES( contextInfoPtr, personalityInfoPtr,
393  keyHandle, keyLength ) );
394  }
395 
396 /* Generate a key */
397 
398 static int aesGenerateKey( CONTEXT_INFO *contextInfoPtr,
399  const int keySizeBits )
400  {
401  PERSONALITY_INFO *personalityInfoPtr;
402  const int keyLength = bitsToBytes( keySizeBits );
403  int keyHandle, status;
404 
405  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
406 
407  REQUIRES( keySizeBits >= bytesToBits( MIN_KEYSIZE ) && \
408  keySizeBits <= bytesToBits( CRYPT_MAX_KEYSIZE ) );
409 
410  /* Find a free personality slot to store the key */
411  status = findFreePersonality( &keyHandle );
412  if( cryptStatusError( status ) )
413  return( status );
414  personalityInfoPtr = &personalityInfo[ keyHandle ];
415 
416  /* Use the hardware RNG to generate the encryption key */
417  status = hwGetRandom( personalityInfoPtr->keyInfo.convKeyInfo, keyLength );
418  if( cryptStatusError( status ) )
419  {
420  deletePersonality( keyHandle );
421  return( status );
422  }
423  return( completeInitKeyAES( contextInfoPtr, personalityInfoPtr,
424  keyHandle, keyLength ) );
425  }
426 
427 /* Encrypt/decrypt data */
428 
429 static int aesEncryptECB( CONTEXT_INFO *contextInfoPtr, void *buffer,
430  int length )
431  {
432  PERSONALITY_INFO *personalityInfoPtr = \
433  &personalityInfo[ contextInfoPtr->deviceObject ];
434 
435  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
436  assert( isWritePtr( buffer, length ) );
437 
438  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
439 
440  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
441  CRYPT_MODE_ECB );
442  return( CRYPT_OK );
443  }
444 static int aesDecryptECB( CONTEXT_INFO *contextInfoPtr, void *buffer,
445  int length )
446  {
447  PERSONALITY_INFO *personalityInfoPtr = \
448  &personalityInfo[ contextInfoPtr->deviceObject ];
449 
450  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
451  assert( isWritePtr( buffer, length ) );
452 
453  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
454 
455  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
456  CRYPT_MODE_ECB );
457  return( CRYPT_OK );
458  }
459 
460 static int aesEncryptCBC( CONTEXT_INFO *contextInfoPtr, void *buffer,
461  int length )
462  {
463  PERSONALITY_INFO *personalityInfoPtr = \
464  &personalityInfo[ contextInfoPtr->deviceObject ];
465 
466  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
467  assert( isWritePtr( buffer, length ) );
468 
469  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
470 
471  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
472  CRYPT_MODE_CBC );
473  return( CRYPT_OK );
474  }
475 static int aesDecryptCBC( CONTEXT_INFO *contextInfoPtr, void *buffer,
476  int length )
477  {
478  PERSONALITY_INFO *personalityInfoPtr = \
479  &personalityInfo[ contextInfoPtr->deviceObject ];
480 
481  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
482  assert( isWritePtr( buffer, length ) );
483 
484  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
485 
486  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
487  CRYPT_MODE_CBC );
488  return( CRYPT_OK );
489  }
490 
491 static int aesEncryptCFB( CONTEXT_INFO *contextInfoPtr, void *buffer,
492  int length )
493  {
494  PERSONALITY_INFO *personalityInfoPtr = \
495  &personalityInfo[ contextInfoPtr->deviceObject ];
496 
497  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
498  assert( isWritePtr( buffer, length ) );
499 
500  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
501 
502  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
503  CRYPT_MODE_CFB );
504  return( CRYPT_OK );
505  }
506 static int aesDecryptCFB( CONTEXT_INFO *contextInfoPtr, void *buffer,
507  int length )
508  {
509  PERSONALITY_INFO *personalityInfoPtr = \
510  &personalityInfo[ contextInfoPtr->deviceObject ];
511 
512  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
513  assert( isWritePtr( buffer, length ) );
514 
515  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
516 
517  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
518  CRYPT_MODE_CFB );
519  return( CRYPT_OK );
520  }
521 
522 static int aesEncryptOFB( CONTEXT_INFO *contextInfoPtr, void *buffer,
523  int length )
524  {
525  PERSONALITY_INFO *personalityInfoPtr = \
526  &personalityInfo[ contextInfoPtr->deviceObject ];
527 
528  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
529  assert( isWritePtr( buffer, length ) );
530 
531  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
532 
533  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
534  CRYPT_MODE_OFB );
535  return( CRYPT_OK );
536  }
537 static int aesDecryptOFB( CONTEXT_INFO *contextInfoPtr, void *buffer,
538  int length )
539  {
540  PERSONALITY_INFO *personalityInfoPtr = \
541  &personalityInfo[ contextInfoPtr->deviceObject ];
542 
543  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
544  assert( isWritePtr( buffer, length ) );
545 
546  REQUIRES( length >= 1 && length <= MAX_INTLENGTH );
547 
548  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_AES,
549  CRYPT_MODE_OFB );
550  return( CRYPT_OK );
551  }
552 
553 /****************************************************************************
554 * *
555 * Asymmetric Capability Interface Routines *
556 * *
557 ****************************************************************************/
558 
559 /* Perform a self-test */
560 
561 static int rsaSelfTest( void )
562  {
563  /* Perform the self-test */
564  /* ... */
565 
566  return( CRYPT_OK );
567  }
568 
569 /* Load a key */
570 
571 static int completeInitKeyRSA( CONTEXT_INFO *contextInfoPtr,
572  PERSONALITY_INFO *personalityInfoPtr,
573  const int keyHandle )
574  {
575  int status;
576 
577  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
578  assert( isWritePtr( personalityInfoPtr, sizeof( PERSONALITY_INFO ) ) );
579 
580  REQUIRES( keyHandle >= 0 && keyHandle < NO_PERSONALITIES );
581 
582  /* This personality is now active and in use, set up the mapping from
583  the crypto hardware personality to the context using the helper
584  function in hardware.c */
585  status = setPersonalityMapping( contextInfoPtr, keyHandle,
586  personalityInfoPtr->storageID,
587  STORAGEID_SIZE );
588  if( cryptStatusError( status ) )
589  {
590  deletePersonality( keyHandle );
591  return( status );
592  }
593  personalityInfoPtr->inUse = TRUE;
594 
595  return( CRYPT_OK );
596  }
597 
598 static void rsaKeyToInternal( BIGNUM_STORAGE *bignumStorage,
599  const CRYPT_PKCINFO_RSA *rsaKeyInfo )
600  {
601  assert( isWritePtr( bignumStorage, \
602  sizeof( BIGNUM_STORAGE ) * NO_BIGNUMS ) );
603  assert( isReadPtr( rsaKeyInfo, sizeof( CRYPT_PKCINFO_RSA ) ) );
604 
605  /* Convert the RSA key components from the generic external
606  representation to the hardware-specific internal format */
607  bignumToInternal( bignumStorage[ 0 ].data, &bignumStorage[ 0 ].dataSize,
608  rsaKeyInfo->n, bitsToBytes( rsaKeyInfo->nLen ) );
609  bignumToInternal( bignumStorage[ 1 ].data, &bignumStorage[ 1 ].dataSize,
610  rsaKeyInfo->e, bitsToBytes( rsaKeyInfo->eLen ) );
611  if( rsaKeyInfo->isPublicKey )
612  return;
613  if( rsaKeyInfo->dLen > 0 )
614  {
615  bignumToInternal( bignumStorage[ 2 ].data,
616  &bignumStorage[ 2 ].dataSize,
617  rsaKeyInfo->d, bitsToBytes( rsaKeyInfo->dLen ) );
618  }
619  bignumToInternal( bignumStorage[ 3 ].data,
620  &bignumStorage[ 3 ].dataSize,
621  rsaKeyInfo->p, bitsToBytes( rsaKeyInfo->pLen ) );
622  bignumToInternal( bignumStorage[ 4 ].data,
623  &bignumStorage[ 4 ].dataSize,
624  rsaKeyInfo->q, bitsToBytes( rsaKeyInfo->qLen ) );
625  if( rsaKeyInfo->e1Len > 0 )
626  {
627  bignumToInternal( bignumStorage[ 5 ].data,
628  &bignumStorage[ 5 ].dataSize,
629  rsaKeyInfo->e1, bitsToBytes( rsaKeyInfo->e1Len ) );
630  bignumToInternal( bignumStorage[ 6 ].data,
631  &bignumStorage[ 6 ].dataSize,
632  rsaKeyInfo->e2, bitsToBytes( rsaKeyInfo->e2Len ) );
633  bignumToInternal( bignumStorage[ 7 ].data,
634  &bignumStorage[ 7 ].dataSize,
635  rsaKeyInfo->u, bitsToBytes( rsaKeyInfo->uLen ) );
636  }
637  }
638 
639 static int rsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
640  const int keyLength )
641  {
642  PERSONALITY_INFO *personalityInfoPtr;
643  int keyHandle, status;
644 
645  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
646  assert( isReadPtr( key, keyLength ) );
647 
648  REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_RSA ) );
649 
650  /* Find a free personality slot to store the key */
651  status = findFreePersonality( &keyHandle );
652  if( cryptStatusError( status ) )
653  return( status );
654  personalityInfoPtr = &personalityInfo[ keyHandle ];
655 
656  /* Load the key into the personality and copy the public-key portions
657  (needed for certificates and the like) to the context using the
658  helper function in hardware.c */
659  rsaKeyToInternal( personalityInfoPtr->keyInfo.pkcKeyInfo, key );
660  status = setPKCinfo( contextInfoPtr,
661  contextInfoPtr->capabilityInfo->cryptAlgo, key );
662  if( cryptStatusError( status ) )
663  {
664  deletePersonality( keyHandle );
665  return( status );
666  }
667  return( completeInitKeyRSA( contextInfoPtr, personalityInfoPtr,
668  keyHandle ) );
669  }
670 
671 /* Generate a key */
672 
673 static int rsaGenerateKey( CONTEXT_INFO *contextInfoPtr,
674  const int keySizeBits )
675  {
676  CRYPT_PKCINFO_RSA rsaKeyInfo;
677  PERSONALITY_INFO *personalityInfoPtr;
678  int keyHandle, status;
679 
680  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
681 
682  REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \
683  keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
684 
685  /* Find a free personality slot to store the key */
686  status = findFreePersonality( &keyHandle );
687  if( cryptStatusError( status ) )
688  return( status );
689  personalityInfoPtr = &personalityInfo[ keyHandle ];
690 
691  /* Since the hardware doesn't provide native keygen capabilities we
692  generate the key components using the helper function in hardware.c */
693  status = generatePKCcomponents( contextInfoPtr, &rsaKeyInfo,
694  keySizeBits );
695  if( cryptStatusError( status ) )
696  {
697  deletePersonality( keyHandle );
698  return( status );
699  }
700  rsaKeyToInternal( personalityInfoPtr->keyInfo.pkcKeyInfo, &rsaKeyInfo );
701  zeroise( &rsaKeyInfo, sizeof( CRYPT_PKCINFO_RSA ) );
702  return( completeInitKeyRSA( contextInfoPtr, personalityInfoPtr,
703  keyHandle ) );
704  }
705 
706 /* Encrypt/decrypt data */
707 
708 static int rsaEncrypt( CONTEXT_INFO *contextInfoPtr, void *buffer,
709  int length )
710  {
711  PERSONALITY_INFO *personalityInfoPtr = \
712  &personalityInfo[ contextInfoPtr->deviceObject ];
713 
714  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
715  assert( isWritePtr( buffer, length ) );
716 
717  REQUIRES( length >= MIN_PKCSIZE && length <= CRYPT_MAX_PKCSIZE );
718 
719  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_RSA,
720  CRYPT_MODE_NONE );
721  return( CRYPT_OK );
722  }
723 
724 static int rsaDecrypt( CONTEXT_INFO *contextInfoPtr, void *buffer,
725  int length )
726  {
727  PERSONALITY_INFO *personalityInfoPtr = \
728  &personalityInfo[ contextInfoPtr->deviceObject ];
729 
730  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
731  assert( isWritePtr( buffer, length ) );
732 
733  REQUIRES( length >= MIN_PKCSIZE && length <= CRYPT_MAX_PKCSIZE );
734 
735  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_RSA,
736  CRYPT_MODE_NONE );
737  return( CRYPT_OK );
738  }
739 
740 /* Sign/sig check data */
741 
742 static int rsaSign( CONTEXT_INFO *contextInfoPtr, void *buffer,
743  int length )
744  {
745  PERSONALITY_INFO *personalityInfoPtr = \
746  &personalityInfo[ contextInfoPtr->deviceObject ];
747 
748  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
749  assert( isWritePtr( buffer, length ) );
750 
751  REQUIRES( length >= MIN_PKCSIZE && length <= CRYPT_MAX_PKCSIZE );
752 
753  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_RSA,
754  CRYPT_MODE_NONE );
755  return( CRYPT_OK );
756  }
757 
758 static int rsaSigCheck( CONTEXT_INFO *contextInfoPtr, void *buffer,
759  int length )
760  {
761  PERSONALITY_INFO *personalityInfoPtr = \
762  &personalityInfo[ contextInfoPtr->deviceObject ];
763 
764  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
765  assert( isWritePtr( buffer, length ) );
766 
767  REQUIRES( length >= MIN_PKCSIZE && length <= CRYPT_MAX_PKCSIZE );
768 
769  dummyEncrypt( personalityInfoPtr, buffer, length, CRYPT_ALGO_RSA,
770  CRYPT_MODE_NONE );
771  return( CRYPT_OK );
772  }
773 
774 /****************************************************************************
775 * *
776 * Hash/MAC Capability Interface Routines *
777 * *
778 ****************************************************************************/
779 
780 /* Perform a self-test */
781 
782 static int shaSelfTest( void )
783  {
784  /* Perform the self-test */
785  /* ... */
786 
787  return( CRYPT_OK );
788  }
789 
790 /* Return context subtype-specific information */
791 
792 static int shaGetInfo( const CAPABILITY_INFO_TYPE type,
793  CONTEXT_INFO *contextInfoPtr,
794  void *data, const int length )
795  {
796  if( type == CAPABILITY_INFO_STATESIZE )
797  {
798  int *valuePtr = ( int * ) data;
799 
800  /* Return the amount of hash-state storage needed by the SHA-1
801  routines. This will be allocated by cryptlib and made available
802  as contextInfoPtr->ctxHash->hashInfo */
803  /* ... */
804  *valuePtr = 0; /* Dummy version doesn't need storage */
805 
806  return( CRYPT_OK );
807  }
808 
809  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
810  }
811 
812 /* Hash data */
813 
814 static int shaHash( CONTEXT_INFO *contextInfoPtr, void *buffer,
815  int length )
816  {
817  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
818  assert( length == 0 || isWritePtr( buffer, length ) );
819 
820  /* If the hash state was reset to allow another round of hashing,
821  reinitialise things */
822  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
823  {
824  /* Initialise hash state in contextInfoPtr->ctxHash->hashInfo */
825  /* ... */
826  }
827 
828  if( length > 0 )
829  {
830  /* Perform the hashing using the hash state information in
831  contextInfoPtr->ctxHash->hashInfo */
832  /* ... */
833  }
834  else
835  {
836  /* Wrap up the hashing from the state information in
837  contextInfoPtr->ctxHash->hashInfo, with the result placed in
838  contextInfoPtr->ctxHash->hash */
839  /* ... */
840  memset( contextInfoPtr->ctxHash->hash, 'X', 20 ); /* Dummy hash val.*/
841  }
842 
843  return( CRYPT_OK );
844  }
845 
846 /****************************************************************************
847 * *
848 * Hardware External Interface *
849 * *
850 ****************************************************************************/
851 
852 /* The capability information for this device */
853 
854 static const CAPABILITY_INFO capabilities[] = {
855  /* The RSA capabilities */
856  { CRYPT_ALGO_RSA, bitsToBytes( 0 ), "RSA", 3,
858  rsaSelfTest, getDefaultInfo, cleanupHardwareContext, NULL, rsaInitKey, rsaGenerateKey,
859  rsaEncrypt, rsaDecrypt, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
860  rsaSign, rsaSigCheck },
861 
862  /* The AES capabilities */
863  { CRYPT_ALGO_AES, bitsToBytes( 128 ), "AES", 3,
864  bitsToBytes( 128 ), bitsToBytes( 128 ), bitsToBytes( 256 ),
865  aesSelfTest, getDefaultInfo, cleanupHardwareContext, initGenericParams, aesInitKey, aesGenerateKey,
866  aesEncryptECB, aesDecryptECB, aesEncryptCBC, aesDecryptCBC,
867  aesEncryptCFB, aesDecryptCFB, aesEncryptOFB, aesDecryptOFB,
868  NULL, NULL /* For GCM */ },
869 
870  /* The SHA-1 capabilities */
871  { CRYPT_ALGO_SHA1, bitsToBytes( 160 ), "SHA-1", 5,
872  bitsToBytes( 0 ), bitsToBytes( 0 ), bitsToBytes( 0 ),
873  shaSelfTest, shaGetInfo, NULL, NULL, NULL, NULL, shaHash, shaHash },
874 
875  /* The end-of-list marker. This value isn't linked into the
876  capabilities list when we call initCapabilities() */
878  };
879 
880 /* Return the hardware capabilities list */
881 
882 int hwGetCapabilities( const CAPABILITY_INFO **capabilityInfo,
883  int *noCapabilities )
884  {
885  assert( isReadPtr( capabilityInfo, sizeof( CAPABILITY_INFO * ) ) );
886  assert( isWritePtr( noCapabilities, sizeof( int ) ) );
887 
888  *capabilityInfo = capabilities;
889  *noCapabilities = FAILSAFE_ARRAYSIZE( capabilities, CAPABILITY_INFO );
890 
891  return( CRYPT_OK );
892  }
893 
894 /* Get random data from the hardware */
895 
896 int hwGetRandom( void *buffer, const int length )
897  {
898  assert( isWritePtr( buffer, length ) );
899 
900  REQUIRES( length >= 1 && length < MAX_INTLENGTH );
901 
902  /* Fill the buffer with random-ish data */
903  dummyGenRandom( buffer, length );
904 
905  return( CRYPT_OK );
906  }
907 
908 /* Look up an item held in the hardware */
909 
910 int hwLookupItem( const void *keyID, const int keyIDlength, int *keyHandle )
911  {
912  assert( isReadPtr( keyID, keyIDlength ) );
913  assert( isWritePtr( keyHandle, sizeof( int ) ) );
914 
915  REQUIRES( keyIDlength >= 4 && keyIDlength <= KEYID_SIZE );
916 
917  /* Clear return value */
918  *keyHandle = CRYPT_ERROR;
919 
920  return( lookupPersonality( keyID, keyIDlength, keyHandle ) );
921  }
922 
923 /* Delete an item held in the hardware */
924 
925 int hwDeleteItem( const int keyHandle )
926  {
927  REQUIRES( keyHandle >= 0 && keyHandle < NO_PERSONALITIES );
928 
929  deletePersonality( keyHandle );
930  return( CRYPT_OK );
931  }
932 
933 /* Initialise/zeroise the hardware, which for this device just consists of
934  clearing the hardware personalities */
935 
936 int hwInitialise( void )
937  {
938  int i;
939 
940  for( i = 0; i < NO_PERSONALITIES; i++ )
941  deletePersonality( i );
942  return( CRYPT_OK );
943  }
944 #endif /* USE_HARDWARE */