1 /****************************************************************************
2 * *
3 * cryptlib PKCS #11 PKC Routines *
4 * Copyright Peter Gutmann 1998-2011 *
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 #include "asn1.h_ext"
16 #else
17 #include "crypt.h"
18 #include "context/context.h"
19 #include "device/device.h"
20 #include "device/pkcs11_api.h"
21 #include "enc_dec/asn1.h"
22 #include "enc_dec/asn1_ext.h"
23 #endif /* Compiler-specific includes */
24
25 #ifdef USE_PKCS11
26
27 /****************************************************************************
28 * *
29 * Utility Routines *
30 * *
31 ****************************************************************************/
32
33 /* Read an attribute value, used to read public-key components. The odd
34 two-phase read is necessary for buggy implementations that fail if the
35 given size isn't exactly the same as the data size */
36
readAttributeValue(PKCS11_INFO * pkcs11Info,const CK_OBJECT_HANDLE hObject,const CK_ATTRIBUTE_TYPE attrType,void * buffer,const int bufMaxLen,int * length)37 static int readAttributeValue( PKCS11_INFO *pkcs11Info,
38 const CK_OBJECT_HANDLE hObject,
39 const CK_ATTRIBUTE_TYPE attrType,
40 void *buffer, const int bufMaxLen,
41 int *length )
42 {
43 CK_ATTRIBUTE attrTemplate = { attrType, NULL_PTR, bufMaxLen };
44 CK_RV status;
45 int cryptStatus;
46
47 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
48 assert( isWritePtr( buffer, bufMaxLen ) );
49 assert( isWritePtr( length, sizeof( int ) ) );
50
51 /* Clear return value */
52 memset( buffer, 0, min( 16, bufMaxLen ) );
53 *length = CRYPT_ERROR;
54
55 status = C_GetAttributeValue( pkcs11Info->hSession, hObject,
56 &attrTemplate, 1 );
57 if( status == CKR_OK )
58 {
59 attrTemplate.pValue = buffer;
60 status = C_GetAttributeValue( pkcs11Info->hSession, hObject,
61 &attrTemplate, 1 );
62 }
63 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
64 if( cryptStatusOK( status ) )
65 *length = attrTemplate.ulValueLen;
66 return( cryptStatus );
67 }
68
69 /* Set an entry in a template to a given value. To make this easier to call
70 we wrap it in a macro that takes care of the FAILSAFE_ARRAYSIZE that's
71 required for each call */
72
73 #define setTemplate( template, attribute, value, length ) \
74 setTemplateEntry( template, \
75 FAILSAFE_ARRAYSIZE( template, CK_ATTRIBUTE ), \
76 attribute, value, length )
77
setTemplateEntry(INOUT_ARRAY (templateSize)CK_ATTRIBUTE * template,IN_LENGTH_SHORT const int templateSize,const CK_ATTRIBUTE_TYPE attribute,IN_BUFFER (length)const void * value,IN_LENGTH_SHORT const int length)78 static void setTemplateEntry( INOUT_ARRAY( templateSize ) \
79 CK_ATTRIBUTE *template,
80 IN_LENGTH_SHORT const int templateSize,
81 const CK_ATTRIBUTE_TYPE attribute,
82 IN_BUFFER( length ) const void *value,
83 IN_LENGTH_SHORT const int length )
84 {
85 CK_ATTRIBUTE *templatePtr = NULL;
86 int i;
87
88 assert( isWritePtr( template, templateSize * sizeof( CK_ATTRIBUTE ) ) );
89 assert( isReadPtr( value, length ) );
90
91 REQUIRES_V( templateSize > 0 && templateSize < 100 );
92 REQUIRES_V( length > 0 && length < MAX_INTLENGTH_SHORT );
93
94 for( i = 0; i < templateSize && template[ i ].type != CKA_NONE; i++ )
95 {
96 if( template[ i ].type == attribute )
97 {
98 templatePtr = &template[ i ];
99 break;
100 }
101 }
102 ENSURES_V( templatePtr != NULL );
103 templatePtr->pValue = ( void * ) value;
104 templatePtr->ulValueLen = length;
105 }
106
107 /* Count the number of entries in a template. Since arrays are oversized by
108 two entries and FAILSAFE_ARRAYSIZE is the array size - 1, the template
109 size should equal FAILSAFE_ARRAYSIZE, with the array size being one
110 smaller than that.
111
112 For the debug build we check that this is actually the case, for the
113 release build we just return the (constant) value FAILSAFE_ARRAYSIZE - 1 */
114
115 #ifdef NDEBUG
116 #define templateCount( template ) \
117 FAILSAFE_ARRAYSIZE( template, CK_ATTRIBUTE ) - 1
118 #else
119
120 #define templateCount( template ) \
121 templateEntryCount( template, \
122 FAILSAFE_ARRAYSIZE( template, CK_ATTRIBUTE ) )
123
templateEntryCount(IN_ARRAY (templateSize)const CK_ATTRIBUTE * template,IN_LENGTH_SHORT const int templateSize)124 static int templateEntryCount( IN_ARRAY( templateSize ) \
125 const CK_ATTRIBUTE *template,
126 IN_LENGTH_SHORT const int templateSize )
127 {
128 int i;
129
130 assert( isReadPtr( template, templateSize * sizeof( CK_ATTRIBUTE ) ) );
131
132 REQUIRES_EXT( templateSize > 0 && templateSize < 100, 0 );
133
134 for( i = 0; i < templateSize && template[ i ].type != CKA_NONE; i++ );
135 ENSURES_EXT( i == templateSize - 1, 0 );
136
137 return( i );
138 }
139 #endif /* Release vs. debug build */
140
141 /* When we've generated or loaded a key, the underlying device may impose
142 additional usage restrictions on it that go beyond what we've requested
143 at object-creation time. In order to deal with this we read back the
144 attributes that are set for the newly-created device object and update
145 the object's action flags to reflect this */
146
updateActionFlags(INOUT PKCS11_INFO * pkcs11Info,IN_HANDLE const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hObject,IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,const BOOLEAN isPrivateKey)147 static int updateActionFlags( INOUT PKCS11_INFO *pkcs11Info,
148 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
149 const CK_OBJECT_HANDLE hObject,
150 IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,
151 const BOOLEAN isPrivateKey )
152 {
153 int actionFlags, cryptStatus;
154
155 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
156
157 REQUIRES( isHandleRangeValid( iCryptContext ) );
158 REQUIRES( isPkcAlgo( cryptAlgo ) );
159
160 cryptStatus = actionFlags = \
161 getActionFlags( pkcs11Info, hObject,
162 isPrivateKey ? KEYMGMT_ITEM_PRIVATEKEY : \
163 KEYMGMT_ITEM_PUBLICKEY,
164 cryptAlgo );
165 if( cryptStatusError( cryptStatus ) )
166 return( cryptStatus );
167 return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
168 ( MESSAGE_CAST ) &actionFlags,
169 CRYPT_IATTRIBUTE_ACTIONPERMS ) );
170 }
171
172 /****************************************************************************
173 * *
174 * Capability Interface Routines *
175 * *
176 ****************************************************************************/
177
178 /* Sign data, check a signature. We use Sign and Verify rather than the
179 xxxRecover variants because there's no need to use Recover, and because
180 many implementations don't do Recover */
181
genericSign(PKCS11_INFO * pkcs11Info,CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,const void * inBuffer,const int inLength,void * outBuffer,const int outLength)182 static int genericSign( PKCS11_INFO *pkcs11Info,
183 CONTEXT_INFO *contextInfoPtr,
184 const CK_MECHANISM *pMechanism,
185 const void *inBuffer, const int inLength,
186 void *outBuffer, const int outLength )
187 {
188 CK_ULONG resultLen = outLength;
189 CK_RV status;
190
191 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
192 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
193 assert( isReadPtr( inBuffer, inLength ) );
194 assert( isWritePtr( outBuffer, outLength ) );
195
196 REQUIRES( inLength > 0 && inLength < MAX_INTLENGTH_SHORT );
197 REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
198
199 /* If we're currently in the middle of a multi-stage sign operation we
200 can't start a new one. We have to perform this tracking explicitly
201 since PKCS #11 only allows one multi-stage operation per session */
202 if( pkcs11Info->hActiveSignObject != CK_OBJECT_NONE )
203 return( CRYPT_ERROR_INCOMPLETE );
204
205 status = C_SignInit( pkcs11Info->hSession,
206 ( CK_MECHANISM_PTR ) pMechanism,
207 contextInfoPtr->deviceObject );
208 if( status == CKR_OK )
209 status = C_Sign( pkcs11Info->hSession, ( CK_BYTE_PTR ) inBuffer,
210 inLength, outBuffer, &resultLen );
211 if( status != CKR_OK )
212 return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
213
214 return( CRYPT_OK );
215 }
216
genericVerify(PKCS11_INFO * pkcs11Info,CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,const void * inBuffer,const int inLength,void * outBuffer,const int outLength)217 static int genericVerify( PKCS11_INFO *pkcs11Info,
218 CONTEXT_INFO *contextInfoPtr,
219 const CK_MECHANISM *pMechanism,
220 const void *inBuffer, const int inLength,
221 void *outBuffer, const int outLength )
222 {
223 CK_RV status;
224
225 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
226 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
227 assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
228 assert( isReadPtr( inBuffer, inLength ) );
229 assert( isWritePtr( outBuffer, outLength ) );
230
231 REQUIRES( inLength > 0 && inLength < MAX_INTLENGTH_SHORT );
232 REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
233
234 /* If we're currently in the middle of a multi-stage sign operation we
235 can't start a new one. We have to perform this tracking explicitly
236 since PKCS #11 only allows one multi-stage operation per session */
237 if( pkcs11Info->hActiveSignObject != CK_OBJECT_NONE )
238 return( CRYPT_ERROR_INCOMPLETE );
239
240 status = C_VerifyInit( pkcs11Info->hSession,
241 ( CK_MECHANISM_PTR ) pMechanism,
242 contextInfoPtr->deviceObject );
243 if( status == CKR_OK )
244 status = C_Verify( pkcs11Info->hSession, ( CK_BYTE_PTR ) inBuffer,
245 inLength, outBuffer, outLength );
246 if( status != CKR_OK )
247 return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
248
249 return( CRYPT_OK );
250 }
251
252 /* Encrypt, decrypt */
253
genericEncrypt(PKCS11_INFO * pkcs11Info,CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,void * buffer,const int length,const int outLength)254 static int genericEncrypt( PKCS11_INFO *pkcs11Info,
255 CONTEXT_INFO *contextInfoPtr,
256 const CK_MECHANISM *pMechanism, void *buffer,
257 const int length, const int outLength )
258 {
259 CK_ULONG resultLen = outLength;
260 CK_RV status;
261
262 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
263 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
264 assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
265 assert( isWritePtr( buffer, length ) );
266 assert( isWritePtr( buffer, outLength ) );
267
268 REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );
269 REQUIRES( outLength > 0 && outLength < MAX_INTLENGTH_SHORT );
270
271 status = C_EncryptInit( pkcs11Info->hSession,
272 ( CK_MECHANISM_PTR ) pMechanism,
273 contextInfoPtr->deviceObject );
274 if( status == CKR_OK )
275 status = C_Encrypt( pkcs11Info->hSession, buffer, length,
276 buffer, &resultLen );
277 if( status != CKR_OK )
278 return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
279
280 /* When performing RSA operations some buggy implementations perform
281 leading-zero trunction, so we restore leading zeroes if necessary */
282 if( ( pMechanism->mechanism == CKM_RSA_X_509 || \
283 pMechanism->mechanism == CKM_RSA_PKCS ) && \
284 ( int ) resultLen < length )
285 {
286 const int delta = length - resultLen;
287
288 REQUIRES( rangeCheck( delta, resultLen, length ) );
289 memmove( ( BYTE * ) buffer + delta, buffer, resultLen );
290 memset( buffer, 0, delta );
291 }
292
293 return( CRYPT_OK );
294 }
295
genericDecrypt(PKCS11_INFO * pkcs11Info,CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,void * buffer,const int length,int * resultLength)296 static int genericDecrypt( PKCS11_INFO *pkcs11Info,
297 CONTEXT_INFO *contextInfoPtr,
298 const CK_MECHANISM *pMechanism, void *buffer,
299 const int length, int *resultLength )
300 {
301 CK_ULONG resultLen = length;
302 CK_RV status;
303
304 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
305 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
306 assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
307 assert( isWritePtr( buffer, length ) );
308 assert( isWritePtr( resultLength, sizeof( int ) ) );
309
310 REQUIRES( length > 0 && length < MAX_INTLENGTH_SHORT );
311
312 status = C_DecryptInit( pkcs11Info->hSession,
313 ( CK_MECHANISM_PTR ) pMechanism,
314 contextInfoPtr->deviceObject );
315 if( status == CKR_OK )
316 status = C_Decrypt( pkcs11Info->hSession, buffer, length,
317 buffer, &resultLen );
318 if( status == CKR_KEY_FUNCTION_NOT_PERMITTED )
319 {
320 static const CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
321 static const CK_KEY_TYPE secretKeyType = CKK_GENERIC_SECRET;
322 static const CK_BBOOL bTrue = TRUE;
323 CK_ATTRIBUTE symTemplate[] = {
324 { CKA_CLASS, ( CK_VOID_PTR ) &secretKeyClass, sizeof( CK_OBJECT_CLASS ) },
325 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &secretKeyType, sizeof( CK_KEY_TYPE ) },
326 { CKA_EXTRACTABLE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
327 { CKA_VALUE_LEN, &resultLen, sizeof( CK_ULONG ) },
328 { CKA_NONE }, { CKA_NONE }
329 };
330 CK_OBJECT_HANDLE hSymKey;
331
332 /* If a straight decrypt isn't allowed, try an unwrap instead and
333 then export the key. This works because we're using the same
334 mechanism as for decrypt and converting the entire "unwrapped key"
335 into a generic secret key that we then extract, which is the
336 same as doing a straight decrypt of the data (this sort of thing
337 should require a note from your mother before you're allowed to do
338 it). The reason why it's done in this roundabout manner is that
339 this is what Netscape tries first, so people doing a minimal
340 implementation do this first and don't bother with anything else.
341 Note that doing it this way is rather slower than a straight
342 decrypt, which is why we try for decrypt first */
343 status = C_UnwrapKey( pkcs11Info->hSession,
344 ( CK_MECHANISM_PTR ) pMechanism,
345 contextInfoPtr->deviceObject, buffer, length,
346 symTemplate, templateCount( symTemplate ),
347 &hSymKey );
348 if( status == CKR_OK )
349 {
350 CK_ATTRIBUTE valueTemplate[] = { CKA_VALUE, buffer, length };
351
352 status = C_GetAttributeValue( pkcs11Info->hSession,
353 hSymKey, valueTemplate, 1 );
354 if( status == CKR_OK )
355 resultLen = valueTemplate[ 0 ].ulValueLen;
356 C_DestroyObject( pkcs11Info->hSession, hSymKey );
357 }
358 }
359 if( status != CKR_OK )
360 return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
361
362 /* When performing raw RSA operations some buggy implementations perform
363 leading-zero trunction, so we restore leading zeroes if necessary. We
364 can't do the restore with the PKCS mechanism since it always returns a
365 result length shorter than the input length */
366 if( pMechanism->mechanism == CKM_RSA_X_509 && \
367 ( int ) resultLen < length )
368 {
369 const int delta = length - resultLen;
370
371 REQUIRES( rangeCheck( delta, resultLen, length ) );
372 memmove( ( BYTE * ) buffer + delta, buffer, resultLen );
373 memset( buffer, 0, delta );
374 resultLen = length;
375 }
376
377 /* Some mechanisms change the data length, in which case we need to tell
378 the caller how much was actually returned */
379 if( resultLength != NULL )
380 *resultLength = ( int ) resultLen;
381 return( CRYPT_OK );
382 }
383
384 /****************************************************************************
385 * *
386 * DH Mapping Functions *
387 * *
388 ****************************************************************************/
389
390 #ifdef USE_DH
391
392 /* DH algorithm-specific mapping functions. These work somewhat differently
393 from the other PKC functions because DH objects are ephemeral, the only
394 fixed values being p and g. In addition there's no real concept of
395 public and private keys, only an object where the CKA_VALUE attribute
396 contains y (nominally the public key) and one where it contains x
397 (nominally the private key). The use of DH objects then is as follows:
398
399 load/genkey: genkey with supplied p and g to produce x and y values;
400 save "public key" (y) as altObjectHandle;
401
402 DH phase 1: return public key CKA_VALUE (= y);
403
404 DH phase 2: derive using private key, y' = mechanism parameters */
405
dhSetPublicComponents(PKCS11_INFO * pkcs11Info,const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hDhKey,const void * q,const int qLen)406 int dhSetPublicComponents( PKCS11_INFO *pkcs11Info,
407 const CRYPT_CONTEXT iCryptContext,
408 const CK_OBJECT_HANDLE hDhKey,
409 const void *q, const int qLen )
410 {
411 BYTE p[ CRYPT_MAX_PKCSIZE + 8 ], g[ CRYPT_MAX_PKCSIZE + 8 ];
412 BYTE y[ CRYPT_MAX_PKCSIZE + 8 ];
413 BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ];
414 MESSAGE_DATA msgData;
415 int pLen, gLen DUMMY_INIT, yLen DUMMY_INIT, keyDataSize, cryptStatus;
416
417 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
418 assert( isReadPtr( q, qLen ) );
419
420 REQUIRES( isHandleRangeValid( iCryptContext ) );
421 REQUIRES( qLen > 0 && qLen <= CRYPT_MAX_PKCSIZE );
422
423 /* Get the public key components from the device */
424 cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_PRIME,
425 p, CRYPT_MAX_PKCSIZE, &pLen );
426 if( cryptStatusOK( cryptStatus ) )
427 cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_BASE,
428 g, CRYPT_MAX_PKCSIZE, &gLen );
429 if( cryptStatusOK( cryptStatus ) )
430 cryptStatus = readAttributeValue( pkcs11Info, hDhKey, CKA_VALUE,
431 y, CRYPT_MAX_PKCSIZE, &yLen );
432 if( cryptStatusError( cryptStatus ) )
433 return( cryptStatus );
434
435 /* Send the public key data to the context. We send the keying
436 information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
437 CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
438 into the high state. We don't want to do this because we're already
439 in the middle of processing a message that does this on completion,
440 all that we're doing here is sending in encoded public key data for
441 use by objects such as certificates */
442 cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 3,
443 &keyDataSize, CRYPT_ALGO_DH, 0,
444 p, pLen, g, gLen, q, qLen, y, yLen );
445 if( cryptStatusOK( cryptStatus ) )
446 {
447 setMessageData( &msgData, keyDataBuffer, keyDataSize );
448 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
449 &msgData,
450 CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
451 }
452 return( cryptStatus );
453 }
454
dhInitKey(CONTEXT_INFO * contextInfoPtr,const void * key,const int keyLength)455 static int dhInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
456 const int keyLength )
457 {
458 static const CK_MECHANISM mechanism = { CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
459 static const CK_BBOOL bTrue = TRUE;
460 CK_ATTRIBUTE privateKeyTemplate[] = {
461 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
462 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
463 { CKA_DERIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
464 { CKA_NONE }, { CKA_NONE }
465 };
466 CK_ATTRIBUTE publicKeyTemplate[] = {
467 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
468 { CKA_DERIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
469 { CKA_PRIME, NULL, 0 },
470 { CKA_BASE, NULL, 0 },
471 { CKA_NONE }, { CKA_NONE }
472 };
473 CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
474 CK_RV status;
475 const CRYPT_PKCINFO_DLP *dhKey = ( CRYPT_PKCINFO_DLP * ) key;
476 CRYPT_DEVICE iCryptDevice;
477 PKCS11_INFO *pkcs11Info;
478 int cryptStatus;
479
480 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
481 assert( isReadPtr( key, keyLength ) );
482
483 REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_DLP ) );
484
485 /* Get the information for the device associated with this context */
486 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
487 &iCryptDevice, &pkcs11Info );
488 if( cryptStatusError( cryptStatus ) )
489 return( cryptStatus );
490
491 /* Generate the keys. We can't set CKA_SENSITIVE for the private key
492 because although this is appropriate for the key (we don't want people
493 extracting the x value), some implementations carry it over to the
494 derived key in phase 2 and make that non-extractable as well */
495 setTemplate( publicKeyTemplate, CKA_PRIME, dhKey->p, dhKey->pLen );
496 setTemplate( publicKeyTemplate, CKA_BASE, dhKey->g, dhKey->gLen );
497 status = C_GenerateKeyPair( pkcs11Info->hSession,
498 ( CK_MECHANISM_PTR ) &mechanism,
499 ( CK_ATTRIBUTE_PTR ) publicKeyTemplate,
500 templateCount( publicKeyTemplate ),
501 ( CK_ATTRIBUTE_PTR ) privateKeyTemplate,
502 templateCount( privateKeyTemplate ),
503 &hPublicKey, &hPrivateKey );
504 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
505 if( cryptStatusError( cryptStatus ) )
506 {
507 krnlReleaseObject( iCryptDevice );
508 return( cryptStatus );
509 }
510
511 /* Send the keying information to the context */
512 cryptStatus = dhSetPublicComponents( pkcs11Info,
513 contextInfoPtr->objectHandle,
514 hPublicKey, dhKey->q,
515 bitsToBytes( dhKey->qLen ) );
516 if( cryptStatusError( cryptStatus ) )
517 {
518 krnlReleaseObject( iCryptDevice );
519 return( cryptStatus );
520 }
521
522 /* Remember what we've set up. Unlike conventional PKC algorithms for
523 which we only store the private-key object handle, for DH key
524 agreement we need to store the handles for both objects */
525 cryptStatus = krnlSendMessage( contextInfoPtr->objectHandle,
526 IMESSAGE_SETATTRIBUTE,
527 ( MESSAGE_CAST ) &hPrivateKey,
528 CRYPT_IATTRIBUTE_DEVICEOBJECT );
529 if( cryptStatusOK( cryptStatus ) )
530 {
531 contextInfoPtr->altDeviceObject = hPublicKey;
532 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
533 }
534 krnlReleaseObject( iCryptDevice );
535 return( cryptStatus );
536 }
537
dhGenerateKey(CONTEXT_INFO * contextInfoPtr,const int keysizeBits)538 static int dhGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
539 {
540 CRYPT_PKCINFO_DLP dhKey;
541 MESSAGE_CREATEOBJECT_INFO createInfo;
542 MESSAGE_DATA msgData;
543 BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
544 STREAM stream;
545 int length, cryptStatus;
546
547 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
548
549 REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
550 keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
551
552 /* CKM_DH_KEY_PAIR_GEN is really a Clayton's key generation mechanism
553 since it doesn't actually generate the p, g values. Because of this
554 we have to generate half the key ourselves in a native context, then
555 copy portions from the native context over in flat form and complete
556 the keygen via the device. The easiest way to do this is to create a
557 native DH context, generate a key, grab the public portions, and
558 destroy the context again. Since the keygen can take awhile and
559 doesn't require the device, we do it before we grab the device */
560 setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_DH );
561 cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
562 IMESSAGE_DEV_CREATEOBJECT, &createInfo,
563 OBJECT_TYPE_CONTEXT );
564 if( cryptStatusError( cryptStatus ) )
565 return( cryptStatus );
566 setMessageData( &msgData, label, 8 );
567 krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
568 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
569 krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S,
570 &msgData, CRYPT_CTXINFO_LABEL );
571 cryptStatus = krnlSendNotifier( createInfo.cryptHandle,
572 IMESSAGE_CTX_GENKEY );
573 if( cryptStatusOK( cryptStatus ) )
574 {
575 setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
576 cryptStatus = krnlSendMessage( createInfo.cryptHandle,
577 IMESSAGE_GETATTRIBUTE_S, &msgData,
578 CRYPT_IATTRIBUTE_KEY_SPKI );
579 }
580 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
581 if( cryptStatusError( cryptStatus ) )
582 return( cryptStatus );
583
584 /* Set up the public key information by extracting the flat values from
585 the SubjectPublicKeyInfo. Note that the data used is represented in
586 DER-canonical form, there may be PKCS #11 implementations that can't
587 handle this (for example they may require p to be zero-padded to make
588 it exactly n bytes rather than (say) n - 1 bytes if the high byte is
589 zero) */
590 cryptInitComponents( &dhKey, CRYPT_KEYTYPE_PUBLIC );
591 sMemConnect( &stream, pubkeyBuffer, msgData.length );
592 readSequence( &stream, NULL ); /* SEQUENCE */
593 readSequence( &stream, NULL ); /* SEQUENCE */
594 readUniversal( &stream ); /* OID */
595 readSequence( &stream, NULL ); /* SEQUENCE */
596 readGenericHole( &stream, &length, 16, BER_INTEGER ); /* p */
597 cryptStatus = sread( &stream, dhKey.p, length );
598 if( cryptStatusOK( cryptStatus ) )
599 {
600 dhKey.pLen = bytesToBits( length );
601 readGenericHole( &stream, &length, 16, BER_INTEGER ); /* q */
602 cryptStatus = sread( &stream, dhKey.q, length );
603 }
604 if( cryptStatusOK( cryptStatus ) )
605 {
606 dhKey.qLen = bytesToBits( length );
607 readGenericHole( &stream, &length, 16, BER_INTEGER ); /* g */
608 cryptStatus = sread( &stream, dhKey.g, length );
609 }
610 if( cryptStatusOK( cryptStatus ) )
611 dhKey.gLen = bytesToBits( length );
612 sMemDisconnect( &stream );
613 REQUIRES( cryptStatusOK( cryptStatus ) );
614
615 /* From here on it's a standard DH key load */
616 return( dhInitKey( contextInfoPtr, &dhKey, sizeof( CRYPT_PKCINFO_DLP ) ) );
617 }
618
dhEncrypt(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)619 static int dhEncrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
620 {
621 CRYPT_DEVICE iCryptDevice;
622 PKCS11_INFO *pkcs11Info;
623 KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
624 int cryptStatus;
625
626 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
627 assert( isWritePtr( buffer, length ) );
628
629 REQUIRES( length == sizeof( KEYAGREE_PARAMS ) );
630
631 /* Get the information for the device associated with this context */
632 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
633 &iCryptDevice, &pkcs11Info );
634 if( cryptStatusError( cryptStatus ) )
635 return( cryptStatus );
636
637 /* Get the y value from phase 1 of the DH key agreement (generated when
638 the key was loaded/generated) from the device */
639 cryptStatus = readAttributeValue( pkcs11Info,
640 contextInfoPtr->altDeviceObject, CKA_VALUE,
641 keyAgreeParams->publicValue, CRYPT_MAX_PKCSIZE,
642 &keyAgreeParams->publicValueLen );
643 krnlReleaseObject( iCryptDevice );
644 return( cryptStatus );
645 }
646
dhDecrypt(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)647 static int dhDecrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
648 {
649 static const CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY;
650 static const CK_KEY_TYPE secretKeyType = CKK_GENERIC_SECRET;
651 static const CK_BBOOL bTrue = TRUE;
652 CK_MECHANISM mechanism = { CKM_DH_PKCS_DERIVE, NULL_PTR, 0 };
653 CK_ULONG valueLen;
654 CK_ATTRIBUTE symTemplate[] = {
655 { CKA_CLASS, ( CK_VOID_PTR ) &secretKeyClass, sizeof( CK_OBJECT_CLASS ) },
656 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &secretKeyType, sizeof( CK_KEY_TYPE ) },
657 { CKA_EXTRACTABLE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
658 { CKA_VALUE_LEN, &valueLen, sizeof( CK_ULONG ) },
659 { CKA_NONE }, { CKA_NONE }
660 };
661 CK_OBJECT_HANDLE hSymKey;
662 CK_RV status;
663 CRYPT_DEVICE iCryptDevice;
664 PKCS11_INFO *pkcs11Info;
665 KEYAGREE_PARAMS *keyAgreeParams = ( KEYAGREE_PARAMS * ) buffer;
666 int cryptStatus;
667
668 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
669 assert( isWritePtr( buffer, length ) );
670
671 REQUIRES( length == sizeof( KEYAGREE_PARAMS ) );
672 REQUIRES( keyAgreeParams->publicValue != NULL && \
673 keyAgreeParams->publicValueLen >= MIN_PKCSIZE && \
674 keyAgreeParams->publicValueLen < MAX_INTLENGTH_SHORT );
675
676 /* Get the information for the device associated with this context */
677 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
678 &iCryptDevice, &pkcs11Info );
679 if( cryptStatusError( cryptStatus ) )
680 return( cryptStatus );
681
682 /* Use the supplied y value to perform phase 2 of the DH key agreement.
683 Since PKCS #11 mechanisms don't allow the resulting data to be
684 returned directly, we move it into a generic secret-key object and
685 then read it from that */
686 valueLen = keyAgreeParams->publicValueLen; /* symTemplate[4].pValue */
687 mechanism.pParameter = keyAgreeParams->publicValue;
688 mechanism.ulParameterLen = keyAgreeParams->publicValueLen;
689 status = C_DeriveKey( pkcs11Info->hSession, &mechanism,
690 contextInfoPtr->deviceObject,
691 symTemplate, templateCount( symTemplate ),
692 &hSymKey );
693 if( status == CKR_OK )
694 {
695 CK_ATTRIBUTE valueTemplate[] = { CKA_VALUE, keyAgreeParams->wrappedKey,
696 valueLen };
697
698 status = C_GetAttributeValue( pkcs11Info->hSession,
699 hSymKey, valueTemplate, 1 );
700 if( status == CKR_OK )
701 keyAgreeParams->wrappedKeyLen = valueTemplate[ 0 ].ulValueLen;
702 C_DestroyObject( pkcs11Info->hSession, hSymKey );
703 }
704 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
705 krnlReleaseObject( iCryptDevice );
706 return( cryptStatus );
707 }
708 #endif /* USE_DH */
709
710 /****************************************************************************
711 * *
712 * RSA Mapping Functions *
713 * *
714 ****************************************************************************/
715
716 /* RSA algorithm-specific mapping functions. Externally we always appear to
717 use the X.509 (raw) mechanism for the encrypt/decrypt/sign/verify
718 functions since cryptlib does its own padding (with workarounds for
719 various bugs and peculiarities). Internally however we have to use the
720 PKCS mechanism since some implementations don't support the X.509
721 mechanism, and add/remove the padding to fake out the presence of a raw
722 RSA mechanism */
723
724 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
rsaSetPublicComponents(INOUT PKCS11_INFO * pkcs11Info,IN_HANDLE const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hRsaKey,const BOOLEAN nativeContext)725 int rsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info,
726 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
727 const CK_OBJECT_HANDLE hRsaKey,
728 const BOOLEAN nativeContext )
729 {
730 BYTE n[ CRYPT_MAX_PKCSIZE + 8 ], e[ CRYPT_MAX_PKCSIZE + 8 ];
731 BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 2 ) + 8 ];
732 MESSAGE_DATA msgData;
733 int nLen, eLen DUMMY_INIT, keyDataSize, cryptStatus;
734
735 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
736
737 REQUIRES( isHandleRangeValid( iCryptContext ) );
738
739 /* Get the public key components from the device */
740 cryptStatus = readAttributeValue( pkcs11Info, hRsaKey, CKA_MODULUS,
741 n, CRYPT_MAX_PKCSIZE, &nLen );
742 if( cryptStatusOK( cryptStatus ) )
743 cryptStatus = readAttributeValue( pkcs11Info, hRsaKey, CKA_PUBLIC_EXPONENT,
744 e, CRYPT_MAX_PKCSIZE, &eLen );
745 if( cryptStatusError( cryptStatus ) )
746 return( cryptStatus );
747
748 /* Send the public key data to the context. We send the keying
749 information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
750 CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
751 into the high state. We don't want to do this because we're already
752 in the middle of processing a message that does this on completion,
753 all that we're doing here is sending in encoded public key data for
754 use by objects such as certificates */
755 cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 2,
756 &keyDataSize, CRYPT_ALGO_RSA, 0,
757 n, nLen, e, eLen, NULL, 0, NULL, 0 );
758 if( cryptStatusError( cryptStatus ) )
759 return( cryptStatus );
760 setMessageData( &msgData, keyDataBuffer, keyDataSize );
761 if( nativeContext )
762 {
763 return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
764 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI ) );
765 }
766 return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
767 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL ) );
768 }
769
rsaSetKeyInfo(PKCS11_INFO * pkcs11Info,CONTEXT_INFO * contextInfoPtr,const CK_OBJECT_HANDLE hPrivateKey,const CK_OBJECT_HANDLE hPublicKey)770 static int rsaSetKeyInfo( PKCS11_INFO *pkcs11Info,
771 CONTEXT_INFO *contextInfoPtr,
772 const CK_OBJECT_HANDLE hPrivateKey,
773 const CK_OBJECT_HANDLE hPublicKey )
774 {
775 MESSAGE_DATA msgData;
776 BYTE idBuffer[ KEYID_SIZE + 8 ];
777 int cryptStatus;
778
779 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
780 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
781
782 /* Remember what we've set up. Note that PKCS #11 tokens create
783 distinct public- and private-key objects but we're only interested
784 in the private-key one, so we store the private-key object handle
785 in the context */
786 cryptStatus = krnlSendMessage( contextInfoPtr->objectHandle,
787 IMESSAGE_SETATTRIBUTE,
788 ( MESSAGE_CAST ) &hPrivateKey,
789 CRYPT_IATTRIBUTE_DEVICEOBJECT );
790 if( cryptStatusError( cryptStatus ) )
791 return( cryptStatus );
792 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
793
794 /* Get the key ID from the context and use it as the object ID. Since
795 some objects won't allow after-the-event ID updates, we don't treat a
796 failure to update as an error. We do however assert on it in debug
797 mode since if we later want to update the key with a certificate then
798 we need the ID set in order to locate the object that the certificate
799 is associated with */
800 setMessageData( &msgData, idBuffer, KEYID_SIZE );
801 cryptStatus = krnlSendMessage( contextInfoPtr->objectHandle,
802 IMESSAGE_GETATTRIBUTE_S, &msgData,
803 CRYPT_IATTRIBUTE_KEYID );
804 if( cryptStatusOK( cryptStatus ) )
805 {
806 CK_ATTRIBUTE idTemplate = { CKA_ID, msgData.data, msgData.length };
807 CK_RV status;
808
809 if( hPublicKey != CK_OBJECT_NONE )
810 {
811 status = C_SetAttributeValue( pkcs11Info->hSession, hPublicKey,
812 &idTemplate, 1 );
813 assert( status == CKR_OK );
814 }
815 status = C_SetAttributeValue( pkcs11Info->hSession, hPrivateKey,
816 &idTemplate, 1 );
817 assert( status == CKR_OK );
818 }
819
820 return( cryptStatus );
821 }
822
rsaInitKey(CONTEXT_INFO * contextInfoPtr,const void * key,const int keyLength)823 static int rsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
824 const int keyLength )
825 {
826 static const CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
827 static const CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
828 static const CK_KEY_TYPE type = CKK_RSA;
829 static const CK_BBOOL bTrue = TRUE;
830 CK_ATTRIBUTE publicKeyTemplate[] = {
831 { CKA_CLASS, ( CK_VOID_PTR ) &pubKeyClass, sizeof( CK_OBJECT_CLASS ) },
832 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
833 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
834 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
835 { CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
836 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
837 { CKA_MODULUS, NULL, 0 },
838 { CKA_PUBLIC_EXPONENT, NULL, 0 },
839 { CKA_NONE }, { CKA_NONE }
840 };
841 CK_ATTRIBUTE privateKeyTemplate[] = {
842 { CKA_CLASS, ( CK_VOID_PTR ) &privKeyClass, sizeof( CK_OBJECT_CLASS ) },
843 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
844 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
845 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
846 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
847 { CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
848 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
849 { CKA_MODULUS, NULL, 0 },
850 { CKA_PUBLIC_EXPONENT, NULL, 0 },
851 { CKA_PRIVATE_EXPONENT, NULL, 0 },
852 { CKA_PRIME_1, NULL, 0 },
853 { CKA_PRIME_2, NULL, 0 },
854 { CKA_EXPONENT_1, NULL, 0 },
855 { CKA_EXPONENT_2, NULL, 0 },
856 { CKA_COEFFICIENT, NULL, 0 },
857 { CKA_NONE }, { CKA_NONE }
858 };
859 const CRYPT_PKCINFO_RSA *rsaKey = ( CRYPT_PKCINFO_RSA * ) key;
860 CK_ATTRIBUTE *keyTemplate = rsaKey->isPublicKey ? \
861 publicKeyTemplate : privateKeyTemplate;
862 const int keyTemplateCount = rsaKey->isPublicKey ? \
863 templateCount( publicKeyTemplate ) : \
864 templateCount( privateKeyTemplate );
865 CRYPT_DEVICE iCryptDevice;
866 PKCS11_INFO *pkcs11Info;
867 CK_OBJECT_HANDLE hRsaKey;
868 CK_RV status;
869 int cryptStatus;
870
871 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
872 assert( isReadPtr( key, keyLength ) );
873
874 REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_RSA ) );
875
876 /* Get the information for the device associated with this context */
877 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
878 &iCryptDevice, &pkcs11Info );
879 if( cryptStatusError( cryptStatus ) )
880 return( cryptStatus );
881
882 /* Set up the key values */
883 if( rsaKey->isPublicKey )
884 {
885 setTemplate( publicKeyTemplate, CKA_MODULUS, rsaKey->n,
886 bitsToBytes( rsaKey->nLen ) );
887 setTemplate( publicKeyTemplate, CKA_PUBLIC_EXPONENT, rsaKey->e,
888 bitsToBytes( rsaKey->eLen ) );
889 }
890 else
891 {
892 setTemplate( privateKeyTemplate, CKA_MODULUS, rsaKey->n,
893 bitsToBytes( rsaKey->nLen ) );
894 setTemplate( privateKeyTemplate, CKA_PUBLIC_EXPONENT, rsaKey->e,
895 bitsToBytes( rsaKey->eLen ) );
896 setTemplate( privateKeyTemplate, CKA_PRIVATE_EXPONENT, rsaKey->d,
897 bitsToBytes( rsaKey->dLen ) );
898 setTemplate( privateKeyTemplate, CKA_PRIME_1, rsaKey->p,
899 bitsToBytes( rsaKey->pLen ) );
900 setTemplate( privateKeyTemplate, CKA_PRIME_2, rsaKey->q,
901 bitsToBytes( rsaKey->qLen ) );
902 setTemplate( privateKeyTemplate, CKA_EXPONENT_1, rsaKey->e1,
903 bitsToBytes( rsaKey->e1Len ) );
904 setTemplate( privateKeyTemplate, CKA_EXPONENT_2, rsaKey->e2,
905 bitsToBytes( rsaKey->e2Len ) );
906 setTemplate( privateKeyTemplate, CKA_COEFFICIENT, rsaKey->u,
907 bitsToBytes( rsaKey->uLen ) );
908 }
909
910 /* Load the key into the token */
911 status = C_CreateObject( pkcs11Info->hSession, keyTemplate,
912 keyTemplateCount, &hRsaKey );
913 zeroise( keyTemplate, sizeof( CK_ATTRIBUTE ) * keyTemplateCount );
914 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
915 if( cryptStatusError( cryptStatus ) )
916 {
917 /* If we're trying to set a public key and this is one of those
918 tinkertoy tokens that only does private-key ops, return a more
919 appropriate error code */
920 if( rsaKey->isPublicKey && \
921 contextInfoPtr->capabilityInfo->encryptFunction == NULL &&
922 contextInfoPtr->capabilityInfo->sigCheckFunction == NULL )
923 cryptStatus = CRYPT_ERROR_NOTAVAIL;
924
925 krnlReleaseObject( iCryptDevice );
926 return( cryptStatus );
927 }
928
929 /* Send the keying information to the context and set up the key ID
930 information */
931 cryptStatus = rsaSetPublicComponents( pkcs11Info,
932 contextInfoPtr->objectHandle, hRsaKey,
933 FALSE );
934 if( cryptStatusOK( cryptStatus ) )
935 cryptStatus = rsaSetKeyInfo( pkcs11Info, contextInfoPtr,
936 hRsaKey, CK_OBJECT_NONE );
937 if( cryptStatusOK( cryptStatus ) )
938 {
939 cryptStatus = updateActionFlags( pkcs11Info,
940 contextInfoPtr->objectHandle,
941 hRsaKey, CRYPT_ALGO_RSA,
942 !rsaKey->isPublicKey );
943 }
944 if( cryptStatusError( cryptStatus ) )
945 C_DestroyObject( pkcs11Info->hSession, hRsaKey );
946 else
947 {
948 /* Remember that this object is backed by a crypto device */
949 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
950 }
951
952 krnlReleaseObject( iCryptDevice );
953 return( cryptStatus );
954 }
955
rsaGenerateKey(CONTEXT_INFO * contextInfoPtr,const int keysizeBits)956 static int rsaGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
957 {
958 static const CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
959 static const CK_BBOOL bTrue = TRUE;
960 static const BYTE exponent[] = { 0x01, 0x00, 0x01 };
961 const CK_ULONG modulusBits = keysizeBits;
962 CK_ATTRIBUTE privateKeyTemplate[] = {
963 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
964 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
965 { CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
966 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
967 { CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
968 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
969 { CKA_NONE }, { CKA_NONE }
970 };
971 CK_ATTRIBUTE publicKeyTemplate[] = {
972 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
973 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
974 { CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
975 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
976 { CKA_PUBLIC_EXPONENT, ( CK_VOID_PTR ) exponent, sizeof( exponent ) },
977 { CKA_MODULUS_BITS, ( CK_VOID_PTR ) &modulusBits, sizeof( CK_ULONG ) },
978 { CKA_NONE }, { CKA_NONE }
979 };
980 CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
981 CRYPT_DEVICE iCryptDevice;
982 PKCS11_INFO *pkcs11Info;
983 CK_RV status;
984 int cryptStatus;
985
986 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
987
988 REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
989 keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
990
991 /* Get the information for the device associated with this context */
992 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
993 &iCryptDevice, &pkcs11Info );
994 if( cryptStatusError( cryptStatus ) )
995 return( cryptStatus );
996
997 /* Generate the keys */
998 status = C_GenerateKeyPair( pkcs11Info->hSession,
999 ( CK_MECHANISM_PTR ) &mechanism,
1000 publicKeyTemplate,
1001 templateCount( publicKeyTemplate ),
1002 privateKeyTemplate,
1003 templateCount( privateKeyTemplate ),
1004 &hPublicKey, &hPrivateKey );
1005 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1006 if( cryptStatusError( cryptStatus ) )
1007 {
1008 krnlReleaseObject( iCryptDevice );
1009 return( cryptStatus );
1010 }
1011
1012 /* Send the keying information to the context and set up the key ID
1013 information */
1014 cryptStatus = rsaSetPublicComponents( pkcs11Info,
1015 contextInfoPtr->objectHandle,
1016 hPublicKey, FALSE );
1017 if( cryptStatusOK( cryptStatus ) )
1018 cryptStatus = rsaSetKeyInfo( pkcs11Info, contextInfoPtr, hPrivateKey,
1019 hPublicKey );
1020 if( cryptStatusOK( cryptStatus ) )
1021 {
1022 cryptStatus = updateActionFlags( pkcs11Info,
1023 contextInfoPtr->objectHandle,
1024 hPrivateKey, CRYPT_ALGO_RSA, TRUE );
1025 }
1026 if( cryptStatusError( cryptStatus ) )
1027 {
1028 C_DestroyObject( pkcs11Info->hSession, hPublicKey );
1029 C_DestroyObject( pkcs11Info->hSession, hPrivateKey );
1030 }
1031 else
1032 {
1033 /* Remember that this object is backed by a crypto device */
1034 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1035 }
1036
1037 krnlReleaseObject( iCryptDevice );
1038 return( cryptStatus );
1039 }
1040
rsaSign(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1041 static int rsaSign( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1042 {
1043 static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
1044 CRYPT_DEVICE iCryptDevice;
1045 PKCS11_INFO *pkcs11Info;
1046 BYTE *bufPtr = buffer;
1047 const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
1048 int cryptStatus, i;
1049
1050 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1051 assert( isWritePtr( buffer, length ) );
1052
1053 REQUIRES( length == keySize );
1054
1055 /* Undo the PKCS #1 padding to make CKM_RSA_PKCS look like
1056 CKM_RSA_X_509 */
1057 REQUIRES( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 1 && bufPtr[ 2 ] == 0xFF );
1058 for( i = 2; i < keySize; i++ )
1059 {
1060 if( bufPtr[ i ] == 0 )
1061 break;
1062 }
1063 i++; /* Skip final 0 byte */
1064
1065 /* Get the information for the device associated with this context */
1066 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1067 &iCryptDevice, &pkcs11Info );
1068 if( cryptStatusError( cryptStatus ) )
1069 return( cryptStatus );
1070 cryptStatus = genericSign( pkcs11Info, contextInfoPtr, &mechanism,
1071 bufPtr + i, keySize - i, buffer, keySize );
1072 krnlReleaseObject( iCryptDevice );
1073 return( cryptStatus );
1074 }
1075
rsaVerify(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1076 static int rsaVerify( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1077 {
1078 static const CK_MECHANISM mechanism = { CKM_RSA_X_509, NULL_PTR, 0 };
1079 CRYPT_DEVICE iCryptDevice;
1080 PKCS11_INFO *pkcs11Info;
1081 BYTE data[ CRYPT_MAX_PKCSIZE + 8 ];
1082 const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
1083 int cryptStatus;
1084
1085 /* This function is present but isn't used as part of any normal
1086 operation because cryptlib does the same thing much faster in
1087 software and because some tokens don't support public-key
1088 operations */
1089 DEBUG_PRINT(( "Warning: rsaVerify() called for device object, should "
1090 "be handled via native object.\n" ));
1091
1092 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1093 assert( isWritePtr( buffer, length ) );
1094
1095 REQUIRES( length == keySize );
1096
1097 /* Get the information for the device associated with this context */
1098 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1099 &iCryptDevice, &pkcs11Info );
1100 if( cryptStatusError( cryptStatus ) )
1101 return( cryptStatus );
1102 cryptStatus = genericVerify( pkcs11Info, contextInfoPtr, &mechanism,
1103 data, keySize, buffer, keySize );
1104 krnlReleaseObject( iCryptDevice );
1105 return( cryptStatus );
1106 }
1107
rsaEncrypt(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1108 static int rsaEncrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1109 {
1110 static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
1111 CRYPT_DEVICE iCryptDevice;
1112 PKCS11_INFO *pkcs11Info;
1113 BYTE *bufPtr = buffer;
1114 const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
1115 int cryptStatus, i;
1116
1117 /* This function is present but isn't used as part of any normal
1118 operation because cryptlib does the same thing much faster in
1119 software and because some tokens don't support public-key
1120 operations. The only way that it can be invoked is by calling
1121 cryptEncrypt() directly on a device context */
1122
1123 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1124 assert( isWritePtr( buffer, length ) );
1125
1126 REQUIRES( length == keySize );
1127
1128 /* Undo the PKCS #1 padding to make CKM_RSA_PKCS look like
1129 CKM_RSA_X_509 */
1130 assert( bufPtr[ 0 ] == 0 && bufPtr[ 1 ] == 2 );
1131 for( i = 2; i < keySize; i++ )
1132 {
1133 if( bufPtr[ i ] == 0 )
1134 break;
1135 }
1136 i++; /* Skip final 0 byte */
1137 memmove( bufPtr, bufPtr + i, keySize - i );
1138
1139 /* Get the information for the device associated with this context */
1140 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1141 &iCryptDevice, &pkcs11Info );
1142 if( cryptStatusError( cryptStatus ) )
1143 return( cryptStatus );
1144 cryptStatus = genericEncrypt( pkcs11Info, contextInfoPtr, &mechanism,
1145 bufPtr, keySize - i, keySize );
1146 krnlReleaseObject( iCryptDevice );
1147 return( cryptStatus );
1148 }
1149
rsaDecrypt(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1150 static int rsaDecrypt( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1151 {
1152 static const CK_MECHANISM mechanism = { CKM_RSA_PKCS, NULL_PTR, 0 };
1153 CRYPT_DEVICE iCryptDevice;
1154 PKCS11_INFO *pkcs11Info;
1155 MESSAGE_DATA msgData;
1156 BYTE *bufPtr = buffer;
1157 const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
1158 int cryptStatus, i, resultLen;
1159
1160 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1161 assert( isWritePtr( buffer, length ) );
1162
1163 REQUIRES( length == keySize );
1164
1165 /* Get the information for the device associated with this context */
1166 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1167 &iCryptDevice, &pkcs11Info );
1168 if( cryptStatusError( cryptStatus ) )
1169 return( cryptStatus );
1170 cryptStatus = genericDecrypt( pkcs11Info, contextInfoPtr, &mechanism,
1171 buffer, keySize, &resultLen );
1172 krnlReleaseObject( iCryptDevice );
1173 if( cryptStatusError( cryptStatus ) )
1174 return( cryptStatus );
1175
1176 /* Redo the PKCS #1 padding so CKM_RSA_PKCS look like CKM_RSA_X_509.
1177 Note that this doesn't have to be cryptographically strong since
1178 it gets stripped as soon as we return to the caller, it just has
1179 to be random:
1180
1181 bufPtr keySize
1182 | |
1183 +---+---+------------+---+----------+
1184 | 0 | 1 | random | 0 | key |
1185 +---+---+------------+---+----------+
1186 | | | |
1187 <------------> <---------->
1188 keySize - resultLen
1189 resultLen - 3
1190
1191 This gets a bit ugly because the random padding has to be nonzero,
1192 which would require using the non-nonce RNG. To work around this,
1193 we look for any zeroes in the data and fill them with some other
1194 value */
1195 REQUIRES( rangeCheck( keySize - resultLen, resultLen, length ) );
1196 memmove( bufPtr + keySize - resultLen, bufPtr, resultLen );
1197 bufPtr[ 0 ] = 0;
1198 bufPtr[ 1 ] = 2;
1199 setMessageData( &msgData, bufPtr + 2, keySize - resultLen - 3 );
1200 cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1201 IMESSAGE_GETATTRIBUTE_S, &msgData,
1202 CRYPT_IATTRIBUTE_RANDOM_NONCE );
1203 for( i = 2; i < keySize - resultLen - 1; i++ )
1204 {
1205 if( bufPtr[ i ] == 0 )
1206 {
1207 /* Create some sort of non-constant non-zero value to replace
1208 the zero byte with, since PKCS #1 can't have zero bytes.
1209 Note again that this doesn't have to be a strong random
1210 value, it just has to vary a bit */
1211 const int pad = 0xAA ^ ( i & 0xFF );
1212 bufPtr[ i ] = pad ? pad : 0x21;
1213 }
1214 }
1215 bufPtr[ keySize - resultLen - 1 ] = 0;
1216 ENSURES( 2 + ( keySize - resultLen - 3 ) + 1 + resultLen == keySize );
1217
1218 return( cryptStatus );
1219 }
1220
1221 /****************************************************************************
1222 * *
1223 * DSA Mapping Functions *
1224 * *
1225 ****************************************************************************/
1226
1227 #ifdef USE_DSA
1228
1229 /* DSA algorithm-specific mapping functions */
1230
dsaSetKeyInfo(PKCS11_INFO * pkcs11Info,const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hPrivateKey,const CK_OBJECT_HANDLE hPublicKey,const void * p,const int pLen,const void * q,const int qLen,const void * g,const int gLen,const void * y,const int yLen,const BOOLEAN nativeContext)1231 static int dsaSetKeyInfo( PKCS11_INFO *pkcs11Info,
1232 const CRYPT_CONTEXT iCryptContext,
1233 const CK_OBJECT_HANDLE hPrivateKey,
1234 const CK_OBJECT_HANDLE hPublicKey,
1235 const void *p, const int pLen,
1236 const void *q, const int qLen,
1237 const void *g, const int gLen,
1238 const void *y, const int yLen,
1239 const BOOLEAN nativeContext )
1240 {
1241 MESSAGE_DATA msgData;
1242 BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 4 ) + 8 ];
1243 BYTE idBuffer[ KEYID_SIZE + 8 ];
1244 int keyDataSize, cryptStatus;
1245
1246 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1247 assert( isReadPtr( p, pLen ) );
1248 assert( isReadPtr( q, qLen ) );
1249 assert( isReadPtr( g, gLen ) );
1250 assert( isReadPtr( y, yLen ) );
1251
1252 REQUIRES( isHandleRangeValid( iCryptContext ) );
1253
1254 /* Send the public key data to the context. We send the keying
1255 information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
1256 CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
1257 into the high state. We don't want to do this because we're already
1258 in the middle of processing a message that does this on completion,
1259 all that we're doing here is sending in encoded public key data for
1260 use by objects such as certificates */
1261 cryptStatus = writeFlatPublicKey( keyDataBuffer, CRYPT_MAX_PKCSIZE * 3,
1262 &keyDataSize, CRYPT_ALGO_DSA, 0,
1263 p, pLen, q, qLen, g, gLen, y, yLen );
1264 if( cryptStatusError( cryptStatus ) )
1265 return( cryptStatus );
1266 setMessageData( &msgData, keyDataBuffer, keyDataSize );
1267 if( nativeContext )
1268 {
1269 /* If we're just setting public key components for a native context,
1270 we're done */
1271 return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1272 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI ) );
1273 }
1274 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1275 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
1276 if( cryptStatusError( cryptStatus ) )
1277 return( cryptStatus );
1278
1279 /* Remember what we've set up. Note that PKCS #11 tokens create
1280 distinct public- and private-key objects but we're only interested
1281 in the private-key one, so we store the private-key object handle
1282 in the context */
1283 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
1284 ( MESSAGE_CAST ) &hPrivateKey,
1285 CRYPT_IATTRIBUTE_DEVICEOBJECT );
1286 if( cryptStatusError( cryptStatus ) )
1287 return( cryptStatus );
1288
1289 /* Get the key ID from the context and use it as the object ID. Since
1290 some objects won't allow after-the-event ID updates, we don't treat a
1291 failure to update as an error */
1292 setMessageData( &msgData, idBuffer, KEYID_SIZE );
1293 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
1294 &msgData, CRYPT_IATTRIBUTE_KEYID );
1295 if( cryptStatusOK( cryptStatus ) )
1296 {
1297 CK_ATTRIBUTE idTemplate = { CKA_ID, msgData.data, msgData.length };
1298
1299 if( hPublicKey != CRYPT_UNUSED )
1300 C_SetAttributeValue( pkcs11Info->hSession, hPublicKey,
1301 &idTemplate, 1 );
1302 C_SetAttributeValue( pkcs11Info->hSession, hPrivateKey,
1303 &idTemplate, 1 );
1304 }
1305
1306 return( cryptStatus );
1307 }
1308
1309 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
dsaSetPublicComponents(INOUT PKCS11_INFO * pkcs11Info,IN_HANDLE const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hDsaKey,const BOOLEAN nativeContext)1310 int dsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info,
1311 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
1312 const CK_OBJECT_HANDLE hDsaKey,
1313 const BOOLEAN nativeContext )
1314 {
1315 BYTE p[ CRYPT_MAX_PKCSIZE + 8 ], q[ CRYPT_MAX_PKCSIZE + 8 ];
1316 BYTE g[ CRYPT_MAX_PKCSIZE + 8 ], y[ CRYPT_MAX_PKCSIZE + 8 ];
1317 int pLen, qLen DUMMY_INIT, gLen DUMMY_INIT, yLen DUMMY_INIT;
1318 int cryptStatus;
1319
1320 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1321
1322 REQUIRES( isHandleRangeValid( iCryptContext ) );
1323
1324 /* Get the public key components from the device */
1325 cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_PRIME,
1326 p, CRYPT_MAX_PKCSIZE, &pLen );
1327 if( cryptStatusOK( cryptStatus ) )
1328 cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_SUBPRIME,
1329 q, CRYPT_MAX_PKCSIZE, &qLen );
1330 if( cryptStatusOK( cryptStatus ) )
1331 cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_BASE,
1332 g, CRYPT_MAX_PKCSIZE, &gLen );
1333 if( cryptStatusOK( cryptStatus ) )
1334 cryptStatus = readAttributeValue( pkcs11Info, hDsaKey, CKA_VALUE,
1335 y, CRYPT_MAX_PKCSIZE, &yLen );
1336 if( cryptStatusError( cryptStatus ) )
1337 return( cryptStatus );
1338
1339 return( dsaSetKeyInfo( pkcs11Info, iCryptContext, CK_OBJECT_NONE, hDsaKey,
1340 p, pLen, q, qLen, g, gLen, y, yLen, nativeContext ) );
1341 }
1342
dsaInitKey(CONTEXT_INFO * contextInfoPtr,const void * key,const int keyLength)1343 static int dsaInitKey( CONTEXT_INFO *contextInfoPtr, const void *key,
1344 const int keyLength )
1345 {
1346 static const CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
1347 static const CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
1348 static const CK_KEY_TYPE type = CKK_DSA;
1349 static const CK_BBOOL bTrue = TRUE;
1350 CK_ATTRIBUTE publicKeyTemplate[] = {
1351 { CKA_CLASS, ( CK_VOID_PTR ) &pubKeyClass, sizeof( CK_OBJECT_CLASS ) },
1352 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
1353 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1354 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1355 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1356 { CKA_PRIME, NULL, 0 },
1357 { CKA_SUBPRIME, NULL, 0 },
1358 { CKA_BASE, NULL, 0 },
1359 { CKA_VALUE, NULL, 0 },
1360 { CKA_NONE }, { CKA_NONE }
1361 };
1362 CK_ATTRIBUTE privateKeyTemplate[] = {
1363 { CKA_CLASS, ( CK_VOID_PTR ) &privKeyClass, sizeof( CK_OBJECT_CLASS ) },
1364 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
1365 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1366 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1367 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1368 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1369 { CKA_PRIME, NULL, 0 },
1370 { CKA_SUBPRIME, NULL, 0 },
1371 { CKA_BASE, NULL, 0 },
1372 { CKA_VALUE, NULL, 0 },
1373 { CKA_NONE }, { CKA_NONE }
1374 };
1375 const CRYPT_PKCINFO_DLP *dsaKey = ( CRYPT_PKCINFO_DLP * ) key;
1376 CK_ATTRIBUTE *keyTemplate = dsaKey->isPublicKey ? \
1377 publicKeyTemplate : privateKeyTemplate;
1378 const int keyTemplateCount = dsaKey->isPublicKey ? \
1379 templateCount( publicKeyTemplate ) : \
1380 templateCount( privateKeyTemplate );
1381 CRYPT_DEVICE iCryptDevice;
1382 PKCS11_INFO *pkcs11Info;
1383 CK_OBJECT_HANDLE hDsaKey;
1384 CK_RV status;
1385 BYTE yValue[ CRYPT_MAX_PKCSIZE + 8 ];
1386 const void *yValuePtr;
1387 int yValueLength, cryptStatus;
1388
1389 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1390 assert( isReadPtr( key, keyLength ) );
1391
1392 REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_DLP ) );
1393
1394 /* Creating a private-key object is somewhat problematic since the
1395 PKCS #11 interpretation of DSA reuses CKA_VALUE for x in the private
1396 key and y in the public key, so it's not possible to determine y from
1397 a private key because the x value is sensitive and can't be extracted
1398 (this isn't used in C_CreateObject() but is needed later for
1399 dsaSetKeyInfo()).
1400
1401 Because of this we have to create a native private-key context (which
1402 will generate the y value from x), read out the y value, and destroy
1403 it again (see the comments in the DSA generate key section for more on
1404 this problem). Since this doesn't require the device, we do it before
1405 we grab the device */
1406 if( !dsaKey->isPublicKey )
1407 {
1408 MESSAGE_CREATEOBJECT_INFO createInfo;
1409 MESSAGE_DATA msgData;
1410 STREAM stream;
1411 BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
1412 void *yValueDataPtr DUMMY_INIT_PTR;
1413 int yValueDataSize;
1414
1415 /* Create a native private-key DSA context, which generates the y
1416 value internally */
1417 setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_DSA );
1418 cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1419 IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1420 OBJECT_TYPE_CONTEXT );
1421 if( cryptStatusError( cryptStatus ) )
1422 return( cryptStatus );
1423 setMessageData( &msgData, label, 8 );
1424 krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
1425 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1426 krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S,
1427 &msgData, CRYPT_CTXINFO_LABEL );
1428 setMessageData( &msgData, ( MESSAGE_CAST ) dsaKey,
1429 sizeof( CRYPT_PKCINFO_DLP ) );
1430 cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1431 IMESSAGE_SETATTRIBUTE_S, &msgData,
1432 CRYPT_CTXINFO_KEY_COMPONENTS );
1433 if( cryptStatusError( cryptStatus ) )
1434 {
1435 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
1436 return( cryptStatus );
1437 }
1438
1439 /* Get the public key data and extract the y value from it. Note
1440 that the data used is represented in DER-canonical form, there may
1441 be PKCS #11 implementations that can't handle this (for example
1442 they may require y to be zero-padded to make it exactly 64 bytes
1443 rather than (say) 63 bytes if the high byte is zero) */
1444 setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
1445 cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1446 IMESSAGE_GETATTRIBUTE_S, &msgData,
1447 CRYPT_IATTRIBUTE_KEY_SPKI );
1448 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
1449 if( cryptStatusError( cryptStatus ) )
1450 return( cryptStatus );
1451 sMemConnect( &stream, msgData.data, msgData.length );
1452 readSequence( &stream, NULL ); /* SEQUENCE { */
1453 readUniversal( &stream ); /* AlgoID */
1454 readBitStringHole( &stream, NULL, 16, DEFAULT_TAG );/* BIT STRING */
1455 status = readGenericHole( &stream, &yValueDataSize, 16,
1456 BER_INTEGER );/* INTEGER */
1457 if( cryptStatusOK( status ) )
1458 status = sMemGetDataBlock( &stream, &yValueDataPtr,
1459 yValueDataSize );
1460 ENSURES( cryptStatusOK( status ) );
1461 ENSURES( yValueDataSize >= 16 && \
1462 yValueDataSize <= CRYPT_MAX_PKCSIZE );
1463 memcpy( yValue, yValueDataPtr, yValueDataSize );
1464 sMemDisconnect( &stream );
1465
1466 /* The y value is the recovered value from the key data */
1467 yValuePtr = yValue;
1468 yValueLength = yValueDataSize;
1469 }
1470 else
1471 {
1472 /* It's a public key, use the pre-generated y value */
1473 yValuePtr = dsaKey->y,
1474 yValueLength = bitsToBytes( dsaKey->yLen );
1475 }
1476
1477 /* Get the information for the device associated with this context */
1478 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1479 &iCryptDevice, &pkcs11Info );
1480 if( cryptStatusError( cryptStatus ) )
1481 return( cryptStatus );
1482
1483 /* Set up the key values */
1484 if( dsaKey->isPublicKey )
1485 {
1486 setTemplate( publicKeyTemplate, CKA_PRIME, dsaKey->p,
1487 bitsToBytes( dsaKey->pLen ) );
1488 setTemplate( publicKeyTemplate, CKA_SUBPRIME, dsaKey->q,
1489 bitsToBytes( dsaKey->qLen ) );
1490 setTemplate( publicKeyTemplate, CKA_BASE, dsaKey->g,
1491 bitsToBytes( dsaKey->gLen ) );
1492 setTemplate( publicKeyTemplate, CKA_VALUE, dsaKey->y,
1493 bitsToBytes( dsaKey->yLen ) );
1494 }
1495 else
1496 {
1497 setTemplate( privateKeyTemplate, CKA_PRIME, dsaKey->p,
1498 bitsToBytes( dsaKey->pLen ) );
1499 setTemplate( privateKeyTemplate, CKA_SUBPRIME, dsaKey->q,
1500 bitsToBytes( dsaKey->qLen ) );
1501 setTemplate( privateKeyTemplate, CKA_BASE, dsaKey->g,
1502 bitsToBytes( dsaKey->gLen ) );
1503 setTemplate( privateKeyTemplate, CKA_VALUE, dsaKey->x,
1504 bitsToBytes( dsaKey->xLen ) );
1505 }
1506
1507 /* Load the key into the token */
1508 status = C_CreateObject( pkcs11Info->hSession, keyTemplate,
1509 keyTemplateCount, &hDsaKey );
1510 zeroise( keyTemplate, sizeof( CK_ATTRIBUTE ) * keyTemplateCount );
1511 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1512 if( cryptStatusError( cryptStatus ) )
1513 {
1514 /* If we're trying to set a public key and this is one of those
1515 tinkertoy tokens that only does private-key ops, return a more
1516 appropriate error code */
1517 if( dsaKey->isPublicKey && \
1518 contextInfoPtr->capabilityInfo->sigCheckFunction == NULL )
1519 cryptStatus = CRYPT_ERROR_NOTAVAIL;
1520
1521 krnlReleaseObject( iCryptDevice );
1522 return( cryptStatus );
1523 }
1524
1525 /* Send the keying information to the context and set up the key ID
1526 information */
1527 cryptStatus = dsaSetKeyInfo( pkcs11Info, contextInfoPtr->objectHandle,
1528 hDsaKey, CK_OBJECT_NONE,
1529 dsaKey->p, bitsToBytes( dsaKey->pLen ),
1530 dsaKey->q, bitsToBytes( dsaKey->qLen ),
1531 dsaKey->g, bitsToBytes( dsaKey->gLen ),
1532 yValuePtr, yValueLength, FALSE );
1533 if( cryptStatusOK( cryptStatus ) )
1534 {
1535 cryptStatus = updateActionFlags( pkcs11Info,
1536 contextInfoPtr->objectHandle,
1537 hDsaKey, CRYPT_ALGO_DSA,
1538 !dsaKey->isPublicKey );
1539 }
1540 if( cryptStatusError( cryptStatus ) )
1541 C_DestroyObject( pkcs11Info->hSession, hDsaKey );
1542 else
1543 {
1544 /* Remember that this object is backed by a crypto device */
1545 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1546 }
1547
1548 krnlReleaseObject( iCryptDevice );
1549 return( cryptStatus );
1550 }
1551
dsaGenerateKey(CONTEXT_INFO * contextInfoPtr,const int keysizeBits)1552 static int dsaGenerateKey( CONTEXT_INFO *contextInfoPtr, const int keysizeBits )
1553 {
1554 static const CK_MECHANISM mechanism = { CKM_DSA_KEY_PAIR_GEN, NULL_PTR, 0 };
1555 static const CK_BBOOL bTrue = TRUE;
1556 CK_ATTRIBUTE privateKeyTemplate[] = {
1557 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1558 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1559 { CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1560 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1561 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1562 { CKA_NONE }, { CKA_NONE }
1563 };
1564 CK_ATTRIBUTE publicKeyTemplate[] = {
1565 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1566 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
1567 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1568 { CKA_PRIME, NULL, 0 },
1569 { CKA_SUBPRIME, NULL, 0 },
1570 { CKA_BASE, NULL, 0 },
1571 { CKA_NONE }, { CKA_NONE }
1572 };
1573 CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
1574 MESSAGE_CREATEOBJECT_INFO createInfo;
1575 MESSAGE_DATA msgData;
1576 CRYPT_DEVICE iCryptDevice;
1577 PKCS11_INFO *pkcs11Info;
1578 BYTE pubkeyBuffer[ ( CRYPT_MAX_PKCSIZE * 3 ) + 8 ], label[ 8 + 8 ];
1579 CK_RV status;
1580 STREAM stream;
1581 void *dataPtr DUMMY_INIT_PTR;
1582 int length, cryptStatus;
1583
1584 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1585
1586 REQUIRES( keysizeBits >= bytesToBits( MIN_PKCSIZE ) && \
1587 keysizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
1588
1589 /* CKM_DSA_KEY_PAIR_GEN is really a Clayton's key generation mechanism
1590 since it doesn't actually generate the p, q, or g values (presumably
1591 it dates back to the original FIPS 186 shared domain parameters idea).
1592 Because of this we'd have to generate half the key ourselves in a
1593 native context, then copy portions from the native context over in
1594 flat form and complete the keygen via the device. The easiest way to
1595 do this is to create a native DSA context, generate a key, grab the
1596 public portions, and destroy the context again (i.e. generate a full
1597 key on a superscalar 2GHz RISC CPU, then throw half of it away, and
1598 regenerate it on a 5MHz 8-bit tinkertoy). Since the keygen can take
1599 awhile and doesn't require the device, we do it before we grab the
1600 device */
1601 setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_DSA );
1602 cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1603 IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1604 OBJECT_TYPE_CONTEXT );
1605 if( cryptStatusError( cryptStatus ) )
1606 return( cryptStatus );
1607 setMessageData( &msgData, label, 8 );
1608 krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
1609 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1610 krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE_S,
1611 &msgData, CRYPT_CTXINFO_LABEL );
1612 cryptStatus = krnlSendNotifier( createInfo.cryptHandle,
1613 IMESSAGE_CTX_GENKEY );
1614 if( cryptStatusOK( cryptStatus ) )
1615 {
1616 setMessageData( &msgData, pubkeyBuffer, CRYPT_MAX_PKCSIZE * 3 );
1617 cryptStatus = krnlSendMessage( createInfo.cryptHandle,
1618 IMESSAGE_GETATTRIBUTE_S, &msgData,
1619 CRYPT_IATTRIBUTE_KEY_SPKI );
1620 }
1621 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
1622 if( cryptStatusError( cryptStatus ) )
1623 return( cryptStatus );
1624
1625 /* Set up the public key information by extracting the flat values from
1626 the SubjectPublicKeyInfo. Note that the data used is represented in
1627 DER-canonical form, there may be PKCS #11 implementations that
1628 can't handle this (for example they may require q to be zero-padded
1629 to make it exactly 20 bytes rather than (say) 19 bytes if the high
1630 byte is zero) */
1631 sMemConnect( &stream, pubkeyBuffer, msgData.length );
1632 readSequence( &stream, NULL ); /* SEQUENCE */
1633 readSequence( &stream, NULL ); /* SEQUENCE */
1634 readUniversal( &stream ); /* OID */
1635 readSequence( &stream, NULL ); /* SEQUENCE */
1636 cryptStatus = readGenericHole( &stream, &length, 16, /* p */
1637 BER_INTEGER );
1638 if( cryptStatusOK( cryptStatus ) )
1639 cryptStatus = sMemGetDataBlock( &stream, &dataPtr, length );
1640 if( cryptStatusError( cryptStatus ) )
1641 retIntError();
1642 setTemplate( publicKeyTemplate, CKA_PRIME, dataPtr, length );
1643 sSkip( &stream, length, MAX_INTLENGTH_SHORT );
1644 cryptStatus = readGenericHole( &stream, &length, 16, /* q */
1645 BER_INTEGER );
1646 if( cryptStatusOK( cryptStatus ) )
1647 cryptStatus = sMemGetDataBlock( &stream, &dataPtr, length );
1648 if( cryptStatusError( cryptStatus ) )
1649 retIntError();
1650 setTemplate( publicKeyTemplate, CKA_SUBPRIME, dataPtr, length );
1651 sSkip( &stream, length, MAX_INTLENGTH_SHORT );
1652 cryptStatus = readGenericHole( &stream, &length, 16, /* g */
1653 BER_INTEGER );
1654 if( cryptStatusOK( cryptStatus ) )
1655 cryptStatus = sMemGetDataBlock( &stream, &dataPtr, length );
1656 if( cryptStatusError( cryptStatus ) )
1657 retIntError();
1658 setTemplate( publicKeyTemplate, CKA_BASE, dataPtr, length );
1659 sMemDisconnect( &stream );
1660
1661 /* Get the information for the device associated with this context */
1662 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1663 &iCryptDevice, &pkcs11Info );
1664 if( cryptStatusError( cryptStatus ) )
1665 return( cryptStatus );
1666
1667 /* Generate the keys */
1668 status = C_GenerateKeyPair( pkcs11Info->hSession,
1669 ( CK_MECHANISM_PTR ) &mechanism,
1670 ( CK_ATTRIBUTE_PTR ) publicKeyTemplate,
1671 templateCount( publicKeyTemplate ),
1672 ( CK_ATTRIBUTE_PTR ) privateKeyTemplate,
1673 templateCount( privateKeyTemplate ),
1674 &hPublicKey, &hPrivateKey );
1675 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
1676 if( cryptStatusError( cryptStatus ) )
1677 {
1678 krnlReleaseObject( iCryptDevice );
1679 return( cryptStatus );
1680 }
1681
1682 /* Read back the generated y value, send the public key information to
1683 the context, and set up the key ID information */
1684 cryptStatus = readAttributeValue( pkcs11Info, hPublicKey, CKA_VALUE,
1685 pubkeyBuffer, CRYPT_MAX_PKCSIZE,
1686 &length );
1687 if( cryptStatusOK( cryptStatus ) )
1688 {
1689 cryptStatus = dsaSetKeyInfo( pkcs11Info, contextInfoPtr->objectHandle,
1690 hPrivateKey, hPublicKey,
1691 publicKeyTemplate[ 3 ].pValue, publicKeyTemplate[ 3 ].ulValueLen,
1692 publicKeyTemplate[ 4 ].pValue, publicKeyTemplate[ 4 ].ulValueLen,
1693 publicKeyTemplate[ 5 ].pValue, publicKeyTemplate[ 5 ].ulValueLen,
1694 pubkeyBuffer, length, FALSE );
1695 }
1696 if( cryptStatusOK( cryptStatus ) )
1697 {
1698 cryptStatus = updateActionFlags( pkcs11Info,
1699 contextInfoPtr->objectHandle,
1700 hPrivateKey, CRYPT_ALGO_DSA, TRUE );
1701 }
1702 if( cryptStatusError( cryptStatus ) )
1703 {
1704 C_DestroyObject( pkcs11Info->hSession, hPublicKey );
1705 C_DestroyObject( pkcs11Info->hSession, hPrivateKey );
1706 }
1707 else
1708 {
1709 /* Remember that this object is backed by a crypto device */
1710 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1711 }
1712
1713 krnlReleaseObject( iCryptDevice );
1714 return( cryptStatus );
1715 }
1716
dsaSign(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1717 static int dsaSign( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1718 {
1719 static const CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 };
1720 CRYPT_DEVICE iCryptDevice;
1721 PKCS11_INFO *pkcs11Info;
1722 DLP_PARAMS *dlpParams = ( DLP_PARAMS * ) buffer;
1723 PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
1724 const PKC_ENCODEDLVALUES_FUNCTION encodeDLValuesFunction = \
1725 FNPTR_GET( dsaKey->encodeDLValuesFunction );
1726 BIGNUM *r, *s;
1727 BYTE signature[ 40 + 8 ];
1728 int cryptStatus;
1729
1730 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1731 assert( isWritePtr( buffer, length ) );
1732
1733 REQUIRES( length == sizeof( DLP_PARAMS ) );
1734 REQUIRES( dlpParams->inParam1 != NULL && \
1735 dlpParams->inLen1 == 20 );
1736 REQUIRES( dlpParams->inParam2 == NULL && dlpParams->inLen2 == 0 );
1737 REQUIRES( dlpParams->outParam != NULL && \
1738 dlpParams->outLen >= ( 2 + 20 ) * 2 && \
1739 dlpParams->outLen < MAX_INTLENGTH_SHORT );
1740 REQUIRES( encodeDLValuesFunction != NULL );
1741
1742 /* Get the information for the device associated with this context */
1743 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1744 &iCryptDevice, &pkcs11Info );
1745 if( cryptStatusError( cryptStatus ) )
1746 return( cryptStatus );
1747 cryptStatus = genericSign( pkcs11Info, contextInfoPtr, &mechanism,
1748 dlpParams->inParam1, dlpParams->inLen1,
1749 signature, 40 );
1750 krnlReleaseObject( iCryptDevice );
1751 if( cryptStatusError( cryptStatus ) )
1752 return( cryptStatus );
1753
1754 /* Encode the result as a DL data block. We have to do this via bignums,
1755 but this isn't a big deal since DSA signing via tokens is almost never
1756 used */
1757 r = BN_new();
1758 if( r == NULL )
1759 return( CRYPT_ERROR_MEMORY );
1760 s = BN_new();
1761 if( s == NULL )
1762 {
1763 BN_free( r );
1764 return( CRYPT_ERROR_MEMORY );
1765 }
1766 cryptStatus = importBignum( r, signature, 20,
1767 bitsToBytes( 160 - 32 ), 20, NULL,
1768 KEYSIZE_CHECK_NONE );
1769 if( cryptStatusOK( cryptStatus ) )
1770 cryptStatus = importBignum( s, signature + 20, 20,
1771 bitsToBytes( 160 - 32 ), 20, NULL,
1772 KEYSIZE_CHECK_NONE );
1773 if( cryptStatusOK( cryptStatus ) )
1774 {
1775 cryptStatus = \
1776 encodeDLValuesFunction( dlpParams->outParam, dlpParams->outLen,
1777 &dlpParams->outLen, r, s,
1778 dlpParams->formatType );
1779 }
1780 BN_clear_free( s );
1781 BN_clear_free( r );
1782 return( cryptStatus );
1783 }
1784
dsaVerify(CONTEXT_INFO * contextInfoPtr,BYTE * buffer,int length)1785 static int dsaVerify( CONTEXT_INFO *contextInfoPtr, BYTE *buffer, int length )
1786 {
1787 /* static const CK_MECHANISM mechanism = { CKM_DSA, NULL_PTR, 0 }; */
1788 /* CRYPT_DEVICE iCryptDevice; */
1789 const DLP_PARAMS *dlpParams = ( DLP_PARAMS * ) buffer;
1790
1791 /* This function is present but isn't used as part of any normal
1792 operation because cryptlib does the same thing much faster in
1793 software and because some tokens don't support public-key
1794 operations */
1795 DEBUG_PRINT(( "Warning: dsaVerify() called for device object, should "
1796 "be handled via native object.\n" ));
1797
1798 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1799 assert( isWritePtr( buffer, length ) );
1800
1801 REQUIRES( length == sizeof( DLP_PARAMS ) );
1802 REQUIRES( dlpParams->inParam1 != NULL && dlpParams->inLen1 == 20 );
1803 REQUIRES( dlpParams->inParam2 != NULL && \
1804 ( ( dlpParams->formatType == CRYPT_FORMAT_CRYPTLIB && \
1805 dlpParams->inLen2 >= 46 ) || \
1806 ( dlpParams->formatType == CRYPT_FORMAT_PGP && \
1807 dlpParams->inLen2 == 44 ) || \
1808 ( dlpParams->formatType == CRYPT_IFORMAT_SSH && \
1809 dlpParams->inLen2 == 40 ) ) );
1810 REQUIRES( dlpParams->outParam == NULL && dlpParams->outLen == 0 );
1811
1812 /* This code can never be called since DSA public-key contexts are
1813 always native contexts */
1814 retIntError();
1815 }
1816 #endif /* USE_DSA */
1817
1818 /****************************************************************************
1819 * *
1820 * ECDSA Mapping Functions *
1821 * *
1822 ****************************************************************************/
1823
1824 #ifdef USE_ECDSA
1825
1826 /* The maximum possible size for an ECDSA SPKI */
1827
1828 #define MAX_ECDSA_SPKI_SIZE ( 16 + MAX_OID_SIZE + MAX_OID_SIZE + \
1829 MAX_PKCSIZE_ECCPOINT )
1830
1831 /* Get an ECDSA SPKI by creating a native public- or private-key context
1832 (which will generate, if necessary, and encode the EC point value), read
1833 it out, and destroy it again (see the comments in the ECDSA init/generate
1834 key section for more on this problem) */
1835
1836 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
1837 static int ecdsaGetSPKI( const CRYPT_PKCINFO_ECC *ecdsaKey,
1838 OUT_BUFFER( spkiMaxLen, *spkiLen ) BYTE *spki,
1839 IN_LENGTH_SHORT_MIN( 32 ) const int spkiMaxLen,
1840 OUT_LENGTH_BOUNDED_Z( spkiMaxLen ) int *spkiLen )
1841 {
1842 CRYPT_CONTEXT iTempEccKey;
1843 MESSAGE_CREATEOBJECT_INFO createInfo;
1844 MESSAGE_DATA msgData;
1845 BYTE label[ 8 + 8 ];
1846 int cryptStatus;
1847
1848 assert( isReadPtr( ecdsaKey, sizeof( CRYPT_PKCINFO_ECC ) ) );
1849 assert( isWritePtr( spki, spkiMaxLen ) );
1850 assert( isWritePtr( spkiLen, sizeof( int ) ) );
1851
1852 REQUIRES( spkiMaxLen >= 32 && spkiMaxLen < MAX_INTLENGTH_SHORT );
1853
1854 /* Clear return values */
1855 memset( spki, 0, min( 16, spkiMaxLen ) );
1856 *spkiLen = 0;
1857
1858 setMessageCreateObjectInfo( &createInfo, CRYPT_ALGO_ECDSA );
1859 cryptStatus = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
1860 IMESSAGE_DEV_CREATEOBJECT, &createInfo,
1861 OBJECT_TYPE_CONTEXT );
1862 if( cryptStatusError( cryptStatus ) )
1863 return( cryptStatus );
1864 iTempEccKey = createInfo.cryptHandle;
1865 setMessageData( &msgData, label, 8 );
1866 krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_GETATTRIBUTE_S,
1867 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1868 krnlSendMessage( iTempEccKey, IMESSAGE_SETATTRIBUTE_S, &msgData,
1869 CRYPT_CTXINFO_LABEL );
1870 setMessageData( &msgData, ( MESSAGE_CAST ) ecdsaKey,
1871 sizeof( CRYPT_PKCINFO_ECC ) );
1872 cryptStatus = krnlSendMessage( iTempEccKey, IMESSAGE_SETATTRIBUTE_S,
1873 &msgData, CRYPT_CTXINFO_KEY_COMPONENTS );
1874 if( cryptStatusError( cryptStatus ) )
1875 {
1876 krnlSendNotifier( iTempEccKey, IMESSAGE_DECREFCOUNT );
1877 return( cryptStatus );
1878 }
1879
1880 /* Get the public key data */
1881 setMessageData( &msgData, spki, spkiMaxLen );
1882 cryptStatus = krnlSendMessage( iTempEccKey, IMESSAGE_GETATTRIBUTE_S,
1883 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI );
1884 krnlSendNotifier( iTempEccKey, IMESSAGE_DECREFCOUNT );
1885
1886 return( cryptStatus );
1887 }
1888
1889 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 6 ) ) \
1890 static int ecdsaSetKeyInfo( INOUT PKCS11_INFO *pkcs11Info,
1891 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
1892 const CK_OBJECT_HANDLE hPrivateKey,
1893 const CK_OBJECT_HANDLE hPublicKey,
1894 IN_ENUM( CRYPT_ECCCURVE ) \
1895 const CRYPT_ECCCURVE_TYPE curveType,
1896 IN_BUFFER( ecPointSize ) const void *ecPoint,
1897 IN_LENGTH_SHORT_MIN( 16 ) const int ecPointSize,
1898 const BOOLEAN nativeContext )
1899 {
1900 MESSAGE_DATA msgData;
1901 BYTE keyDataBuffer[ MAX_ECDSA_SPKI_SIZE + 8 ];
1902 BYTE idBuffer[ KEYID_SIZE + 8 ];
1903 int keyDataSize, cryptStatus;
1904
1905 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1906 assert( isReadPtr( ecPoint, ecPointSize ) );
1907
1908 REQUIRES( curveType > CRYPT_ECCCURVE_NONE && \
1909 curveType < CRYPT_ECCCURVE_LAST );
1910 REQUIRES( isHandleRangeValid( iCryptContext ) );
1911 REQUIRES( ecPointSize >= 16 && ecPointSize < MAX_INTLENGTH_SHORT );
1912
1913 /* Send the public key data to the context. We send the keying
1914 information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
1915 CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
1916 into the high state. We don't want to do this because we're already
1917 in the middle of processing a message that does this on completion,
1918 all that we're doing here is sending in encoded public key data for
1919 use by objects such as certificates */
1920 cryptStatus = writeFlatPublicKey( keyDataBuffer, MAX_ECDSA_SPKI_SIZE,
1921 &keyDataSize, CRYPT_ALGO_ECDSA,
1922 curveType, ecPoint, ecPointSize,
1923 NULL, 0, NULL, 0, NULL, 0 );
1924 if( cryptStatusError( cryptStatus ) )
1925 return( cryptStatus );
1926 setMessageData( &msgData, keyDataBuffer, keyDataSize );
1927 if( nativeContext )
1928 {
1929 /* If we're just setting public key components for a native context,
1930 we're done */
1931 return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1932 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI ) );
1933 }
1934 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
1935 &msgData, CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL );
1936 if( cryptStatusError( cryptStatus ) )
1937 return( cryptStatus );
1938
1939 /* Remember what we've set up. Note that PKCS #11 tokens create
1940 distinct public- and private-key objects but we're only interested
1941 in the private-key one, so we store the private-key object handle
1942 in the context */
1943 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
1944 ( MESSAGE_CAST ) &hPrivateKey,
1945 CRYPT_IATTRIBUTE_DEVICEOBJECT );
1946 if( cryptStatusError( cryptStatus ) )
1947 return( cryptStatus );
1948
1949 /* Get the key ID from the context and use it as the object ID. Since
1950 some objects won't allow after-the-event ID updates, we don't treat a
1951 failure to update as an error */
1952 setMessageData( &msgData, idBuffer, KEYID_SIZE );
1953 cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
1954 &msgData, CRYPT_IATTRIBUTE_KEYID );
1955 if( cryptStatusOK( cryptStatus ) )
1956 {
1957 CK_ATTRIBUTE idTemplate = { CKA_ID, msgData.data, msgData.length };
1958
1959 if( hPublicKey != CRYPT_UNUSED )
1960 C_SetAttributeValue( pkcs11Info->hSession, hPublicKey,
1961 &idTemplate, 1 );
1962 C_SetAttributeValue( pkcs11Info->hSession, hPrivateKey,
1963 &idTemplate, 1 );
1964 }
1965
1966 return( cryptStatus );
1967 }
1968
1969 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
ecdsaSetPublicComponents(INOUT PKCS11_INFO * pkcs11Info,IN_HANDLE const CRYPT_CONTEXT iCryptContext,const CK_OBJECT_HANDLE hEcdsaKey,const BOOLEAN nativeContext)1970 int ecdsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info,
1971 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
1972 const CK_OBJECT_HANDLE hEcdsaKey,
1973 const BOOLEAN nativeContext )
1974 {
1975 CRYPT_ECCCURVE_TYPE curveType;
1976 STREAM stream;
1977 BYTE encodedPoint[ 8 + MAX_PKCSIZE_ECCPOINT + 8 ];
1978 void *pointPtr DUMMY_INIT_PTR;
1979 int encodedPointSize DUMMY_INIT, pointSize, cryptStatus;
1980
1981 assert( isWritePtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
1982
1983 REQUIRES( isHandleRangeValid( iCryptContext ) );
1984
1985 /* Get the public key components from the device */
1986 cryptStatus = getEccCurveType( pkcs11Info, hEcdsaKey, &curveType );
1987 if( cryptStatusOK( cryptStatus ) )
1988 cryptStatus = readAttributeValue( pkcs11Info, hEcdsaKey, CKA_EC_POINT,
1989 encodedPoint, 8 + MAX_PKCSIZE_ECCPOINT,
1990 &encodedPointSize );
1991 if( cryptStatusError( cryptStatus ) )
1992 return( cryptStatus );
1993
1994 /* For no known reason the ECC point is further encoded by wrapping it
1995 inside an OCTET STRING, so we have to undo this encoding before we
1996 can continue */
1997 sMemConnect( &stream, encodedPoint, encodedPointSize );
1998 cryptStatus = readOctetStringHole( &stream, &pointSize,
1999 MIN_PKCSIZE_ECCPOINT_THRESHOLD,
2000 DEFAULT_TAG );
2001 if( cryptStatusOK( cryptStatus ) )
2002 cryptStatus = sMemGetDataBlock( &stream, &pointPtr, pointSize );
2003 sMemDisconnect( &stream );
2004 if( cryptStatusError( cryptStatus ) )
2005 return( cryptStatus );
2006
2007 return( ecdsaSetKeyInfo( pkcs11Info, iCryptContext, CK_OBJECT_NONE,
2008 hEcdsaKey, curveType, pointPtr, pointSize,
2009 nativeContext ) );
2010 }
2011
2012 /* ECDSA algorithm-specific mapping functions */
2013
2014 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
ecdsaInitKey(INOUT CONTEXT_INFO * contextInfoPtr,IN_BUFFER (keyLength)const void * key,IN_LENGTH_FIXED (sizeof (CRYPT_PKCINFO_ECC))const int keyLength)2015 static int ecdsaInitKey( INOUT CONTEXT_INFO *contextInfoPtr,
2016 IN_BUFFER( keyLength ) const void *key,
2017 IN_LENGTH_FIXED( sizeof( CRYPT_PKCINFO_ECC ) ) \
2018 const int keyLength )
2019 {
2020 static const CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
2021 static const CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
2022 static const CK_KEY_TYPE type = CKK_EC;
2023 static const CK_BBOOL bTrue = TRUE;
2024 CK_ATTRIBUTE publicKeyTemplate[] = {
2025 { CKA_CLASS, ( CK_VOID_PTR ) &pubKeyClass, sizeof( CK_OBJECT_CLASS ) },
2026 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
2027 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2028 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2029 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
2030 { CKA_EC_PARAMS, NULL, 0 },
2031 { CKA_EC_POINT, NULL, 0 },
2032 { CKA_NONE }, { CKA_NONE }
2033 };
2034 CK_ATTRIBUTE privateKeyTemplate[] = {
2035 { CKA_CLASS, ( CK_VOID_PTR ) &privKeyClass, sizeof( CK_OBJECT_CLASS ) },
2036 { CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
2037 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2038 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2039 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2040 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
2041 { CKA_EC_PARAMS, NULL, 0 },
2042 { CKA_VALUE, NULL, 0 },
2043 { CKA_NONE }, { CKA_NONE }
2044 };
2045 const CRYPT_PKCINFO_ECC *ecdsaKey = ( CRYPT_PKCINFO_ECC * ) key;
2046 CK_ATTRIBUTE *keyTemplate = ecdsaKey->isPublicKey ? \
2047 publicKeyTemplate : privateKeyTemplate;
2048 const int keyTemplateCount = ecdsaKey->isPublicKey ? \
2049 templateCount( publicKeyTemplate ) : \
2050 templateCount( privateKeyTemplate );
2051 CK_OBJECT_HANDLE hEcdsaKey;
2052 CK_RV status;
2053 CRYPT_DEVICE iCryptDevice;
2054 PKCS11_INFO *pkcs11Info;
2055 STREAM stream;
2056 BYTE oidBuffer[ MAX_OID_SIZE + 8 ];
2057 BYTE spkiBuffer[ MAX_ECDSA_SPKI_SIZE + 8 ];
2058 BYTE encodedPoint[ 8 + MAX_PKCSIZE_ECCPOINT + 8 ];
2059 void *ecPointPtr DUMMY_INIT_PTR;
2060 int oidSize DUMMY_INIT, spkiSize, encodedPointSize DUMMY_INIT;
2061 int ecPointSize, cryptStatus;
2062
2063 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
2064 assert( isReadPtr( key, keyLength ) );
2065
2066 REQUIRES( keyLength == sizeof( CRYPT_PKCINFO_ECC ) );
2067
2068 /* Get the information that we'll need to specify the public-key
2069 parameters */
2070 sMemOpen( &stream, oidBuffer, MAX_OID_SIZE );
2071 cryptStatus = writeECCOID( &stream, ecdsaKey->curveType );
2072 if( cryptStatusOK( cryptStatus ) )
2073 oidSize = stell( &stream );
2074 sMemDisconnect( &stream );
2075 if( cryptStatusError( cryptStatus ) )
2076 return( cryptStatus );
2077
2078 /* Creating both public- and private-key ECDSA objects is problematic.
2079 For the public-key object we need to encode the EC point in the
2080 peculiar X9.62 form, wrapped up in an OCTET STRING (because the spec
2081 says so). The private-key object on the other hand doesn't use
2082 CKA_EC_POINT at all so it's not possible to determine it from a
2083 private key (this isn't used in C_CreateObject() but is needed later
2084 for ecdsaSetKeyInfo()).
2085
2086 Because of this we have to create a native public- or private-key
2087 context (which will generate and encode the EC point value), read it
2088 out, and destroy it again (see the comments in the ECDSA generate key
2089 section for more on this problem). Since this doesn't require the
2090 device, we do it before we grab the device */
2091 cryptStatus = ecdsaGetSPKI( ecdsaKey, spkiBuffer, MAX_ECDSA_SPKI_SIZE,
2092 &spkiSize );
2093 if( cryptStatusError( cryptStatus ) )
2094 return( cryptStatus );
2095 sMemConnect( &stream, spkiBuffer, spkiSize );
2096 readSequence( &stream, NULL ); /* SEQUENCE { */
2097 readUniversal( &stream ); /* AlgoID */
2098 cryptStatus = readBitStringHole( &stream, &ecPointSize, 16,
2099 DEFAULT_TAG );/* BIT STRING */
2100 if( cryptStatusOK( cryptStatus ) )
2101 cryptStatus = sMemGetDataBlock( &stream, &ecPointPtr, ecPointSize );
2102 ENSURES( cryptStatusOK( cryptStatus ) );
2103 sMemDisconnect( &stream );
2104
2105 /* Write the encoded EC point, wrapped in an OCTET STRING tag */
2106 sMemOpen( &stream, encodedPoint, 8 + MAX_PKCSIZE_ECCPOINT );
2107 cryptStatus = writeOctetString( &stream, ecPointPtr, ecPointSize,
2108 DEFAULT_TAG );
2109 if( cryptStatusOK( cryptStatus ) )
2110 encodedPointSize = stell( &stream );
2111 sMemDisconnect( &stream );
2112 ENSURES( cryptStatusOK( cryptStatus ) );
2113
2114 /* Get the information for the device associated with this context */
2115 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
2116 &iCryptDevice, &pkcs11Info );
2117 if( cryptStatusError( cryptStatus ) )
2118 return( cryptStatus );
2119
2120 /* Set up the key values */
2121 if( ecdsaKey->isPublicKey )
2122 {
2123 setTemplate( publicKeyTemplate, CKA_EC_PARAMS, oidBuffer, oidSize );
2124 setTemplate( publicKeyTemplate, CKA_EC_POINT, encodedPoint,
2125 encodedPointSize );
2126 }
2127 else
2128 {
2129 setTemplate( privateKeyTemplate, CKA_EC_PARAMS, oidBuffer, oidSize );
2130 setTemplate( privateKeyTemplate, CKA_VALUE, ecdsaKey->d,
2131 bitsToBytes( ecdsaKey->dLen ) );
2132 }
2133
2134 /* Load the key into the token */
2135 status = C_CreateObject( pkcs11Info->hSession, keyTemplate,
2136 keyTemplateCount, &hEcdsaKey );
2137 zeroise( keyTemplate, sizeof( CK_ATTRIBUTE ) * keyTemplateCount );
2138 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
2139 if( cryptStatusError( cryptStatus ) )
2140 {
2141 /* If we're trying to set a public key and this is one of those
2142 tinkertoy tokens that only does private-key ops, return a more
2143 appropriate error code */
2144 if( ecdsaKey->isPublicKey && \
2145 contextInfoPtr->capabilityInfo->sigCheckFunction == NULL )
2146 cryptStatus = CRYPT_ERROR_NOTAVAIL;
2147
2148 krnlReleaseObject( iCryptDevice );
2149 return( cryptStatus );
2150 }
2151
2152 /* Send the keying information to the context and set up the key ID
2153 information */
2154 cryptStatus = ecdsaSetKeyInfo( pkcs11Info, contextInfoPtr->objectHandle,
2155 hEcdsaKey, CK_OBJECT_NONE,
2156 ecdsaKey->curveType,
2157 ecPointPtr, ecPointSize, FALSE );
2158 if( cryptStatusOK( cryptStatus ) )
2159 {
2160 cryptStatus = updateActionFlags( pkcs11Info,
2161 contextInfoPtr->objectHandle,
2162 hEcdsaKey, CRYPT_ALGO_ECDSA,
2163 !ecdsaKey->isPublicKey );
2164 }
2165 if( cryptStatusError( cryptStatus ) )
2166 C_DestroyObject( pkcs11Info->hSession, hEcdsaKey );
2167 else
2168 {
2169 /* Remember that this object is backed by a crypto device */
2170 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
2171 }
2172
2173 krnlReleaseObject( iCryptDevice );
2174 return( cryptStatus );
2175 }
2176
2177 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
2178 static int ecdsaGenerateKey( INOUT CONTEXT_INFO *contextInfoPtr,
2179 IN_LENGTH_SHORT_MIN( MIN_PKCSIZE_ECC * 8 ) \
2180 const int keySizeBits )
2181 {
2182 static const CK_MECHANISM mechanism = { CKM_ECDSA_KEY_PAIR_GEN, NULL_PTR, 0 };
2183 static const CK_BBOOL bTrue = TRUE;
2184 CK_ATTRIBUTE privateKeyTemplate[] = {
2185 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2186 { CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2187 { CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2188 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
2189 { CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2190 { CKA_NONE }, { CKA_NONE }
2191 };
2192 CK_ATTRIBUTE publicKeyTemplate[] = {
2193 { CKA_TOKEN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2194 { CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize },
2195 { CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
2196 { CKA_EC_PARAMS, NULL, 0 },
2197 { CKA_NONE }, { CKA_NONE }
2198 };
2199 CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
2200 CK_RV status;
2201 CRYPT_DEVICE iCryptDevice;
2202 CRYPT_ECCCURVE_TYPE curveType;
2203 PKCS11_INFO *pkcs11Info;
2204 STREAM stream;
2205 BYTE oidBuffer[ MAX_OID_SIZE + 8 ];
2206 int oidSize DUMMY_INIT, cryptStatus;
2207
2208 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
2209
2210 REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE_ECC ) && \
2211 keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE_ECC ) );
2212
2213 /* Get the information that we'll need to specify the public-key
2214 parameters */
2215 cryptStatus = getECCFieldID( bitsToBytes( keySizeBits ), &curveType );
2216 ENSURES( cryptStatusOK( cryptStatus ) );
2217 sMemOpen( &stream, oidBuffer, MAX_OID_SIZE );
2218 cryptStatus = writeECCOID( &stream, curveType );
2219 if( cryptStatusOK( cryptStatus ) )
2220 oidSize = stell( &stream );
2221 sMemDisconnect( &stream );
2222 if( cryptStatusError( cryptStatus ) )
2223 return( cryptStatus );
2224 setTemplate( publicKeyTemplate, CKA_EC_PARAMS, oidBuffer, oidSize );
2225
2226 /* Get the information for the device associated with this context */
2227 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
2228 &iCryptDevice, &pkcs11Info );
2229 if( cryptStatusError( cryptStatus ) )
2230 return( cryptStatus );
2231
2232 /* Generate the keys */
2233 status = C_GenerateKeyPair( pkcs11Info->hSession,
2234 ( CK_MECHANISM_PTR ) &mechanism,
2235 ( CK_ATTRIBUTE_PTR ) publicKeyTemplate,
2236 templateCount( publicKeyTemplate ),
2237 ( CK_ATTRIBUTE_PTR ) privateKeyTemplate,
2238 templateCount( privateKeyTemplate ),
2239 &hPublicKey, &hPrivateKey );
2240 cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
2241 if( cryptStatusError( cryptStatus ) )
2242 {
2243 krnlReleaseObject( iCryptDevice );
2244 return( cryptStatus );
2245 }
2246
2247 /* Send the public key information to the context and set up the key ID
2248 information */
2249 cryptStatus = ecdsaSetPublicComponents( pkcs11Info,
2250 contextInfoPtr->objectHandle,
2251 hPublicKey, FALSE );
2252 // Returns CKR_ATTRIBUTE_TYPE_INVALID on CKA_EC_PARAMS read.
2253 if( cryptStatusOK( cryptStatus ) )
2254 {
2255 cryptStatus = updateActionFlags( pkcs11Info,
2256 contextInfoPtr->objectHandle,
2257 hPrivateKey, CRYPT_ALGO_ECDSA, TRUE );
2258 }
2259 if( cryptStatusError( cryptStatus ) )
2260 {
2261 C_DestroyObject( pkcs11Info->hSession, hPublicKey );
2262 C_DestroyObject( pkcs11Info->hSession, hPrivateKey );
2263 }
2264 else
2265 {
2266 /* Remember that this object is backed by a crypto device */
2267 contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
2268 }
2269
2270 krnlReleaseObject( iCryptDevice );
2271 return( cryptStatus );
2272 }
2273
2274 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
ecdsaSign(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (noBytes)BYTE * buffer,IN_LENGTH_FIXED (sizeof (DLP_PARAMS))int noBytes)2275 static int ecdsaSign( INOUT CONTEXT_INFO *contextInfoPtr,
2276 INOUT_BUFFER_FIXED( noBytes ) BYTE *buffer,
2277 IN_LENGTH_FIXED( sizeof( DLP_PARAMS ) ) int noBytes )
2278 {
2279 static const CK_MECHANISM mechanism = { CKM_ECDSA, NULL_PTR, 0 };
2280 CRYPT_DEVICE iCryptDevice;
2281 PKCS11_INFO *pkcs11Info;
2282 DLP_PARAMS *eccParams = ( DLP_PARAMS * ) buffer;
2283 PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
2284 const PKC_ENCODEDLVALUES_FUNCTION encodeDLValuesFunction = \
2285 FNPTR_GET( dsaKey->encodeDLValuesFunction );
2286 BIGNUM *r, *s;
2287 BYTE signature[ ( CRYPT_MAX_PKCSIZE_ECC * 2 ) + 8 ];
2288 const int keySize = bitsToBytes( contextInfoPtr->ctxPKC->keySizeBits );
2289 int cryptStatus;
2290
2291 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
2292 assert( isWritePtr( eccParams, sizeof( DLP_PARAMS ) ) );
2293 assert( isReadPtr( eccParams->inParam1, eccParams->inLen1 ) );
2294 assert( isWritePtr( eccParams->outParam, eccParams->outLen ) );
2295
2296 REQUIRES( noBytes == sizeof( DLP_PARAMS ) );
2297 REQUIRES( eccParams->inParam2 == NULL && eccParams->inLen2 == 0 );
2298 REQUIRES( eccParams->outLen >= MIN_CRYPT_OBJECTSIZE && \
2299 eccParams->outLen < MAX_INTLENGTH_SHORT );
2300 REQUIRES( encodeDLValuesFunction != NULL );
2301
2302 /* Get the information for the device associated with this context */
2303 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
2304 &iCryptDevice, &pkcs11Info );
2305 if( cryptStatusError( cryptStatus ) )
2306 return( cryptStatus );
2307 cryptStatus = genericSign( pkcs11Info, contextInfoPtr, &mechanism,
2308 eccParams->inParam1, eccParams->inLen1,
2309 signature, CRYPT_MAX_PKCSIZE_ECC * 2 );
2310 krnlReleaseObject( iCryptDevice );
2311 if( cryptStatusError( cryptStatus ) )
2312 return( cryptStatus );
2313
2314 /* PKCS #11 uses a bizarre signature-encoding form in which signing
2315 creates a fixed-length byte string of which the first half is r and
2316 the second half is s, zero-padded as required. Before we can return
2317 this to the caller we have to rewrite it in X9.62 form. We have to
2318 do this via bignums, but this isn't a big deal since ECDSA signing
2319 via tokens is almost never used */
2320 r = BN_new();
2321 if( r == NULL )
2322 return( CRYPT_ERROR_MEMORY );
2323 s = BN_new();
2324 if( s == NULL )
2325 {
2326 BN_free( r );
2327 return( CRYPT_ERROR_MEMORY );
2328 }
2329 cryptStatus = importBignum( r, signature, keySize,
2330 MIN_PKCSIZE_ECC_THRESHOLD, keySize, NULL,
2331 KEYSIZE_CHECK_NONE );
2332 if( cryptStatusOK( cryptStatus ) )
2333 {
2334 cryptStatus = importBignum( s, signature + keySize, keySize,
2335 MIN_PKCSIZE_ECC_THRESHOLD, keySize, NULL,
2336 KEYSIZE_CHECK_NONE );
2337 }
2338 if( cryptStatusOK( cryptStatus ) )
2339 {
2340 cryptStatus = \
2341 encodeDLValuesFunction( eccParams->outParam, eccParams->outLen,
2342 &eccParams->outLen, r, s,
2343 eccParams->formatType );
2344 }
2345 BN_clear_free( s );
2346 BN_clear_free( r );
2347 return( cryptStatus );
2348 }
2349
2350 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
ecdsaVerify(INOUT CONTEXT_INFO * contextInfoPtr,IN_BUFFER (noBytes)BYTE * buffer,IN_LENGTH_FIXED (sizeof (DLP_PARAMS))int noBytes)2351 static int ecdsaVerify( INOUT CONTEXT_INFO *contextInfoPtr,
2352 IN_BUFFER( noBytes ) BYTE *buffer,
2353 IN_LENGTH_FIXED( sizeof( DLP_PARAMS ) ) int noBytes )
2354 {
2355 /* static const CK_MECHANISM mechanism = { CKM_ECDSA, NULL_PTR, 0 }; */
2356 /* CRYPT_DEVICE iCryptDevice; */
2357 DLP_PARAMS *eccParams = ( DLP_PARAMS * ) buffer;
2358
2359 /* This function is present but isn't used as part of any normal
2360 operation because cryptlib does the same thing much faster in
2361 software and because some tokens don't support public-key
2362 operations */
2363 DEBUG_PRINT(( "Warning: ecdsaVerify() called for device object, should "
2364 "be handled via native object.\n" ));
2365
2366 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
2367 assert( isWritePtr( eccParams, sizeof( DLP_PARAMS ) ) );
2368 assert( isReadPtr( eccParams->inParam1, eccParams->inLen1 ) );
2369 assert( isReadPtr( eccParams->inParam2, eccParams->inLen2 ) );
2370
2371 REQUIRES( noBytes == sizeof( DLP_PARAMS ) );
2372 REQUIRES( eccParams->outParam == NULL && eccParams->outLen == 0 );
2373
2374 /* This code can never be called since ECDSA public-key contexts are
2375 always native contexts */
2376 retIntError();
2377 }
2378 #endif /* USE_ECDSA */
2379
2380 /****************************************************************************
2381 * *
2382 * Device Capability Routines *
2383 * *
2384 ****************************************************************************/
2385
2386 /* PKC mechanism information */
2387
2388 static const PKCS11_MECHANISM_INFO mechanismInfoPKC[] = {
2389 /* The handling of the RSA mechanism is a bit odd. Almost everyone
2390 supports CKM_RSA_X_509 even though what's reported as being supported
2391 is CKM_RSA_PKCS, however the PKCS mechanism is often implemented in a
2392 buggy manner with all sorts of problems with handling the padding.
2393 The safest option would be to use the raw RSA one and do the padding
2394 ourselves, which means that it'll always be done right. Since some
2395 implementations report raw RSA as being unavailable even though it's
2396 present, we detect it by checking for the PKCS mechanism but using
2397 raw RSA. However, some implementations genuinely don't do raw RSA, so
2398 the code fakes it by removing/adding dummy PKCS padding as required
2399 so that the caller sees raw RSA and the device sees PKCS. This is a
2400 compromise: We can handle the real (rather than faked) PKCS padding
2401 ourselves and work around bugs in the output from other
2402 implementations, but we can't implement any new mechanisms other than
2403 PKCS without support in the device. The only implementation where
2404 even this causes problems is some versions of GemSAFE, which don't do
2405 raw RSA and also get the PKCS mechanism wrong */
2406 #ifdef USE_DH
2407 { CKM_DH_PKCS_DERIVE, CKM_DH_PKCS_KEY_PAIR_GEN, CKM_NONE, CKF_NONE,
2408 CRYPT_ALGO_DH, CRYPT_MODE_NONE, CKK_DH,
2409 NULL, dhInitKey, dhGenerateKey,
2410 dhEncrypt, dhDecrypt, NULL, NULL },
2411 #endif /* USE_DH */
2412 { CKM_RSA_PKCS, CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_NONE, CKF_NONE,
2413 CRYPT_ALGO_RSA, CRYPT_MODE_NONE, CKK_RSA,
2414 NULL, rsaInitKey, rsaGenerateKey,
2415 rsaEncrypt, rsaDecrypt, rsaSign, rsaVerify },
2416 #ifdef USE_DSA
2417 { CKM_DSA, CKM_DSA_KEY_PAIR_GEN, CKM_NONE, CKF_NONE,
2418 CRYPT_ALGO_DSA, CRYPT_MODE_NONE, CKK_DSA,
2419 NULL, dsaInitKey, dsaGenerateKey,
2420 NULL, NULL, dsaSign, dsaVerify },
2421 #endif /* USE_DSA */
2422 #ifdef USE_ECDSA
2423 { CKM_ECDSA, CKM_EC_KEY_PAIR_GEN, CKM_NONE, CKF_EC_F_P | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS,
2424 CRYPT_ALGO_ECDSA, CRYPT_MODE_NONE, CKK_ECDSA,
2425 NULL, ecdsaInitKey, ecdsaGenerateKey,
2426 NULL, NULL, ecdsaSign, ecdsaVerify },
2427 #endif /* USE_ECDSA */
2428 { CKM_NONE, CKM_NONE, CKM_NONE, CKF_NONE, CRYPT_ERROR, CRYPT_ERROR, },
2429 { CKM_NONE, CKM_NONE, CKM_NONE, CKF_NONE, CRYPT_ERROR, CRYPT_ERROR, }
2430 };
2431
2432 CHECK_RETVAL_PTR_NONNULL STDC_NONNULL_ARG( ( 1 ) ) \
getMechanismInfoPKC(OUT int * mechanismInfoSize)2433 const PKCS11_MECHANISM_INFO *getMechanismInfoPKC( OUT int *mechanismInfoSize )
2434 {
2435 assert( isWritePtr( mechanismInfoSize, sizeof( int ) ) );
2436
2437 *mechanismInfoSize = FAILSAFE_ARRAYSIZE( mechanismInfoPKC, \
2438 PKCS11_MECHANISM_INFO );
2439 return( mechanismInfoPKC );
2440 }
2441 #endif /* USE_PKCS11 */
2442