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