cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
keyload.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Key Load Routines *
4 * Copyright Peter Gutmann 1992-2011 *
5 * *
6 ****************************************************************************/
7 
8 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
9 #if defined( INC_ALL )
10  #include "crypt.h"
11  #include "context.h"
12 #else
13  #include "crypt.h"
14  #include "context/context.h"
15 #endif /* Compiler-specific includes */
16 
17 /* The default size of the salt for PKCS #5v2 key derivation, needed when we
18  set the CRYPT_CTXINFO_KEYING_VALUE */
19 
20 #define PKCS5_SALT_SIZE 8 /* 64 bits */
21 
22 /****************************************************************************
23 * *
24 * Utility Functions *
25 * *
26 ****************************************************************************/
27 
28 /* Convert a key attribute type into a key format type */
29 
30 CHECK_RETVAL \
32  OUT_ENUM_OPT( KEYFORMAT ) KEYFORMAT_TYPE *keyformat )
33  {
34  static const MAP_TABLE attributeMapTbl[] = {
35  { CRYPT_IATTRIBUTE_KEY_SSH, KEYFORMAT_SSH },
36  { CRYPT_IATTRIBUTE_KEY_SSH1, KEYFORMAT_SSH1 },
37  { CRYPT_IATTRIBUTE_KEY_SSL, KEYFORMAT_SSL },
38  { CRYPT_IATTRIBUTE_KEY_PGP, KEYFORMAT_PGP },
39  { CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL, KEYFORMAT_PGP },
40  { CRYPT_IATTRIBUTE_KEY_SPKI, KEYFORMAT_CERT },
41  { CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL, KEYFORMAT_CERT },
42  { CRYPT_ERROR, 0 }, { CRYPT_ERROR, 0 }
43  };
44  int value, status;
45 
46  assert( isWritePtr( keyformat, sizeof( KEYFORMAT_TYPE ) ) );
47 
48  REQUIRES( isAttribute( attribute ) || \
49  isInternalAttribute( attribute ) );
50 
51  /* Clear return value */
52  *keyformat = KEYFORMAT_NONE;
53 
54  status = mapValue( attribute, &value, attributeMapTbl,
55  FAILSAFE_ARRAYSIZE( attributeMapTbl, MAP_TABLE ) );
56  ENSURES( cryptStatusOK( status ) );
57  *keyformat = value;
58 
59  return( CRYPT_OK );
60  }
61 
62 /****************************************************************************
63 * *
64 * Key Parameter Handling Functions *
65 * *
66 ****************************************************************************/
67 
68 /* Initialise crypto parameters such as the IV and encryption mode, shared
69  by most capabilities. This is never called directly, but is accessed
70  through function pointers in the capability lists */
71 
73 int initGenericParams( INOUT CONTEXT_INFO *contextInfoPtr,
74  IN_ENUM( KEYPARAM ) const KEYPARAM_TYPE paramType,
75  IN_OPT const void *data,
76  IN_INT const int dataLength )
77  {
78  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
79 
80  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
81 
82  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
83  REQUIRES( paramType > KEYPARAM_NONE && paramType < KEYPARAM_LAST );
84 
85  /* Set the en/decryption mode if required */
86  switch( paramType )
87  {
88  case KEYPARAM_MODE:
89  {
91  contextInfoPtr->capabilityInfo;
92 
93  REQUIRES( data == NULL );
94  REQUIRES( dataLength > CRYPT_MODE_NONE && \
95  dataLength < CRYPT_MODE_LAST );
96 
97  switch( dataLength )
98  {
99  case CRYPT_MODE_ECB:
100  contextInfoPtr->encryptFunction = \
101  capabilityInfoPtr->encryptFunction;
102  contextInfoPtr->decryptFunction = \
103  capabilityInfoPtr->decryptFunction;
104  break;
105  case CRYPT_MODE_CBC:
106  contextInfoPtr->encryptFunction = \
107  capabilityInfoPtr->encryptCBCFunction;
108  contextInfoPtr->decryptFunction = \
109  capabilityInfoPtr->decryptCBCFunction;
110  break;
111  case CRYPT_MODE_CFB:
112  contextInfoPtr->encryptFunction = \
113  capabilityInfoPtr->encryptCFBFunction;
114  contextInfoPtr->decryptFunction = \
115  capabilityInfoPtr->decryptCFBFunction;
116  break;
117  case CRYPT_MODE_OFB:
118  contextInfoPtr->encryptFunction = \
119  capabilityInfoPtr->encryptOFBFunction;
120  contextInfoPtr->decryptFunction = \
121  capabilityInfoPtr->decryptOFBFunction;
122  break;
123  case CRYPT_MODE_GCM:
124  contextInfoPtr->encryptFunction = \
125  capabilityInfoPtr->encryptGCMFunction;
126  contextInfoPtr->decryptFunction = \
127  capabilityInfoPtr->decryptGCMFunction;
128  break;
129  default:
130  retIntError();
131  }
132  ENSURES( ( contextInfoPtr->encryptFunction == NULL && \
133  contextInfoPtr->decryptFunction == NULL ) || \
134  ( contextInfoPtr->encryptFunction != NULL && \
135  contextInfoPtr->decryptFunction != NULL ) );
136  if( contextInfoPtr->encryptFunction == NULL || \
137  contextInfoPtr->decryptFunction == NULL )
138  {
139  setErrorInfo( contextInfoPtr, CRYPT_CTXINFO_MODE,
141  return( CRYPT_ERROR_NOTAVAIL );
142  }
143  convInfo->mode = dataLength;
144 
145  return( CRYPT_OK );
146  }
147 
148  case KEYPARAM_IV:
149  assert( isReadPtr( data, dataLength ) );
150 
151  REQUIRES( data != NULL && \
152  dataLength >= 8 && dataLength <= CRYPT_MAX_IVSIZE );
153 
154  /* Load an IV of the required length */
155  memcpy( convInfo->iv, data, dataLength );
156  convInfo->ivLength = dataLength;
157  convInfo->ivCount = 0;
158  memcpy( convInfo->currentIV, convInfo->iv, dataLength );
159  contextInfoPtr->flags |= CONTEXT_FLAG_IV_SET;
160 
161  return( CRYPT_OK );
162  }
163 
164  retIntError();
165  }
166 
167 /* Check that user-supplied supplied PKC parameters make sense (algorithm-
168  parameter-specific validity checks are performed at a lower level).
169  Although the checks are somewhat specific to particular PKC algorithm
170  classes we have to do them at this point in order to avoid duplicating
171  them in every plug-in PKC module, and because strictly speaking it's the
172  job of the higher-level code to ensure that the lower-level routines get
173  fed at least approximately valid input */
174 
175 #ifndef USE_FIPS140
176 
178 static int checkPKCparams( IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,
179  const void *keyInfo )
180  {
181  const CRYPT_PKCINFO_RSA *rsaKey = ( CRYPT_PKCINFO_RSA * ) keyInfo;
182 
183  REQUIRES( isPkcAlgo( cryptAlgo ) );
184  REQUIRES( keyInfo != NULL );
185 
186  /* The ECC check is somewhat different to the others because ECC key
187  sizes work in different ways so we have to special-case this one */
188  if( isEccAlgo( cryptAlgo ) )
189  {
190  const CRYPT_PKCINFO_ECC *eccKey = ( CRYPT_PKCINFO_ECC * ) keyInfo;
191 
192  assert( isReadPtr( keyInfo, sizeof( CRYPT_PKCINFO_ECC ) ) );
193 
194  /* Check the general info and make sure that all required values are
195  initialised */
196  if( ( eccKey->isPublicKey != TRUE && eccKey->isPublicKey != FALSE ) )
197  return( CRYPT_ARGERROR_STR1 );
198 #if 0 /* For now we always require the use of named curves, which means
199  that the domain parameters can't be explicitly set */
200  if( eccKey->curveType != CRYPT_ECCCURVE_NONE )
201  {
202  if( eccKey->pLen <= 0 || eccKey->aLen <= 0 || eccKey->bLen <= 0 || \
203  eccKey->gxLen <= 0 || eccKey->gyLen <= 0 || eccKey->nLen <= 0 || \
204  eccKey->qxLen <= 0 || eccKey->qyLen <= 0 || eccKey->dLen < 0 )
205  return( CRYPT_ARGERROR_STR1 );
206  }
207  else
208 #endif /* 0 */
209  {
210  if( eccKey->pLen != 0 || eccKey->aLen != 0 || eccKey->bLen != 0 || \
211  eccKey->gxLen != 0 || eccKey->gyLen != 0 || eccKey->nLen != 0 || \
212  eccKey->hLen != 0 || eccKey->qxLen <= 0 || eccKey->qyLen <= 0 || \
213  eccKey->dLen < 0 )
214  return( CRYPT_ARGERROR_STR1 );
215  if( eccKey->curveType <= CRYPT_ECCCURVE_NONE || \
216  eccKey->curveType >= CRYPT_ECCCURVE_LAST )
217  return( CRYPT_ARGERROR_STR1 );
218  }
219 
220  /* Check the parameters and public components */
221  if( isShortECCKey( eccKey->pLen ) )
222  {
223  /* Special-case handling for insecure-sized public keys */
224  return( CRYPT_ERROR_NOSECURE );
225  }
226 #if 0 /* Already checked above */
227  if( eccKey->curveType != CRYPT_ECCCURVE_NONE )
228  {
229  if( eccKey->pLen < bytesToBits( ECCPARAM_MIN_P ) || \
230  eccKey->pLen > bytesToBits( ECCPARAM_MAX_P ) || \
231  eccKey->aLen < bytesToBits( ECCPARAM_MIN_A ) || \
232  eccKey->aLen > bytesToBits( ECCPARAM_MAX_A ) || \
233  eccKey->bLen < bytesToBits( ECCPARAM_MIN_B ) || \
234  eccKey->bLen > bytesToBits( ECCPARAM_MAX_B ) || \
235  eccKey->gxLen < bytesToBits( ECCPARAM_MIN_GX ) || \
236  eccKey->gxLen > bytesToBits( ECCPARAM_MAX_GX ) || \
237  eccKey->gyLen < bytesToBits( ECCPARAM_MIN_GY ) || \
238  eccKey->gyLen > bytesToBits( ECCPARAM_MAX_GY ) || \
239  eccKey->nLen < bytesToBits( ECCPARAM_MIN_N ) || \
240  eccKey->nLen > bytesToBits( ECCPARAM_MAX_N ) || \
241  eccKey->hLen < 1 || \
242  eccKey->hLen > bytesToBits( ECCPARAM_MAX_N ) )
243  return( CRYPT_ARGERROR_STR1 );
244  }
245 #endif /* 0 */
246  if( eccKey->qxLen < bytesToBits( ECCPARAM_MIN_QX ) || \
247  eccKey->qxLen > bytesToBits( ECCPARAM_MAX_QX ) || \
248  eccKey->qyLen < bytesToBits( ECCPARAM_MIN_QY ) || \
249  eccKey->qyLen > bytesToBits( ECCPARAM_MAX_QY ) )
250  return( CRYPT_ARGERROR_STR1 );
251  if( eccKey->isPublicKey )
252  return( CRYPT_OK );
253 
254  /* Check the private components */
255  if( eccKey->dLen < bytesToBits( ECCPARAM_MIN_D ) || \
256  eccKey->dLen > bytesToBits( ECCPARAM_MAX_D ) )
257  return( CRYPT_ARGERROR_STR1 );
258  return( CRYPT_OK );
259  }
260 
261  /* For the non-ECC algorithms the DLP check is simpler than the RSA one
262  because there are less odd parameter combinations possible so we get
263  this one out of the way first. Note that we don't get PKCS #3 DH
264  keys at this level so we always require that q be present */
265  if( isDlpAlgo( cryptAlgo ) )
266  {
267  const CRYPT_PKCINFO_DLP *dlpKey = ( CRYPT_PKCINFO_DLP * ) keyInfo;
268 
269  assert( isReadPtr( keyInfo, sizeof( CRYPT_PKCINFO_DLP ) ) );
270 
271  /* Check the general info and make sure that all required values are
272  initialised */
273  if( ( dlpKey->isPublicKey != TRUE && dlpKey->isPublicKey != FALSE ) )
274  return( CRYPT_ARGERROR_STR1 );
275  if( dlpKey->pLen <= 0 || dlpKey->qLen <= 0 || dlpKey->gLen <= 0 || \
276  dlpKey->yLen < 0 || dlpKey->xLen < 0 )
277  return( CRYPT_ARGERROR_STR1 );
278 
279  /* Check the public components */
280  if( isShortPKCKey( dlpKey->pLen ) )
281  {
282  /* Special-case handling for insecure-sized public keys */
283  return( CRYPT_ERROR_NOSECURE );
284  }
285  if( dlpKey->pLen < bytesToBits( DLPPARAM_MIN_P ) || \
286  dlpKey->pLen > bytesToBits( DLPPARAM_MAX_P ) || \
287  dlpKey->qLen < bytesToBits( DLPPARAM_MIN_Q ) || \
288  dlpKey->qLen > bytesToBits( DLPPARAM_MAX_Q ) || \
289  dlpKey->gLen < bytesToBits( DLPPARAM_MIN_G ) || \
290  dlpKey->gLen > bytesToBits( DLPPARAM_MAX_G ) || \
291  dlpKey->yLen < bytesToBits( 0 ) || \
292  dlpKey->yLen > bytesToBits( DLPPARAM_MAX_Y ) )
293  /* y may be 0 if only x and the public parameters are available */
294  {
295  return( CRYPT_ARGERROR_STR1 );
296  }
297  if( !( dlpKey->p[ bitsToBytes( dlpKey->pLen ) - 1 ] & 0x01 ) || \
298  !( dlpKey->q[ bitsToBytes( dlpKey->qLen ) - 1 ] & 0x01 ) )
299  return( CRYPT_ARGERROR_STR1 ); /* Quick non-prime check */
300  if( dlpKey->isPublicKey )
301  return( CRYPT_OK );
302 
303  /* Check the private components */
304  if( dlpKey->xLen < bytesToBits( DLPPARAM_MIN_X ) || \
305  dlpKey->xLen > bytesToBits( DLPPARAM_MAX_X ) )
306  return( CRYPT_ARGERROR_STR1 );
307  return( CRYPT_OK );
308  }
309 
310  assert( isReadPtr( keyInfo, sizeof( CRYPT_PKCINFO_RSA ) ) );
311 
312  /* Check the general info and make sure that all required values are
313  initialised */
314  if( rsaKey->isPublicKey != TRUE && rsaKey->isPublicKey != FALSE )
315  return( CRYPT_ARGERROR_STR1 );
316  if( rsaKey->nLen <= 0 || rsaKey->eLen <= 0 || \
317  rsaKey->dLen < 0 || rsaKey->pLen < 0 || rsaKey->qLen < 0 || \
318  rsaKey->uLen < 0 || rsaKey->e1Len < 0 || rsaKey->e2Len < 0 )
319  return( CRYPT_ARGERROR_STR1 );
320 
321  /* Check the public components */
322  if( isShortPKCKey( rsaKey->nLen ) )
323  {
324  /* Special-case handling for insecure-sized public keys */
325  return( CRYPT_ERROR_NOSECURE );
326  }
327  if( rsaKey->nLen < bytesToBits( RSAPARAM_MIN_N ) || \
328  rsaKey->nLen > bytesToBits( RSAPARAM_MAX_N ) || \
329  rsaKey->eLen < bytesToBits( RSAPARAM_MIN_E ) || \
330  rsaKey->eLen > bytesToBits( RSAPARAM_MAX_E ) || \
331  rsaKey->eLen > rsaKey->nLen )
332  return( CRYPT_ARGERROR_STR1 );
333  if( !( rsaKey->n[ bitsToBytes( rsaKey->nLen ) - 1 ] & 0x01 ) || \
334  !( rsaKey->e[ bitsToBytes( rsaKey->eLen ) - 1 ] & 0x01 ) )
335  return( CRYPT_ARGERROR_STR1 ); /* Quick non-prime check */
336  if( rsaKey->isPublicKey )
337  return( CRYPT_OK );
338 
339  /* Check the private components. This can get somewhat complex, possible
340  combinations are:
341 
342  d, p, q
343  d, p, q, u
344  d, p, q, e1, e2, u
345  p, q, e1, e2, u
346 
347  The reason for some of the odder combinations is that some
348  implementations don't use all of the values (for example d isn't
349  needed at all for the CRT shortcut) or recreate them when the key is
350  loaded. If only d, p, and q are present we recreate e1 and e2 from
351  them, we also create u if necessary */
352  if( rsaKey->pLen < bytesToBits( RSAPARAM_MIN_P ) || \
353  rsaKey->pLen > bytesToBits( RSAPARAM_MAX_P ) || \
354  rsaKey->pLen >= rsaKey->nLen || \
355  rsaKey->qLen < bytesToBits( RSAPARAM_MIN_Q ) || \
356  rsaKey->qLen > bytesToBits( RSAPARAM_MAX_Q ) || \
357  rsaKey->qLen >= rsaKey->nLen )
358  return( CRYPT_ARGERROR_STR1 );
359  if( !( rsaKey->p[ bitsToBytes( rsaKey->pLen ) - 1 ] & 0x01 ) || \
360  !( rsaKey->q[ bitsToBytes( rsaKey->qLen ) - 1 ] & 0x01 ) )
361  return( CRYPT_ARGERROR_STR1 ); /* Quick non-prime check */
362  if( rsaKey->dLen <= 0 && rsaKey->e1Len <= 0 )
363  {
364  /* Must have either d or e1 et al */
365  return( CRYPT_ARGERROR_STR1 );
366  }
367  if( rsaKey->dLen > 0 && \
368  ( rsaKey->dLen < bytesToBits( RSAPARAM_MIN_D ) || \
369  rsaKey->dLen > bytesToBits( RSAPARAM_MAX_D ) ) )
370  return( CRYPT_ARGERROR_STR1 );
371  if( rsaKey->e1Len > 0 && \
372  ( rsaKey->e1Len < bytesToBits( RSAPARAM_MIN_EXP1 ) || \
373  rsaKey->e1Len > bytesToBits( RSAPARAM_MAX_EXP1 ) || \
374  rsaKey->e2Len < bytesToBits( RSAPARAM_MIN_EXP2 ) || \
375  rsaKey->e2Len > bytesToBits( RSAPARAM_MAX_EXP2 ) ) )
376  return( CRYPT_ARGERROR_STR1 );
377  if( rsaKey->uLen > 0 && \
378  ( rsaKey->uLen < bytesToBits( RSAPARAM_MIN_U ) || \
379  rsaKey->uLen > bytesToBits( RSAPARAM_MAX_U ) ) )
380  return( CRYPT_ARGERROR_STR1 );
381  return( CRYPT_OK );
382  }
383 #endif /* USE_FIPS140 */
384 
385 /****************************************************************************
386 * *
387 * Key Load Functions *
388 * *
389 ****************************************************************************/
390 
391 /* Load a key into a CONTEXT_INFO structure. These functions are called by
392  the various higher-level functions that move a key into a context */
393 
395 static int loadKeyConvFunction( INOUT CONTEXT_INFO *contextInfoPtr,
396  IN_BUFFER( keyLength ) const void *key,
397  IN_LENGTH_KEY const int keyLength )
398  {
399  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
400 
401  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
402 
403  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
404  REQUIRES( keyLength >= MIN_KEYSIZE && keyLength <= CRYPT_MAX_KEYSIZE );
405 
406  /* If we don't need an IV, record it as being set */
407  if( !needsIV( contextInfoPtr->ctxConv->mode ) || \
408  isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
409  contextInfoPtr->flags |= CONTEXT_FLAG_IV_SET;
410 
411  /* Perform the key setup */
412  return( capabilityInfoPtr->initKeyFunction( contextInfoPtr, key,
413  keyLength ) );
414  }
415 
417 static int loadKeyPKCFunction( INOUT CONTEXT_INFO *contextInfoPtr,
418  IN_BUFFER_OPT( keyLength ) const void *key,
419  IN_LENGTH_SHORT_Z const int keyLength )
420  {
421  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
422  int status;
423 
424  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
425  assert( ( key == NULL ) || isReadPtr( key, keyLength ) );
426 
427  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
428  REQUIRES( ( key == NULL && keyLength == 0 ) || \
429  ( key != NULL && \
430  keyLength > 16 && keyLength < MAX_INTLENGTH_SHORT ) );
431  /* The key data for this function may be NULL if the values
432  have been read from encoded X.509/SSH/SSL/PGP data straight
433  into the context bignums */
434 
435 #ifndef USE_FIPS140
436  /* If we're loading from externally-supplied parameters, make sure that
437  the parameters make sense */
438  if( key != NULL )
439  {
440  status = checkPKCparams( capabilityInfoPtr->cryptAlgo, key );
441  if( cryptStatusError( status ) )
442  return( status );
443  contextInfoPtr->flags |= 0x08; /* Tell lib_kg to check params too */
444  }
445 #endif /* USE_FIPS140 */
446 
447  /* Load the keying info */
448  status = capabilityInfoPtr->initKeyFunction( contextInfoPtr, key,
449  keyLength );
450  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
451  clearTempBignums( contextInfoPtr->ctxPKC );
452  return( status );
453  }
454 
455 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
456 static int loadKeyMacFunction( INOUT CONTEXT_INFO *contextInfoPtr,
457  IN_BUFFER( keyLength ) const void *key,
458  IN_LENGTH_KEY const int keyLength )
459  {
460  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
461  assert( isReadPtr( key, keyLength ) );
462 
463  REQUIRES( contextInfoPtr->type == CONTEXT_MAC );
464  REQUIRES( keyLength >= MIN_KEYSIZE && keyLength <= CRYPT_MAX_KEYSIZE );
465 
466  return( contextInfoPtr->capabilityInfo->initKeyFunction( contextInfoPtr,
467  key, keyLength ) );
468  }
469 
470 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
471 static int loadKeyGenericFunction( INOUT CONTEXT_INFO *contextInfoPtr,
472  IN_BUFFER( keyLength ) const void *key,
473  IN_LENGTH_KEY const int keyLength )
474  {
475  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
476  assert( isReadPtr( key, keyLength ) );
477 
478  REQUIRES( contextInfoPtr->type == CONTEXT_GENERIC );
479  REQUIRES( keyLength >= bitsToBytes( 128 ) && \
480  keyLength <= CRYPT_MAX_KEYSIZE );
481 
482  return( contextInfoPtr->capabilityInfo->initKeyFunction( contextInfoPtr,
483  key, keyLength ) );
484  }
485 
486 /****************************************************************************
487 * *
488 * Key Component Load Functions *
489 * *
490 ****************************************************************************/
491 
492 /* Load an encoded X.509/SSH/SSL/PGP key into a context. This is used for
493  two purposes, to load public key components into native contexts and to
494  save encoded X.509 public-key data for use in certificates associated
495  with non-native contexts held in a device. The latter is required
496  because there's no key data stored with the context itself that we can
497  use to create the SubjectPublicKeyInfo, however it's necessary to have
498  SubjectPublicKeyInfo available for certificate requests/certificates.
499 
500  Normally this is sufficient because cryptlib always generates native
501  contexts for public keys/certificates and for private keys the data is
502  generated in the device with the encoded public components attached to
503  the context as described above. However for DH keys this gets a bit more
504  complex because although the private key is generated in the device, in
505  the case of the DH responder this is only the DH x value, with the
506  parameters (p and g) being supplied externally by the initiator. This
507  means that it's necessary to decode at least some of the public key data
508  in order to create the y value after the x value has been generated in
509  the device. The only situation where this functionality is currently
510  needed is for the SSHv2 code, which at the moment always uses native DH
511  contexts. For this reason we leave off resolving this issue until it's
512  actually required */
513 
515 int setEncodedKey( INOUT CONTEXT_INFO *contextInfoPtr,
517  IN_BUFFER( keyDataLen ) const void *keyData,
518  IN_LENGTH_SHORT const int keyDataLen )
519  {
520  static const int actionFlags = \
521  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_NONE_EXTERNAL ) | \
523  static const int actionFlagsDH = ACTION_PERM_NONE_EXTERNAL_ALL;
524  static const int actionFlagsPGP = \
525  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
526  MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL );
527  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
528  STREAM stream;
530  int status;
531 
532  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
533  assert( isReadPtr( keyData, keyDataLen ) );
534 
535  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
536  REQUIRES( needsKey( contextInfoPtr ) || \
537  ( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) );
538  REQUIRES( keyType == CRYPT_IATTRIBUTE_KEY_SPKI || \
539  keyType == CRYPT_IATTRIBUTE_KEY_PGP || \
540  keyType == CRYPT_IATTRIBUTE_KEY_SSH || \
541  keyType == CRYPT_IATTRIBUTE_KEY_SSH1 || \
542  keyType == CRYPT_IATTRIBUTE_KEY_SSL || \
543  keyType == CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL || \
544  keyType == CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL );
545  REQUIRES( keyDataLen >= 2 && keyDataLen < MAX_INTLENGTH_SHORT );
546  /* Can be very short in the case of ECC curve IDs */
547 
548  /* If the keys are held externally (e.g. in a crypto device), copy the
549  SubjectPublicKeyInfo data in and set up any other information that we
550  may need from it. This information is used when loading a context
551  from a key contained in a device, for which the actual key components
552  aren't directly available in the context but may be needed in the
553  future for things like certificate requests and certificates */
554  if( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY )
555  {
556  REQUIRES( keyType == CRYPT_IATTRIBUTE_KEY_SPKI || \
557  keyType == CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
558 
559  if( ( contextInfoPtr->ctxPKC->publicKeyInfo = \
560  clAlloc( "setEncodedKey", keyDataLen ) ) == NULL )
561  return( CRYPT_ERROR_MEMORY );
562  memcpy( contextInfoPtr->ctxPKC->publicKeyInfo, keyData, keyDataLen );
563  contextInfoPtr->ctxPKC->publicKeyInfoSize = keyDataLen;
564  return( contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr ) );
565  }
566 
567  /* Read the appropriately-formatted key data into the context, applying
568  a lowest-common-denominator set of usage flags to the loaded key */
569  status = attributeToFormatType( keyType, &formatType );
570  if( cryptStatusError( status ) )
571  return( status );
572  sMemConnect( &stream, keyData, keyDataLen );
573  status = contextInfoPtr->ctxPKC->readPublicKeyFunction( &stream,
574  contextInfoPtr, formatType );
575  sMemDisconnect( &stream );
576  if( cryptStatusError( status ) )
577  return( status );
578 
579  /* If it's a partial load of the initial public portions of a private
580  key with further key component operations to follow, there's nothing
581  more to do at this point and we're done */
582  if( keyType == CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL || \
583  keyType == CRYPT_IATTRIBUTE_KEY_PGP_PARTIAL )
584  return( contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr ) );
585 
586  /* Perform an internal load that uses the key component values that
587  we've just read into the context */
588  contextInfoPtr->flags |= CONTEXT_FLAG_ISPUBLICKEY;
589  status = contextInfoPtr->loadKeyFunction( contextInfoPtr, NULL, 0 );
590  if( cryptStatusError( status ) )
591  {
592  /* Map the status to a more appropriate code if necessary */
593  return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
594  }
595  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
596 
597  /* Restrict the key usage to public-key-only actions if necessary. For
598  PGP key loads (which, apart from the restrictions specified with the
599  stored key data aren't constrained by the presence of ACLs in the
600  form of certificates) we allow external usage, for DH (whose keys can be
601  both public and private keys even though technically it's a public
602  key) we allow both encryption and decryption usage, and for public
603  keys read from certificates we allow internal usage only */
604  status = krnlSendMessage( contextInfoPtr->objectHandle,
606  ( keyType == CRYPT_IATTRIBUTE_KEY_PGP ) ? \
607  ( MESSAGE_CAST ) &actionFlagsPGP : \
608  ( isKeyxAlgo( capabilityInfoPtr->cryptAlgo ) ) ? \
609  ( MESSAGE_CAST ) &actionFlagsDH : \
610  ( MESSAGE_CAST ) &actionFlags,
611  CRYPT_IATTRIBUTE_ACTIONPERMS );
612  if( cryptStatusError( status ) )
613  return( status );
614  return( contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr ) );
615  }
616 
617 /* Load the components of a composite PKC key into a context */
618 
619 #ifndef USE_FIPS140
620 
621 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
622 int setKeyComponents( INOUT CONTEXT_INFO *contextInfoPtr,
623  IN_BUFFER( keyDataLen ) const void *keyData,
624  IN_LENGTH_SHORT_MIN( 32 ) const int keyDataLen )
625  {
626  static const int actionFlags = \
627  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL ) | \
628  MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL );
629  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
630  BOOLEAN isPublicKey;
631  int status;
632 
633  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
634  assert( isReadPtr( keyData, keyDataLen ) );
635 
636  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
637  needsKey( contextInfoPtr ) );
638  REQUIRES( keyDataLen == sizeof( CRYPT_PKCINFO_RSA ) || \
639  keyDataLen == sizeof( CRYPT_PKCINFO_DLP ) || \
640  keyDataLen == sizeof( CRYPT_PKCINFO_ECC ) );
641 
642  /* If it's a private key we need to have a key label set before we can
643  continue. The checking for this is a bit complex because at this
644  point all that the context knows is that it's a generic PKC context,
645  but it won't know whether it's a public- or private-key context until
646  the key is actually loaded. To determine what it'll become we look
647  into the key data to see what's being loaded */
648  isPublicKey = isEccAlgo( capabilityInfoPtr->cryptAlgo ) ? \
649  ( ( CRYPT_PKCINFO_ECC * ) keyData )->isPublicKey : \
650  isDlpAlgo( capabilityInfoPtr->cryptAlgo ) ? \
651  ( ( CRYPT_PKCINFO_DLP * ) keyData )->isPublicKey : \
652  ( ( CRYPT_PKCINFO_RSA * ) keyData )->isPublicKey;
653  if( !isPublicKey && contextInfoPtr->labelSize <= 0 )
654  return( CRYPT_ERROR_NOTINITED );
655 
656  /* If it's a dummy object with keys held externally (e.g. in a crypto
657  device) we need a key label set in order to access the object at a
658  later date */
659  if( ( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) && \
660  contextInfoPtr->labelSize <= 0 )
661  return( CRYPT_ERROR_NOTINITED );
662 
663  /* Load the key components into the context */
664  status = contextInfoPtr->loadKeyFunction( contextInfoPtr, keyData,
665  keyDataLen );
666  if( cryptStatusError( status ) )
667  return( status );
668  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET | CONTEXT_FLAG_PBO;
669 
670  /* Restrict the key usage to public-key-only actions if it's a public
671  key. DH keys act as both public and private keys so we don't
672  restrict their usage */
673  if( ( contextInfoPtr->flags & CONTEXT_FLAG_ISPUBLICKEY ) && \
674  ( capabilityInfoPtr->cryptAlgo != CRYPT_ALGO_DH ) )
675  {
676  status = krnlSendMessage( contextInfoPtr->objectHandle,
678  ( MESSAGE_CAST ) &actionFlags,
679  CRYPT_IATTRIBUTE_ACTIONPERMS );
680  if( cryptStatusError( status ) )
681  return( status );
682  }
683 
684  return( contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr ) );
685  }
686 #endif /* !USE_FIPS140 */
687 
688 /****************************************************************************
689 * *
690 * Key Generation Functions *
691 * *
692 ****************************************************************************/
693 
694 /* Generate a key into a CONTEXT_INFO structure */
695 
697 static int generateKeyConvFunction( INOUT CONTEXT_INFO *contextInfoPtr )
698  {
699  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
701  int keyLength = contextInfoPtr->ctxConv->userKeyLength, status;
702 
703  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
704 
705  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
706 
707  /* If there's no key size specified, use the default length */
708  if( keyLength <= 0 )
709  keyLength = capabilityInfoPtr->keySize;
710 
711  /* If the context is implemented in a crypto device it may have the
712  capability to generate the key itself so if there's a keygen function
713  present we call this to generate the key directly into the context
714  rather than generating it ourselves and loading it in. Note that to
715  export this key we'll need to use an exporting context which is also
716  located in the device, since we can't access it externally */
717  if( capabilityInfoPtr->generateKeyFunction != NULL )
718  {
719  return( capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
720  bytesToBits( keyLength ) ) );
721  }
722 
723  /* Generate a random session key into the context. We load the random
724  data directly into the pagelocked encryption context and pass that in
725  as the key buffer, loadKey() won't copy the data if src == dest */
726  setMessageData( &msgData, contextInfoPtr->ctxConv->userKey, keyLength );
728  &msgData, CRYPT_IATTRIBUTE_RANDOM );
729  if( cryptStatusError( status ) )
730  return( status );
731  return( contextInfoPtr->loadKeyFunction( contextInfoPtr,
732  contextInfoPtr->ctxConv->userKey, keyLength ) );
733  }
734 
736 static int generateKeyPKCFunction( INOUT CONTEXT_INFO *contextInfoPtr )
737  {
738  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
739  int keyLength = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
740  int status;
741 
742  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
743 
744  REQUIRES( contextInfoPtr->type == CONTEXT_PKC );
745 
746  /* Set up supplementary key information */
747  contextInfoPtr->ctxPKC->pgpCreationTime = getApproxTime();
748 
749  /* If there's no key size specified, use the default length */
750  if( keyLength <= 0 )
751  keyLength = capabilityInfoPtr->keySize;
752 
753  /* Generate the key into the context */
754  status = capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
755  bytesToBits( keyLength ) );
756  if( !( contextInfoPtr->flags & CONTEXT_FLAG_DUMMY ) )
757  clearTempBignums( contextInfoPtr->ctxPKC );
758  if( cryptStatusError( status ) )
759  return( status );
760  return( contextInfoPtr->ctxPKC->calculateKeyIDFunction( contextInfoPtr ) );
761  }
762 
764 static int generateKeyMacFunction( INOUT CONTEXT_INFO *contextInfoPtr )
765  {
766  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
768  int keyLength = contextInfoPtr->ctxMAC->userKeyLength, status;
769 
770  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
771 
772  REQUIRES( contextInfoPtr->type == CONTEXT_MAC );
773 
774  /* If there's no key size specified, use the default length */
775  if( keyLength <= 0 )
776  keyLength = capabilityInfoPtr->keySize;
777 
778  /* If the context is implemented in a crypto device it may have the
779  capability to generate the key itself so if there's a keygen function
780  present we call this to generate the key directly into the context
781  rather than generating it ourselves and loading it in. Note that to
782  export this key we'll need to use an exporting context which is also
783  located in the device, since we can't access it externally */
784  if( capabilityInfoPtr->generateKeyFunction != NULL )
785  {
786  return( capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
787  bytesToBits( keyLength ) ) );
788  }
789 
790  /* Generate a random session key into the context. We load the random
791  data directly into the pagelocked encryption context and pass that in
792  as the key buffer, loadKey() won't copy the data if src == dest */
793  setMessageData( &msgData, contextInfoPtr->ctxMAC->userKey, keyLength );
795  &msgData, CRYPT_IATTRIBUTE_RANDOM );
796  if( cryptStatusError( status ) )
797  return( status );
798  return( contextInfoPtr->loadKeyFunction( contextInfoPtr,
799  contextInfoPtr->ctxMAC->userKey, keyLength ) );
800  }
801 
803 static int generateKeyGenericFunction( INOUT CONTEXT_INFO *contextInfoPtr )
804  {
805  const CAPABILITY_INFO *capabilityInfoPtr = contextInfoPtr->capabilityInfo;
807  int keyLength = contextInfoPtr->ctxGeneric->genericSecretLength, status;
808 
809  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
810 
811  REQUIRES( contextInfoPtr->type == CONTEXT_GENERIC );
812 
813  /* If there's no key size specified, use the default length */
814  if( keyLength <= 0 )
815  keyLength = capabilityInfoPtr->keySize;
816 
817  /* If the context is implemented in a crypto device it may have the
818  capability to generate the key itself so if there's a keygen function
819  present we call this to generate the key directly into the context
820  rather than generating it ourselves and loading it in. Note that to
821  export this key we'll need to use an exporting context which is also
822  located in the device, since we can't access it externally */
823  if( capabilityInfoPtr->generateKeyFunction != NULL )
824  {
825  return( capabilityInfoPtr->generateKeyFunction( contextInfoPtr,
826  bytesToBits( keyLength ) ) );
827  }
828 
829  /* Generate a random session key into the context. We load the random
830  data directly into the pagelocked encryption context and pass that in
831  as the key buffer, loadKey() won't copy the data if src == dest */
832  setMessageData( &msgData, contextInfoPtr->ctxGeneric->genericSecret, keyLength );
834  &msgData, CRYPT_IATTRIBUTE_RANDOM );
835  if( cryptStatusError( status ) )
836  return( status );
837  return( contextInfoPtr->loadKeyFunction( contextInfoPtr,
838  contextInfoPtr->ctxGeneric->genericSecret, keyLength ) );
839  }
840 
841 /****************************************************************************
842 * *
843 * Key Derivation Functions *
844 * *
845 ****************************************************************************/
846 
847 /* Derive a key into a context from a user-supplied keying value */
848 
849 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
850 int deriveKey( INOUT CONTEXT_INFO *contextInfoPtr,
851  IN_BUFFER( keyValueLen ) const void *keyValue,
852  IN_LENGTH_SHORT const int keyValueLen )
853  {
855  static const MAP_TABLE mapTbl[] = {
861  };
862  int hmacAlgo = ( contextInfoPtr->type == CONTEXT_CONV ) ? \
863  contextInfoPtr->ctxConv->keySetupAlgorithm : \
864  contextInfoPtr->ctxMAC->keySetupAlgorithm;
865  int value = DUMMY_INIT, status;
866 
867  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
868  assert( isReadPtr( keyValue, keyValueLen ) );
869 
870  REQUIRES( contextInfoPtr->type == CONTEXT_CONV || \
871  contextInfoPtr->type == CONTEXT_MAC );
872  REQUIRES( needsKey( contextInfoPtr ) );
873  REQUIRES( keyValueLen > 0 && keyValueLen < MAX_INTLENGTH_SHORT );
874 
875  /* If it's a persistent context we need to have a key label set before
876  we can continue */
877  if( ( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) && \
878  contextInfoPtr->labelSize <= 0 )
879  return( CRYPT_ERROR_NOTINITED );
880 
881  /* Set up various derivation parameters if they're not already set */
882  if( hmacAlgo == CRYPT_ALGO_NONE )
883  {
884  status = krnlSendMessage( contextInfoPtr->ownerHandle,
885  IMESSAGE_GETATTRIBUTE, &hmacAlgo,
887  if( cryptStatusOK( status ) )
888  status = mapValue( hmacAlgo, &value, mapTbl,
889  FAILSAFE_ARRAYSIZE( mapTbl, MAP_TABLE ) );
890  if( cryptStatusError( status ) )
891  return( status );
892  hmacAlgo = value;
893  }
894  if( contextInfoPtr->type == CONTEXT_CONV )
895  {
896  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
897  int keySize = convInfo->userKeyLength;
898 
899  keySize = ( convInfo->userKeyLength > 0 ) ? \
900  convInfo->userKeyLength : \
901  contextInfoPtr->capabilityInfo->keySize;
902  if( convInfo->saltLength <= 0 )
903  {
904  MESSAGE_DATA nonceMsgData;
905 
906  setMessageData( &nonceMsgData, convInfo->salt, PKCS5_SALT_SIZE );
908  IMESSAGE_GETATTRIBUTE_S, &nonceMsgData,
909  CRYPT_IATTRIBUTE_RANDOM_NONCE );
910  if( cryptStatusError( status ) )
911  return( status );
912  convInfo->saltLength = PKCS5_SALT_SIZE;
913  }
914  convInfo->keySetupAlgorithm = hmacAlgo;
915  setMechanismDeriveInfo( &mechanismInfo, convInfo->userKey, keySize,
916  keyValue, keyValueLen,
917  convInfo->keySetupAlgorithm,
918  convInfo->salt, convInfo->saltLength,
919  convInfo->keySetupIterations );
920  if( mechanismInfo.iterations <= 0 )
921  {
922  status = krnlSendMessage( contextInfoPtr->ownerHandle,
924  &mechanismInfo.iterations,
926  if( cryptStatusError( status ) )
927  return( status );
928  convInfo->keySetupIterations = mechanismInfo.iterations;
929  }
930  }
931  else
932  {
933  MAC_INFO *macInfo = contextInfoPtr->ctxMAC;
934  int keySize;
935 
936  keySize = ( macInfo->userKeyLength > 0 ) ? \
937  macInfo->userKeyLength : \
938  contextInfoPtr->capabilityInfo->keySize;
939  if( macInfo->saltLength <= 0 )
940  {
941  MESSAGE_DATA nonceMsgData;
942 
943  setMessageData( &nonceMsgData, macInfo->salt, PKCS5_SALT_SIZE );
945  IMESSAGE_GETATTRIBUTE_S, &nonceMsgData,
946  CRYPT_IATTRIBUTE_RANDOM_NONCE );
947  if( cryptStatusError( status ) )
948  return( status );
949  macInfo->saltLength = PKCS5_SALT_SIZE;
950  }
951  contextInfoPtr->ctxConv->keySetupAlgorithm = hmacAlgo;
952  setMechanismDeriveInfo( &mechanismInfo, macInfo->userKey, keySize,
953  keyValue, keyValueLen,
954  macInfo->keySetupAlgorithm,
955  macInfo->salt, macInfo->saltLength,
956  macInfo->keySetupIterations );
957  if( mechanismInfo.iterations <= 0 )
958  {
959  status = krnlSendMessage( contextInfoPtr->ownerHandle,
961  &mechanismInfo.iterations,
963  if( cryptStatusError( status ) )
964  return( status );
965  macInfo->keySetupIterations = mechanismInfo.iterations;
966  }
967  }
968 
969  /* Turn the user key into an encryption context key and load the key
970  into the context */
972  &mechanismInfo, MECHANISM_DERIVE_PKCS5 );
973  if( cryptStatusOK( status ) )
974  status = contextInfoPtr->loadKeyFunction( contextInfoPtr,
975  mechanismInfo.dataOut,
976  mechanismInfo.dataOutLength );
977  if( cryptStatusOK( status ) )
978  contextInfoPtr->flags |= CONTEXT_FLAG_KEY_SET;
979  zeroise( &mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) );
980 
981  return( status );
982  }
983 
984 /****************************************************************************
985 * *
986 * Context Access Routines *
987 * *
988 ****************************************************************************/
989 
990 STDC_NONNULL_ARG( ( 1 ) ) \
991 void initKeyHandling( INOUT CONTEXT_INFO *contextInfoPtr )
992  {
993  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
994 
995  /* Set the access method pointers */
996  switch( contextInfoPtr->type )
997  {
998  case CONTEXT_CONV:
999  contextInfoPtr->loadKeyFunction = loadKeyConvFunction;
1000  contextInfoPtr->generateKeyFunction = generateKeyConvFunction;
1001  break;
1002 
1003  case CONTEXT_PKC:
1004  contextInfoPtr->loadKeyFunction = loadKeyPKCFunction;
1005  contextInfoPtr->generateKeyFunction = generateKeyPKCFunction;
1006  break;
1007 
1008  case CONTEXT_MAC:
1009  contextInfoPtr->loadKeyFunction = loadKeyMacFunction;
1010  contextInfoPtr->generateKeyFunction = generateKeyMacFunction;
1011  break;
1012 
1013  case CONTEXT_GENERIC:
1014  contextInfoPtr->loadKeyFunction = loadKeyGenericFunction;
1015  contextInfoPtr->generateKeyFunction = generateKeyGenericFunction;
1016  break;
1017 
1018  default:
1019  retIntError_Void();
1020  }
1021  }