cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
pkcs11_pkc.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib PKCS #11 PKC Routines *
4 * Copyright Peter Gutmann 1998-2006 *
5 * *
6 ****************************************************************************/
7 
8 #define PKC_CONTEXT /* Tell context.h that we're working with PKC contexts */
9 #if defined( INC_ALL )
10  #include "crypt.h"
11  #include "context.h"
12  #include "device.h"
13  #include "pkcs11_api.h"
14  #include "asn1.h"
15 #else
16  #include "crypt.h"
17  #include "context/context.h"
18  #include "device/device.h"
19  #include "device/pkcs11_api.h"
20  #include "enc_dec/asn1.h"
21 #endif /* Compiler-specific includes */
22 
23 #ifdef USE_PKCS11
24 
25 /****************************************************************************
26 * *
27 * Utility Routines *
28 * *
29 ****************************************************************************/
30 
31 /* Read an attribute value, used to read public-key components. The odd
32  two-phase read is necessary for buggy implementations that fail if the
33  given size isn't exactly the same as the data size */
34 
35 static int readAttributeValue( PKCS11_INFO *pkcs11Info,
36  const CK_OBJECT_HANDLE hObject,
37  const CK_ATTRIBUTE_TYPE attrType,
38  void *buffer, const int bufMaxLen,
39  int *length )
40  {
41  CK_ATTRIBUTE attrTemplate = { attrType, NULL_PTR, bufMaxLen };
42  CK_RV status;
43  int cryptStatus;
44 
45  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
46  assert( isWritePtr( buffer, bufMaxLen ) );
47  assert( isWritePtr( length, sizeof( int ) ) );
48 
49  /* Clear return value */
50  memset( buffer, 0, min( 16, bufMaxLen ) );
51  *length = CRYPT_ERROR;
52 
53  status = C_GetAttributeValue( pkcs11Info->hSession, hObject,
54  &attrTemplate, 1 );
55  if( status == CKR_OK )
56  {
57  attrTemplate.pValue = buffer;
58  status = C_GetAttributeValue( pkcs11Info->hSession, hObject,
59  &attrTemplate, 1 );
60  }
61  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
62  if( cryptStatusOK( status ) )
63  *length = attrTemplate.ulValueLen;
64  return( cryptStatus );
65  }
66 
67 /****************************************************************************
68 * *
69 * Capability Interface Routines *
70 * *
71 ****************************************************************************/
72 
73 /* Sign data, check a signature. We use Sign and Verify rather than the
74  xxxRecover variants because there's no need to use Recover, and because
75  many implementations don't do Recover */
76 
77 static int genericSign( PKCS11_INFO *pkcs11Info,
79  const CK_MECHANISM *pMechanism,
80  const void *inBuffer, const int inLength,
81  void *outBuffer, const int outLength )
82  {
83  CK_ULONG resultLen = outLength;
84  CK_RV status;
85 
86  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
87  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
88  assert( isReadPtr( inBuffer, inLength ) );
89  assert( isWritePtr( outBuffer, outLength ) );
90 
91  REQUIRES( inLength > 0 && inLength < MAX_INTLENGTH_SHORT );
92  REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
93 
94  /* If we're currently in the middle of a multi-stage sign operation we
95  can't start a new one. We have to perform this tracking explicitly
96  since PKCS #11 only allows one multi-stage operation per session */
97  if( pkcs11Info->hActiveSignObject != CK_OBJECT_NONE )
98  return( CRYPT_ERROR_INCOMPLETE );
99 
100  status = C_SignInit( pkcs11Info->hSession,
101  ( CK_MECHANISM_PTR ) pMechanism,
102  contextInfoPtr->deviceObject );
103  if( status == CKR_OK )
104  status = C_Sign( pkcs11Info->hSession, ( CK_BYTE_PTR ) inBuffer,
105  inLength, outBuffer, &resultLen );
106  if( status != CKR_OK )
107  return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
108 
109  return( CRYPT_OK );
110  }
111 
112 static int genericVerify( PKCS11_INFO *pkcs11Info,
113  CONTEXT_INFO *contextInfoPtr,
114  const CK_MECHANISM *pMechanism,
115  const void *inBuffer, const int inLength,
116  void *outBuffer, const int outLength )
117  {
118  CK_RV status;
119 
120  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
121  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
122  assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
123  assert( isReadPtr( inBuffer, inLength ) );
124  assert( isWritePtr( outBuffer, outLength ) );
125 
126  REQUIRES( inLength > 0 && inLength < MAX_INTLENGTH_SHORT );
127  REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
128 
129  /* If we're currently in the middle of a multi-stage sign operation we
130  can't start a new one. We have to perform this tracking explicitly
131  since PKCS #11 only allows one multi-stage operation per session */
132  if( pkcs11Info->hActiveSignObject != CK_OBJECT_NONE )
133  return( CRYPT_ERROR_INCOMPLETE );
134 
135  status = C_VerifyInit( pkcs11Info->hSession,
136  ( CK_MECHANISM_PTR ) pMechanism,
137  contextInfoPtr->deviceObject );
138  if( status == CKR_OK )
139  status = C_Verify( pkcs11Info->hSession, ( CK_BYTE_PTR ) inBuffer,
140  inLength, outBuffer, outLength );
141  if( status != CKR_OK )
142  return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
143 
144  return( CRYPT_OK );
145  }
146 
147 /* Encrypt, decrypt */
148 
149 static int genericEncrypt( PKCS11_INFO *pkcs11Info,
150  CONTEXT_INFO *contextInfoPtr,
151  const CK_MECHANISM *pMechanism, void *buffer,
152  const int length, const int outLength )
153  {
154  CK_ULONG resultLen = outLength;
155  CK_RV status;
156 
157  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
158  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
159  assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
160  assert( isWritePtr( buffer, length ) );
161  assert( isWritePtr( buffer, outLength ) );
162 
163  REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );
164  REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
165 
166  status = C_EncryptInit( pkcs11Info->hSession,
167  ( CK_MECHANISM_PTR ) pMechanism,
168  contextInfoPtr->deviceObject );
169  if( status == CKR_OK )
170  status = C_Encrypt( pkcs11Info->hSession, buffer, length,
171  buffer, &resultLen );
172  if( status != CKR_OK )
173  return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
174 
175  /* When performing RSA operations some buggy implementations perform
176  leading-zero trunction, so we restore leading zeroes if necessary */
177  if( ( pMechanism->mechanism == CKM_RSA_X_509 || \
178  pMechanism->mechanism == CKM_RSA_PKCS ) && \
179  ( int ) resultLen < length )
180  {
181  const int delta = length - resultLen;
182 
183  REQUIRES( rangeCheck( delta, resultLen, length ) );
184  memmove( ( BYTE * ) buffer + delta, buffer, resultLen );
185  memset( buffer, 0, delta );
186  }
187 
188  return( CRYPT_OK );
189  }
190 
191 static int genericDecrypt( PKCS11_INFO *pkcs11Info,
192  CONTEXT_INFO *contextInfoPtr,
193  const CK_MECHANISM *pMechanism, void *buffer,
194  const int length, int *resultLength )
195  {
196  CK_ULONG resultLen = length;
197  CK_RV status;
198 
199  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
200  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
201  assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
202  assert( isWritePtr( buffer, length ) );
203  assert( isWritePtr( resultLength, sizeof( int ) ) );
204 
205  REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );
206 
207  status = C_DecryptInit( pkcs11Info->hSession,
208  ( CK_MECHANISM_PTR ) pMechanism,
209  contextInfoPtr->deviceObject );
210  if( status == CKR_OK )
211  status = C_Decrypt( pkcs11Info->hSession, buffer, length,
212  buffer, &resultLen );
213  if( status == CKR_KEY_FUNCTION_NOT_PERMITTED )
214  {
215  static const CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
216  static const CK_KEY_TYPE secretKeyType = CKK_GENERIC_SECRET;
217  static const CK_BBOOL bTrue = TRUE;
218  CK_ATTRIBUTE symTemplate[] = {
219  { CKA_CLASS, ( CK_VOID_PTR ) &secretKeyClass, sizeof( CK_OBJECT_CLASS ) },
220  { CKA_KEY_TYPE, ( CK_VOID_PTR ) &secretKeyType, sizeof( CK_KEY_TYPE ) },
221  { CKA_EXTRACTABLE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
222  { CKA_VALUE_LEN, &resultLen, sizeof( CK_ULONG ) }
223  };
224  CK_OBJECT_HANDLE hSymKey;
225 
226  /* If a straight decrypt isn't allowed, try an unwrap instead and
227  then export the key. This works because we're using the same
228  mechanism as for decrypt and converting the entire "unwrapped key"
229  into a generic secret key that we then extract, which is the
230  same as doing a straight decrypt of the data (this sort of thing
231  should require a note from your mother before you're allowed to do
232  it). The reason why it's done in this roundabout manner is that
233  this is what Netscape tries first, so people doing a minimal
234  implementation do this first and don't bother with anything else.
235  Note that doing it this way is rather slower than a straight
236  decrypt, which is why we try for decrypt first */
237  status = C_UnwrapKey( pkcs11Info->hSession,
238  ( CK_MECHANISM_PTR ) pMechanism,
239  contextInfoPtr->deviceObject, buffer, length,
240  symTemplate, 4, &hSymKey );
241  if( status == CKR_OK )
242  {
243  CK_ATTRIBUTE valueTemplate[] = { CKA_VALUE, buffer, length };
244 
245  status = C_GetAttributeValue( pkcs11Info->hSession,
246  hSymKey, valueTemplate, 1 );
247  if( status == CKR_OK )
248  resultLen = valueTemplate[ 0 ].ulValueLen;
249  C_DestroyObject( pkcs11Info->hSession, hSymKey );
250  }
251  }
252  if( status != CKR_OK )
253  return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
254 
255  /* When performing raw RSA operations some buggy implementations perform
256  leading-zero trunction, so we restore leading zeroes if necessary. We
257  can't do the restore with the PKCS mechanism since it always returns a
258  result length shorter than the input length */
259  if( pMechanism->mechanism == CKM_RSA_X_509 && \
260  ( int ) resultLen < length )
261  {
262  const int delta = length - resultLen;
263 
264  REQUIRES( rangeCheck( delta, resultLen, length ) );
265  memmove( ( BYTE * ) buffer + delta, buffer, resultLen );
266  memset( buffer, 0, delta );
267  resultLen = length;
268  }
269 
270  /* Some mechanisms change the data length, in which case we need to tell
271  the caller how much was actually returned */
272  if( resultLength != NULL )
273  *resultLength = ( int ) resultLen;
274  return( CRYPT_OK );
275  }
276 
277 /****************************************************************************
278 * *
279 * DH Mapping Functions *
280 * *
281 ****************************************************************************/
282 
283 /* DH algorithm-specific mapping functions. These work somewhat differently
284  from the other PKC functions because DH objects are ephemeral, the only
285  fixed values being p and g. In addition there's no real concept of
286  public and private keys, only an object where the CKA_VALUE attribute
287  contains y (nominally the public key) and one where it contains x
288  (nominally the private key). The use of DH objects then is as follows:
289 
290  load/genkey: genkey with supplied p and g to produce x and y values;
291  save "public key" (y) as altObjectHandle;
292 
293  DH phase 1: return public key CKA_VALUE (= y);
294 
295  DH phase 2: derive using private key, y' = mechanism parameters */
296 
297 int dhSetPublicComponents( PKCS11_INFO *pkcs11Info,
299  const CK_OBJECT_HANDLE hDhKey,
300  const void *q, const int qLen )
301  {
302  BYTE p[ CRYPT_MAX_PKCSIZE + 8 ], g[ CRYPT_MAX_PKCSIZE + 8 ];
303  BYTE y[ CRYPT_MAX_PKCSIZE + 8 ];
304  BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ];
306  int pLen, gLen = DUMMY_INIT, yLen = DUMMY_INIT, keyDataSize, cryptStatus;
307 
308  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
309  assert( isReadPtr( q, qLen ) );
310 
311  REQUIRES( isHandleRangeValid( iCryptContext ) );
312  REQUIRES( qLen > 0 && qLen <= CRYPT_MAX_PKCSIZE );
313 
314  /* Get the public key components from the device */
315  cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_PRIME,
316  p, CRYPT_MAX_PKCSIZE, &pLen );
317  if( cryptStatusOK( cryptStatus ) )
318  cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_BASE,
319  g, CRYPT_MAX_PKCSIZE, &gLen );
320  if( cryptStatusOK( cryptStatus ) )
321  cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_VALUE,
322  y, CRYPT_MAX_PKCSIZE, &yLen );
323  if( cryptStatusError( cryptStatus ) )
324  return( cryptStatus );
325 
326  /* Send the public key data to the context. We send the keying
327  information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
328  CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
329  into the high state. We don't want to do this because we're already
330  in the middle of processing a message that does this on completion,
331  all that we're doing here is sending in encoded public key data for
332  use by objects such as certificates */
333  cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 3,
334  &keyDataSize, CRYPT_ALGO_DH,
335  p, pLen, g, gLen, q, qLen, y, yLen );
336  if( cryptStatusOK( cryptStatus ) )
337  {
338  setMessageData( &msgData, keyDataBuffer, keyDataSize );
339  cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
340  &msgData,
341  CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
342  }
343  return( cryptStatus );
344  }
345 
346 static int dhInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
347  const int keyLength )
348  {
349  static const CK_MECHANISM mechanism = { CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
350  static const CK_BBOOL bTrue = TRUE;
351  CK_ATTRIBUTE privateKeyTemplate[] = {
352  { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
353  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
354  { CKA_DERIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
355  };
356  CK_ATTRIBUTE publicKeyTemplate[] = {
357  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
358  { CKA_DERIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
359  { CKA_PRIME, NULL, 0 },
360  { CKA_BASE, NULL, 0 },
361  };
362  CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
363  CK_RV status;
364  const CRYPT_PKCINFO_DLP *dhKey = ( CRYPT_PKCINFO_DLP * ) key;
365  CRYPT_DEVICE iCryptDevice;
366  PKCS11_INFO *pkcs11Info;
367  int cryptStatus;
368 
369  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
370  assert( isReadPtr( key, keyLength ) );
371 
372  REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_DLP ) );
373 
374  /* Get the information for the device associated with this context */
375  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
376  &iCryptDevice, &pkcs11Info );
377  if( cryptStatusError( cryptStatus ) )
378  return( cryptStatus );
379 
380  /* Generate the keys. We can't set CKA_SENSITIVE for the private key
381  because although this is appropriate for the key (we don't want people
382  extracting the x value), some implementations carry it over to the
383  derived key in phase 2 and make that non-extractable as well */
384  publicKeyTemplate[ 2 ].pValue = ( CK_VOID_PTR ) dhKey->p;
385  publicKeyTemplate[ 2 ].ulValueLen = bitsToBytes( dhKey->pLen );
386  publicKeyTemplate[ 3 ].pValue = ( CK_VOID_PTR ) dhKey->g;
387  publicKeyTemplate[ 3 ].ulValueLen = bitsToBytes( dhKey->gLen );
388  status = C_GenerateKeyPair( pkcs11Info->hSession,
389  ( CK_MECHANISM_PTR ) &mechanism,
390  ( CK_ATTRIBUTE_PTR ) publicKeyTemplate, 4,
391  ( CK_ATTRIBUTE_PTR ) privateKeyTemplate, 3,
392  &hPublicKey, &hPrivateKey );
393  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
394  if( cryptStatusError( cryptStatus ) )
395  {
396  krnlReleaseObject( iCryptDevice );
397  return( cryptStatus );
398  }
399 
400  /* Send the keying information to the context */
401  cryptStatus = dhSetPublicComponents( pkcs11Info,
402  contextInfoPtr->objectHandle,
403  hPublicKey, dhKey->q,
404  bitsToBytes( dhKey->qLen ) );
405  if( cryptStatusError( cryptStatus ) )
406  {
407  krnlReleaseObject( iCryptDevice );
408  return( cryptStatus );
409  }
410 
411  /* Remember what we've set up */
413  ( MESSAGE_CAST ) &hPrivateKey,
414  CRYPT_IATTRIBUTE_DEVICEOBJECT );
415  contextInfoPtr->altDeviceObject = hPublicKey;
416  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
417  krnlReleaseObject( iCryptDevice );
418  return( cryptStatus );
419  }
420 
421 static int dhGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
422  {
423  CRYPT_PKCINFO_DLP dhKey;
424  MESSAGE_CREATEOBJECT_INFO createInfo;
426  BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
427  STREAM stream;
428  int length, cryptStatus;
429 
430  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
431 
432  REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
433  keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
434 
435  /* CKM_DH_KEY_PAIR_GEN is really a Clayton's key generation mechanism
436  since it doesn't actually generate the p, g values. Because of this
437  we have to generate half the key ourselves in a native context, then
438  copy portions from the native context over in flat form and complete
439  the keygen via the device. The easiest way to do this is to create a
440  native DH context, generate a key, grab the public portions, and
441  destroy the context again. Since the keygen can take awhile and
442  doesn't require the device, we do it before we grab the device */
444  cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
445  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
447  if( cryptStatusError( cryptStatus ) )
448  return( cryptStatus );
449  setMessageData( &msgData, label, 8 );
451  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
453  &msgData, CRYPT_CTXINFO_LABEL );
454  cryptStatus = krnlSendNotifier( createInfo.cryptHandle,
456  if( cryptStatusOK( cryptStatus ) )
457  {
458  setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
459  cryptStatus = krnlSendMessage( createInfo.cryptHandle,
460  IMESSAGE_GETATTRIBUTE_S, &msgData,
461  CRYPT_IATTRIBUTE_KEY_SPKI );
462  }
464  if( cryptStatusError( cryptStatus ) )
465  return( cryptStatus );
466 
467  /* Set up the public key information by extracting the flat values from
468  the SubjectPublicKeyInfo. Note that the data used is represented in
469  DER-canonical form, there may be PKCS #11 implementations that can't
470  handle this (for example they may require p to be zero-padded to make
471  it exactly n bytes rather than (say) n - 1 bytes if the high byte is
472  zero) */
474  sMemConnect( &stream, pubkeyBuffer, msgData.length );
475  readSequence( &stream, NULL ); /* SEQUENCE */
476  readSequence( &stream, NULL ); /* SEQUENCE */
477  readUniversal( &stream ); /* OID */
478  readSequence( &stream, NULL ); /* SEQUENCE */
479  readGenericHole( &stream, &length, 16, BER_INTEGER ); /* p */
480  cryptStatus = sread( &stream, dhKey.p, length );
481  if( cryptStatusOK( cryptStatus ) )
482  {
483  dhKey.pLen = bytesToBits( length );
484  readGenericHole( &stream, &length, 16, BER_INTEGER ); /* q */
485  cryptStatus = sread( &stream, dhKey.q, length );
486  }
487  if( cryptStatusOK( cryptStatus ) )
488  {
489  dhKey.qLen = bytesToBits( length );
490  readGenericHole( &stream, &length, 16, BER_INTEGER ); /* g */
491  cryptStatus = sread( &stream, dhKey.g, length );
492  }
493  if( cryptStatusOK( cryptStatus ) )
494  dhKey.gLen = bytesToBits( length );
495  sMemDisconnect( &stream );
496  REQUIRES( cryptStatusOK( cryptStatus ) );
497 
498  /* From here on it's a standard DH key load */
499  return( dhInitKey( contextInfoPtr, &dhKey, sizeof( CRYPT_PKCINFO_DLP ) ) );
500  }
501 
502 static int dhEncrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
503  {
504  CK_ATTRIBUTE yValueTemplate = { CKA_VALUE, NULL, CRYPT_MAX_PKCSIZE };
505  CK_RV status;
506  CRYPT_DEVICE iCryptDevice;
507  PKCS11_INFO *pkcs11Info;
508  KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
509  int cryptStatus;
510 
511  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
512  assert( isWritePtr( buffer, length ) );
513 
514  REQUIRES( length == sizeof( KEYAGREE_PARAMS ) );
515 
516  /* Get the information for the device associated with this context */
517  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
518  &iCryptDevice, &pkcs11Info );
519  if( cryptStatusError( cryptStatus ) )
520  return( cryptStatus );
521 
522  /* Get the y value from phase 1 of the DH key agreement (generated when
523  the key was loaded/generated) from the device. The odd two-phase y
524  value read is necessary for buggy implementations that fail if the
525  given size isn't exactly the same as the data size */
526  status = C_GetAttributeValue( pkcs11Info->hSession,
527  contextInfoPtr->altDeviceObject,
528  &yValueTemplate, 1 );
529  if( status == CKR_OK )
530  {
531  yValueTemplate.pValue = keyAgreeParams->publicValue;
532  status = C_GetAttributeValue( pkcs11Info->hSession,
533  contextInfoPtr->altDeviceObject,
534  &yValueTemplate, 1 );
535  }
536  if( status == CKR_OK )
537  keyAgreeParams->publicValueLen = yValueTemplate.ulValueLen;
538  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
539  krnlReleaseObject( iCryptDevice );
540  return( cryptStatus );
541  }
542 
543 static int dhDecrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
544  {
545  static const CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
546  static const CK_KEY_TYPE secretKeyType = CKK_GENERIC_SECRET;
547  static const CK_BBOOL bTrue = TRUE;
548  CK_MECHANISM mechanism = { CKM_DH_PKCS_DERIVE, NULL_PTR, 0 };
550  CK_ATTRIBUTE symTemplate[] = {
551  { CKA_CLASS, ( CK_VOID_PTR ) &secretKeyClass, sizeof( CK_OBJECT_CLASS ) },
552  { CKA_KEY_TYPE, ( CK_VOID_PTR ) &secretKeyType, sizeof( CK_KEY_TYPE ) },
553  { CKA_EXTRACTABLE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
554  { CKA_VALUE_LEN, &valueLen, sizeof( CK_ULONG ) }
555  };
556  CK_OBJECT_HANDLE hSymKey;
557  CK_RV status;
558  CRYPT_DEVICE iCryptDevice;
559  PKCS11_INFO *pkcs11Info;
560  KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
561  int cryptStatus;
562 
563  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
564  assert( isWritePtr( buffer, length ) );
565 
566  REQUIRES( length == sizeof( KEYAGREE_PARAMS ) );
567  REQUIRES( keyAgreeParams->publicValue != NULL && \
568  keyAgreeParams->publicValueLen >= MIN_PKCSIZE && \
569  keyAgreeParams->publicValueLen < MAX_INTLENGTH_SHORT );
570 
571  /* Get the information for the device associated with this context */
572  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
573  &iCryptDevice, &pkcs11Info );
574  if( cryptStatusError( cryptStatus ) )
575  return( cryptStatus );
576 
577  /* Use the supplied y value to perform phase 2 of the DH key agreement.
578  Since PKCS #11 mechanisms don't allow the resulting data to be
579  returned directly, we move it into a generic secret-key object and
580  then read it from that */
581  valueLen = keyAgreeParams->publicValueLen; /* symTemplate[4].pValue */
582  mechanism.pParameter = keyAgreeParams->publicValue;
583  mechanism.ulParameterLen = keyAgreeParams->publicValueLen;
584  status = C_DeriveKey( pkcs11Info->hSession, &mechanism,
585  contextInfoPtr->deviceObject,
586  symTemplate, 4, &hSymKey );
587  if( status == CKR_OK )
588  {
589  CK_ATTRIBUTE valueTemplate[] = { CKA_VALUE, keyAgreeParams->wrappedKey,
590  valueLen };
591 
592  status = C_GetAttributeValue( pkcs11Info->hSession,
593  hSymKey, valueTemplate, 1 );
594  if( status == CKR_OK )
595  keyAgreeParams->wrappedKeyLen = valueTemplate[ 0 ].ulValueLen;
596  C_DestroyObject( pkcs11Info->hSession, hSymKey );
597  }
598  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
599  krnlReleaseObject( iCryptDevice );
600  return( cryptStatus );
601  }
602 
603 /****************************************************************************
604 * *
605 * RSA Mapping Functions *
606 * *
607 ****************************************************************************/
608 
609 /* RSA algorithm-specific mapping functions. Externally we always appear to
610  use the X.509 (raw) mechanism for the encrypt/decrypt/sign/verify
611  functions since cryptlib does its own padding (with workarounds for
612  various bugs and peculiarities). Internally however we have to use the
613  PKCS mechanism since some implementations don't support the X.509
614  mechanism, and add/remove the padding to fake out the presence of a raw
615  RSA mechanism */
616 
617 int rsaSetPublicComponents( PKCS11_INFO *pkcs11Info,
618  const CRYPT_CONTEXT iCryptContext,
619  const CK_OBJECT_HANDLE hRsaKey,
620  const BOOLEAN nativeContext )
621  {
622  BYTE n[ CRYPT_MAX_PKCSIZE + 8 ], e[ CRYPT_MAX_PKCSIZE + 8 ];
623  BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 2 ) + 8 ];
625  int nLen, eLen = DUMMY_INIT, keyDataSize, cryptStatus;
626 
627  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
628 
629  REQUIRES( isHandleRangeValid( iCryptContext ) );
630 
631  /* Get the public key components from the device */
632  cryptStatus = readAttributeValue( pkcs11Info, hRsaKey, CKA_MODULUS,
633  n, CRYPT_MAX_PKCSIZE, &nLen );
634  if( cryptStatusOK( cryptStatus ) )
635  cryptStatus = readAttributeValue( pkcs11Info, hRsaKey, CKA_PUBLIC_EXPONENT,
636  e, CRYPT_MAX_PKCSIZE, &eLen );
637  if( cryptStatusError( cryptStatus ) )
638  return( cryptStatus );
639 
640  /* Send the public key data to the context. We send the keying
641  information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
642  CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
643  into the high state. We don't want to do this because we're already
644  in the middle of processing a message that does this on completion,
645  all that we're doing here is sending in encoded public key data for
646  use by objects such as certificates */
647  cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 2,
648  &keyDataSize, CRYPT_ALGO_RSA,
649  n, nLen, e, eLen, NULL, 0, NULL, 0 );
650  if( cryptStatusError( cryptStatus ) )
651  return( cryptStatus );
652  setMessageData( &msgData, keyDataBuffer, keyDataSize );
653  if( nativeContext )
654  {
655  return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
656  &msgData, CRYPT_IATTRIBUTE_KEY_SPKI ) );
657  }
658  return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
659  &msgData, CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL ) );
660  }
661 
662 static int rsaSetKeyInfo( PKCS11_INFO *pkcs11Info,
663  CONTEXT_INFO *contextInfoPtr,
664  const CK_OBJECT_HANDLE hPrivateKey,
665  const CK_OBJECT_HANDLE hPublicKey )
666  {
668  BYTE idBuffer[ KEYID_SIZE + 8 ];
669  int cryptStatus;
670 
671  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
672  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
673 
674  /* Remember what we've set up */
676  ( MESSAGE_CAST ) &hPrivateKey,
677  CRYPT_IATTRIBUTE_DEVICEOBJECT );
678  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
679 
680  /* Get the key ID from the context and use it as the object ID. Since
681  some objects won't allow after-the-event ID updates, we don't treat a
682  failure to update as an error */
683  setMessageData( &msgData, idBuffer, KEYID_SIZE );
684  cryptStatus = krnlSendMessage( contextInfoPtr->objectHandle,
685  IMESSAGE_GETATTRIBUTE_S, &msgData,
686  CRYPT_IATTRIBUTE_KEYID );
687  if( cryptStatusOK( cryptStatus ) )
688  {
689  CK_ATTRIBUTE idTemplate = { CKA_ID, msgData.data, msgData.length };
690 
691  if( hPublicKey != CK_OBJECT_NONE )
692  C_SetAttributeValue( pkcs11Info->hSession, hPublicKey,
693  &idTemplate, 1 );
694  C_SetAttributeValue( pkcs11Info->hSession, hPrivateKey,
695  &idTemplate, 1 );
696  }
697 
698  return( cryptStatus );
699  }
700 
701 static int rsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
702  const int keyLength )
703  {
704  static const CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
705  static const CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
706  static const CK_KEY_TYPE type = CKK_RSA;
707  static const CK_BBOOL bTrue = TRUE;
708  CK_ATTRIBUTE rsaKeyTemplate[] = {
709  /* Shared fields */
710  { CKA_CLASS, ( CK_VOID_PTR ) &privKeyClass, sizeof( CK_OBJECT_CLASS ) },
711  { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
712  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
713  { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
714  { CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
715  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
716  { CKA_MODULUS, NULL, 0 },
717  { CKA_PUBLIC_EXPONENT, NULL, 0 },
718  /* Private-key only fields */
719  { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
720  { CKA_PRIVATE_EXPONENT, NULL, 0 },
721  { CKA_PRIME_1, NULL, 0 },
722  { CKA_PRIME_2, NULL, 0 },
723  { CKA_EXPONENT_1, NULL, 0 },
724  { CKA_EXPONENT_2, NULL, 0 },
725  { CKA_COEFFICIENT, NULL, 0 },
726  };
727  const CRYPT_PKCINFO_RSA *rsaKey = ( CRYPT_PKCINFO_RSA * ) key;
728  CRYPT_DEVICE iCryptDevice;
729  PKCS11_INFO *pkcs11Info;
730  CK_OBJECT_HANDLE hRsaKey;
731  CK_RV status;
732  const int templateCount = rsaKey->isPublicKey ? 8 : 15;
733  int cryptStatus;
734 
735  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
736  assert( isReadPtr( key, keyLength ) );
737 
738  REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_RSA ) );
739 
740  /* Get the information for the device associated with this context */
741  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
742  &iCryptDevice, &pkcs11Info );
743  if( cryptStatusError( cryptStatus ) )
744  return( cryptStatus );
745 
746  /* Set up the key values */
747  rsaKeyTemplate[ 6 ].pValue = ( CK_VOID_PTR ) rsaKey->n;
748  rsaKeyTemplate[ 6 ].ulValueLen = bitsToBytes( rsaKey->nLen );
749  rsaKeyTemplate[ 7 ].pValue = ( CK_VOID_PTR ) rsaKey->e;
750  rsaKeyTemplate[ 7 ].ulValueLen = bitsToBytes( rsaKey->eLen );
751  if( !rsaKey->isPublicKey )
752  {
753  rsaKeyTemplate[ 9 ].pValue = ( CK_VOID_PTR ) rsaKey->d;
754  rsaKeyTemplate[ 9 ].ulValueLen = bitsToBytes( rsaKey->dLen );
755  rsaKeyTemplate[ 10 ].pValue = ( CK_VOID_PTR ) rsaKey->p;
756  rsaKeyTemplate[ 10 ].ulValueLen = bitsToBytes( rsaKey->pLen );
757  rsaKeyTemplate[ 11 ].pValue = ( CK_VOID_PTR ) rsaKey->q;
758  rsaKeyTemplate[ 11 ].ulValueLen = bitsToBytes( rsaKey->qLen );
759  rsaKeyTemplate[ 12 ].pValue = ( CK_VOID_PTR ) rsaKey->e1;
760  rsaKeyTemplate[ 12 ].ulValueLen = bitsToBytes( rsaKey->e1Len );
761  rsaKeyTemplate[ 13 ].pValue = ( CK_VOID_PTR ) rsaKey->e2;
762  rsaKeyTemplate[ 13 ].ulValueLen = bitsToBytes( rsaKey->e2Len );
763  rsaKeyTemplate[ 14 ].pValue = ( CK_VOID_PTR ) rsaKey->u;
764  rsaKeyTemplate[ 14 ].ulValueLen = bitsToBytes( rsaKey->uLen );
765  }
766  else
767  {
768  /* If it's a public key, we need to change the type and indication of
769  the operations that it's allowed to perform */
770  rsaKeyTemplate[ 0 ].pValue = ( CK_VOID_PTR ) &pubKeyClass;
771  rsaKeyTemplate[ 3 ].type = CKA_VERIFY;
772  rsaKeyTemplate[ 4 ].type = CKA_ENCRYPT;
773  }
774 
775  /* Load the key into the token */
776  status = C_CreateObject( pkcs11Info->hSession, rsaKeyTemplate,
777  templateCount, &hRsaKey );
778  zeroise( rsaKeyTemplate, sizeof( CK_ATTRIBUTE ) * templateCount );
779  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
780  if( cryptStatusError( cryptStatus ) )
781  {
782  /* If we're trying to set a public key and this is one of those
783  tinkertoy tokens that only does private-key ops, return a more
784  appropriate error code */
785  if( rsaKey->isPublicKey && \
786  contextInfoPtr->capabilityInfo->encryptFunction == NULL &&
787  contextInfoPtr->capabilityInfo->sigCheckFunction == NULL )
788  cryptStatus = CRYPT_ERROR_NOTAVAIL;
789 
790  krnlReleaseObject( iCryptDevice );
791  return( cryptStatus );
792  }
793 
794  /* Send the keying information to the context and set up the key ID
795  information */
796  cryptStatus = rsaSetPublicComponents( pkcs11Info,
797  contextInfoPtr->objectHandle, hRsaKey,
798  FALSE );
799  if( cryptStatusOK( cryptStatus ) )
800  cryptStatus = rsaSetKeyInfo( pkcs11Info, contextInfoPtr,
801  hRsaKey, CK_OBJECT_NONE );
802  if( cryptStatusError( cryptStatus ) )
803  C_DestroyObject( pkcs11Info->hSession, hRsaKey );
804  else
805  {
806  /* Remember that this object is backed by a crypto device */
807  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
808  }
809 
810  krnlReleaseObject( iCryptDevice );
811  return( cryptStatus );
812  }
813 
814 static int rsaGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
815  {
816  static const CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
817  static const CK_BBOOL bTrue = TRUE;
818  static const BYTE exponent[] = { 0x01, 0x00, 0x01 };
819  const CK_ULONG modulusBits = keysizeBits;
820  CK_ATTRIBUTE privateKeyTemplate[] = {
821  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
822  { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
823  { CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
824  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
825  { CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
826  { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
827  };
828  CK_ATTRIBUTE publicKeyTemplate[] = {
829  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
830  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
831  { CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
832  { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
833  { CKA_PUBLIC_EXPONENT, ( CK_VOID_PTR ) exponent, sizeof( exponent ) },
834  { CKA_MODULUS_BITS, ( CK_VOID_PTR ) &modulusBits, sizeof( CK_ULONG ) }
835  };
836  CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
837  CRYPT_DEVICE iCryptDevice;
838  PKCS11_INFO *pkcs11Info;
839  CK_RV status;
840  int cryptStatus;
841 
842  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
843 
844  REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
845  keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
846 
847  /* Get the information for the device associated with this context */
848  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
849  &iCryptDevice, &pkcs11Info );
850  if( cryptStatusError( cryptStatus ) )
851  return( cryptStatus );
852 
853  /* Patch in the key size and generate the keys */
854  status = C_GenerateKeyPair( pkcs11Info->hSession,
855  ( CK_MECHANISM_PTR ) &mechanism,
856  publicKeyTemplate, 6, privateKeyTemplate, 6,
857  &hPublicKey, &hPrivateKey );
858  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
859  if( cryptStatusError( cryptStatus ) )
860  {
861  krnlReleaseObject( iCryptDevice );
862  return( cryptStatus );
863  }
864 
865  /* Send the keying information to the context and set up the key ID
866  information */
867  cryptStatus = rsaSetPublicComponents( pkcs11Info,
868  contextInfoPtr->objectHandle,
869  hPublicKey, FALSE );
870  if( cryptStatusOK( cryptStatus ) )
871  cryptStatus = rsaSetKeyInfo( pkcs11Info, contextInfoPtr, hPrivateKey,
872  hPublicKey );
873  if( cryptStatusError( cryptStatus ) )
874  {
875  C_DestroyObject( pkcs11Info->hSession, hPublicKey );
876  C_DestroyObject( pkcs11Info->hSession, hPrivateKey );
877  }
878  else
879  {
880  /* Remember that this object is backed by a crypto device */
881  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
882  }
883 
884  krnlReleaseObject( iCryptDevice );
885  return( cryptStatus );
886  }
887 
888 static int rsaSign( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
889  {
890  static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
891  CRYPT_DEVICE iCryptDevice;
892  PKCS11_INFO *pkcs11Info;
893  BYTE *bufPtr = buffer;
894  const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
895  int cryptStatus, i;
896 
897  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
898  assert( isWritePtr( buffer, length ) );
899 
900  REQUIRES( length == keySize );
901 
902  /* Undo the PKCS #1 padding to make CKM_RSA_PKCS look like
903  CKM_RSA_X_509 */
904  assert( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 1 && bufPtr[ 2 ] == 0xFF );
905  for( i = 2; i < keySize; i++ )
906  {
907  if( bufPtr[ i ] == 0 )
908  break;
909  }
910  i++; /* Skip final 0 byte */
911 
912  /* Get the information for the device associated with this context */
913  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
914  &iCryptDevice, &pkcs11Info );
915  if( cryptStatusError( cryptStatus ) )
916  return( cryptStatus );
917  cryptStatus = genericSign( pkcs11Info, contextInfoPtr, &mechanism,
918  bufPtr + i, keySize - i, buffer, keySize );
919  krnlReleaseObject( iCryptDevice );
920  return( cryptStatus );
921  }
922 
923 static int rsaVerify( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
924  {
925  static const CK_MECHANISM mechanism = { CKM_RSA_X_509, NULL_PTR, 0 };
926  CRYPT_DEVICE iCryptDevice;
927  PKCS11_INFO *pkcs11Info;
928  BYTE data[ CRYPT_MAX_PKCSIZE + 8 ];
929  const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
930  int cryptStatus;
931 
932  /* This function is present but isn't used as part of any normal
933  operation because cryptlib does the same thing much faster in
934  software and because some tokens don't support public-key
935  operations */
936 
937  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
938  assert( isWritePtr( buffer, length ) );
939 
940  REQUIRES( length == keySize );
941 
942  /* Get the information for the device associated with this context */
943  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
944  &iCryptDevice, &pkcs11Info );
945  if( cryptStatusError( cryptStatus ) )
946  return( cryptStatus );
947  cryptStatus = genericVerify( pkcs11Info, contextInfoPtr, &mechanism,
948  data, keySize, buffer, keySize );
949  krnlReleaseObject( iCryptDevice );
950  return( cryptStatus );
951  }
952 
953 static int rsaEncrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
954  {
955  static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
956  CRYPT_DEVICE iCryptDevice;
957  PKCS11_INFO *pkcs11Info;
958  BYTE *bufPtr = buffer;
959  const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
960  int cryptStatus, i;
961 
962  /* This function is present but isn't used as part of any normal
963  operation because cryptlib does the same thing much faster in
964  software and because some tokens don't support public-key
965  operations. The only way that it can be invoked is by calling
966  cryptEncrypt() directly on a device context */
967 
968  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
969  assert( isWritePtr( buffer, length ) );
970 
971  REQUIRES( length == keySize );
972 
973  /* Undo the PKCS #1 padding to make CKM_RSA_PKCS look like
974  CKM_RSA_X_509 */
975  assert( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 2 );
976  for( i = 2; i < keySize; i++ )
977  {
978  if( bufPtr[ i ] == 0 )
979  break;
980  }
981  i++; /* Skip final 0 byte */
982  memmove( bufPtr, bufPtr + i, keySize - i );
983 
984  /* Get the information for the device associated with this context */
985  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
986  &iCryptDevice, &pkcs11Info );
987  if( cryptStatusError( cryptStatus ) )
988  return( cryptStatus );
989  cryptStatus = genericEncrypt( pkcs11Info, contextInfoPtr, &mechanism,
990  bufPtr, keySize - i, keySize );
991  krnlReleaseObject( iCryptDevice );
992  return( cryptStatus );
993  }
994 
995 static int rsaDecrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
996  {
997  static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
998  CRYPT_DEVICE iCryptDevice;
999  PKCS11_INFO *pkcs11Info;
1001  BYTE *bufPtr = buffer;
1002  const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
1003  int cryptStatus, i, resultLen;
1004 
1005  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1006  assert( isWritePtr( buffer, length ) );
1007 
1008  REQUIRES( length == keySize );
1009 
1010  /* Get the information for the device associated with this context */
1011  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1012  &iCryptDevice, &pkcs11Info );
1013  if( cryptStatusError( cryptStatus ) )
1014  return( cryptStatus );
1015  cryptStatus = genericDecrypt( pkcs11Info, contextInfoPtr, &mechanism,
1016  buffer, keySize, &resultLen );
1017  krnlReleaseObject( iCryptDevice );
1018  if( cryptStatusError( cryptStatus ) )
1019  return( cryptStatus );
1020 
1021  /* Redo the PKCS #1 padding to CKM_RSA_PKCS look like CKM_RSA_X_509.
1022  Note that this doesn't have to be cryptographically strong since
1023  it gets stripped as soon as we return to the caller, it just has
1024  to be random:
1025 
1026  bufPtr keySize
1027  | |
1028  +---+---+------------+---+----------+
1029  | 0 | 1 | random | 0 | key |
1030  +---+---+------------+---+----------+
1031  | | | |
1032  <------------> <---------->
1033  keySize - resultLen
1034  resultLen - 3
1035 
1036  This gets a bit ugly because the random padding has to be nonzero,
1037  which would require using the non-nonce RNG. To work around this,
1038  we look for any zeroes in the data and fill them with some other
1039  value */
1040  REQUIRES( rangeCheck( keySize - resultLen, resultLen, length ) );
1041  memmove( bufPtr + keySize - resultLen, bufPtr, resultLen );
1042  bufPtr[ 0 ] = 0;
1043  bufPtr[ 1 ] = 2;
1044  setMessageData( &msgData, bufPtr + 2, keySize - resultLen - 3 );
1045  cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1046  IMESSAGE_GETATTRIBUTE_S, &msgData,
1047  CRYPT_IATTRIBUTE_RANDOM_NONCE );
1048  for( i = 2; i < keySize - resultLen - 1; i++ )
1049  {
1050  if( bufPtr[ i ] == 0 )
1051  {
1052  /* Create some sort of non-constant non-zero value to replace
1053  the zero byte with, since PKCS #1 can't have zero bytes.
1054  Note again that this doesn't have to be a strong random
1055  value, it just has to vary a bit */
1056  const int pad = 0xAA ^ ( i & 0xFF );
1057  bufPtr[ i ] = pad ? pad : 0x21;
1058  }
1059  }
1060  bufPtr[ keySize - resultLen - 1 ] = 0;
1061  ENSURES( 2 + ( keySize - resultLen - 3 ) + 1 + resultLen == keySize );
1062 
1063  return( cryptStatus );
1064  }
1065 
1066 /****************************************************************************
1067 * *
1068 * DSA Mapping Functions *
1069 * *
1070 ****************************************************************************/
1071 
1072 /* DSA algorithm-specific mapping functions */
1073 
1074 static int dsaSetKeyInfo( PKCS11_INFO *pkcs11Info,
1075  const CRYPT_CONTEXT iCryptContext,
1076  const CK_OBJECT_HANDLE hPrivateKey,
1077  const CK_OBJECT_HANDLE hPublicKey,
1078  const void *p, const int pLen,
1079  const void *q, const int qLen,
1080  const void *g, const int gLen,
1081  const void *y, const int yLen,
1082  const BOOLEAN nativeContext )
1083  {
1085  BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 4 ) + 8 ];
1086  BYTE idBuffer[ KEYID_SIZE + 8 ];
1087  int keyDataSize, cryptStatus;
1088 
1089  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1090  assert( isReadPtr( p, pLen ) );
1091  assert( isReadPtr( q, qLen ) );
1092  assert( isReadPtr( g, gLen ) );
1093  assert( isReadPtr( y, yLen ) );
1094 
1095  REQUIRES( isHandleRangeValid( iCryptContext ) );
1096 
1097  /* Send the public key data to the context. We send the keying
1098  information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
1099  CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
1100  into the high state. We don't want to do this because we're already
1101  in the middle of processing a message that does this on completion,
1102  all that we're doing here is sending in encoded public key data for
1103  use by objects such as certificates */
1104  cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 3,
1105  &keyDataSize, CRYPT_ALGO_DSA,
1106  p, pLen, q, qLen, g, gLen, y, yLen );
1107  if( cryptStatusError( cryptStatus ) )
1108  return( cryptStatus );
1109  setMessageData( &msgData, keyDataBuffer, keyDataSize );
1110  if( nativeContext )
1111  {
1112  /* If we're just setting public key components for a native context,
1113  we're done */
1114  return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1115  &msgData, CRYPT_IATTRIBUTE_KEY_SPKI ) );
1116  }
1117  cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1118  &msgData, CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
1119  if( cryptStatusError( cryptStatus ) )
1120  return( cryptStatus );
1121 
1122  /* Remember what we've set up */
1123  krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
1124  ( MESSAGE_CAST ) &hPrivateKey,
1125  CRYPT_IATTRIBUTE_DEVICEOBJECT );
1126 
1127  /* Get the key ID from the context and use it as the object ID. Since
1128  some objects won't allow after-the-even ID updates, we don't treat a
1129  failure to update as an error */
1130  setMessageData( &msgData, idBuffer, KEYID_SIZE );
1131  cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
1132  &msgData, CRYPT_IATTRIBUTE_KEYID );
1133  if( cryptStatusOK( cryptStatus ) )
1134  {
1135  CK_ATTRIBUTE idTemplate = { CKA_ID, msgData.data, msgData.length };
1136 
1137  if( hPublicKey != CRYPT_UNUSED )
1138  C_SetAttributeValue( pkcs11Info->hSession, hPublicKey,
1139  &idTemplate, 1 );
1140  C_SetAttributeValue( pkcs11Info->hSession, hPrivateKey,
1141  &idTemplate, 1 );
1142  }
1143 
1144  return( cryptStatus );
1145  }
1146 
1147 int dsaSetPublicComponents( PKCS11_INFO *pkcs11Info,
1148  const CRYPT_CONTEXT iCryptContext,
1149  const CK_OBJECT_HANDLE hDsaKey )
1150  {
1151  BYTE p[ CRYPT_MAX_PKCSIZE + 8 ], q[ CRYPT_MAX_PKCSIZE + 8 ];
1152  BYTE g[ CRYPT_MAX_PKCSIZE + 8 ], y[ CRYPT_MAX_PKCSIZE + 8 ];
1153  int pLen, qLen = DUMMY_INIT, gLen = DUMMY_INIT, yLen = DUMMY_INIT;
1154  int cryptStatus;
1155 
1156  assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1157 
1158  REQUIRES( isHandleRangeValid( iCryptContext ) );
1159 
1160  /* Get the public key components from the device */
1161  cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_PRIME,
1162  p, CRYPT_MAX_PKCSIZE, &pLen );
1163  if( cryptStatusOK( cryptStatus ) )
1164  cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_SUBPRIME,
1165  q, CRYPT_MAX_PKCSIZE, &qLen );
1166  if( cryptStatusOK( cryptStatus ) )
1167  cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_BASE,
1168  g, CRYPT_MAX_PKCSIZE, &gLen );
1169  if( cryptStatusOK( cryptStatus ) )
1170  cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_VALUE,
1171  y, CRYPT_MAX_PKCSIZE, &yLen );
1172  if( cryptStatusError( cryptStatus ) )
1173  return( cryptStatus );
1174 
1175  return( dsaSetKeyInfo( pkcs11Info, iCryptContext, CK_OBJECT_NONE, hDsaKey,
1176  p, pLen, q, qLen, g, gLen, y, yLen, TRUE ) );
1177  }
1178 
1179 static int dsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
1180  const int keyLength )
1181  {
1182  static const CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
1183  static const CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
1184  static const CK_KEY_TYPE type = CKK_DSA;
1185  static const CK_BBOOL bTrue = TRUE;
1186  CK_ATTRIBUTE dsaKeyTemplate[] = {
1187  /* Shared fields */
1188  { CKA_CLASS, ( CK_VOID_PTR ) &privKeyClass, sizeof( CK_OBJECT_CLASS ) },
1189  { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
1190  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1191  { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1192  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1193  { CKA_PRIME, NULL, 0 },
1194  { CKA_SUBPRIME, NULL, 0 },
1195  { CKA_BASE, NULL, 0 },
1196  { CKA_VALUE, NULL, 0 },
1197  /* Private-key only fields */
1198  { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1199  };
1200  const CRYPT_PKCINFO_DLP *dsaKey = ( CRYPT_PKCINFO_DLP * ) key;
1201  CRYPT_DEVICE iCryptDevice;
1202  PKCS11_INFO *pkcs11Info;
1203  CK_OBJECT_HANDLE hDsaKey;
1204  CK_RV status;
1205  BYTE yValue[ CRYPT_MAX_PKCSIZE + 8 ];
1206  const void *yValuePtr;
1207  const int templateCount = dsaKey->isPublicKey ? 9 : 10;
1208  int yValueLength, cryptStatus;
1209 
1210  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1211  assert( isReadPtr( key, keyLength ) );
1212 
1213  REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_DLP ) );
1214 
1215  /* Creating a private-key object is somewhat problematic since the
1216  PKCS #11 interpretation of DSA reuses CKA_VALUE for x in the private
1217  key and y in the public key, so it's not possible to determine y from
1218  a private key because the x value is sensitive and can't be extracted.
1219  Because of this we have to create a native private-key context (which
1220  will generate the y value from x), read out the y value, and destroy
1221  it again (see the comments in the DSA generate key section for more on
1222  this problem). Since this doesn't require the device, we do it before
1223  we grab the device */
1224  if( !dsaKey->isPublicKey )
1225  {
1226  MESSAGE_CREATEOBJECT_INFO createInfo;
1228  STREAM stream;
1229  BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
1230  void *yValueDataPtr = DUMMY_INIT_PTR;
1231  int yValueDataSize;
1232 
1233  /* Create a native private-key DSA context, which generates the y
1234  value internally */
1236  cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1237  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1239  if( cryptStatusError( cryptStatus ) )
1240  return( cryptStatus );
1241  setMessageData( &msgData, label, 8 );
1243  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1245  &msgData, CRYPT_CTXINFO_LABEL );
1246  setMessageData( &msgData, ( MESSAGE_CAST ) dsaKey,
1247  sizeof( CRYPT_PKCINFO_DLP ) );
1248  cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1249  IMESSAGE_SETATTRIBUTE_S, &msgData,
1251  if( cryptStatusError( cryptStatus ) )
1252  {
1254  return( cryptStatus );
1255  }
1256 
1257  /* Get the public key data and extract the y value from it. Note
1258  that the data used is represented in DER-canonical form, there may
1259  be PKCS #11 implementations that can't handle this (for example
1260  they may require y to be zero-padded to make it exactly 64 bytes
1261  rather than (say) 63 bytes if the high byte is zero) */
1262  setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
1263  cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1264  IMESSAGE_GETATTRIBUTE_S, &msgData,
1265  CRYPT_IATTRIBUTE_KEY_SPKI );
1267  if( cryptStatusError( cryptStatus ) )
1268  return( cryptStatus );
1269  sMemConnect( &stream, msgData.data, msgData.length );
1270  readSequence( &stream, NULL ); /* SEQUENCE { */
1271  readUniversal( &stream ); /* AlgoID */
1272  readBitStringHole( &stream, NULL, 16, DEFAULT_TAG );/* BIT STRING */
1273  status = readGenericHole( &stream, &yValueDataSize, 16,
1274  BER_INTEGER );/* INTEGER */
1275  if( cryptStatusOK( status ) )
1276  status = sMemGetDataBlock( &stream, &yValueDataPtr,
1277  yValueDataSize );
1278  ENSURES( cryptStatusOK( status ) );
1279  ENSURES( yValueDataSize >= 16 && \
1280  yValueDataSize <= CRYPT_MAX_PKCSIZE );
1281  memcpy( yValue, yValueDataPtr, yValueDataSize );
1282  sMemDisconnect( &stream );
1283 
1284  /* The y value is the recovered value from the key data */
1285  yValuePtr = yValue;
1286  yValueLength = yValueDataSize;
1287  }
1288  else
1289  {
1290  /* It's a public key, use the pre-generated y value */
1291  yValuePtr = dsaKey->y,
1292  yValueLength = bitsToBytes( dsaKey->yLen );
1293  }
1294 
1295  /* Get the information for the device associated with this context */
1296  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1297  &iCryptDevice, &pkcs11Info );
1298  if( cryptStatusError( cryptStatus ) )
1299  return( cryptStatus );
1300 
1301  /* Set up the key values */
1302  dsaKeyTemplate[ 5 ].pValue = ( CK_VOID_PTR ) dsaKey->p;
1303  dsaKeyTemplate[ 5 ].ulValueLen = bitsToBytes( dsaKey->pLen );
1304  dsaKeyTemplate[ 6 ].pValue = ( CK_VOID_PTR ) dsaKey->q;
1305  dsaKeyTemplate[ 6 ].ulValueLen = bitsToBytes( dsaKey->qLen );
1306  dsaKeyTemplate[ 7 ].pValue = ( CK_VOID_PTR ) dsaKey->g;
1307  dsaKeyTemplate[ 7 ].ulValueLen = bitsToBytes( dsaKey->gLen );
1308  if( !dsaKey->isPublicKey )
1309  {
1310  dsaKeyTemplate[ 8 ].pValue = ( CK_VOID_PTR ) dsaKey->x;
1311  dsaKeyTemplate[ 8 ].ulValueLen = bitsToBytes( dsaKey->xLen );
1312  }
1313  else
1314  {
1315  dsaKeyTemplate[ 8 ].pValue = ( CK_VOID_PTR ) dsaKey->y;
1316  dsaKeyTemplate[ 8 ].ulValueLen = bitsToBytes( dsaKey->yLen );
1317 
1318  /* If it's a public key, we need to change the type and the
1319  indication of the operations that it's allowed to perform */
1320  dsaKeyTemplate[ 0 ].pValue = ( CK_VOID_PTR ) &pubKeyClass;
1321  dsaKeyTemplate[ 3 ].type = CKA_VERIFY;
1322  }
1323 
1324  /* Load the key into the token */
1325  status = C_CreateObject( pkcs11Info->hSession, dsaKeyTemplate,
1326  templateCount, &hDsaKey );
1327  zeroise( dsaKeyTemplate, sizeof( CK_ATTRIBUTE ) * templateCount );
1328  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1329  if( cryptStatusError( cryptStatus ) )
1330  {
1331  /* If we're trying to set a public key and this is one of those
1332  tinkertoy tokens that only does private-key ops, return a more
1333  appropriate error code */
1334  if( dsaKey->isPublicKey && \
1335  contextInfoPtr->capabilityInfo->sigCheckFunction == NULL )
1336  cryptStatus = CRYPT_ERROR_NOTAVAIL;
1337 
1338  krnlReleaseObject( iCryptDevice );
1339  return( cryptStatus );
1340  }
1341 
1342  /* Send the keying information to the context and set up the key ID
1343  information */
1344  cryptStatus = dsaSetKeyInfo( pkcs11Info, contextInfoPtr->objectHandle,
1345  hDsaKey, CK_OBJECT_NONE,
1346  dsaKey->p, bitsToBytes( dsaKey->pLen ),
1347  dsaKey->q, bitsToBytes( dsaKey->qLen ),
1348  dsaKey->g, bitsToBytes( dsaKey->gLen ),
1349  yValuePtr, yValueLength, FALSE );
1350  if( cryptStatusError( cryptStatus ) )
1351  C_DestroyObject( pkcs11Info->hSession, hDsaKey );
1352  else
1353  /* Remember that this object is backed by a crypto device */
1354  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1355 
1356  krnlReleaseObject( iCryptDevice );
1357  return( cryptStatus );
1358  }
1359 
1360 static int dsaGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
1361  {
1362  static const CK_MECHANISM mechanism = { CKM_DSA_KEY_PAIR_GEN, NULL_PTR, 0 };
1363  static const CK_BBOOL bTrue = TRUE;
1364  CK_ATTRIBUTE privateKeyTemplate[] = {
1365  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1366  { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1367  { CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1368  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1369  { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1370  };
1371  CK_ATTRIBUTE publicKeyTemplate[] = {
1372  { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1373  { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1374  { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1375  { CKA_PRIME, NULL, 0 },
1376  { CKA_SUBPRIME, NULL, 0 },
1377  { CKA_BASE, NULL, 0 },
1378  };
1379  CK_ATTRIBUTE yValueTemplate = { CKA_VALUE, NULL, CRYPT_MAX_PKCSIZE * 2 };
1380  CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
1381  MESSAGE_CREATEOBJECT_INFO createInfo;
1383  CRYPT_DEVICE iCryptDevice;
1384  PKCS11_INFO *pkcs11Info;
1385  BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
1386  CK_RV status;
1387  STREAM stream;
1388  void *dataPtr = DUMMY_INIT_PTR;
1389  int length, cryptStatus;
1390 
1391  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1392 
1393  REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
1394  keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
1395 
1396  /* CKM_DSA_KEY_PAIR_GEN is really a Clayton's key generation mechanism
1397  since it doesn't actually generate the p, q, or g values (presumably
1398  it dates back to the original FIPS 186 shared domain parameters idea).
1399  Because of this we'd have to generate half the key ourselves in a
1400  native context, then copy portions from the native context over in
1401  flat form and complete the keygen via the device. The easiest way to
1402  do this is to create a native DSA context, generate a key, grab the
1403  public portions, and destroy the context again (i.e. generate a full
1404  key on a superscalar 2GHz RISC CPU, then throw half of it away, and
1405  regenerate it on a 5MHz 8-bit tinkertoy). Since the keygen can take
1406  awhile and doesn't require the device, we do it before we grab the
1407  device */
1409  cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1410  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1412  if( cryptStatusError( cryptStatus ) )
1413  return( cryptStatus );
1414  setMessageData( &msgData, label, 8 );
1416  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1418  &msgData, CRYPT_CTXINFO_LABEL );
1419  cryptStatus = krnlSendNotifier( createInfo.cryptHandle,
1421  if( cryptStatusOK( cryptStatus ) )
1422  {
1423  setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
1424  cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1425  IMESSAGE_GETATTRIBUTE_S, &msgData,
1426  CRYPT_IATTRIBUTE_KEY_SPKI );
1427  }
1429  if( cryptStatusError( cryptStatus ) )
1430  return( cryptStatus );
1431 
1432  /* Set up the public key information by extracting the flat values from
1433  the SubjectPublicKeyInfo. Note that the data used is represented in
1434  DER-canonical form, there may be PKCS #11 implementations that
1435  can't handle this (for example they may require q to be zero-padded
1436  to make it exactly 20 bytes rather than (say) 19 bytes if the high
1437  byte is zero) */
1438  sMemConnect( &stream, pubkeyBuffer, msgData.length );
1439  readSequence( &stream, NULL ); /* SEQUENCE */
1440  readSequence( &stream, NULL ); /* SEQUENCE */
1441  readUniversal( &stream ); /* OID */
1442  readSequence( &stream, NULL ); /* SEQUENCE */
1443  status = readGenericHole( &stream, &length, 16, BER_INTEGER ); /* p */
1444  if( cryptStatusOK( status ) )
1445  status = sMemGetDataBlock( &stream, &dataPtr, length );
1446  if( cryptStatusError( status ) )
1447  retIntError();
1448  publicKeyTemplate[ 3 ].pValue = dataPtr;
1449  publicKeyTemplate[ 3 ].ulValueLen = length;
1450  sSkip( &stream, length );
1451  status = readGenericHole( &stream, &length, 16, BER_INTEGER ); /* q */
1452  if( cryptStatusOK( status ) )
1453  status = sMemGetDataBlock( &stream, &dataPtr, length );
1454  if( cryptStatusError( status ) )
1455  retIntError();
1456  publicKeyTemplate[ 4 ].pValue = dataPtr;
1457  publicKeyTemplate[ 4 ].ulValueLen = length;
1458  sSkip( &stream, length );
1459  status = readGenericHole( &stream, &length, 16, BER_INTEGER ); /* g */
1460  if( cryptStatusOK( status ) )
1461  status = sMemGetDataBlock( &stream, &dataPtr, length );
1462  if( cryptStatusError( status ) )
1463  retIntError();
1464  publicKeyTemplate[ 5 ].pValue = dataPtr;
1465  publicKeyTemplate[ 5 ].ulValueLen = length;
1466  sMemDisconnect( &stream );
1467 
1468  /* Get the information for the device associated with this context */
1469  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1470  &iCryptDevice, &pkcs11Info );
1471  if( cryptStatusError( cryptStatus ) )
1472  return( cryptStatus );
1473 
1474  /* Generate the keys */
1475  status = C_GenerateKeyPair( pkcs11Info->hSession,
1476  ( CK_MECHANISM_PTR ) &mechanism,
1477  ( CK_ATTRIBUTE_PTR ) publicKeyTemplate, 6,
1478  ( CK_ATTRIBUTE_PTR ) privateKeyTemplate, 5,
1479  &hPublicKey, &hPrivateKey );
1480  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1481  if( cryptStatusError( cryptStatus ) )
1482  {
1483  krnlReleaseObject( iCryptDevice );
1484  return( cryptStatus );
1485  }
1486 
1487  /* Read back the generated y value, send the public key information to
1488  the context, and set up the key ID information. The odd two-phase y
1489  value read is necessary for buggy implementations that fail if the
1490  given size isn't exactly the same as the data size */
1491  status = C_GetAttributeValue( pkcs11Info->hSession, hPublicKey,
1492  &yValueTemplate, 1 );
1493  if( status == CKR_OK )
1494  {
1495  yValueTemplate.pValue = pubkeyBuffer;
1496  status = C_GetAttributeValue( pkcs11Info->hSession, hPublicKey,
1497  &yValueTemplate, 1 );
1498  }
1499  cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1500  if( cryptStatusOK( cryptStatus ) )
1501  cryptStatus = dsaSetKeyInfo( pkcs11Info, contextInfoPtr->objectHandle,
1502  hPrivateKey, hPublicKey,
1503  publicKeyTemplate[ 3 ].pValue, publicKeyTemplate[ 3 ].ulValueLen,
1504  publicKeyTemplate[ 4 ].pValue, publicKeyTemplate[ 4 ].ulValueLen,
1505  publicKeyTemplate[ 5 ].pValue, publicKeyTemplate[ 5 ].ulValueLen,
1506  yValueTemplate.pValue, yValueTemplate.ulValueLen, FALSE );
1507  if( cryptStatusError( cryptStatus ) )
1508  {
1509  C_DestroyObject( pkcs11Info->hSession, hPublicKey );
1510  C_DestroyObject( pkcs11Info->hSession, hPrivateKey );
1511  }
1512  else
1513  /* Remember that this object is backed by a crypto device */
1514  contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1515 
1516  krnlReleaseObject( iCryptDevice );
1517  return( cryptStatus );
1518  }
1519 
1520 static int dsaSign( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1521  {
1522  static const CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 };
1523  CRYPT_DEVICE iCryptDevice;
1524  PKCS11_INFO *pkcs11Info;
1525  DLP_PARAMS *dlpParams = ( DLP_PARAMS * ) buffer;
1526  PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
1527  BIGNUM *r, *s;
1528  BYTE signature[ 40 + 8 ];
1529  int cryptStatus;
1530 
1531  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1532  assert( isWritePtr( buffer, length ) );
1533 
1534  REQUIRES( length == sizeof( DLP_PARAMS ) );
1535  REQUIRES( dlpParams->inParam1 != NULL && \
1536  dlpParams->inLen1 == 20 );
1537  REQUIRES( dlpParams->inParam2 == NULL && dlpParams->inLen2 == 0 );
1538  REQUIRES( dlpParams->outParam != NULL && \
1539  dlpParams->outLen >= ( 2 + 20 ) * 2 && \
1540  dlpParams->outLen < MAX_INTLENGTH_SHORT );
1541 
1542  /* Get the information for the device associated with this context */
1543  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1544  &iCryptDevice, &pkcs11Info );
1545  if( cryptStatusError( cryptStatus ) )
1546  return( cryptStatus );
1547  cryptStatus = genericSign( pkcs11Info, contextInfoPtr, &mechanism,
1548  dlpParams->inParam1, dlpParams->inLen1,
1549  signature, 40 );
1550  krnlReleaseObject( iCryptDevice );
1551  if( cryptStatusError( cryptStatus ) )
1552  return( cryptStatus );
1553 
1554  /* Encode the result as a DL data block. We have to do this via bignums,
1555  but this isn't a big deal since DSA signing via tokens is almost never
1556  used */
1557  r = BN_new();
1558  if( r == NULL )
1559  return( CRYPT_ERROR_MEMORY );
1560  s = BN_new();
1561  if( s == NULL )
1562  {
1563  BN_free( r );
1564  return( CRYPT_ERROR_MEMORY );
1565  }
1566  cryptStatus = importBignum( r, signature, 20,
1567  bitsToBytes( 160 - 32 ), 20, NULL,
1569  if( cryptStatusOK( cryptStatus ) )
1570  cryptStatus = importBignum( r, signature + 20, 20,
1571  bitsToBytes( 160 - 32 ), 20, NULL,
1573  if( cryptStatusOK( cryptStatus ) )
1574  {
1575  cryptStatus = \
1576  dsaKey->encodeDLValuesFunction( dlpParams->outParam,
1577  dlpParams->outLen, &dlpParams->outLen,
1578  r, s, dlpParams->formatType );
1579  }
1580  BN_clear_free( s );
1581  BN_clear_free( r );
1582  return( cryptStatus );
1583  }
1584 
1585 static int dsaVerify( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1586  {
1587  static const CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 };
1588 /* CRYPT_DEVICE iCryptDevice; */
1589  DLP_PARAMS *dlpParams = ( DLP_PARAMS * ) buffer;
1590  PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
1591  BIGNUM r, s;
1592 /* BYTE signature[ 40 + 8 ]; */
1593  int cryptStatus;
1594 
1595  /* This function is present but isn't used as part of any normal
1596  operation because cryptlib does the same thing much faster in
1597  software and because some tokens don't support public-key
1598  operations */
1599 
1600  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1601  assert( isWritePtr( buffer, length ) );
1602 
1603  REQUIRES( length == sizeof( DLP_PARAMS ) );
1604  REQUIRES( dlpParams->inParam1 != NULL && dlpParams->inLen1 == 20 );
1605  REQUIRES( dlpParams->inParam2 != NULL && \
1606  ( ( dlpParams->formatType == CRYPT_FORMAT_CRYPTLIB && \
1607  dlpParams->inLen2 >= 46 ) || \
1608  ( dlpParams->formatType == CRYPT_FORMAT_PGP && \
1609  dlpParams->inLen2 == 44 ) || \
1610  ( dlpParams->formatType == CRYPT_IFORMAT_SSH && \
1611  dlpParams->inLen2 == 40 ) ) );
1612  REQUIRES( dlpParams->outParam == NULL && dlpParams->outLen == 0 );
1613 
1614  /* Decode the values from a DL data block and make sure r and s are
1615  valid */
1616  BN_init( &r );
1617  BN_init( &s );
1618  cryptStatus = \
1619  dsaKey->decodeDLValuesFunction( dlpParams->inParam2, dlpParams->inLen2,
1620  &r, &s, NULL, dlpParams->formatType );
1621  if( cryptStatusError( cryptStatus ) )
1622  return( cryptStatus );
1623 
1624  /* This code can never be called since DSA public-key contexts are
1625  always native contexts */
1626  retIntError();
1627 
1628 #if 0
1629  /* Get the information for the device associated with this context */
1630  cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1631  &iCryptDevice, &pkcs11Info );
1632  if( cryptStatusError( cryptStatus ) )
1633  return( cryptStatus );
1634  cryptStatus = genericVerify( pkcs11Info, contextInfoPtr, &mechanism,
1635  buffer, 20, signature, 40 );
1636  krnlReleaseObject( iCryptDevice );
1637  return( cryptStatus );
1638 #endif /* 0 */
1639  }
1640 
1641 /****************************************************************************
1642 * *
1643 * Device Capability Routines *
1644 * *
1645 ****************************************************************************/
1646 
1647 /* PKC mechanism information */
1648 
1649 static const PKCS11_MECHANISM_INFO mechanismInfoPKC[] = {
1650  /* The handling of the RSA mechanism is a bit odd. Almost everyone
1651  supports CKM_RSA_X_509 even though what's reported as being supported
1652  is CKM_RSA_PKCS, however the PKCS mechanism is often implemented in a
1653  buggy manner with all sorts of problems with handling the padding.
1654  The safest option would be to use the raw RSA one and do the padding
1655  ourselves, which means that it'll always be done right. Since some
1656  implementations report raw RSA as being unavailable even though it's
1657  present, we detect it by checking for the PKCS mechanism but using
1658  raw RSA. However, some implementations genuinely don't do raw RSA, so
1659  the code fakes it by removing/adding dummy PKCS padding as required
1660  so that the caller sees raw RSA and the device sees PKCS. This is a
1661  compromise: We can handle the real (rather than faked) PKCS padding
1662  ourselves and work around bugs in the output from other
1663  implementations, but we can't implement any new mechanisms other than
1664  PKCS without support in the device. The only implementation where
1665  even this causes problems is some versions of GemSAFE, which don't do
1666  raw RSA and also get the PKCS mechanism wrong */
1667 #ifdef USE_DH
1669  NULL, dhInitKey, dhGenerateKey,
1670  dhEncrypt, dhDecrypt, NULL, NULL },
1671 #endif /* USE_DH */
1673  NULL, rsaInitKey, rsaGenerateKey,
1674  rsaEncrypt, rsaDecrypt, rsaSign, rsaVerify },
1675 #ifdef USE_DSA
1677  NULL, dsaInitKey, dsaGenerateKey,
1678  NULL, NULL, dsaSign, dsaVerify },
1679 #endif /* USE_DSA */
1680  { CKM_NONE, CKM_NONE, CKM_NONE, CRYPT_ERROR, CRYPT_ERROR, },
1681  { CKM_NONE, CKM_NONE, CKM_NONE, CRYPT_ERROR, CRYPT_ERROR, }
1682  };
1683 
1684 const PKCS11_MECHANISM_INFO *getMechanismInfoPKC( int *mechanismInfoSize )
1685  {
1686  assert( isWritePtr( mechanismInfoSize, sizeof( int ) ) );
1687 
1688  *mechanismInfoSize = FAILSAFE_ARRAYSIZE( mechanismInfoPKC, \
1689  PKCS11_MECHANISM_INFO );
1690  return( mechanismInfoPKC );
1691  }
1692 #endif /* USE_PKCS11 */