cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
cryptctx.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Encryption Context Routines *
4 * Copyright Peter Gutmann 1992-2008 *
5 * *
6 ****************************************************************************/
7 
8 /* "Modern cryptography is nothing more than a mathematical framework for
9  debating the implications of various paranoid delusions"
10  - Don Alvarez */
11 
12 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
13 #include "crypt.h"
14 #ifdef INC_ALL
15  #include "context.h"
16  #include "asn1.h"
17 #else
18  #include "context/context.h"
19  #include "enc_dec/asn1.h"
20 #endif /* Compiler-specific includes */
21 
22 /* The number of bytes of data that we check to make sure that the
23  encryption operation succeeded. See the comment in encryptData() before
24  changing this */
25 
26 #define ENCRYPT_CHECKSIZE 16
27 
28 /* When we're allocating subtype-specific data to be stored alongside the
29  main CONTEXT_INFO, we align it to a certain block size both for efficient
30  access and to ensure that the pointer to it from the main CONTEXT_INFO
31  doesn't result in a segfault. The following works for all current
32  processor types */
33 
34 #define STORAGE_ALIGN_SIZE 8
35 #define CONTEXT_INFO_ALIGN_SIZE \
36  roundUp( sizeof( CONTEXT_INFO ), STORAGE_ALIGN_SIZE )
37 #define ALIGN_CONTEXT_PTR( basePtr, type ) \
38  ( type * ) ( ( BYTE * ) ( basePtr ) + CONTEXT_INFO_ALIGN_SIZE )
39 
40 /****************************************************************************
41 * *
42 * Utility Functions *
43 * *
44 ****************************************************************************/
45 
46 /* Initialise pointers to context-specific storage areas */
47 
49 static int initContextConvStorage( INOUT CONTEXT_INFO *contextInfoPtr,
50  IN_LENGTH_SHORT const int storageAlignSize )
51  {
52  BOOLEAN isClonedContext = ( contextInfoPtr->ctxConv != NULL ) ? \
53  TRUE : FALSE;
54  int diff = DUMMY_INIT, newDiff, stateStorageSize, status;
55 
56  /* If this is a cloned context then the cloning operation may have moved
57  the relative position of the key data around in memory, since the
58  granularity of its allocation differs from that of the memory
59  allocator. In order to determine whether we have to correct things,
60  we remember the old offset of the keying data from the context
61  storage and compare it to the new offset */
62  if( isClonedContext )
63  diff = ptr_diff( contextInfoPtr->ctxConv->key,
64  contextInfoPtr->ctxConv );
65 
66  /* Calculate the offsets of the context storage and keying data */
67  contextInfoPtr->ctxConv = ALIGN_CONTEXT_PTR( contextInfoPtr, CONV_INFO );
68  contextInfoPtr->ctxConv->key = \
69  ptr_align( ( BYTE * ) contextInfoPtr->ctxConv + sizeof( CONV_INFO ),
70  storageAlignSize );
71 
72  /* If this is a newly-initialised context then we're done */
73  if( !isClonedContext )
74  return( CRYPT_OK );
75 
76  /* Check whether the keying data offset has changed from the original to
77  the cloned context */
78  newDiff = ptr_diff( contextInfoPtr->ctxConv->key,
79  contextInfoPtr->ctxConv );
80  if( newDiff == diff )
81  return( CRYPT_OK );
82 
83  /* The start of the actual keying data within the keying data memory
84  block has changed due to the cloned memory block starting at a
85  different offset, we need to move the keying data do its new
86  location */
87  status = contextInfoPtr->capabilityInfo->getInfoFunction( CAPABILITY_INFO_STATESIZE,
88  NULL, &stateStorageSize, 0 );
89  if( cryptStatusError( status ) )
90  return( status );
91  memmove( ( BYTE * ) contextInfoPtr->ctxConv + newDiff,
92  ( BYTE * ) contextInfoPtr->ctxConv + diff, stateStorageSize );
93 
94  return( CRYPT_OK );
95  }
96 
98 static int initContextStorage( INOUT CONTEXT_INFO *contextInfoPtr,
99  IN_LENGTH_SHORT const int storageAlignSize )
100  {
101  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
102 
103  REQUIRES( ( contextInfoPtr->type == CONTEXT_PKC && \
104  storageAlignSize == 0 ) || \
105  ( contextInfoPtr->type != CONTEXT_PKC && \
106  storageAlignSize >= 4 && storageAlignSize <= 128 ) );
107 
108  switch( contextInfoPtr->type )
109  {
110  case CONTEXT_CONV:
111  /* Handling storage for conventional contexts is sufficiently
112  complicated in the presence of context cloning that we do it
113  in a separate function */
114  return( initContextConvStorage( contextInfoPtr, storageAlignSize ) );
115 
116  case CONTEXT_HASH:
117  contextInfoPtr->ctxHash = \
118  ALIGN_CONTEXT_PTR( contextInfoPtr, HASH_INFO );
119  contextInfoPtr->ctxHash->hashInfo = \
120  ptr_align( ( BYTE * ) contextInfoPtr->ctxConv + sizeof( HASH_INFO ),
121  storageAlignSize );
122  break;
123 
124  case CONTEXT_MAC:
125  contextInfoPtr->ctxMAC = \
126  ALIGN_CONTEXT_PTR( contextInfoPtr, MAC_INFO );
127  contextInfoPtr->ctxMAC->macInfo = \
128  ptr_align( ( BYTE * ) contextInfoPtr->ctxConv + sizeof( MAC_INFO ),
129  storageAlignSize );
130  break;
131 
132  case CONTEXT_PKC:
133  contextInfoPtr->ctxPKC = \
134  ALIGN_CONTEXT_PTR( contextInfoPtr, PKC_INFO );
135  break;
136 
137  case CONTEXT_GENERIC:
138  contextInfoPtr->ctxGeneric = \
139  ALIGN_CONTEXT_PTR( contextInfoPtr, GENERIC_INFO );
140  break;
141 
142  default:
143  retIntError();
144  }
145 
146  return( CRYPT_OK );
147  }
148 
149 /* Perform any context-specific checks that a context meets the given
150  requirements (general checks have already been performed by the kernel).
151  Although these checks are automatically performed by the kernel when we
152  try and use the context, they're duplicated here to allow for better
153  error reporting by catching problems when the context is first passed to
154  a cryptlib function rather than much later and at a lower level when the
155  kernel disallows the action */
156 
158 static int checkContext( INOUT CONTEXT_INFO *contextInfoPtr,
160  const MESSAGE_CHECK_TYPE checkType )
161  {
162  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
163 
164  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
165 
166  REQUIRES( checkType > MESSAGE_CHECK_NONE && \
167  checkType < MESSAGE_CHECK_LAST );
168 
169  /* If it's a check that an object's ready for key generation we can
170  perform the check without requiring any algorithm-specific
171  gyrations */
172  if( checkType == MESSAGE_CHECK_KEYGEN_READY )
173  {
174  /* Make sure that there isn't already a key loaded */
175  if( !needsKey( contextInfoPtr ) )
176  return( CRYPT_ERROR_INITED );
177 
178  /* Make sure that we can actually generate a key. This should be
179  enforced by the kernel anyway but we use a backup check here */
180  if( capabilityInfoPtr->generateKeyFunction == NULL )
181  return( CRYPT_ERROR_NOTAVAIL );
182 
183  return( CRYPT_OK );
184  }
185 
186  /* If it's a check for the (potential) ability to perform conventional
187  encryption or MACing at some point in the future, without necessarily
188  currently having a key loaded for the task, we're done */
189  if( checkType == MESSAGE_CHECK_CRYPT_READY || \
190  checkType == MESSAGE_CHECK_MAC_READY )
191  return( CRYPT_OK );
192 
193  /* Perform general checks */
194  if( contextInfoPtr->type != CONTEXT_HASH && needsKey( contextInfoPtr ) )
195  return( CRYPT_ERROR_NOTINITED );
196 
197  /* If it's a hash, MAC, conventional encryption, or basic PKC check,
198  we're done */
199  if( checkType == MESSAGE_CHECK_CRYPT || \
200  checkType == MESSAGE_CHECK_HASH || \
201  checkType == MESSAGE_CHECK_MAC || \
202  checkType == MESSAGE_CHECK_PKC )
203  return( CRYPT_OK );
204 
205  /* Check for key-agreement algorithms */
206  if( isKeyxAlgo( capabilityInfoPtr->cryptAlgo ) )
207  {
208  /* DH can never be used for encryption or signatures (if it is then
209  we call it Elgamal) and KEA is explicitly for key agreement only.
210  Note that the status of DH is a bit ambiguous in that every DH key
211  is both a public and private key, in order to avoid confusion in
212  situations where we're checking for real private keys we always
213  denote a DH context as key-agreement only without taking a side
214  about whether it's a public or private key */
215  return( ( checkType == MESSAGE_CHECK_PKC_KA_EXPORT || \
216  checkType == MESSAGE_CHECK_PKC_KA_IMPORT ) ? \
218  }
219  if( checkType == MESSAGE_CHECK_PKC_KA_EXPORT || \
220  checkType == MESSAGE_CHECK_PKC_KA_IMPORT )
221  {
222  /* A key agreement check requires a key agreement algorithm */
223  return( CRYPT_ARGERROR_OBJECT );
224  }
225 
226  /* We're down to various public-key checks */
227  REQUIRES( checkType == MESSAGE_CHECK_PKC_PRIVATE || \
228  checkType == MESSAGE_CHECK_PKC_ENCRYPT || \
229  checkType == MESSAGE_CHECK_PKC_DECRYPT || \
230  checkType == MESSAGE_CHECK_PKC_SIGCHECK || \
231  checkType == MESSAGE_CHECK_PKC_SIGN || \
232  checkType == MESSAGE_CHECK_CERT || \
233  checkType == MESSAGE_CHECK_CA );
234 
235  /* Check that it's a private key if this is required */
236  if( ( checkType == MESSAGE_CHECK_PKC_PRIVATE || \
237  checkType == MESSAGE_CHECK_PKC_DECRYPT || \
238  checkType == MESSAGE_CHECK_PKC_SIGN ) && \
239  ( contextInfoPtr->flags & CONTEXT_FLAG_ISPUBLICKEY ) )
240  return( CRYPT_ARGERROR_OBJECT );
241 
242  return( CRYPT_OK );
243  }
244 
245 /****************************************************************************
246 * *
247 * Data Encryption Functions *
248 * *
249 ****************************************************************************/
250 
251 /* Encrypt a block of data */
252 
254 static int encryptDataConv( INOUT CONTEXT_INFO *contextInfoPtr,
255  IN_BUFFER( dataLength ) void *data,
256  IN_LENGTH_Z const int dataLength )
257  {
258  BYTE savedData[ ENCRYPT_CHECKSIZE + 8 ];
259  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
260  const int savedDataLength = min( dataLength, ENCRYPT_CHECKSIZE );
261  int status;
262 
263  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
264  assert( isWritePtr( data, dataLength ) );
265 
266  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
267  REQUIRES( !needsKey( contextInfoPtr ) );
268  REQUIRES( dataLength >= 0 && dataLength < MAX_INTLENGTH );
269  REQUIRES( isStreamCipher( capabilityInfoPtr->cryptAlgo ) || \
270  !needsIV( contextInfoPtr->ctxConv->mode ) ||
271  ( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) );
272 
273  memcpy( savedData, data, savedDataLength );
274  status = contextInfoPtr->encryptFunction( contextInfoPtr, data,
275  dataLength );
276  if( cryptStatusError( status ) || savedDataLength <= 8 )
277  {
278  zeroise( savedData, savedDataLength );
279  return( status );
280  }
281 
282  /* Check for a catastrophic failure of the encryption. A check of
283  a single block unfortunately isn't completely foolproof for 64-bit
284  blocksize ciphers in CBC mode because of the way the IV is applied to
285  the input. For the CBC encryption operation:
286 
287  out = enc( in ^ IV )
288 
289  if out == IV the operation turns into a no-op. Consider the simple
290  case where IV == in, so IV ^ in == 0. Then out = enc( 0 ) == IV,
291  with the input appearing again at the output. In fact for a 64-bit
292  block cipher this can occur during normal operation once every 2^32
293  blocks. Although the chances of this happening are fairly low (the
294  collision would have to occur on the first encrypted block in a
295  message since that's the one that we check), we check the first two
296  blocks if we're using a 64-bit block cipher in CBC mode in order to
297  reduce false positives */
298  if( !memcmp( savedData, data, savedDataLength ) )
299  {
300  zeroise( data, dataLength );
301  status = CRYPT_ERROR_FAILED;
302  }
303  zeroise( savedData, savedDataLength );
304  return( status );
305  }
306 
307 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
308 static int encryptDataPKC( INOUT CONTEXT_INFO *contextInfoPtr,
309  IN_BUFFER( dataLength ) void *data,
310  IN_LENGTH_PKC const int dataLength )
311  {
312  BYTE savedData[ ENCRYPT_CHECKSIZE + 8 ];
313  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
314  const BOOLEAN isDLP = isDlpAlgo( capabilityInfoPtr->cryptAlgo );
315  const BOOLEAN isECC = isEccAlgo( capabilityInfoPtr->cryptAlgo );
316  int status;
317 
318  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
319  assert( isWritePtr( data, dataLength ) );
320 
321  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
322  REQUIRES( !needsKey( contextInfoPtr ) );
323 
324  /* Key agreement algorithms are treated as a special case since they
325  don't actually encrypt the data */
326  if( isKeyxAlgo( capabilityInfoPtr->cryptAlgo ) )
327  {
328  REQUIRES( dataLength == sizeof( KEYAGREE_PARAMS ) );
329 
330  status = contextInfoPtr->encryptFunction( contextInfoPtr, data,
331  dataLength );
332  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
333  clearTempBignums( contextInfoPtr->ctxPKC );
334  return( status );
335  }
336 
337  REQUIRES( ( ( isDLP || isECC ) && \
338  dataLength == sizeof( DLP_PARAMS ) ) || \
339  ( ( !isDLP && !isECC ) && \
340  dataLength >= MIN_PKCSIZE && \
341  dataLength <= CRYPT_MAX_PKCSIZE ) );
342 
343  memcpy( savedData, ( isDLP || isECC ) ? \
344  ( ( DLP_PARAMS * ) data )->inParam1 : data,
346  status = contextInfoPtr->encryptFunction( contextInfoPtr, data,
347  dataLength );
348  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
349  clearTempBignums( contextInfoPtr->ctxPKC );
350  if( cryptStatusError( status ) )
351  {
352  zeroise( savedData, ENCRYPT_CHECKSIZE );
353  return( status );
354  }
355 
356  /* Check for a catastrophic failure of the encryption */
357  if( isDLP || isECC )
358  {
359  DLP_PARAMS *dlpParams = ( DLP_PARAMS * ) data;
360 
361  if( !memcmp( savedData, dlpParams->outParam,
363  {
364  zeroise( dlpParams->outParam, dlpParams->outLen );
365  status = CRYPT_ERROR_FAILED;
366  }
367  }
368  else
369  {
370  if( !memcmp( savedData, data, ENCRYPT_CHECKSIZE ) )
371  {
372  zeroise( data, dataLength );
373  status = CRYPT_ERROR_FAILED;
374  }
375  }
376  zeroise( savedData, ENCRYPT_CHECKSIZE );
377 
378  return( status );
379  }
380 
381 /****************************************************************************
382 * *
383 * Context Message Handler *
384 * *
385 ****************************************************************************/
386 
387 /* Handle a message sent to an encryption context */
388 
390 static int contextMessageFunction( INOUT TYPECAST( CONTEXT_INFO * ) \
391  void *objectInfoPtr,
393  void *messageDataPtr,
394  IN_INT_Z const int messageValue )
395  {
396  CONTEXT_INFO *contextInfoPtr = ( CONTEXT_INFO * ) objectInfoPtr;
397  const CAPABILITY_INFO *capabilityInfo = contextInfoPtr->capabilityInfo;
398  int status;
399 
400  assert( isWritePtr( objectInfoPtr, sizeof( CONTEXT_INFO ) ) );
401 
402  REQUIRES( message > MESSAGE_NONE && message < MESSAGE_LAST );
403  REQUIRES( messageValue >= 0 && messageValue < MAX_INTLENGTH );
404 
405  /* Process destroy object messages */
406  if( message == MESSAGE_DESTROY )
407  {
408  const CONTEXT_TYPE contextType = contextInfoPtr->type;
409 
410  REQUIRES( messageDataPtr == NULL && messageValue == 0 );
411 
412  /* Perform any algorithm-specific shutdown */
413  if( capabilityInfo->endFunction != NULL )
414  capabilityInfo->endFunction( contextInfoPtr );
415 
416  /* Perform context-type-specific cleanup */
417  if( contextType == CONTEXT_PKC )
418  freeContextBignums( contextInfoPtr->ctxPKC,
419  contextInfoPtr->flags );
420 
421  return( CRYPT_OK );
422  }
423 
424  /* Process attribute get/set/delete messages */
425  if( isAttributeMessage( message ) )
426  {
427  REQUIRES( message == MESSAGE_GETATTRIBUTE || \
428  message == MESSAGE_GETATTRIBUTE_S || \
429  message == MESSAGE_SETATTRIBUTE || \
430  message == MESSAGE_SETATTRIBUTE_S || \
431  message == MESSAGE_DELETEATTRIBUTE );
432  REQUIRES( isAttribute( messageValue ) || \
433  isInternalAttribute( messageValue ) );
434 
435  if( message == MESSAGE_GETATTRIBUTE )
436  return( getContextAttribute( contextInfoPtr,
437  ( int * ) messageDataPtr,
438  messageValue ) );
439  if( message == MESSAGE_GETATTRIBUTE_S )
440  return( getContextAttributeS( contextInfoPtr,
441  ( MESSAGE_DATA * ) messageDataPtr,
442  messageValue ) );
443  if( message == MESSAGE_SETATTRIBUTE )
444  {
445  /* CRYPT_IATTRIBUTE_INITIALISED is purely a notification message
446  with no parameters so we don't pass it down to the attribute-
447  handling code */
448  if( messageValue == CRYPT_IATTRIBUTE_INITIALISED )
449  return( CRYPT_OK );
450 
451  return( setContextAttribute( contextInfoPtr,
452  *( ( int * ) messageDataPtr ),
453  messageValue ) );
454  }
455  if( message == MESSAGE_SETATTRIBUTE_S )
456  {
457  const MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;
458 
459  return( setContextAttributeS( contextInfoPtr, msgData->data,
460  msgData->length, messageValue ) );
461  }
462  if( message == MESSAGE_DELETEATTRIBUTE )
463  return( deleteContextAttribute( contextInfoPtr, messageValue ) );
464 
465  retIntError();
466  }
467 
468  /* Process action messages */
469  if( isActionMessage( message ) )
470  {
471  assert( ( message == MESSAGE_CTX_HASH && \
472  ( messageValue == 0 || \
473  isReadPtr( messageDataPtr, messageValue ) ) ) || \
474  isWritePtr( messageDataPtr, messageValue ) );
475 
476  switch( message )
477  {
478  case MESSAGE_CTX_ENCRYPT:
479  if( contextInfoPtr->type == CONTEXT_PKC )
480  status = encryptDataPKC( contextInfoPtr, messageDataPtr,
481  messageValue );
482  else
483  status = encryptDataConv( contextInfoPtr, messageDataPtr,
484  messageValue );
485  assert( cryptStatusOK( status ) ); /* Debug warning only */
486  break;
487 
488  case MESSAGE_CTX_DECRYPT:
489  REQUIRES( !needsKey( contextInfoPtr ) );
490  REQUIRES( contextInfoPtr->type == CONTEXT_PKC || \
491  ( isStreamCipher( capabilityInfo->cryptAlgo ) || \
492  !needsIV( contextInfoPtr->ctxConv->mode ) ||
493  ( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) ) );
494 
495  status = contextInfoPtr->decryptFunction( contextInfoPtr,
496  messageDataPtr, messageValue );
497  if( contextInfoPtr->type == CONTEXT_PKC && \
498  !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
499  clearTempBignums( contextInfoPtr->ctxPKC );
500  assert( cryptStatusOK( status ) ); /* Debug warning only */
501  break;
502 
503  case MESSAGE_CTX_SIGN:
504  status = capabilityInfo->signFunction( contextInfoPtr,
505  messageDataPtr, messageValue );
506  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
507  clearTempBignums( contextInfoPtr->ctxPKC );
508  assert( cryptStatusOK( status ) ); /* Debug warning only */
509  break;
510 
512  status = capabilityInfo->sigCheckFunction( contextInfoPtr,
513  messageDataPtr, messageValue );
514  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
515  clearTempBignums( contextInfoPtr->ctxPKC );
516  break;
517 
518  case MESSAGE_CTX_HASH:
519  REQUIRES( contextInfoPtr->type == CONTEXT_HASH || \
520  contextInfoPtr->type == CONTEXT_MAC );
521 
522  /* If we've already completed the hashing/MACing we can't
523  continue */
524  if( contextInfoPtr->flags & CONTEXT_FLAG_HASH_DONE )
525  return( CRYPT_ERROR_COMPLETE );
526 
527  status = capabilityInfo->encryptFunction( contextInfoPtr,
528  messageDataPtr, messageValue );
529  if( messageValue > 0 )
530  {
531  /* Usually the MAC initialisation happens when we load
532  the key, but if we've deleted the MAC value to process
533  another piece of data it'll happen on-demand so we
534  have to set the flag here */
535  contextInfoPtr->flags |= CONTEXT_FLAG_HASH_INITED;
536  }
537  else
538  {
539  /* Usually a hash of zero bytes is used to wrap up an
540  ongoing hash operation, however it can also be the
541  only operation if a zero-byte string is being hashed.
542  To handle this we have to set the inited flag as well
543  as the done flag */
544  contextInfoPtr->flags |= CONTEXT_FLAG_HASH_DONE | \
545  CONTEXT_FLAG_HASH_INITED;
546  }
547  assert( cryptStatusOK( status ) ); /* Debug warning only */
548  break;
549 
550  default:
551  retIntError();
552  }
553  return( status );
554  }
555 
556  /* Process messages that compare object properties or clone the object */
557  if( message == MESSAGE_COMPARE )
558  {
559  const MESSAGE_DATA *msgData = ( MESSAGE_DATA * ) messageDataPtr;
560 
561  assert( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );
562 
563  REQUIRES( messageValue == MESSAGE_COMPARE_HASH || \
564  messageValue == MESSAGE_COMPARE_ICV || \
565  messageValue == MESSAGE_COMPARE_KEYID || \
566  messageValue == MESSAGE_COMPARE_KEYID_PGP || \
567  messageValue == MESSAGE_COMPARE_KEYID_OPENPGP );
568 
569  switch( messageValue )
570  {
572  REQUIRES( contextInfoPtr->type == CONTEXT_HASH || \
573  contextInfoPtr->type == CONTEXT_MAC );
574 
575  /* If it's a hash or MAC context, compare the hash value */
576  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_DONE ) )
577  return( CRYPT_ERROR_INCOMPLETE );
578  if( contextInfoPtr->type == CONTEXT_HASH && \
579  msgData->length == capabilityInfo->blockSize && \
580  compareDataConstTime( msgData->data,
581  contextInfoPtr->ctxHash->hash,
582  msgData->length ) )
583  return( CRYPT_OK );
584  if( contextInfoPtr->type == CONTEXT_MAC && \
585  msgData->length == capabilityInfo->blockSize && \
586  compareDataConstTime( msgData->data,
587  contextInfoPtr->ctxMAC->mac,
588  msgData->length ) )
589  return( CRYPT_OK );
590  break;
591 
592  case MESSAGE_COMPARE_ICV:
593  {
594  BYTE icv[ CRYPT_MAX_HASHSIZE + 8 ];
595 
596  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
597 
598  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_GCM )
599  return( CRYPT_ERROR_NOTAVAIL );
600  status = capabilityInfo->getInfoFunction( CAPABILITY_INFO_ICV,
601  contextInfoPtr, icv, msgData->length );
602  if( cryptStatusError( status ) )
603  return( status );
604  if( compareDataConstTime( msgData->data, icv,
605  msgData->length ) )
606  return( CRYPT_OK );
607  break;
608  }
609 
611  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
612 
613  /* If it's a PKC context, compare the key ID */
614  if( msgData->length == KEYID_SIZE && \
615  !memcmp( msgData->data, contextInfoPtr->ctxPKC->keyID,
616  KEYID_SIZE ) )
617  return( CRYPT_OK );
618  break;
619 
621  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
622 
623  /* If it's a PKC context, compare the PGP key ID */
624  if( ( contextInfoPtr->flags & CONTEXT_FLAG_PGPKEYID_SET ) && \
625  msgData->length == PGP_KEYID_SIZE && \
626  !memcmp( msgData->data, contextInfoPtr->ctxPKC->pgp2KeyID,
627  PGP_KEYID_SIZE ) )
628  return( CRYPT_OK );
629  break;
630 
632  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
633 
634  /* If it's a PKC context, compare the OpenPGP key ID */
635  if( ( contextInfoPtr->flags & CONTEXT_FLAG_OPENPGPKEYID_SET ) && \
636  msgData->length == PGP_KEYID_SIZE && \
637  !memcmp( msgData->data, contextInfoPtr->ctxPKC->openPgpKeyID,
638  PGP_KEYID_SIZE ) )
639  return( CRYPT_OK );
640  break;
641 
642  default:
643  retIntError();
644  }
645 
646  /* The comparison failed */
647  return( CRYPT_ERROR );
648  }
649 
650  /* Process messages that check a context */
651  if( message == MESSAGE_CHECK )
652  return( checkContext( contextInfoPtr, messageValue ) );
653 
654  /* Process internal notification messages */
655  if( message == MESSAGE_CHANGENOTIFY )
656  {
657  switch( messageValue )
658  {
660  /* State-change reflected down from the controlling certificate
661  object, this doesn't affect us */
662  break;
663 
665  {
666  const CRYPT_HANDLE iCryptHandle = *( ( int * ) messageDataPtr );
667  int storageAlignSize;
668 
669  REQUIRES( contextInfoPtr->type == CONTEXT_CONV || \
670  contextInfoPtr->type == CONTEXT_HASH || \
671  contextInfoPtr->type == CONTEXT_MAC );
672  REQUIRES( contextInfoPtr->objectHandle != iCryptHandle );
673 
674  /* We've been cloned, update the object handle and internal
675  state pointers */
676  contextInfoPtr->objectHandle = iCryptHandle;
677  status = capabilityInfo->getInfoFunction( CAPABILITY_INFO_STATEALIGNTYPE,
678  NULL, &storageAlignSize, 0 );
679  if( cryptStatusError( status ) )
680  return( status );
681  status = initContextStorage( contextInfoPtr, storageAlignSize );
682  if( cryptStatusError( status ) )
683  return( status );
684  break;
685  }
686 
688  /* The second stage of a cloning, update the owner handle */
689  contextInfoPtr->ownerHandle = *( ( int * ) messageDataPtr );
690  break;
691 
692  default:
693  retIntError();
694  }
695 
696  return( CRYPT_OK );
697  }
698 
699  /* Process object-specific messages */
700  if( message == MESSAGE_CTX_GENKEY )
701  {
702  static const int actionFlags = \
703  MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
704  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL ) | \
705  MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL ) | \
706  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
707  MK_ACTION_PERM( MESSAGE_CTX_HASH, ACTION_PERM_ALL );
708 
709  REQUIRES( contextInfoPtr->type == CONTEXT_CONV || \
710  contextInfoPtr->type == CONTEXT_MAC || \
711  contextInfoPtr->type == CONTEXT_PKC || \
712  contextInfoPtr->type == CONTEXT_GENERIC );
713  REQUIRES( needsKey( contextInfoPtr ) );
714 
715  /* If it's a private key context or a persistent context we need to
716  have a key label set before we can continue */
717  if( ( ( contextInfoPtr->type == CONTEXT_PKC ) || \
718  ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ) && \
719  contextInfoPtr->labelSize <= 0 )
720  return( CRYPT_ERROR_NOTINITED );
721 
722  /* Generate a new key into the context */
723  status = contextInfoPtr->generateKeyFunction( contextInfoPtr );
724  if( cryptStatusError( status ) )
725  return( status );
726 
727  /* There's now a key loaded, remember this and disable further key
728  generation. The kernel won't allow a keygen anyway once the
729  object is in the high state but taking this additional step can't
730  hurt */
731  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
732  return( krnlSendMessage( contextInfoPtr->objectHandle,
734  ( MESSAGE_CAST ) &actionFlags,
735  CRYPT_IATTRIBUTE_ACTIONPERMS ) );
736  }
737  if( message == MESSAGE_CTX_GENIV )
738  {
740  BYTE iv[ CRYPT_MAX_IVSIZE + 8 ];
741  const int ivSize = capabilityInfo->blockSize;
742 
743  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
744 
745  /* If it's not a conventional encryption context or it's a mode that
746  doesn't use an IV then the generate IV operation is meaningless */
747  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
748  isStreamCipher( capabilityInfo->cryptAlgo ) )
749  return( CRYPT_ERROR_NOTAVAIL );
750 
751  /* Generate a new IV and load it */
752  setMessageData( &msgData, iv, ivSize );
754  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
755  if( cryptStatusOK( status ) )
756  status = capabilityInfo->initParamsFunction( contextInfoPtr,
757  KEYPARAM_IV, iv, ivSize );
758  return( status );
759  }
760 
761  retIntError();
762  }
763 
764 /* Create an encryption context based on an encryption capability template.
765  This is a common function called by devices to create a context once
766  they've got the appropriate capability template */
767 
769 int createContextFromCapability( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext,
771  const CAPABILITY_INFO *capabilityInfoPtr,
772  IN_FLAGS_Z( CREATEOBJECT ) const int objectFlags )
773  {
774  const CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;
775  const CONTEXT_TYPE contextType = \
776  ( isConvAlgo( cryptAlgo ) ) ? CONTEXT_CONV : \
777  ( isPkcAlgo( cryptAlgo ) ) ? CONTEXT_PKC : \
778  ( isHashAlgo( cryptAlgo ) ) ? CONTEXT_HASH : \
779  ( isMacAlgo( cryptAlgo ) ) ? CONTEXT_MAC : \
780  ( isSpecialAlgo( cryptAlgo ) ) ? CONTEXT_GENERIC : \
781  CONTEXT_NONE;
783  OBJECT_SUBTYPE subType;
784  const int createFlags = objectFlags | \
785  ( needsSecureMemory( contextType ) ? \
786  CREATEOBJECT_FLAG_SECUREMALLOC : 0 );
787  int sideChannelProtectionLevel, storageSize;
788  int stateStorageSize = 0, stateStorageAlignSize = 0;
789  int actionFlags = 0, actionPerms = ACTION_PERM_ALL, status;
790 
791  assert( isWritePtr( iCryptContext, sizeof( CRYPT_CONTEXT ) ) );
792  assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );
793 
794  REQUIRES( ( iCryptOwner == DEFAULTUSER_OBJECT_HANDLE ) || \
795  isHandleRangeValid( iCryptOwner ) );
796  REQUIRES( objectFlags >= CREATEOBJECT_FLAG_NONE && \
797  objectFlags <= CREATEOBJECT_FLAG_MAX );
798  REQUIRES( cryptAlgo > CRYPT_ALGO_NONE && \
799  cryptAlgo < CRYPT_ALGO_LAST );
800  REQUIRES( contextType > CONTEXT_NONE && contextType < CONTEXT_LAST );
801 
802  /* Clear return value */
803  *iCryptContext = CRYPT_ERROR;
804 
805  /* Get general config information */
806  status = krnlSendMessage( iCryptOwner, IMESSAGE_GETATTRIBUTE,
807  &sideChannelProtectionLevel,
809  if( cryptStatusError( status ) )
810  return( status );
811  if( contextType != CONTEXT_PKC )
812  {
813  status = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_STATESIZE,
814  NULL, &stateStorageSize, 0 );
815  if( cryptStatusOK( status ) )
816  status = capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_STATEALIGNTYPE,
817  NULL, &stateStorageAlignSize, 0 );
818  if( cryptStatusError( status ) )
819  return( status );
820  }
821 
822  /* Set up subtype-specific information */
823  switch( contextType )
824  {
825  case CONTEXT_CONV:
826  subType = SUBTYPE_CTX_CONV;
827  storageSize = sizeof( CONV_INFO );
828  if( capabilityInfoPtr->encryptFunction != NULL || \
829  capabilityInfoPtr->encryptCBCFunction != NULL || \
830  capabilityInfoPtr->encryptCFBFunction != NULL || \
831  capabilityInfoPtr->encryptOFBFunction != NULL || \
832  capabilityInfoPtr->encryptGCMFunction != NULL )
833  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT,
834  ACTION_PERM_ALL );
835  if( capabilityInfoPtr->decryptFunction != NULL || \
836  capabilityInfoPtr->decryptCBCFunction != NULL || \
837  capabilityInfoPtr->decryptCFBFunction != NULL || \
838  capabilityInfoPtr->decryptOFBFunction != NULL || \
839  capabilityInfoPtr->decryptGCMFunction != NULL )
840  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_DECRYPT,
841  ACTION_PERM_ALL );
843  break;
844 
845  case CONTEXT_PKC:
846  subType = SUBTYPE_CTX_PKC;
847  storageSize = sizeof( PKC_INFO );
848  if( isDlpAlgo( cryptAlgo ) || isEccAlgo( cryptAlgo ) )
849  {
850  /* The DLP- and ECDLP-based PKC's have somewhat specialised
851  usage requirements so we don't allow direct access by
852  users */
853  actionPerms = ACTION_PERM_NONE_EXTERNAL;
854  }
855  if( capabilityInfoPtr->encryptFunction != NULL )
856  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT,
857  actionPerms );
858  if( capabilityInfoPtr->decryptFunction != NULL )
859  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_DECRYPT,
860  actionPerms );
861  if( capabilityInfoPtr->signFunction != NULL )
862  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGN,
863  actionPerms );
864  if( capabilityInfoPtr->sigCheckFunction != NULL )
865  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK,
866  actionPerms );
868  break;
869 
870  case CONTEXT_HASH:
871  subType = SUBTYPE_CTX_HASH;
872  storageSize = sizeof( HASH_INFO );
874  break;
875 
876  case CONTEXT_MAC:
877  subType = SUBTYPE_CTX_MAC;
878  storageSize = sizeof( MAC_INFO );
879  actionFlags = MK_ACTION_PERM( MESSAGE_CTX_HASH, ACTION_PERM_ALL ) | \
880  MK_ACTION_PERM( MESSAGE_CTX_GENKEY, ACTION_PERM_ALL );
881  break;
882 
883  case CONTEXT_GENERIC:
884  subType = SUBTYPE_CTX_GENERIC;
885  storageSize = sizeof( GENERIC_INFO );
887  break;
888 
889  default:
890  retIntError();
891  }
892  if( actionFlags <= 0 )
893  {
894  /* There are no actions enabled for this capability, bail out rather
895  than creating an unusable context */
896  DEBUG_DIAG(( "No actions available for this capability" ));
897  assert( DEBUG_WARN );
898  return( CRYPT_ERROR_NOTAVAIL );
899  }
900 
901  /* Create the context and initialise the variables in it. The storage is
902  allocated as follows:
903 
904  +-----------+ --+
905  | | |
906  | CTX_INFO | --- ctxConv --+ |
907  | | | | CONTEXT_INFO_ALIGN_SIZE
908  +-----------+ | |
909  |###########| Pad to 8-byte boundary|
910  +-----------+ <-------------+ --+
911  | | |
912  | CONV_INFO | ---- key -----+ | storageSize
913  | | | |
914  +-----------+ | --+
915  |###########| Pad to ALIGNSIZE boundary
916  +-----------+ <-------------+ --- Aligned by initContextStorage()
917  | |
918  | Key |
919  | |
920  +-----------+
921 
922  Since we don't know at this point what the alignment requirements for
923  the key storage will be because we don't know what contextInfoPtr
924  will by until it's allocated, we over-allocate the state storage by
925  ALIGNSIZE bytes to allow the key data to be aligned with an ALIGNSIZE
926  block.
927 
928  The aligned-alloc for the key storage can get quite complex, some
929  Unix systems have posix_memalign(), and VC++ 2005 and newer have
930  _aligned_malloc(), but these are too non-portable to rely on. What we
931  have to do instead is allocate enough spare space at the end of the key
932  data for alignment. Since the address for the start of the key data
933  has to be be a multiple of ALIGNSIZE, adding ALIGNSIZE extra bytes to
934  the allocation guarantees that we have enough space, with the key data
935  being starting somewhere in the first 16 bytes of the allocated
936  block. The rest is done by initContextStorage() */
937  status = krnlCreateObject( iCryptContext, ( void ** ) &contextInfoPtr,
938  CONTEXT_INFO_ALIGN_SIZE + storageSize + \
939  ( stateStorageSize + stateStorageAlignSize ),
940  OBJECT_TYPE_CONTEXT, subType, createFlags,
941  iCryptOwner, actionFlags,
942  contextMessageFunction );
943  if( cryptStatusError( status ) )
944  return( status );
945  ANALYSER_HINT( contextInfoPtr != NULL );
946  contextInfoPtr->objectHandle = *iCryptContext;
947  contextInfoPtr->ownerHandle = iCryptOwner;
948  contextInfoPtr->capabilityInfo = capabilityInfoPtr;
949  contextInfoPtr->type = contextType;
950 #ifdef USE_DEVICES
951  contextInfoPtr->deviceObject = \
952  contextInfoPtr->altDeviceObject = CRYPT_ERROR;
953 #endif /* USE_DEVICES */
954  status = initContextStorage( contextInfoPtr, stateStorageAlignSize );
955  if( cryptStatusError( status ) )
956  {
957  /* Enqueue a destroy message for the context and tell the kernel
958  that we're done */
959  krnlSendNotifier( *iCryptContext, IMESSAGE_DESTROY );
960  krnlSendMessage( *iCryptContext, IMESSAGE_SETATTRIBUTE,
961  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
962  return( status );
963  }
964  if( sideChannelProtectionLevel > 0 )
965  contextInfoPtr->flags |= CONTEXT_FLAG_SIDECHANNELPROTECTION;
966  if( contextInfoPtr->type == CONTEXT_PKC && \
967  !( objectFlags & CREATEOBJECT_FLAG_DUMMY ) )
968  {
969  status = initContextBignums( contextInfoPtr->ctxPKC,
970  sideChannelProtectionLevel,
971  isEccAlgo( cryptAlgo ) );
972  if( cryptStatusError( status ) )
973  {
974  /* Enqueue a destroy message for the context and tell the kernel
975  that we're done */
976  krnlSendNotifier( *iCryptContext, IMESSAGE_DESTROY );
977  krnlSendMessage( *iCryptContext, IMESSAGE_SETATTRIBUTE,
978  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
979  return( status );
980  }
981  }
982  if( contextInfoPtr->type == CONTEXT_CONV )
983  {
984  /* Set the default encryption mode, which is always CBC if possible,
985  and the corresponding en/decryption handler */
986  if( capabilityInfoPtr->encryptCBCFunction != NULL )
987  {
988  contextInfoPtr->ctxConv->mode = CRYPT_MODE_CBC;
989  contextInfoPtr->encryptFunction = \
990  capabilityInfoPtr->encryptCBCFunction;
991  contextInfoPtr->decryptFunction = \
992  capabilityInfoPtr->decryptCBCFunction;
993  }
994  else
995  {
996  /* There's no CBC mode available, fall back to increasingly
997  sub-optimal choices of mode. For stream ciphers the only
998  available mode is OFB so this isn't a problem, but for
999  block ciphers it'll cause problems because most crypto
1000  protocols only allow CBC mode. In addition we don't fall
1001  back to GCM, which is a sufficiently unusual mode that we
1002  require it to be explicitly enabled by the user */
1003  if( capabilityInfoPtr->encryptCFBFunction != NULL )
1004  {
1005  contextInfoPtr->ctxConv->mode = CRYPT_MODE_CFB;
1006  contextInfoPtr->encryptFunction = \
1007  capabilityInfoPtr->encryptCFBFunction;
1008  contextInfoPtr->decryptFunction = \
1009  capabilityInfoPtr->decryptCFBFunction;
1010  }
1011  else
1012  {
1013  if( capabilityInfoPtr->encryptOFBFunction != NULL )
1014  {
1015  contextInfoPtr->ctxConv->mode = CRYPT_MODE_OFB;
1016  contextInfoPtr->encryptFunction = \
1017  capabilityInfoPtr->encryptOFBFunction;
1018  contextInfoPtr->decryptFunction = \
1019  capabilityInfoPtr->decryptOFBFunction;
1020  }
1021  else
1022  {
1023  contextInfoPtr->ctxConv->mode = CRYPT_MODE_ECB;
1024  contextInfoPtr->encryptFunction = \
1025  capabilityInfoPtr->encryptFunction;
1026  contextInfoPtr->decryptFunction = \
1027  capabilityInfoPtr->decryptFunction;
1028  }
1029  }
1030  }
1031  }
1032  else
1033  {
1034  /* There's only one possible en/decryption handler */
1035  contextInfoPtr->encryptFunction = capabilityInfoPtr->encryptFunction;
1036  contextInfoPtr->decryptFunction = capabilityInfoPtr->decryptFunction;
1037  }
1038  if( contextInfoPtr->type != CONTEXT_HASH )
1039  {
1040  /* Set up the key handling functions */
1041  initKeyHandling( contextInfoPtr );
1042  }
1043  if( contextInfoPtr->type == CONTEXT_PKC )
1044  {
1045  /* Set up the key read/write functions */
1046  initKeyID( contextInfoPtr );
1047  initKeyRead( contextInfoPtr );
1048  initKeyWrite( contextInfoPtr );
1049  }
1050 
1051  REQUIRES( contextInfoPtr->type == CONTEXT_HASH || \
1052  ( contextInfoPtr->loadKeyFunction != NULL && \
1053  contextInfoPtr->generateKeyFunction != NULL ) );
1054  REQUIRES( ( cryptAlgo == CRYPT_ALGO_DSA || \
1055  cryptAlgo == CRYPT_ALGO_ECDSA || \
1056  isSpecialAlgo( cryptAlgo ) ) || \
1057  ( contextInfoPtr->encryptFunction != NULL && \
1058  contextInfoPtr->decryptFunction != NULL ) );
1059  REQUIRES( contextInfoPtr->type != CONTEXT_PKC || \
1060  ( contextInfoPtr->ctxPKC->writePublicKeyFunction != NULL && \
1061  contextInfoPtr->ctxPKC->writePrivateKeyFunction != NULL && \
1062  contextInfoPtr->ctxPKC->readPublicKeyFunction != NULL && \
1063  contextInfoPtr->ctxPKC->readPrivateKeyFunction != NULL ) );
1064 
1065  /* If this is a dummy object remember that it's just a placeholder with
1066  actions handled externally. If it's a persistent object (backed by a
1067  permanent key in a crypto device), record this */
1068  if( objectFlags & CREATEOBJECT_FLAG_DUMMY )
1069  contextInfoPtr->flags |= CONTEXT_FLAG_DUMMY;
1070  if( objectFlags & CREATEOBJECT_FLAG_PERSISTENT )
1071  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1072 
1073  /* We've finished setting up the object type-specific info, tell the
1074  kernel that the object is ready for use */
1075  status = krnlSendMessage( *iCryptContext, IMESSAGE_SETATTRIBUTE,
1076  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
1077  if( cryptStatusOK( status ) && contextInfoPtr->type == CONTEXT_HASH )
1078  {
1079  /* If it's a hash context there's no explicit keygen or load so we
1080  need to send an "object initialised" message to get the kernel to
1081  move it into the high state. If this isn't done, any attempt to
1082  use the object will be blocked */
1083  status = krnlSendMessage( *iCryptContext, IMESSAGE_SETATTRIBUTE,
1085  CRYPT_IATTRIBUTE_INITIALISED );
1086  }
1087  if( cryptStatusError( status ) )
1088  {
1089  *iCryptContext = CRYPT_ERROR;
1090  return( status );
1091  }
1092  return( CRYPT_OK );
1093  }
1094 
1095 /* Create an encryption context object */
1096 
1097 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1098 int createContext( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo,
1099  IN TYPECAST( CAPABILITY_INFO * ) const void *auxDataPtr,
1100  IN_FLAGS_Z( CREATEOBJECT ) const int auxValue )
1101  {
1104  int status;
1105 
1106  assert( isReadPtr( createInfo, sizeof( MESSAGE_CREATEOBJECT_INFO ) ) );
1107  assert( isReadPtr( auxDataPtr, sizeof( CAPABILITY_INFO ) ) );
1108 
1109  REQUIRES( auxValue >= CREATEOBJECT_FLAG_NONE && \
1110  auxValue <= CREATEOBJECT_FLAG_MAX );
1111  REQUIRES( createInfo->arg1 > CRYPT_ALGO_NONE && \
1112  createInfo->arg1 < CRYPT_ALGO_LAST );
1113 
1114  /* Find the capability corresponding to the algorithm */
1115  capabilityInfoPtr = findCapabilityInfo( auxDataPtr, createInfo->arg1 );
1116  if( capabilityInfoPtr == NULL )
1117  return( CRYPT_ERROR_NOTAVAIL );
1118 
1119  /* Pass the call on to the lower-level create function */
1120  status = createContextFromCapability( &iCryptContext,
1121  createInfo->cryptOwner,
1122  capabilityInfoPtr, auxValue );
1123  if( cryptStatusOK( status ) )
1124  createInfo->cryptHandle = iCryptContext;
1125  return( status );
1126  }