cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_attr.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Encryption Context Attribute Routines *
4 * Copyright Peter Gutmann 1992-2008 *
5 * *
6 ****************************************************************************/
7 
8 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
9 #include "crypt.h"
10 #ifdef INC_ALL
11  #include "context.h"
12  #include "asn1.h"
13 #else
14  #include "context/context.h"
15  #include "enc_dec/asn1.h"
16 #endif /* Compiler-specific includes */
17 
18 /****************************************************************************
19 * *
20 * Utility Functions *
21 * *
22 ****************************************************************************/
23 
24 /* Exit after setting extended error information */
25 
27 static int exitError( INOUT CONTEXT_INFO *contextInfoPtr,
28  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus,
29  IN_ENUM( CRYPT_ERRTYPE ) const CRYPT_ERRTYPE_TYPE errorType,
30  IN_ERROR const int status )
31  {
32  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
33 
34  REQUIRES( isAttribute( errorLocus ) || \
35  isInternalAttribute( errorLocus ) );
36  REQUIRES( errorType > CRYPT_ERRTYPE_NONE && \
37  errorType < CRYPT_ERRTYPE_LAST );
38  REQUIRES( cryptStatusError( status ) );
39 
40  setErrorInfo( contextInfoPtr, errorLocus, errorType );
41  return( status );
42  }
43 
45 static int exitErrorInited( INOUT CONTEXT_INFO *contextInfoPtr,
46  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
47  {
48  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
49 
50  REQUIRES( isAttribute( errorLocus ) || \
51  isInternalAttribute( errorLocus ) );
52 
53  return( exitError( contextInfoPtr, errorLocus,
55  }
56 
58 static int exitErrorNotInited( INOUT CONTEXT_INFO *contextInfoPtr,
59  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
60  {
61  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
62 
63  REQUIRES( isAttribute( errorLocus ) || \
64  isInternalAttribute( errorLocus ) );
65 
66  return( exitError( contextInfoPtr, errorLocus,
68  }
69 
71 static int exitErrorNotFound( INOUT CONTEXT_INFO *contextInfoPtr,
72  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE errorLocus )
73  {
74  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
75 
76  REQUIRES( isAttribute( errorLocus ) || \
77  isInternalAttribute( errorLocus ) );
78 
79  return( exitError( contextInfoPtr, errorLocus,
81  }
82 
83 /****************************************************************************
84 * *
85 * Get Attributes *
86 * *
87 ****************************************************************************/
88 
89 /* Get a numeric/boolean attribute */
90 
92 int getContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
93  OUT_INT_Z int *valuePtr,
95  {
96  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
97  const CONTEXT_TYPE contextType = contextInfoPtr->type;
98  int value;
99 
100  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
101  assert( isWritePtr( valuePtr, sizeof( int ) ) );
102 
103  REQUIRES( isAttribute( attribute ) || \
104  isInternalAttribute( attribute ) );
105 
106  /* Clear return value */
107  *valuePtr = 0;
108 
109  switch( attribute )
110  {
112  *valuePtr = contextInfoPtr->errorType;
113  return( CRYPT_OK );
114 
116  *valuePtr = contextInfoPtr->errorLocus;
117  return( CRYPT_OK );
118 
120  *valuePtr = ( contextInfoPtr->flags & \
121  CONTEXT_FLAG_SIDECHANNELPROTECTION ) ? 1 : 0;
122  /* This is actually a protection level rather than a
123  boolean value, although internally it's stored as
124  a boolean flag */
125  return( CRYPT_OK );
126 
127  case CRYPT_CTXINFO_ALGO:
128  *valuePtr = capabilityInfoPtr->cryptAlgo;
129  return( CRYPT_OK );
130 
131  case CRYPT_CTXINFO_MODE:
132  REQUIRES( contextType == CONTEXT_CONV );
133 
134  *valuePtr = contextInfoPtr->ctxConv->mode;
135  return( CRYPT_OK );
136 
138  switch( contextType )
139  {
140  case CONTEXT_CONV:
141  value = contextInfoPtr->ctxConv->userKeyLength;
142  break;
143 
144  case CONTEXT_PKC:
145  value = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
146  break;
147 
148  case CONTEXT_MAC:
149  value = contextInfoPtr->ctxMAC->userKeyLength;
150  break;
151 
152  case CONTEXT_GENERIC:
153  value = contextInfoPtr->ctxGeneric->genericSecretLength;
154  break;
155 
156  default:
157  retIntError();
158  }
159  if( value <= 0 )
160  {
161  /* If a key hasn't been loaded yet then we return the
162  default key size */
163  value = capabilityInfoPtr->keySize;
164  }
165  *valuePtr = value;
166  return( CRYPT_OK );
167 
169  if( contextType == CONTEXT_CONV && \
170  ( contextInfoPtr->ctxConv->mode == CRYPT_MODE_CFB || \
171  contextInfoPtr->ctxConv->mode == CRYPT_MODE_OFB ) )
172  *valuePtr = 1; /* Block cipher in stream mode */
173  else
174  *valuePtr = capabilityInfoPtr->blockSize;
175  return( CRYPT_OK );
176 
178  REQUIRES( contextType == CONTEXT_CONV );
179 
180  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
181  isStreamCipher( capabilityInfoPtr->cryptAlgo ) )
182  return( CRYPT_ERROR_NOTAVAIL );
183  *valuePtr = capabilityInfoPtr->blockSize;
184  return( CRYPT_OK );
185 
188  switch( contextType )
189  {
190  case CONTEXT_CONV:
191  value = contextInfoPtr->ctxConv->keySetupAlgorithm;
192  break;
193 
194  case CONTEXT_MAC:
195  value = contextInfoPtr->ctxMAC->keySetupAlgorithm;
196  break;
197 
198  default:
199  retIntError();
200  }
201  if( value <= 0 )
202  return( exitErrorNotInited( contextInfoPtr,
204  *valuePtr = value;
205  return( CRYPT_OK );
206 
209  switch( contextType )
210  {
211  case CONTEXT_CONV:
212  value = contextInfoPtr->ctxConv->keySetupIterations;
213  break;
214 
215  case CONTEXT_MAC:
216  value = contextInfoPtr->ctxMAC->keySetupIterations;
217  break;
218 
219  default:
220  retIntError();
221  }
222  if( value <= 0 )
223  return( exitErrorNotInited( contextInfoPtr,
225  *valuePtr = value;
226  return( CRYPT_OK );
227 
229  *valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? \
230  TRUE : FALSE;
231  return( CRYPT_OK );
232 
233  case CRYPT_IATTRIBUTE_KEYFEATURES:
234  REQUIRES( contextType == CONTEXT_PKC );
235 
236  *valuePtr = ( contextInfoPtr->flags & CONTEXT_FLAG_PBO ) ? 1 : 0;
237 #ifdef USE_DEVICES
238  *valuePtr |= isHandleRangeValid( contextInfoPtr->deviceObject ) ? 2 : 0;
239 #endif /* USE_DEVICES */
240  return( CRYPT_OK );
241 
242  case CRYPT_IATTRIBUTE_DEVICEOBJECT:
243 #ifdef USE_DEVICES
244  if( isHandleRangeValid( contextInfoPtr->deviceObject ) )
245  {
246  *valuePtr = contextInfoPtr->deviceObject;
247  return( CRYPT_OK );
248  }
249 #endif /* USE_DEVICES */
250  return( CRYPT_ERROR_NOTFOUND );
251  }
252 
253  retIntError();
254  }
255 
256 /* Get a string attribute */
257 
258 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
259 int getContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
262  {
263  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
264  const CONTEXT_TYPE contextType = contextInfoPtr->type;
265  int status;
266 
267  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
268  assert( isWritePtr( msgData, sizeof( MESSAGE_DATA ) ) );
269 
270  REQUIRES( isAttribute( attribute ) || \
271  isInternalAttribute( attribute ) );
272 
273  switch( attribute )
274  {
276  return( attributeCopy( msgData, capabilityInfoPtr->algoName,
277  capabilityInfoPtr->algoNameLen ) );
278 
280  REQUIRES( contextType == CONTEXT_CONV );
281 
282  switch( contextInfoPtr->ctxConv->mode )
283  {
284  case CRYPT_MODE_ECB:
285  return( attributeCopy( msgData, "ECB", 3 ) );
286  case CRYPT_MODE_CBC:
287  return( attributeCopy( msgData, "CBC", 3 ) );
288  case CRYPT_MODE_CFB:
289  return( attributeCopy( msgData, "CFB", 3 ) );
290  case CRYPT_MODE_OFB:
291  return( attributeCopy( msgData, "OFB", 3 ) );
292  }
293  retIntError();
294 
296  REQUIRES( contextType == CONTEXT_CONV || \
297  contextType == CONTEXT_MAC );
298 
299  if( contextType == CONTEXT_CONV )
300  {
301  if( contextInfoPtr->ctxConv->saltLength <= 0 )
302  return( exitErrorInited( contextInfoPtr,
304  return( attributeCopy( msgData, contextInfoPtr->ctxConv->salt,
305  contextInfoPtr->ctxConv->saltLength ) );
306  }
307  if( contextInfoPtr->ctxMAC->saltLength <= 0 )
308  return( exitErrorInited( contextInfoPtr,
310  return( attributeCopy( msgData, contextInfoPtr->ctxMAC->salt,
311  contextInfoPtr->ctxMAC->saltLength ) );
312 
313  case CRYPT_CTXINFO_IV:
314  REQUIRES( contextType == CONTEXT_CONV );
315 
316  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
317  isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
318  return( CRYPT_ERROR_NOTAVAIL );
319  if( !( contextInfoPtr->flags & CONTEXT_FLAG_IV_SET ) )
320  return( exitErrorNotInited( contextInfoPtr, CRYPT_CTXINFO_IV ) );
321  return( attributeCopy( msgData, contextInfoPtr->ctxConv->iv,
322  contextInfoPtr->ctxConv->ivLength ) );
323 
325  REQUIRES( contextType == CONTEXT_HASH || \
326  contextType == CONTEXT_MAC );
327 
328  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
329  return( CRYPT_ERROR_NOTINITED );
330  if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_DONE ) )
331  return( CRYPT_ERROR_INCOMPLETE );
332  return( attributeCopy( msgData, ( contextType == CONTEXT_HASH ) ? \
333  contextInfoPtr->ctxHash->hash : \
334  contextInfoPtr->ctxMAC->mac,
335  capabilityInfoPtr->blockSize ) );
336 
337  case CRYPT_CTXINFO_LABEL:
338  if( contextInfoPtr->labelSize <= 0 )
339  return( exitErrorNotInited( contextInfoPtr,
341  return( attributeCopy( msgData, contextInfoPtr->label,
342  contextInfoPtr->labelSize ) );
343 
344  case CRYPT_IATTRIBUTE_KEYID:
345  REQUIRES( contextType == CONTEXT_PKC );
346  REQUIRES( memcmp( contextInfoPtr->ctxPKC->keyID,
347  "\x00\x00\x00\x00\x00\x00\x00\x00", 8 ) );
348 
349  return( attributeCopy( msgData, contextInfoPtr->ctxPKC->keyID,
350  KEYID_SIZE ) );
351 
352  case CRYPT_IATTRIBUTE_KEYID_PGP2:
353  REQUIRES( contextType == CONTEXT_PKC );
354 
355  if( !( contextInfoPtr->flags & CONTEXT_FLAG_PGPKEYID_SET ) )
356  return( CRYPT_ERROR_NOTFOUND );
357  return( attributeCopy( msgData, contextInfoPtr->ctxPKC->pgp2KeyID,
358  PGP_KEYID_SIZE ) );
359 
360  case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
361  REQUIRES( contextType == CONTEXT_PKC );
362 
363  if( !( contextInfoPtr->flags & CONTEXT_FLAG_OPENPGPKEYID_SET ) )
364  return( CRYPT_ERROR_NOTFOUND );
365  return( attributeCopy( msgData, contextInfoPtr->ctxPKC->openPgpKeyID,
366  PGP_KEYID_SIZE ) );
367 
368  case CRYPT_IATTRIBUTE_KEY_SPKI:
369  case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
370  /* CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL is used to read from dummy
371  contexts used as placeholders for external crypto hardware
372  functionality, these aren't necessarily in the high state as
373  required by a CRYPT_IATTRIBUTE_KEY_SPKI read when they're
374  accessed because the hardware may not be ready yet but we
375  can still fetch the stored public-key data from them */
376  REQUIRES( contextType == CONTEXT_PKC && \
377  !needsKey( contextInfoPtr ) );
378 
379  if( contextInfoPtr->ctxPKC->publicKeyInfo != NULL )
380  {
381  /* If the data is available in pre-encoded form, copy it
382  out */
383  return( attributeCopy( msgData, contextInfoPtr->ctxPKC->publicKeyInfo,
384  contextInfoPtr->ctxPKC->publicKeyInfoSize ) );
385  }
386  ENSURES( attribute == CRYPT_IATTRIBUTE_KEY_SPKI );
387  /* Drop through */
388 
389  case CRYPT_IATTRIBUTE_KEY_PGP:
390  case CRYPT_IATTRIBUTE_KEY_SSH:
391  case CRYPT_IATTRIBUTE_KEY_SSH1:
392  case CRYPT_IATTRIBUTE_KEY_SSL:
393  {
394  STREAM stream;
396 
397  REQUIRES( contextType == CONTEXT_PKC && \
398  !needsKey( contextInfoPtr ) );
399 
400  /* Write the appropriately-formatted key data from the context */
401  status = attributeToFormatType( attribute, &formatType );
402  if( cryptStatusError( status ) )
403  return( status );
404  sMemOpenOpt( &stream, msgData->data, msgData->length );
405  status = contextInfoPtr->ctxPKC->writePublicKeyFunction( &stream,
406  contextInfoPtr, formatType,
407  "public_key", 10 );
408  if( cryptStatusOK( status ) )
409  msgData->length = stell( &stream );
410  sMemDisconnect( &stream );
411  return( status );
412  }
413 
414  case CRYPT_IATTRIBUTE_PGPVALIDITY:
415  REQUIRES( contextType == CONTEXT_PKC );
416 
417  *( ( time_t * ) msgData->data ) = \
418  contextInfoPtr->ctxPKC->pgpCreationTime;
419  return( CRYPT_OK );
420 
421  case CRYPT_IATTRIBUTE_DEVICESTORAGEID:
422 #ifdef USE_HARDWARE
423  if( contextInfoPtr->deviceStorageIDset )
424  return( attributeCopy( msgData, contextInfoPtr->deviceStorageID,
425  KEYID_SIZE ) );
426 #endif /* USE_HARDWARE */
427  return( CRYPT_ERROR_NOTFOUND );
428 
429  case CRYPT_IATTRIBUTE_ENCPARAMS:
430  REQUIRES( contextType == CONTEXT_GENERIC );
431 
432  if( contextInfoPtr->ctxGeneric->encAlgoParamSize <= 0 )
433  return( CRYPT_ERROR_NOTFOUND );
434  return( attributeCopy( msgData,
435  contextInfoPtr->ctxGeneric->encAlgoParams,
436  contextInfoPtr->ctxGeneric->encAlgoParamSize ) );
437 
438  case CRYPT_IATTRIBUTE_MACPARAMS:
439  REQUIRES( contextType == CONTEXT_GENERIC );
440 
441  if( contextInfoPtr->ctxGeneric->macAlgoParamSize <= 0 )
442  return( CRYPT_ERROR_NOTFOUND );
443  return( attributeCopy( msgData,
444  contextInfoPtr->ctxGeneric->macAlgoParams,
445  contextInfoPtr->ctxGeneric->macAlgoParamSize ) );
446 
447  case CRYPT_IATTRIBUTE_ICV:
448  REQUIRES( contextType == CONTEXT_CONV );
449 
450  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_GCM )
451  return( CRYPT_ERROR_NOTAVAIL );
452  return( capabilityInfoPtr->getInfoFunction( CAPABILITY_INFO_ICV,
453  contextInfoPtr, msgData->data,
454  msgData->length ) );
455  }
456 
457  retIntError();
458  }
459 
460 /****************************************************************************
461 * *
462 * Set Attributes *
463 * *
464 ****************************************************************************/
465 
466 /* Set a numeric/boolean attribute */
467 
469 int setContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
470  IN_INT_Z const int value,
471  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
472  {
473  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
474  const CONTEXT_TYPE contextType = contextInfoPtr->type;
475  int *valuePtr;
476 
477  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
478 
479  REQUIRES( value >= 0 && value < MAX_INTLENGTH );
480  REQUIRES( isAttribute( attribute ) || \
481  isInternalAttribute( attribute ) );
482 
483  switch( attribute )
484  {
486  if( value > 0 )
487  contextInfoPtr->flags |= CONTEXT_FLAG_SIDECHANNELPROTECTION;
488  else
489  contextInfoPtr->flags &= ~CONTEXT_FLAG_SIDECHANNELPROTECTION;
490  return( CRYPT_OK );
491 
492  case CRYPT_CTXINFO_MODE:
493  REQUIRES( contextType == CONTEXT_CONV );
494 
495  /* If the mode for the context isn't set to the initial default
496  value, it's already been explicitly set and we can't change
497  it again. This isn't quite as straightforward as it seems
498  because the definition of "initial default mode" is a bit
499  vague, for stream ciphers it's OFB, for block ciphers it's
500  usually CBC unless we're working with specific hardware
501  crypto that only supports one mode and that mode isn't CBC.
502  For now this only seems to be ECB so we add a special-case
503  check for ECB-only operation */
504  if( isStreamCipher( capabilityInfoPtr->cryptAlgo ) )
505  {
506  /* It's a stream cipher, the only possible mode is an
507  implicit OFB so any attempt to change it isn't valid */
508  return( exitErrorInited( contextInfoPtr,
509  CRYPT_CTXINFO_MODE ) );
510  }
511  else
512  {
513 #if 1 /* So far no devices without CBC support have been
514  encountered, so we always assume a default of CBC */
515  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_CBC )
516  return( exitErrorInited( contextInfoPtr,
517  CRYPT_CTXINFO_MODE ) );
518 #else
519  if( capabilityInfoPtr->encryptCBCFunction != NULL )
520  {
521  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_CBC )
522  return( exitErrorInited( contextInfoPtr,
523  CRYPT_CTXINFO_MODE ) );
524  }
525  else
526  {
527  /* This algorithm isn't available in CBC mode, the
528  default will be ECB */
529  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_ECB )
530  return( exitErrorInited( contextInfoPtr,
531  CRYPT_CTXINFO_MODE ) );
532  }
533 #endif
534  }
535 
536  /* Set the en/decryption mode */
537  return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
538  KEYPARAM_MODE, NULL, value ) );
539 
541  /* Make sure that the requested size is within range */
543  value > capabilityInfoPtr->maxKeySize )
544  return( CRYPT_ARGERROR_NUM1 );
545 
546  /* Get the location to store the key size and make sure that
547  it's not already set */
548  switch( contextType )
549  {
550  case CONTEXT_CONV:
551  valuePtr = &contextInfoPtr->ctxConv->userKeyLength;
552  break;
553 
554  case CONTEXT_PKC:
555  valuePtr = &contextInfoPtr->ctxPKC->keySizeBits;
556  break;
557 
558  case CONTEXT_MAC:
559  valuePtr = &contextInfoPtr->ctxMAC->userKeyLength;
560  break;
561 
562  case CONTEXT_GENERIC:
563  valuePtr = &contextInfoPtr->ctxGeneric->genericSecretLength;
564  break;
565 
566  default:
567  retIntError();
568  }
569  if( *valuePtr != 0 )
570  return( exitErrorInited( contextInfoPtr,
572 
573  /* Trim the user-supplied value to the correct shape, taking
574  into account various issues such as limitations with the
575  underlying crypto code/hardware and interop problems with
576  algorithms that allow excessively long keys. In virtute sunt
577  multi ascensus.
578 
579  If it's a PKC key then there's nothing further to do, since
580  the range check above is all that we need. ECC keys are a
581  bit complicated because if we're using fixed curve parameters
582  (which in practice we always do) there are only a small
583  number of quantised key sizes that we can use, but since some
584  of those correspond to very odd bit sizes like 521 bits that
585  can't be specified as an integral byte count what we do in
586  the ECC code is use the nearest fixed curve parameters equal
587  to or above the given value, avoiding the need for the caller
588  to play guessing games as to which byte-count value
589  corresponds to which curve.
590 
591  For conventional/MAC keys we need to limit the maximum
592  working key length to a sane size since the other side may
593  not be able to handle stupidly large keys */
594  if( contextType == CONTEXT_PKC )
595  *valuePtr = bytesToBits( value );
596  else
597  *valuePtr = min( value, MAX_WORKING_KEYSIZE );
598  return( CRYPT_OK );
599 
601  REQUIRES( contextType == CONTEXT_HASH || \
602  contextType == CONTEXT_MAC );
603 
604  /* Some hash (and corresponding MAC) algorithms have variable-
605  length outputs, in which case the blocksize is user-
606  definable */
607  if( capabilityInfoPtr->initParamsFunction == NULL )
608  return( CRYPT_ERROR_NOTAVAIL );
609  return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
610  KEYPARAM_BLOCKSIZE, NULL, value ) );
611 
614  {
615  CRYPT_ALGO_TYPE *algoValuePtr;
616 
617  REQUIRES( contextType == CONTEXT_CONV || \
618  contextType == CONTEXT_MAC );
619 
620  /* The kernel only allows (potentially) valid values to be set,
621  but these may be disabled at the algorithm level so we have
622  to perform an additional check here */
623  if( !algoAvailable( value ) )
624  {
625  return( exitError( contextInfoPtr, attribute,
628  }
629 
630  algoValuePtr = ( contextType == CONTEXT_CONV ) ? \
631  &contextInfoPtr->ctxConv->keySetupAlgorithm : \
632  &contextInfoPtr->ctxMAC->keySetupAlgorithm;
633  if( *algoValuePtr != CRYPT_ALGO_NONE )
634  return( exitErrorInited( contextInfoPtr, attribute ) );
635  *algoValuePtr = value;
636  return( CRYPT_OK );
637  }
638 
641  REQUIRES( contextType == CONTEXT_CONV || \
642  contextType == CONTEXT_MAC );
643 
644  valuePtr = ( contextType == CONTEXT_CONV ) ? \
645  &contextInfoPtr->ctxConv->keySetupIterations : \
646  &contextInfoPtr->ctxMAC->keySetupIterations;
647  if( *valuePtr )
648  return( exitErrorInited( contextInfoPtr,
650  *valuePtr = value;
651  return( CRYPT_OK );
652 
654  /* The is-object-persistent attribute functions as follows:
655 
656  | Software | Hardware
657  -----+----------+-------------------
658  PKC | R/O (1) | R/O (2)
659  -----+----------+-------------------
660  Conv | R/O (1) | R/W low state (3)
661  | | R/O high state
662 
663  (1) = Set if stored to or read from a keyset.
664  (2) = Always set. Private-key objects are automatically
665  created as persistent objects, public-key objects
666  are (transparently) created as software objects since
667  the operation is much faster on the host system than
668  by going via the device.
669  (3) = Can be set in the low state, if set then the object
670  is created as a persistent object in the device.
671 
672  Most of these checks are enforced by the kernel, the one
673  thing that the ACL language can't specify is the requirement
674  that a persistent conventional-encryption object be tied to
675  a device, which we do explicitly here */
676  if( ( value != 0 ) && \
677  !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
678  return( CRYPT_ERROR_PERMISSION );
679 
680  /* Set or clear the persistent flag as required */
681  if( value != 0 )
682  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
683  else
684  contextInfoPtr->flags &= ~CONTEXT_FLAG_PERSISTENT;
685  return( CRYPT_OK );
686 
687  case CRYPT_IATTRIBUTE_KEYSIZE:
688  /* If it's a private key context or a persistent context we need
689  to have a key label set before we can continue */
690  if( ( ( contextInfoPtr->type == CONTEXT_PKC ) || \
691  ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ) && \
692  contextInfoPtr->labelSize <= 0 )
693  retIntError();
694 
695  /* If the key is held outside the context (e.g. in a device) we
696  may need to manually supply the key-related information
697  needed by the context if it can't be obtained through other
698  means such as when the SubjectPublicKeyInfo is set */
699  switch( contextType )
700  {
701  case CONTEXT_CONV:
702  contextInfoPtr->ctxConv->userKeyLength = value;
703  break;
704 
705  case CONTEXT_PKC:
706  contextInfoPtr->ctxPKC->keySizeBits = bytesToBits( value );
707  break;
708 
709  case CONTEXT_MAC:
710  contextInfoPtr->ctxMAC->userKeyLength = value;
711  break;
712 
713  case CONTEXT_GENERIC:
714  contextInfoPtr->ctxGeneric->genericSecretLength = value;
715  break;
716 
717  default:
718  retIntError();
719  }
720  return( CRYPT_OK );
721 
722  case CRYPT_IATTRIBUTE_DEVICEOBJECT:
723 #ifdef USE_DEVICES
724  /* Setting the device object means that the crypto functionality
725  for the context is enabled, which means that it's effectively
726  in the key-loaded state, however for standard key-loaded
727  operations to be possible certain other preconditions need to
728  be met, which we check for here */
729  REQUIRES( ( contextType == CONTEXT_CONV && \
730  contextInfoPtr->ctxConv->userKeyLength > 0 ) || \
731  ( contextType == CONTEXT_PKC && \
732  contextInfoPtr->ctxPKC->keySizeBits > 0 && \
733  contextInfoPtr->ctxPKC->publicKeyInfo != NULL ) || \
734  ( contextType == CONTEXT_MAC && \
735  contextInfoPtr->ctxMAC->userKeyLength > 0 ) || \
736  ( contextType == CONTEXT_GENERIC && \
737  contextInfoPtr->ctxGeneric->genericSecretLength > 0 ) || \
738  ( contextType == CONTEXT_HASH ) );
739 
740  /* Remember the reference to the associated crypto functionality
741  in the device */
742  contextInfoPtr->deviceObject = value;
743  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
744 #endif /* USE_DEVICES */
745  return( CRYPT_OK );
746  }
747 
748  retIntError();
749  }
750 
751 /* Set a string attribute */
752 
753 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
754 int setContextAttributeS( INOUT CONTEXT_INFO *contextInfoPtr,
755  IN_BUFFER( dataLength ) const void *data,
756  IN_LENGTH const int dataLength,
757  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
758  {
759  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
760  const CONTEXT_TYPE contextType = contextInfoPtr->type;
761  int status;
762 
763  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
764  assert( isReadPtr( data, dataLength ) );
765 
766  REQUIRES( dataLength > 0 && dataLength < MAX_INTLENGTH );
767  REQUIRES( isAttribute( attribute ) || \
768  isInternalAttribute( attribute ) );
769 
770  switch( attribute )
771  {
773  REQUIRES( contextType == CONTEXT_CONV || \
774  contextType == CONTEXT_MAC );
775  REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_HASHSIZE );
776 
777  if( contextType == CONTEXT_CONV )
778  {
779  if( contextInfoPtr->ctxConv->saltLength > 0 )
780  return( exitErrorInited( contextInfoPtr,
782  memcpy( contextInfoPtr->ctxConv->salt, data, dataLength );
783  contextInfoPtr->ctxConv->saltLength = dataLength;
784  return( CRYPT_OK );
785  }
786  if( contextInfoPtr->ctxMAC->saltLength > 0 )
787  return( exitErrorInited( contextInfoPtr,
789  memcpy( contextInfoPtr->ctxMAC->salt, data, dataLength );
790  contextInfoPtr->ctxMAC->saltLength = dataLength;
791  return( CRYPT_OK );
792 
794  return( deriveKey( contextInfoPtr, data, dataLength ) );
795 
796  case CRYPT_CTXINFO_KEY:
797  REQUIRES( contextType == CONTEXT_CONV || \
798  contextType == CONTEXT_MAC || \
799  contextType == CONTEXT_GENERIC );
800  REQUIRES( needsKey( contextInfoPtr ) );
801 
802  /* If it's a persistent context we need to have a key label set
803  before we can continue */
804  if( ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) && \
805  contextInfoPtr->labelSize <= 0 )
806  return( exitErrorNotInited( contextInfoPtr,
808 
809  /* The kernel performs a general check on the size of this
810  attribute but doesn't know about context subtype-specific
811  limits so we perform a context-specific check here */
812  if( dataLength < capabilityInfoPtr->minKeySize || \
813  dataLength > capabilityInfoPtr->maxKeySize )
814  return( CRYPT_ARGERROR_NUM1 );
815 
816  /* Load the key into the context */
817  status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
818  data, dataLength );
819  if( cryptStatusOK( status ) )
820  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
821  return( status );
822 
823 #ifndef USE_FIPS140
825  return( setKeyComponents( contextInfoPtr, data, dataLength ) );
826 #endif /* !USE_FIPS140 */
827 
828  case CRYPT_CTXINFO_IV:
829  REQUIRES( contextType == CONTEXT_CONV );
830 
831  /* If it's a mode that doesn't use an IV then the load IV
832  operation is meaningless */
833  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
834  isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
835  return( CRYPT_ERROR_NOTAVAIL );
836 
837  /* Make sure that the data size is valid. GCM is handled
838  specially because the default IV size is somewhat smaller
839  than the cipher block size */
840  if( contextInfoPtr->ctxConv->mode == CRYPT_MODE_GCM )
841  {
842  if( dataLength < 8 || \
843  dataLength > capabilityInfoPtr->blockSize )
844  return( CRYPT_ARGERROR_NUM1 );
845  }
846  else
847  {
848  if( dataLength != capabilityInfoPtr->blockSize )
849  return( CRYPT_ARGERROR_NUM1 );
850  }
851 
852  /* Load the IV */
853  return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
854  KEYPARAM_IV, data, dataLength ) );
855 
856  case CRYPT_CTXINFO_LABEL:
857  {
859 
860  if( contextInfoPtr->labelSize > 0 )
861  return( exitErrorInited( contextInfoPtr,
863 
864  /* Check any device object that the context is associated with
865  to ensure that nothing with that label already exists in the
866  device. For keysets the check for duplicates is performed
867  when the context is explicitly added to the keyset but with
868  devices the context will be implicitly created within the
869  device at some future point (at context creation, on key
870  load/generation, or at some other point) that depends on the
871  device. Because of this we perform a preemptive check for
872  duplicates to avoid a potentially confusing error condition
873  at some indeterminate point in the future.
874 
875  Since objects are typed, we have to check for the three
876  possible { label, type } combinations. In theory we could
877  require that labels are only unique per object type but this
878  can lead to problems with underlying devices or keysets that
879  only support a check by label and not by { label, type }
880  combination. In addition we can't send the message to the
881  context because the kernel won't forward this message type
882  (sending a get-key message to a context doesn't make sense)
883  so we have to explicitly get the dependent device and then
884  send the get-key directly to it */
885  status = krnlSendMessage( contextInfoPtr->objectHandle,
886  IMESSAGE_GETDEPENDENT, &iCryptHandle,
888  if( cryptStatusOK( status ) && \
889  ( iCryptHandle != SYSTEM_OBJECT_HANDLE ) )
890  {
891  MESSAGE_KEYMGMT_INFO getkeyInfo;
892 
894  data, dataLength, NULL, 0,
896  status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
897  &getkeyInfo, KEYMGMT_ITEM_SECRETKEY );
898  if( cryptStatusError( status ) )
899  status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
900  &getkeyInfo,
902  if( cryptStatusError( status ) )
903  status = krnlSendMessage( iCryptHandle, IMESSAGE_KEY_GETKEY,
904  &getkeyInfo,
906  if( cryptStatusOK( status ) )
907  {
908  /* We've found something with this label already
909  present, we can't use it again */
910  return( CRYPT_ERROR_DUPLICATE );
911  }
912  assert( !cryptArgError( status ) );
913  }
914 
915  /* Fall through */
916  }
917 
918  case CRYPT_IATTRIBUTE_EXISTINGLABEL:
919  REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
920 
921  /* The difference between CRYPT_CTXINFO_LABEL and
922  CRYPT_IATTRIBUTE_EXISTINGLABEL is that the latter is used to
923  set a label for a context that's being instantiated from a
924  persistent object in a device. We can't perform the
925  duplicate-label check in this case because we'll always get a
926  match for the device object's label */
927  if( contextInfoPtr->labelSize > 0 )
928  return( exitErrorInited( contextInfoPtr,
930 
931  /* Set the label */
932  memcpy( contextInfoPtr->label, data, dataLength );
933  contextInfoPtr->labelSize = dataLength;
934  return( CRYPT_OK );
935 
936  case CRYPT_IATTRIBUTE_KEYID_OPENPGP:
937  REQUIRES( contextType == CONTEXT_PKC );
938  REQUIRES( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA || \
939  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
940  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );
941  REQUIRES( dataLength == PGP_KEYID_SIZE );
942 
943  memcpy( contextInfoPtr->ctxPKC->openPgpKeyID, data, dataLength );
944  contextInfoPtr->flags |= CONTEXT_FLAG_OPENPGPKEYID_SET;
945 
946  /* If it's a non-PGP 2.x key type, set the PGP 2.x keyID to the
947  OpenPGP keyID. This is necessary because non-PGP 2.x keys can
948  be used with PGP 2.x message formats which would imply the use
949  of a PGP 2.x keyID except that it's not defined for this key
950  type */
951  if( contextInfoPtr->capabilityInfo->cryptAlgo != CRYPT_ALGO_RSA )
952  {
953  memcpy( contextInfoPtr->ctxPKC->pgp2KeyID,
954  contextInfoPtr->ctxPKC->openPgpKeyID, PGP_KEYID_SIZE );
955  contextInfoPtr->flags |= CONTEXT_FLAG_PGPKEYID_SET;
956  }
957  return( CRYPT_OK );
958 
959  case CRYPT_IATTRIBUTE_KEY_SPKI:
960  case CRYPT_IATTRIBUTE_KEY_PGP:
961  case CRYPT_IATTRIBUTE_KEY_SSH:
962  case CRYPT_IATTRIBUTE_KEY_SSH1:
963  case CRYPT_IATTRIBUTE_KEY_SSL:
964  case CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL:
965  case CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL:
966  REQUIRES( contextType == CONTEXT_PKC );
967 
968  return( setEncodedKey( contextInfoPtr, attribute, data,
969  dataLength ) );
970 
971  case CRYPT_IATTRIBUTE_PGPVALIDITY:
972  REQUIRES( contextType == CONTEXT_PKC );
973 
974  contextInfoPtr->ctxPKC->pgpCreationTime = *( ( time_t * ) data );
975  return( CRYPT_OK );
976 
977  case CRYPT_IATTRIBUTE_DEVICESTORAGEID:
978 #ifdef USE_HARDWARE
979  REQUIRES( dataLength > 0 && dataLength <= KEYID_SIZE );
980  memset( contextInfoPtr->deviceStorageID, 0, KEYID_SIZE );
981  memcpy( contextInfoPtr->deviceStorageID, data, dataLength );
982  contextInfoPtr->deviceStorageIDset = TRUE;
983 #endif /* USE_HARDWARE */
984  return( CRYPT_OK );
985 
986  case CRYPT_IATTRIBUTE_ENCPARAMS:
987  REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
988 
989  memcpy( contextInfoPtr->ctxGeneric->encAlgoParams, data,
990  dataLength );
991  contextInfoPtr->ctxGeneric->encAlgoParamSize = dataLength;
992 
993  return( CRYPT_OK );
994 
995  case CRYPT_IATTRIBUTE_MACPARAMS:
996  REQUIRES( dataLength > 0 && dataLength <= CRYPT_MAX_TEXTSIZE );
997 
998  memcpy( contextInfoPtr->ctxGeneric->macAlgoParams, data,
999  dataLength );
1000  contextInfoPtr->ctxGeneric->macAlgoParamSize = dataLength;
1001 
1002  return( CRYPT_OK );
1003 
1004  case CRYPT_IATTRIBUTE_AAD:
1005  REQUIRES( contextType == CONTEXT_CONV );
1006 
1007  if( contextInfoPtr->ctxConv->mode != CRYPT_MODE_GCM )
1008  return( CRYPT_ERROR_NOTAVAIL );
1009 
1010  /* Process the AAD */
1011  return( capabilityInfoPtr->initParamsFunction( contextInfoPtr,
1012  KEYPARAM_AAD , data, dataLength ) );
1013  }
1014 
1015  retIntError();
1016  }
1017 
1018 /****************************************************************************
1019 * *
1020 * Delete Attributes *
1021 * *
1022 ****************************************************************************/
1023 
1024 /* Delete an attribute */
1025 
1026 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
1027 int deleteContextAttribute( INOUT CONTEXT_INFO *contextInfoPtr,
1028  IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute )
1029  {
1030  const CONTEXT_TYPE contextType = contextInfoPtr->type;
1031 
1032  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1033 
1034  REQUIRES( isAttribute( attribute ) || \
1035  isInternalAttribute( attribute ) );
1036 
1037  switch( attribute )
1038  {
1040  REQUIRES( contextType == CONTEXT_CONV || \
1041  contextType == CONTEXT_MAC );
1042 
1043  if( contextType == CONTEXT_CONV )
1044  {
1045  if( contextInfoPtr->ctxConv->keySetupAlgorithm == CRYPT_ALGO_NONE )
1046  return( exitErrorNotFound( contextInfoPtr,
1048  contextInfoPtr->ctxConv->keySetupAlgorithm = CRYPT_ALGO_NONE;
1049  return( CRYPT_OK );
1050  }
1051  if( contextInfoPtr->ctxMAC->keySetupAlgorithm == CRYPT_ALGO_NONE )
1052  return( exitErrorNotFound( contextInfoPtr,
1054  contextInfoPtr->ctxMAC->keySetupAlgorithm = CRYPT_ALGO_NONE;
1055  return( CRYPT_OK );
1056 
1058  REQUIRES( contextType == CONTEXT_CONV || \
1059  contextType == CONTEXT_MAC );
1060 
1061  if( contextType == CONTEXT_CONV )
1062  {
1063  if( contextInfoPtr->ctxConv->keySetupIterations == 0 )
1064  return( exitErrorNotFound( contextInfoPtr,
1066  contextInfoPtr->ctxConv->keySetupIterations = 0;
1067  return( CRYPT_OK );
1068  }
1069  if( contextInfoPtr->ctxMAC->keySetupIterations == 0 )
1070  return( exitErrorNotFound( contextInfoPtr,
1072  contextInfoPtr->ctxMAC->keySetupIterations = 0;
1073  return( CRYPT_OK );
1074 
1076  REQUIRES( contextType == CONTEXT_CONV || \
1077  contextType == CONTEXT_MAC );
1078 
1079  if( contextType == CONTEXT_CONV )
1080  {
1081  if( contextInfoPtr->ctxConv->saltLength == 0 )
1082  return( exitErrorNotFound( contextInfoPtr,
1084  zeroise( contextInfoPtr->ctxConv->salt, CRYPT_MAX_HASHSIZE );
1085  contextInfoPtr->ctxConv->saltLength = 0;
1086  return( CRYPT_OK );
1087  }
1088  if( contextInfoPtr->ctxMAC->saltLength == 0 )
1089  return( exitErrorNotFound( contextInfoPtr,
1091  zeroise( contextInfoPtr->ctxMAC->salt, CRYPT_MAX_HASHSIZE );
1092  contextInfoPtr->ctxMAC->saltLength = 0;
1093  return( CRYPT_OK );
1094 
1095  case CRYPT_CTXINFO_IV:
1096  REQUIRES( contextType == CONTEXT_CONV );
1097 
1098  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
1099  isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1100  return( exitErrorNotFound( contextInfoPtr,
1101  CRYPT_CTXINFO_IV ) );
1102  contextInfoPtr->ctxConv->ivLength = \
1103  contextInfoPtr->ctxConv->ivCount = 0;
1104  contextInfoPtr->flags &= ~CONTEXT_FLAG_IV_SET;
1105  return( CRYPT_OK );
1106 
1107  case CRYPT_CTXINFO_LABEL:
1108  if( contextInfoPtr->labelSize <= 0 )
1109  return( exitErrorNotFound( contextInfoPtr,
1110  CRYPT_CTXINFO_LABEL ) );
1111  zeroise( contextInfoPtr->label, contextInfoPtr->labelSize );
1112  contextInfoPtr->labelSize = 0;
1113  return( CRYPT_OK );
1114 
1116  switch( contextType )
1117  {
1118  case CONTEXT_HASH:
1119  zeroise( contextInfoPtr->ctxHash->hash, CRYPT_MAX_HASHSIZE );
1120  break;
1121 
1122  case CONTEXT_MAC:
1123  zeroise( contextInfoPtr->ctxMAC->mac, CRYPT_MAX_HASHSIZE );
1124  break;
1125 
1126  default:
1127  retIntError();
1128  }
1129  contextInfoPtr->flags &= ~( CONTEXT_FLAG_HASH_INITED | \
1130  CONTEXT_FLAG_HASH_DONE );
1131  return( CRYPT_OK );
1132  }
1133 
1134  retIntError();
1135  }