1 /****************************************************************************
2 *																			*
3 *							cryptlib PKCS #11 Routines						*
4 *						Copyright Peter Gutmann 1998-2005					*
5 *																			*
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9   #include "crypt.h"
10   #include "context.h"
11   #include "device.h"
12   #include "pkcs11_api.h"
13   #include "dev_mech.h"
14   #include "asn1.h"
15 #else
16   #include "crypt.h"
17   #include "context/context.h"
18   #include "device/device.h"
19   #include "device/pkcs11_api.h"
20   #include "enc_dec/asn1.h"
21   #include "mechs/dev_mech.h"
22 #endif /* Compiler-specific includes */
23 
24 /* Define the following to generate conventional/MAC keys inside the PKCS
25    #11 device rather than in cryptlib.  Note that this imposes a number of
26    restrictions on the use of encryption keys, see the note for
27    cipherGenerateKey() for more details */
28 
29 #define USE_HW_KEYGEN
30 
31 /* Some devices use extended login mechanisms to get around PKCS #11's
32    somewhat-simplistic username-and-password model, if we detect the
33    presence of the extended mechanism we enable extended-login
34    functionality */
35 
36 #if 0		/* Private vendor #1's extensions for token login */
37 #define CKU_EXTENDED		3
38 /* When CKU_EXTENDED is used, the data passed to C_Login() is no longer a
39    straight string but the following structured value */
40 typedef struct {
41 	CK_UTF8CHAR_PTR	*username;	/* User name */
42 	CK_ULONG name_len;			/* Length of user name */
43 	CK_VOID_PTR context;		/* Token-specific context data */
44 	CK_ULONG context_size;		/* Size of context data */
45 	} CK_EXTENDED_LOGIN;
46 #endif /* 0 */
47 
48 #ifdef CKU_EXTENDED
49   #define USE_EXTENDED_LOGIN
50 #endif /* CKU_EXTENDED */
51 
52 #ifdef USE_PKCS11
53 
54 /* The max. number of drivers we can work with and the max.number of slots
55    per driver */
56 
57 #define MAX_PKCS11_DRIVERS		5
58 #define MAX_PKCS11_SLOTS		16
59 
60 /****************************************************************************
61 *																			*
62 *						 		Utility Routines							*
63 *																			*
64 ****************************************************************************/
65 
66 /* Map a PKCS #11-specific error to a cryptlib error */
67 
68 CHECK_RETVAL \
pkcs11MapError(const CK_RV errorCode,IN_STATUS const int defaultError)69 int pkcs11MapError( const CK_RV errorCode,
70 					IN_STATUS const int defaultError )
71 	{
72 	REQUIRES( cryptStatusError( defaultError ) );
73 
74 	switch( ( int ) errorCode )
75 		{
76 		case CKR_OK:
77 			return( CRYPT_OK );
78 
79 		case CKR_HOST_MEMORY:
80 		case CKR_DEVICE_MEMORY:
81 			return( CRYPT_ERROR_MEMORY );
82 
83 		case CKR_DEVICE_ERROR:
84 		case CKR_DEVICE_REMOVED:
85 		case CKR_TOKEN_NOT_PRESENT:
86 			return( CRYPT_ERROR_SIGNALLED );
87 
88 		case CKR_PIN_INCORRECT:
89 		case CKR_PIN_INVALID:
90 		case CKR_PIN_LEN_RANGE:
91 		case CKR_PIN_EXPIRED:
92 		case CKR_PIN_LOCKED:
93 			return( CRYPT_ERROR_WRONGKEY );
94 
95 		case CKR_DATA_INVALID:
96 		case CKR_ENCRYPTED_DATA_INVALID:
97 		case CKR_WRAPPED_KEY_INVALID:
98 			return( CRYPT_ERROR_BADDATA );
99 
100 		case CKR_SIGNATURE_INVALID:
101 			return( CRYPT_ERROR_SIGNATURE );
102 
103 		case CKR_KEY_NOT_WRAPPABLE:
104 		case CKR_KEY_UNEXTRACTABLE:
105 		case CKR_TOKEN_WRITE_PROTECTED:
106 		case CKR_INFORMATION_SENSITIVE:
107 			return( CRYPT_ERROR_PERMISSION );
108 
109 		case CKR_DATA_LEN_RANGE:
110 		case CKR_ENCRYPTED_DATA_LEN_RANGE:
111 		case CKR_SIGNATURE_LEN_RANGE:
112 		case CKR_UNWRAPPING_KEY_SIZE_RANGE:
113 		case CKR_WRAPPING_KEY_SIZE_RANGE:
114 		case CKR_WRAPPED_KEY_LEN_RANGE:
115 			return( CRYPT_ERROR_OVERFLOW );
116 
117 		case CKR_SESSION_EXISTS:
118 		case CKR_SESSION_READ_ONLY_EXISTS:
119 		case CKR_SESSION_READ_WRITE_SO_EXISTS:
120 		case CKR_USER_ALREADY_LOGGED_IN:
121 		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
122 		case CKR_CRYPTOKI_NOT_INITIALIZED:
123 			return( CRYPT_ERROR_INITED );
124 
125 		case CKR_USER_NOT_LOGGED_IN:
126 		case CKR_USER_PIN_NOT_INITIALIZED:
127 		case CKR_CRYPTOKI_ALREADY_INITIALIZED:
128 			return( CRYPT_ERROR_NOTINITED );
129 
130 		case CKR_RANDOM_NO_RNG:
131 			return( CRYPT_ERROR_RANDOM );
132 
133 		case CKR_OPERATION_ACTIVE:
134 			return( CRYPT_ERROR_TIMEOUT );
135 
136 		case CKR_TOKEN_NOT_RECOGNIZED:
137 			return( CRYPT_ERROR_NOTFOUND );
138 		}
139 
140 	return( defaultError );
141 	}
142 
143 /* Extract the time from a PKCS #11 tokenInfo structure */
144 
145 STDC_NONNULL_ARG( ( 1 ) ) \
getTokenTime(const CK_TOKEN_INFO * tokenInfo)146 time_t getTokenTime( const CK_TOKEN_INFO *tokenInfo )
147 	{
148 	STREAM stream;
149 	BYTE buffer[ 32 + 8 ];
150 	time_t theTime = MIN_TIME_VALUE + 1;
151 	int length DUMMY_INIT, status;
152 
153 	assert( isReadPtr( tokenInfo, sizeof( CK_TOKEN_INFO ) ) );
154 
155 	/* Convert the token time to an ASN.1 time string that we can read using
156 	   the standard ASN.1 routines by writing a dummy time value and inserting
157 	   the token's time string in its place */
158 	sMemOpen( &stream, buffer, 32 );
159 	status = writeGeneralizedTime( &stream, theTime, DEFAULT_TAG );
160 	if( cryptStatusOK( status ) )
161 		length = stell( &stream );
162 	sMemDisconnect( &stream );
163 	if( cryptStatusError( status ) )
164 		return( 0 );
165 	memcpy( buffer + 2, tokenInfo->utcTime, 14 );
166 	sMemConnect( &stream, buffer, length );
167 	status = readGeneralizedTime( &stream, &theTime );
168 	sMemDisconnect( &stream );
169 
170 	return( ( cryptStatusOK( status ) ) ? theTime : 0 );
171 	}
172 
173 /* Get access to the PKCS #11 device associated with a context */
174 
175 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \
getContextDeviceInfo(IN_HANDLE const CRYPT_HANDLE iCryptContext,OUT_HANDLE_OPT CRYPT_DEVICE * iCryptDevice,OUT_PTR_COND PKCS11_INFO ** pkcs11InfoPtrPtr)176 int getContextDeviceInfo( IN_HANDLE const CRYPT_HANDLE iCryptContext,
177 						  OUT_HANDLE_OPT CRYPT_DEVICE *iCryptDevice,
178 						  OUT_PTR_COND PKCS11_INFO **pkcs11InfoPtrPtr )
179 	{
180 	CRYPT_DEVICE iLocalDevice;
181 	DEVICE_INFO *deviceInfo;
182 	int cryptStatus;
183 
184 	assert( isWritePtr( iCryptDevice, sizeof( CRYPT_DEVICE ) ) );
185 	assert( isWritePtr( pkcs11InfoPtrPtr, sizeof( PKCS11_INFO * ) ) );
186 
187 	REQUIRES( isHandleRangeValid( iCryptContext ) );
188 
189 	/* Clear return values */
190 	*iCryptDevice = CRYPT_ERROR;
191 	*pkcs11InfoPtrPtr = NULL;
192 
193 	/* Get the the device associated with this context */
194 	cryptStatus = krnlSendMessage( iCryptContext, IMESSAGE_GETDEPENDENT,
195 								   &iLocalDevice, OBJECT_TYPE_DEVICE );
196 	if( cryptStatusError( cryptStatus ) )
197 		return( cryptStatus );
198 
199 	/* Get the PKCS #11 information from the device information */
200 	cryptStatus = krnlAcquireObject( iLocalDevice, OBJECT_TYPE_DEVICE,
201 									 ( void ** ) &deviceInfo,
202 									 CRYPT_ERROR_SIGNALLED );
203 	if( cryptStatusError( cryptStatus ) )
204 		return( cryptStatus );
205 	*iCryptDevice = iLocalDevice;
206 	*pkcs11InfoPtrPtr = deviceInfo->devicePKCS11;
207 
208 	return( CRYPT_OK );
209 	}
210 
211 /* Create and try and use a dummy object to check for various PKCS #11
212    driver bugs */
213 
214 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkDriverBugs(const PKCS11_INFO * pkcs11Info)215 static int checkDriverBugs( const PKCS11_INFO *pkcs11Info )
216 	{
217 	static const CK_OBJECT_CLASS class = CKO_SECRET_KEY;
218 	const CK_KEY_TYPE type = CKK_DES;
219 	static const CK_BBOOL bFalse = FALSE, bTrue = TRUE;
220 	const CK_ATTRIBUTE keyTemplate[] = {
221 		{ CKA_CLASS, ( CK_VOID_PTR ) &class, sizeof( CK_OBJECT_CLASS ) },
222 		{ CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
223 		{ CKA_TOKEN, ( CK_VOID_PTR ) &bFalse, sizeof( CK_BBOOL ) },
224 		{ CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
225 		{ CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
226 		{ CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
227 		{ CKA_VALUE, "12345678", 8 }	/* Dummy key value */
228 		};
229 	const CK_MECHANISM mechanism = { CKM_DES_ECB, NULL, 0 };
230 	CK_OBJECT_HANDLE hObject;
231 	CK_RV status;
232 
233 	assert( isReadPtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
234 
235 	/* Try and create the sort of object that'd normally require a login.
236 	   This can fail for reasons other than driver bugs (for example DES
237 	   isn't supported for this token type) so we only check for the
238 	   specific error code returned by a login bug */
239 	status = C_CreateObject( pkcs11Info->hSession,
240 							 ( CK_ATTRIBUTE_PTR ) keyTemplate, 7, &hObject );
241 	if( status == CKR_USER_NOT_LOGGED_IN )
242 		{
243 		DEBUG_DIAG(( "PKCS #11 driver bug detected, attempt to log in to "
244 					 "the device apparently succeeded but logged-on "
245 					 "operation failed with CKR_USER_NOT_LOGGED_IN" ));
246 		assert( DEBUG_WARN );
247 		return( CRYPT_ERROR_NOTINITED );
248 		}
249 	ENSURES( hObject != CK_OBJECT_NONE );
250 
251 	/* Try and use the object to encrypt data (or at least call the pre-
252 	   encrypt call, which should be enough to shake out most bugs) */
253 	status = C_EncryptInit( pkcs11Info->hSession,
254 							( CK_MECHANISM_PTR ) &mechanism, hObject );
255 	C_DestroyObject( pkcs11Info->hSession, hObject );
256 	if( status != CKR_OK )
257 		{
258 		DEBUG_DIAG(( "PKCS #11 driver bug detected, attempt to use object "
259 					 "in logged-in device failed with error code %lX, this "
260 					 "can happen when using C_InitToken() rather than the "
261 					 "proprietary vendor-supplied utility to initialise "
262 					 "the device", status ));
263 		assert( DEBUG_WARN );
264 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
265 		}
266 
267 	return( CRYPT_OK );
268 	}
269 
270 /****************************************************************************
271 *																			*
272 *					Device Init/Shutdown/Device Control Routines			*
273 *																			*
274 ****************************************************************************/
275 
276 /* Handle device control functions */
277 
278 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
controlFunction(INOUT DEVICE_INFO * deviceInfo,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type,IN_BUFFER_OPT (dataLength)void * data,IN_LENGTH_SHORT_Z const int dataLength,INOUT_OPT MESSAGE_FUNCTION_EXTINFO * messageExtInfo)279 static int controlFunction( INOUT DEVICE_INFO *deviceInfo,
280 							IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type,
281 							IN_BUFFER_OPT( dataLength ) void *data,
282 							IN_LENGTH_SHORT_Z const int dataLength,
283 							INOUT_OPT MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
284 	{
285 	CK_RV status;
286 	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
287 
288 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
289 	assert( isAttribute( type ) || isInternalAttribute( type ) );
290 
291 	/* Handle token present/active checks */
292 	if( type == CRYPT_DEVINFO_LOGGEDIN )
293 		{
294 		CK_TOKEN_INFO tokenInfo;
295 		CK_SLOT_INFO slotInfo;
296 
297 		/* Check whether the user is still logged in.  This is rather
298 		   problematic because some devices can't detect a token removal,
299 		   and if they do they often can't report it to the driver.  It's
300 		   also possible in some devices to remove the token and re-insert
301 		   it later without that being regarded as logging out (or you can
302 		   remove the smart card and insert your frequent flyer card and
303 		   it's still regarded as a card present).  In addition if the
304 		   reader supports its own authentication mechanisms (even if it
305 		   forces a logout if the token is removed) it's possible for the
306 		   user to reinsert the token and reauthenticate themselves and it
307 		   appears as if they never logged out.  In fact the only totally
308 		   foolproof way to detect a token removal/change is to try and use
309 		   the token to perform a crypto operation, which is a rather
310 		   suboptimal detection mechanism.
311 
312 		   Because of this, the best that we can do here is check the token-
313 		   present flag and report a token-changed error if it's not set.
314 		   In addition since some devices only do a minimal check with
315 		   C_GetSlotInfo() (e.g. checking whether a microswitch is held
316 		   open by something in the slot, see above) we first call
317 		   C_GetTokenInfo(), which has a greater chance of actually trying
318 		   to access the token, before we call C_GetSlotInfo().
319 
320 		   If there's a problem reported, we don't perform an implicit
321 		   shutdown since the user may choose to re-authenticate to the
322 		   device or perform some other action that we have no control over
323 		   in response to the token-removed notification */
324 		status = C_GetTokenInfo( pkcs11Info->slotID, &tokenInfo );
325 		if( status != CKR_OK )
326 			return( pkcs11MapError( status, CRYPT_ERROR_SIGNALLED ) );
327 		status = C_GetSlotInfo( pkcs11Info->slotID, &slotInfo );
328 		if( status != CKR_OK )
329 			return( pkcs11MapError( status, CRYPT_ERROR_SIGNALLED ) );
330 		if( !( slotInfo.flags & CKF_TOKEN_PRESENT ) )
331 			return( CRYPT_ERROR_SIGNALLED );
332 
333 		return( CRYPT_OK );
334 		}
335 
336 	/* Handle user authorisation */
337 	if( type == CRYPT_DEVINFO_AUTHENT_USER || \
338 		type == CRYPT_DEVINFO_AUTHENT_SUPERVISOR )
339 		{
340 #ifdef USE_EXTENDED_LOGIN
341 		const CK_USER_TYPE userType = CKU_EXTENDED;
342 #else
343 		const CK_USER_TYPE userType = \
344 				( type == CRYPT_DEVINFO_AUTHENT_USER ) ? CKU_USER : CKU_SO;
345 #endif /* USE_EXTENDED_LOGIN */
346 
347 		REQUIRES( data != NULL );
348 
349 		/* Make sure that the PIN is within range */
350 		if( dataLength < pkcs11Info->minPinSize || \
351 			dataLength > pkcs11Info->maxPinSize )
352 			return( CRYPT_ARGERROR_NUM1 );
353 
354 		/* If the user is already logged in, log them out before we try
355 		   logging in with a new authentication value */
356 		if( deviceInfo->flags & DEVICE_LOGGEDIN )
357 			{
358 			C_Logout( pkcs11Info->hSession );
359 			deviceInfo->flags &= ~DEVICE_LOGGEDIN;
360 			}
361 
362 		/* Authenticate the user to the device */
363 		status = C_Login( pkcs11Info->hSession, userType,
364 						  ( CK_CHAR_PTR ) data,
365 						  ( CK_ULONG ) dataLength );
366 		if( status != CKR_OK )
367 			{
368 			int cryptStatus;
369 
370 			/* The check for CKR_USER_ALREADY_LOGGED_IN is logical since we
371 			   may already be logged in from another session, however
372 			   several buggy drivers return CKR_USER_ALREADY_LOGGED_IN
373 			   without actually logging the user in so that all further
374 			   operations fail with CKR_USER_NOT_LOGGED_IN.  To try and
375 			   detect this, if we get a CKR_USER_ALREADY_LOGGED_IN we try
376 			   and create the sort of object that's likely to require a
377 			   login and use that to see whether we're really logged in or
378 			   not */
379 			if( status != CKR_USER_ALREADY_LOGGED_IN )
380 				return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
381 			cryptStatus = checkDriverBugs( pkcs11Info );
382 			return( cryptStatusError( cryptStatus ) ? \
383 					cryptStatus : CRYPT_ERROR_FAILED );
384 			}
385 
386 		/* The device is now ready for use */
387 		deviceInfo->flags |= DEVICE_LOGGEDIN;
388 		return( CRYPT_OK );
389 		}
390 
391 	/* Handle authorisation value changes.  The initialise SO/user PIN
392 	   functionality is a bit awkward in that it has to fill the gap between
393 	   C_InitToken() (which usually sets the SSO PIN but may also take an
394 	   initialisation PIN and leave the token in a state where the only valid
395 	   operation is to set the SSO PIN) and C_SetPIN() (which can only set the
396 	   SSO PIN for the SSO or the user PIN for the user).  Setting the user
397 	   PIN by the SSO, which is usually required to perform any useful (non-
398 	   administrative) function with the token, requires the special-case
399 	   C_InitPIN().  In addition we can't speculatively set the user PIN to
400 	   be the same as the SSO PIN (which would be useful because in most
401 	   cases the user *is* the SSO, thus ensuring that the device behaves as
402 	   expected when the user isn't even aware that there are SSO and user
403 	   roles) because devices that implement an FSM for initialisation will
404 	   move into an undesired state once the SSO -> user change is triggered.
405 
406 	   The FSM for initialisation on devices that perform a multi-stage
407 	   bootstrap and require all of the various intialisation functions to
408 	   be used one after the other (e.g. Fortezza) is:
409 
410 			uninitialised/zeroised
411 					v
412 				C_InitToken			(enter init or SSO PIN)
413 					v
414 				initialised
415 					v
416 				C_SetPIN			(change init PIN -> SSO PIN)
417 					v
418 			  SSO initialised
419 					v
420 				C_InitPIN			(set user PIN)
421 					v
422 			  user initialised
423 					v
424 				C_Logout
425 				C_Login				(move from SO -> user state)
426 
427 		The final logout/login is only needed with some tokens, in others
428 		the move to user state is automatic once the user PIN is set by the
429 		SO */
430 	if( type == CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR )
431 		{
432 		REQUIRES( data != NULL );
433 
434 		/* Make sure that the PIN is within range */
435 		if( dataLength < pkcs11Info->minPinSize || \
436 			dataLength > pkcs11Info->maxPinSize )
437 			return( CRYPT_ARGERROR_NUM1 );
438 
439 		/* Make sure that there's an SSO PIN present from a previous device
440 		   initialisation */
441 		if( pkcs11Info->defaultSSOPinLen <= 0 )
442 			{
443 			setErrorInfo( deviceInfo, CRYPT_DEVINFO_INITIALISE,
444 						  CRYPT_ERRTYPE_ATTR_ABSENT );
445 			return( CRYPT_ERROR_NOTINITED );
446 			}
447 
448 		/* Change the SSO PIN from the initialisation PIN.  Once we've done
449 		   this we clear the initial SSO PIN, since it's no longer valid in
450 		   the new state */
451 		status = C_SetPIN( pkcs11Info->hSession, pkcs11Info->defaultSSOPin,
452 						   pkcs11Info->defaultSSOPinLen,
453 						   ( CK_CHAR_PTR ) data, ( CK_ULONG ) dataLength );
454 		zeroise( pkcs11Info->defaultSSOPin, CRYPT_MAX_TEXTSIZE );
455 		pkcs11Info->defaultSSOPinLen = 0;
456 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
457 		}
458 	if( type == CRYPT_DEVINFO_SET_AUTHENT_USER )
459 		{
460 		REQUIRES( data != NULL );
461 
462 		/* Make sure that the PIN is within range */
463 		if( dataLength < pkcs11Info->minPinSize || \
464 			dataLength > pkcs11Info->maxPinSize )
465 			return( CRYPT_ARGERROR_NUM1 );
466 
467 		status = C_InitPIN( pkcs11Info->hSession, ( CK_CHAR_PTR ) data,
468 							( CK_ULONG ) dataLength );
469 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
470 		}
471 
472 	/* Handle initialisation and zeroisation */
473 	if( type == CRYPT_DEVINFO_INITIALISE || \
474 		type == CRYPT_DEVINFO_ZEROISE )
475 		{
476 		CK_SESSION_HANDLE hSession;
477 		CK_CHAR label[ 32 + 8 ];
478 		int cryptStatus;
479 
480 		REQUIRES( data != NULL );
481 
482 		/* Make sure that the PIN is within range */
483 		if( dataLength < pkcs11Info->minPinSize || \
484 			dataLength > pkcs11Info->maxPinSize )
485 			return( CRYPT_ARGERROR_NUM1 );
486 
487 		/* If there's a session active with the device, log out and terminate
488 		   the session, since the token initialisation will reset this */
489 		if( pkcs11Info->hSession != CK_OBJECT_NONE )
490 			{
491 			C_Logout( pkcs11Info->hSession );
492 			C_CloseSession( pkcs11Info->hSession );
493 			pkcs11Info->hSession = CK_OBJECT_NONE;
494 			}
495 
496 		/* Initialise/clear the device, setting the initial SSO PIN */
497 		memset( label, ' ', 32 );
498 		status = C_InitToken( pkcs11Info->slotID,
499 							  ( CK_CHAR_PTR ) data,
500 							  ( CK_ULONG ) dataLength, label );
501 		if( status != CKR_OK )
502 			return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
503 
504 		/* Reopen the session with the device */
505 		status = C_OpenSession( pkcs11Info->slotID,
506 								CKF_RW_SESSION | CKF_SERIAL_SESSION,
507 								NULL_PTR, NULL_PTR, &hSession );
508 		if( status != CKR_OK )
509 			return( pkcs11MapError( status, CRYPT_ERROR_OPEN ) );
510 		ENSURES( hSession != CK_OBJECT_NONE );
511 		pkcs11Info->hSession = hSession;
512 
513 		/* If it's a straight zeroise, we're done */
514 		if( type == CRYPT_DEVINFO_ZEROISE )
515 			return( CRYPT_OK );
516 
517 		/* We're initialising it, log in as supervisor.  In theory we could
518 		   also set the initial user PIN to the same as the SSO PIN at this
519 		   point because the user usually won't be aware of the presence of
520 		   an SSO role or the need to set a PIN for it, but this can run into
521 		   problems with tokens that only allow the user PIN to be modified
522 		   by the SSO after they've set it for the first time, so if the user
523 		   *is* aware of the existence of an SSO role then once they log in
524 		   as SSO they can no longer set the user PIN */
525 		status = C_Login( pkcs11Info->hSession, CKU_SO,
526 						  ( CK_CHAR_PTR ) data, ( CK_ULONG ) dataLength );
527 		if( status != CKR_OK )
528 			{
529 			C_Logout( pkcs11Info->hSession );
530 			C_CloseSession( pkcs11Info->hSession );
531 			pkcs11Info->hSession = CK_OBJECT_NONE;
532 			return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
533 			}
534 
535 		/* Remember the default SSO PIN for use with a future C_SetPIN() */
536 		memcpy( pkcs11Info->defaultSSOPin, data, dataLength );
537 		pkcs11Info->defaultSSOPinLen = dataLength;
538 
539 		/* A number of PKCS #11 devices can't actually be initialised
540 		   through C_InitToken() but require a vendor-supplied proprietary
541 		   application to do this, apparently succeeding with C_InitToken()
542 		   but then failing in various strange and unpredictable ways later
543 		   on.  We try and detect this situation here by creating a dummy
544 		   object in the device and trying to use it */
545 		cryptStatus = checkDriverBugs( pkcs11Info );
546 		if( cryptStatusError( cryptStatus ) )
547 			return( cryptStatus );
548 
549 		/* We're logged in and ready to go */
550 		deviceInfo->flags |= DEVICE_LOGGEDIN;
551 		return( CRYPT_OK );
552 		}
553 
554 	/* Handle high-reliability time */
555 	if( type == CRYPT_IATTRIBUTE_TIME )
556 		{
557 		CK_TOKEN_INFO tokenInfo;
558 		time_t *timePtr = ( time_t * ) data, theTime;
559 
560 		REQUIRES( data != NULL );
561 
562 		/* Get the token's time, returned as part of the token information
563 		   structure */
564 		status = C_GetTokenInfo( pkcs11Info->slotID, &tokenInfo );
565 		if( status != CKR_OK )
566 			return( pkcs11MapError( status, CRYPT_ERROR_SIGNALLED ) );
567 		if( ( theTime = getTokenTime( &tokenInfo ) ) <= MIN_TIME_VALUE )
568 			return( CRYPT_ERROR_NOTAVAIL );
569 		*timePtr = theTime;
570 		return( CRYPT_OK );
571 		}
572 
573 	retIntError();
574 	}
575 
576 /****************************************************************************
577 *																			*
578 *						 	Capability Interface Routines					*
579 *																			*
580 ****************************************************************************/
581 
582 /* Encrypt, decrypt */
583 
584 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4 ) ) \
genericEncrypt(const PKCS11_INFO * pkcs11Info,const CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,INOUT_BUFFER_FIXED (length)void * buffer,IN_LENGTH const int length,IN_LENGTH const int outLength)585 static int genericEncrypt( const PKCS11_INFO *pkcs11Info,
586 						   const CONTEXT_INFO *contextInfoPtr,
587 						   const CK_MECHANISM *pMechanism,
588 						   INOUT_BUFFER_FIXED( length ) void *buffer,
589 						   IN_LENGTH const int length,
590 						   IN_LENGTH const int outLength )
591 	{
592 	CK_ULONG resultLen = outLength;
593 	CK_RV status;
594 
595 	assert( isReadPtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
596 	assert( isReadPtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
597 	assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
598 	assert( isWritePtr( buffer, length ) );
599 
600 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
601 	REQUIRES( length == outLength );
602 
603 	status = C_EncryptInit( pkcs11Info->hSession,
604 							( CK_MECHANISM_PTR ) pMechanism,
605 							contextInfoPtr->deviceObject );
606 	if( status == CKR_OK )
607 		status = C_Encrypt( pkcs11Info->hSession, buffer, length,
608 							buffer, &resultLen );
609 	if( status != CKR_OK )
610 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
611 	return( CRYPT_OK );
612 	}
613 
614 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 4 ) ) \
genericDecrypt(const PKCS11_INFO * pkcs11Info,const CONTEXT_INFO * contextInfoPtr,const CK_MECHANISM * pMechanism,INOUT_BUFFER_FIXED (length)void * buffer,IN_LENGTH const int length)615 static int genericDecrypt( const PKCS11_INFO *pkcs11Info,
616 						   const CONTEXT_INFO *contextInfoPtr,
617 						   const CK_MECHANISM *pMechanism,
618 						   INOUT_BUFFER_FIXED( length ) void *buffer,
619 						   IN_LENGTH const int length )
620 	{
621 	CK_ULONG resultLen = length;
622 	CK_RV status;
623 
624 	assert( isReadPtr( pkcs11Info, sizeof( PKCS11_INFO ) ) );
625 	assert( isReadPtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
626 	assert( isReadPtr( pMechanism, sizeof( CK_MECHANISM ) ) );
627 	assert( isWritePtr( buffer, length ) );
628 
629 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
630 
631 	status = C_DecryptInit( pkcs11Info->hSession,
632 							( CK_MECHANISM_PTR ) pMechanism,
633 							contextInfoPtr->deviceObject );
634 	if( status == CKR_OK )
635 		status = C_Decrypt( pkcs11Info->hSession, buffer, length,
636 							buffer, &resultLen );
637 	if( status != CKR_OK )
638 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
639 	return( CRYPT_OK );
640 	}
641 
642 /* Clean up the object associated with a context.  The CONTEXT_INFO * is
643    actually a const in this case but we need to leave it non-const to make
644    it type-compatible with the function pointer in the CONTEXT_INFO */
645 
646 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
genericEndFunction(INOUT CONTEXT_INFO * contextInfoPtr)647 int genericEndFunction( /* const */ INOUT CONTEXT_INFO *contextInfoPtr )
648 	{
649 	CRYPT_DEVICE iCryptDevice;
650 	PKCS11_INFO *pkcs11Info;
651 	int cryptStatus;
652 
653 	assert( isReadPtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
654 
655 	/* Since the device object that corresponds to the cryptlib object is
656 	   created on-demand, it may not exist yet if the action that triggers
657 	   the on-demand creation hasn't been taken yet.  If no device object
658 	   exists, we're done */
659 	if( contextInfoPtr->deviceObject == CRYPT_ERROR )
660 		return( CRYPT_OK );
661 
662 	/* Get the information for the device associated with this context */
663 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
664 										&iCryptDevice, &pkcs11Info );
665 	if( cryptStatusError( cryptStatus ) )
666 		return( cryptStatus );
667 
668 	/* If we're deleting an object that's in the middle of a multi-stage
669 	   operation, record the fact that the operation has now ended.  We
670 	   have to perform this tracking explicitly since PKCS #11 only allows
671 	   one multi-stage operation per session */
672 	if( pkcs11Info->hActiveSignObject == contextInfoPtr->deviceObject )
673 		pkcs11Info->hActiveSignObject = CK_OBJECT_NONE;
674 
675 	/* If this is a persistent object, we can't destroy it.  This is a bit
676 	   problematic since PKCS #11 doesn't differentiate between releasing
677 	   an object handle and destroying (deleting) it, which means that
678 	   repeatedly instantiating a persistent object (via getItemFunction())
679 	   and then destroying it leaks a PKCS #11 handle each time.
680 	   Unfortunately there's nothing that we can do about this since the
681 	   problem lies at the PKCS #11 level */
682 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
683 		{
684 		krnlReleaseObject( iCryptDevice );
685 		return( CRYPT_OK );
686 		}
687 
688 	/* Destroy the object */
689 	C_DestroyObject( pkcs11Info->hSession, contextInfoPtr->deviceObject );
690 	if( contextInfoPtr->altDeviceObject != CK_OBJECT_NONE )
691 		{
692 		C_DestroyObject( pkcs11Info->hSession,
693 						 contextInfoPtr->altDeviceObject );
694 		}
695 	krnlReleaseObject( iCryptDevice );
696 
697 	return( CRYPT_OK );
698 	}
699 
700 /****************************************************************************
701 *																			*
702 *					Conventional Crypto/MAC Key Load Functions				*
703 *																			*
704 ****************************************************************************/
705 
706 /* Get a PKCS #11 mechanism corresponding to a cryptlib algorithm and
707    optional mode */
708 
709 typedef enum { MECH_NONE, MECH_CONV, MECH_MAC, MECH_CONV_KEYGEN,
710 			   MECH_MAC_KEYGEN, MECH_LAST } GETMECH_TYPE;
711 
712 static CK_MECHANISM_TYPE getMechanism( const GETMECH_TYPE mechType,
713 									   IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,
714 									   IN_MODE const CRYPT_MODE_TYPE cryptMode );
715 
716 /* Set up a key template and context information in preparation for creating
717    a device object */
718 
719 STDC_NONNULL_ARG( ( 1 ) ) \
adjustKeyParity(INOUT_BUFFER_FIXED (length)BYTE * key,IN_LENGTH_SHORT const int length)720 static void adjustKeyParity( INOUT_BUFFER_FIXED( length ) BYTE *key,
721 							 IN_LENGTH_SHORT const int length )
722 	{
723 	int i;
724 
725 	assert( isWritePtr( key, length ) );
726 
727 	REQUIRES_V( length > 0 && length < MAX_INTLENGTH_SHORT );
728 
729 	/* Adjust a key to have odd parity, needed for DES keys */
730 	for( i = 0; i < length; i++ )
731 		{
732 		int ch = byteToInt( key[ i ] );
733 
734 		ch = ( ch & 0x55 ) + ( ( ch >> 1 ) & 0x55 );
735 		ch = ( ch & 0x33 ) + ( ( ch >> 2 ) & 0x33 );
736 		if( !( ( ch + ( ch >> 4 ) ) & 0x01 ) )
737 			key[ i ] ^= 1;
738 		}
739 	}
740 
741 /* Load a key into a device object */
742 
743 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
744 static int initKey( INOUT CONTEXT_INFO *contextInfoPtr,
745 					INOUT_ARRAY( templateCount ) \
746 						CK_ATTRIBUTE *keyTemplate,
747 					IN_RANGE( 4, 10 ) const int templateCount,
748 					IN_BUFFER( keyLength ) const void *key,
749 					IN_LENGTH_SHORT const int keyLength )
750 	{
751 	CRYPT_DEVICE iCryptDevice;
752 	const CRYPT_ALGO_TYPE cryptAlgo = \
753 				contextInfoPtr->capabilityInfo->cryptAlgo;
754 	PKCS11_INFO *pkcs11Info;
755 	CK_OBJECT_HANDLE hObject;
756 	CK_RV status;
757 	BYTE *contextKeyPtr;
758 	int *contextKeyLenPtr;
759 	int keySize = \
760 		( cryptAlgo == CRYPT_ALGO_DES || cryptAlgo == CRYPT_ALGO_3DES ) ? \
761 		contextInfoPtr->capabilityInfo->keySize : keyLength;
762 	int cryptStatus;
763 
764 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
765 	assert( isWritePtr( keyTemplate, \
766 						templateCount * sizeof( CK_ATTRIBUTE ) ) );
767 	assert( isReadPtr( key, keyLength ) );
768 
769 	REQUIRES( templateCount >= 8 && templateCount <= 10 );
770 	REQUIRES( keyLength > 0 && keyLength < MAX_INTLENGTH_SHORT );
771 
772 	/* Get the information for the device associated with this context */
773 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
774 										&iCryptDevice, &pkcs11Info );
775 	if( cryptStatusError( cryptStatus ) )
776 		return( cryptStatus );
777 
778 	/* Set up pointers to the appropriate object sub-type data */
779 	if( contextInfoPtr->type == CONTEXT_CONV )
780 		{
781 		contextKeyPtr = contextInfoPtr->ctxConv->userKey;
782 		contextKeyLenPtr = &contextInfoPtr->ctxConv->userKeyLength;
783 		}
784 	else
785 		{
786 		REQUIRES( contextInfoPtr->type == CONTEXT_MAC );
787 
788 		contextKeyPtr = contextInfoPtr->ctxMAC->userKey;
789 		contextKeyLenPtr = &contextInfoPtr->ctxMAC->userKeyLength;
790 		}
791 
792 	/* Copy the key to internal storage */
793 	if( contextKeyPtr != key )
794 		memcpy( contextKeyPtr, key, keyLength );
795 	*contextKeyLenPtr = keyLength;
796 
797 	/* Special-case handling for 2-key vs.3-key 3DES */
798 	if( cryptAlgo == CRYPT_ALGO_3DES )
799 		{
800 		/* If the supplied key contains only two DES keys, adjust the key to
801 		   make it the equivalent of 3-key 3DES.  In addition since the
802 		   nominal keysize is for 2-key 3DES, we have to make the actual
803 		   size the maximum size, corresponding to 3-key 3DES */
804 		if( keyLength <= bitsToBytes( 64 * 2 ) )
805 			{
806 			memcpy( contextKeyPtr + bitsToBytes( 64 * 2 ),
807 					contextKeyPtr, bitsToBytes( 64 ) );
808 			}
809 		keySize = contextInfoPtr->capabilityInfo->maxKeySize;
810 		}
811 
812 	/* If we're using DES we have to adjust the key parity because the spec
813 	   says so, almost all implementations do this anyway but there's always
814 	   the odd one out that we have to cater for */
815 	if( cryptAlgo == CRYPT_ALGO_DES || cryptAlgo == CRYPT_ALGO_3DES )
816 		adjustKeyParity( contextKeyPtr, keySize );
817 
818 	/* Set up the key values.  Since the key passed in by the user may be
819 	   smaller than the keysize required by algorithms that use fixed-size
820 	   keys, we use the (optionally) zero-padded key of the correct length
821 	   held in the context rather than the variable-length user-supplied
822 	   one */
823 	REQUIRES( keyTemplate[ 7 ].type == CKA_VALUE );
824 	keyTemplate[ 7 ].pValue = contextKeyPtr;
825 	keyTemplate[ 7 ].ulValueLen = keySize;
826 
827 	/* Load the key into the token */
828 	status = C_CreateObject( pkcs11Info->hSession, keyTemplate,
829 							 templateCount, &hObject );
830 	cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
831 	if( cryptStatusOK( cryptStatus ) )
832 		{
833 		ENSURES( hObject != CK_OBJECT_NONE );
834 
835 		contextInfoPtr->deviceObject = hObject;
836 		}
837 	else
838 		{
839 		zeroise( contextInfoPtr->ctxConv->userKey, keyLength );
840 		contextInfoPtr->ctxConv->userKeyLength = 0;
841 		}
842 	zeroise( keyTemplate, sizeof( CK_ATTRIBUTE ) * templateCount );
843 	krnlReleaseObject( iCryptDevice );
844 	return( cryptStatus );
845 	}
846 
847 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherInitKey(INOUT CONTEXT_INFO * contextInfoPtr,IN_BUFFER (keyLength)const void * key,IN_LENGTH_SHORT const int keyLength)848 static int cipherInitKey( INOUT CONTEXT_INFO *contextInfoPtr,
849 						  IN_BUFFER( keyLength ) const void *key,
850 						  IN_LENGTH_SHORT const int keyLength )
851 	{
852 	static const CK_OBJECT_CLASS class = CKO_SECRET_KEY;
853 	static const CK_BBOOL bFalse = FALSE, bTrue = TRUE;
854 	const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
855 	CK_ATTRIBUTE keyTemplate[] = {
856 		/* General-purpose fields */
857 		{ CKA_CLASS, ( CK_VOID_PTR ) &class, sizeof( CK_OBJECT_CLASS ) },
858 		{ CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
859 		{ CKA_TOKEN, ( CK_VOID_PTR ) &bFalse, sizeof( CK_BBOOL ) },
860 		{ CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
861 		{ CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
862 		{ CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
863 		{ CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
864 		{ CKA_VALUE, NULL_PTR, 0 },
865 		/* Persistent-object only fields */
866 		{ CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
867 		};
868 	const int templateCount = \
869 				( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? 9 : 8;
870 
871 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
872 	assert( isReadPtr( key, keyLength ) );
873 
874 	REQUIRES( keyLength > 0 && keyLength < MAX_INTLENGTH_SHORT );
875 
876 	/* If this is meant to be a persistent object, modify the template to
877 	   make it a persistent token object and adjust the template entry count
878 	   to include the object label */
879 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
880 		keyTemplate[ 2 ].pValue = ( CK_VOID_PTR ) &bTrue;
881 
882 	return( initKey( contextInfoPtr, keyTemplate, templateCount,
883 					 key, keyLength ) );
884 	}
885 
886 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
hmacInitKey(INOUT CONTEXT_INFO * contextInfoPtr,IN_BUFFER (keyLength)const void * key,IN_LENGTH_SHORT const int keyLength)887 static int hmacInitKey( INOUT CONTEXT_INFO *contextInfoPtr,
888 						IN_BUFFER( keyLength ) const void *key,
889 						IN_LENGTH_SHORT const int keyLength )
890 	{
891 	static const CK_OBJECT_CLASS class = CKO_SECRET_KEY;
892 	static const CK_BBOOL bFalse = FALSE, bTrue = TRUE;
893 	const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
894 	CK_ATTRIBUTE keyTemplate[] = {
895 		/* General-purpose fields */
896 		{ CKA_CLASS, ( CK_VOID_PTR ) &class, sizeof( CK_OBJECT_CLASS ) },
897 		{ CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
898 		{ CKA_TOKEN, ( CK_VOID_PTR ) &bFalse, sizeof( CK_BBOOL ) },
899 		{ CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
900 		{ CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
901 		{ CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
902 		{ CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
903 		{ CKA_VALUE, NULL_PTR, 0 },
904 		/* Persistent-object only fields */
905 		{ CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
906 		};
907 	const int templateCount = \
908 				( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? 9 : 8;
909 
910 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
911 	assert( isReadPtr( key, keyLength ) );
912 
913 	REQUIRES( keyLength > 0 && keyLength < MAX_INTLENGTH_SHORT );
914 
915 	/* If this is meant to be a persistent object, modify the template to
916 	   make it a persistent token object and adjust the template entry count
917 	   to include the object label */
918 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
919 		keyTemplate[ 2 ].pValue = ( CK_VOID_PTR ) &bTrue;
920 
921 	return( initKey( contextInfoPtr, keyTemplate, templateCount,
922 					 key, keyLength ) );
923 	}
924 
925 /* Generate a key into a device object.  Normally we generate keys inside
926    cryptlib and load them into the device object (so a keygen becomes a
927    keygen inside cryptlib followed by a cipherInitKey()) in order to make
928    sure that the key data is accessible from the context.  If we didn't do
929    this, the user would have to be very careful to perform all key wrap/
930    unwrap operations only via device objects.  This is particularly
931    problematic with public-key operations since cryptlib always instantiates
932    public-key objects as cryptlib native objects since they're so much
933    quicker in that form.  So for example importing a certificate and then
934    using it to wrap a conventional encryption key that's been generated in
935    a device is impossible because the key to wrap isn't accessible to the
936    public-key context tied to the certificate.  Because of this,
937    USE_HW_KEYGEN should be used with great care */
938 
939 #ifdef USE_HW_KEYGEN
940 
941 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
942 static int generateKey( INOUT CONTEXT_INFO *contextInfoPtr,
943 						INOUT_ARRAY( templateCount ) \
944 							CK_ATTRIBUTE *keyTemplate,
945 						IN_RANGE( 4, 10 ) const int templateCount,
946 						const BOOLEAN isMAC )
947 	{
948 	CRYPT_DEVICE iCryptDevice;
949 	PKCS11_INFO *pkcs11Info;
950 	CK_MECHANISM mechanism = { contextInfoPtr->capabilityInfo->paramKeyGen,
951 							   NULL_PTR, 0 };
952 	CK_OBJECT_HANDLE hObject;
953 	CK_RV status;
954 	int cryptStatus;
955 
956 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
957 	assert( isWritePtr( keyTemplate, \
958 						templateCount * sizeof( CK_ATTRIBUTE ) ) );
959 
960 	REQUIRES( templateCount >= 4 && templateCount <= 10 );
961 
962 	/* Get the information for the device associated with this context */
963 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
964 										&iCryptDevice, &pkcs11Info );
965 	if( cryptStatusError( cryptStatus ) )
966 		return( cryptStatus );
967 
968 	/* Generate the key into the token */
969 	status = C_GenerateKey( pkcs11Info->hSession, &mechanism,
970 							keyTemplate, templateCount, &hObject );
971 	cryptStatus = pkcs11MapError( status, CRYPT_ERROR_FAILED );
972 	if( cryptStatusOK( cryptStatus ) )
973 		{
974 		ENSURES( hObject != CK_OBJECT_NONE );
975 
976 		contextInfoPtr->deviceObject = hObject;
977 		}
978 	zeroise( keyTemplate, sizeof( CK_ATTRIBUTE ) * templateCount );
979 	krnlReleaseObject( iCryptDevice );
980 	return( cryptStatus );
981 	}
982 
983 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
cipherGenerateKey(INOUT CONTEXT_INFO * contextInfoPtr,IN_RANGE (bytesToBits (MIN_KEYSIZE),bytesToBits (CRYPT_MAX_PKCSIZE))const int keySizeBits)984 static int cipherGenerateKey( INOUT CONTEXT_INFO *contextInfoPtr,
985 							  IN_RANGE( bytesToBits( MIN_KEYSIZE ),
986 										bytesToBits( CRYPT_MAX_PKCSIZE ) ) \
987 								const int keySizeBits )
988 	{
989 	static const CK_OBJECT_CLASS class = CKO_SECRET_KEY;
990 	static const CK_BBOOL bFalse = FALSE, bTrue = TRUE;
991 	const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
992 	const CK_ULONG length = bitsToBytes( keySizeBits );
993 	CK_ATTRIBUTE keyTemplate[] = {
994 		/* General-purpose fields */
995 		{ CKA_CLASS, ( CK_VOID_PTR ) &class, sizeof( CK_OBJECT_CLASS ) },
996 		{ CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
997 		{ CKA_TOKEN, ( CK_VOID_PTR ) &bFalse, sizeof( CK_BBOOL ) },
998 		{ CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
999 		{ CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1000 		{ CKA_ENCRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1001 		{ CKA_DECRYPT, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1002 		{ CKA_VALUE_LEN, ( CK_VOID_PTR ) &length, sizeof( CK_ULONG ) },
1003 		/* Persistent-object only fields */
1004 		{ CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
1005 		};
1006 	const int templateCount = \
1007 				( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? 9 : 8;
1008 
1009 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1010 
1011 	REQUIRES( keySizeBits >= bytesToBits( MIN_KEYSIZE ) && \
1012 			  keySizeBits <= bytesToBits( CRYPT_MAX_KEYSIZE ) );
1013 
1014 	/* If this is meant to be a persistent object, modify the template to
1015 	   make it a persistent token object and adjust the template entry count
1016 	   to include the object label */
1017 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
1018 		keyTemplate[ 2 ].pValue = ( CK_VOID_PTR ) &bTrue;
1019 
1020 	return( generateKey( contextInfoPtr, keyTemplate, templateCount, FALSE ) );
1021 	}
1022 
1023 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
hmacGenerateKey(INOUT CONTEXT_INFO * contextInfoPtr,IN_RANGE (bytesToBits (MIN_KEYSIZE),bytesToBits (CRYPT_MAX_PKCSIZE))const int keySizeBits)1024 static int hmacGenerateKey( INOUT CONTEXT_INFO *contextInfoPtr,
1025 							IN_RANGE( bytesToBits( MIN_KEYSIZE ),
1026 									  bytesToBits( CRYPT_MAX_PKCSIZE ) ) \
1027 								const int keySizeBits )
1028 	{
1029 	static const CK_OBJECT_CLASS class = CKO_SECRET_KEY;
1030 	static const CK_BBOOL bFalse = FALSE, bTrue = TRUE;
1031 	const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
1032 	const CK_ULONG length = bitsToBytes( keySizeBits );
1033 	CK_ATTRIBUTE keyTemplate[] = {
1034 		/* General-purpose fields */
1035 		{ CKA_CLASS, ( CK_VOID_PTR ) &class, sizeof( CK_OBJECT_CLASS ) },
1036 		{ CKA_KEY_TYPE, ( CK_VOID_PTR ) &type, sizeof( CK_KEY_TYPE ) },
1037 		{ CKA_TOKEN, ( CK_VOID_PTR ) &bFalse, sizeof( CK_BBOOL ) },
1038 		{ CKA_PRIVATE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1039 		{ CKA_SENSITIVE, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1040 		{ CKA_SIGN, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1041 		{ CKA_VERIFY, ( CK_VOID_PTR ) &bTrue, sizeof( CK_BBOOL ) },
1042 		{ CKA_VALUE_LEN, ( CK_VOID_PTR ) &length, sizeof( CK_ULONG ) },
1043 		/* Persistent-object only fields */
1044 		{ CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
1045 		};
1046 	const int templateCount = \
1047 				( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT ) ? 9 : 8;
1048 
1049 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1050 
1051 	REQUIRES( keySizeBits >= bytesToBits( MIN_KEYSIZE ) && \
1052 			  keySizeBits <= bytesToBits( CRYPT_MAX_KEYSIZE ) );
1053 
1054 	/* If this is meant to be a persistent object, modify the template to
1055 	   make it a persistent token object and adjust the template entry count
1056 	   to include the object label */
1057 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
1058 		keyTemplate[ 2 ].pValue = ( CK_VOID_PTR ) &bTrue;
1059 
1060 	return( generateKey( contextInfoPtr, keyTemplate, templateCount, TRUE ) );
1061 	}
1062 #else
1063 
1064 #define cipherGenerateKey	NULL
1065 #define hmacGenerateKey		NULL
1066 
1067 #endif /* USE_HW_KEYGEN */
1068 
1069 /****************************************************************************
1070 *																			*
1071 *						 Conventional Crypto Mapping Functions				*
1072 *																			*
1073 ****************************************************************************/
1074 
1075 /* Encrypt/decrypt data */
1076 
1077 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherEncrypt(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)void * buffer,IN_LENGTH const int length,const CK_MECHANISM_TYPE mechanismType)1078 static int cipherEncrypt( INOUT CONTEXT_INFO *contextInfoPtr,
1079 						  INOUT_BUFFER_FIXED( length ) void *buffer,
1080 						  IN_LENGTH const int length,
1081 						  const CK_MECHANISM_TYPE mechanismType )
1082 	{
1083 	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1084 	CRYPT_DEVICE iCryptDevice;
1085 	PKCS11_INFO *pkcs11Info;
1086 	const int ivSize = contextInfoPtr->capabilityInfo->blockSize;
1087 	int cryptStatus;
1088 
1089 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1090 	assert( isWritePtr( buffer, length ) );
1091 
1092 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1093 
1094 	/* Set up mode-specific IV parameters if required */
1095 	if( needsIV( contextInfoPtr->ctxConv->mode ) && \
1096 		!isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1097 		{
1098 		mechanism.pParameter = contextInfoPtr->ctxConv->currentIV;
1099 		mechanism.ulParameterLen = ivSize;
1100 		}
1101 
1102 	/* Get the information for the device associated with this context */
1103 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1104 										&iCryptDevice, &pkcs11Info );
1105 	if( cryptStatusError( cryptStatus ) )
1106 		return( cryptStatus );
1107 
1108 	cryptStatus = genericEncrypt( pkcs11Info, contextInfoPtr, &mechanism, buffer,
1109 								  length, length );
1110 	if( cryptStatusOK( cryptStatus ) )
1111 		{
1112 		if( needsIV( contextInfoPtr->ctxConv->mode ) && \
1113 			!isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1114 			{
1115 			/* Since PKCS #11 assumes that either all data is encrypted at
1116 			   once or that a given mechanism is devoted entirely to a single
1117 			   operation, we have to preserve the state (the IV) across
1118 			   calls */
1119 			memcpy( contextInfoPtr->ctxConv->currentIV, \
1120 					( BYTE * ) buffer + length - ivSize, ivSize );
1121 			}
1122 		}
1123 	krnlReleaseObject( iCryptDevice );
1124 
1125 	return( cryptStatus );
1126 	}
1127 
1128 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherDecrypt(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)void * buffer,IN_LENGTH const int length,const CK_MECHANISM_TYPE mechanismType)1129 static int cipherDecrypt( INOUT CONTEXT_INFO *contextInfoPtr,
1130 						  INOUT_BUFFER_FIXED( length ) void *buffer,
1131 						  IN_LENGTH const int length,
1132 						  const CK_MECHANISM_TYPE mechanismType )
1133 	{
1134 	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1135 	CRYPT_DEVICE iCryptDevice;
1136 	PKCS11_INFO *pkcs11Info;
1137 	BYTE ivBuffer[ CRYPT_MAX_IVSIZE + 8 ];
1138 	const int ivSize = contextInfoPtr->capabilityInfo->blockSize;
1139 	int cryptStatus;
1140 
1141 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1142 	assert( isWritePtr( buffer, length ) );
1143 
1144 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1145 
1146 	/* Set up mode-specific IV parameters if required.  In addition we have
1147 	   to save the end of the ciphertext as the IV for the next block */
1148 	if( needsIV( contextInfoPtr->ctxConv->mode ) && \
1149 		!isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1150 		{
1151 		mechanism.pParameter = contextInfoPtr->ctxConv->currentIV;
1152 		mechanism.ulParameterLen = ivSize;
1153 		memcpy( ivBuffer, ( BYTE * ) buffer + length - ivSize, ivSize );
1154 		}
1155 
1156 	/* Get the information for the device associated with this context */
1157 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1158 										&iCryptDevice, &pkcs11Info );
1159 	if( cryptStatusError( cryptStatus ) )
1160 		return( cryptStatus );
1161 
1162 	cryptStatus = genericDecrypt( pkcs11Info, contextInfoPtr, &mechanism, buffer,
1163 								  length );
1164 	if( cryptStatusOK( cryptStatus ) )
1165 		{
1166 		if( needsIV( contextInfoPtr->ctxConv->mode ) && \
1167 			!isStreamCipher( contextInfoPtr->capabilityInfo->cryptAlgo ) )
1168 			{
1169 			/* Since PKCS #11 assumes that either all data is encrypted at
1170 			   once or that a given mechanism is devoted entirely to a single
1171 			   operation, we have to preserve the state (the IV) across
1172 			   calls */
1173 			memcpy( contextInfoPtr->ctxConv->currentIV, ivBuffer, ivSize );
1174 			}
1175 		}
1176 	krnlReleaseObject( iCryptDevice );
1177 	return( cryptStatus );
1178 	}
1179 
1180 /* Map a cryptlib algorithm and mode to a PKCS #11 mechanism type, with
1181    shortcuts for the most frequently-used algorithm(s) */
1182 
1183 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherEncryptECB(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1184 static int cipherEncryptECB( INOUT CONTEXT_INFO *contextInfoPtr,
1185 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1186 							 IN_LENGTH int length )
1187 	{
1188 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1189 	assert( isWritePtr( buffer, length ) );
1190 
1191 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1192 
1193 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_3DES )
1194 		return( cipherEncrypt( contextInfoPtr, buffer, length, CKM_DES3_ECB ) );
1195 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_AES )
1196 		return( cipherEncrypt( contextInfoPtr, buffer, length, CKM_AES_ECB ) );
1197 	return( cipherEncrypt( contextInfoPtr, buffer, length,
1198 				getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1199 							  CRYPT_MODE_ECB ) ) );
1200 	}
1201 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherEncryptCBC(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1202 static int cipherEncryptCBC( INOUT CONTEXT_INFO *contextInfoPtr,
1203 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1204 							 IN_LENGTH int length )
1205 	{
1206 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1207 	assert( isWritePtr( buffer, length ) );
1208 
1209 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1210 
1211 	return( cipherEncrypt( contextInfoPtr, buffer, length,
1212 						   contextInfoPtr->capabilityInfo->paramDefaultMech ) );
1213 	}
1214 #if defined( USE_RC4 )
1215 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherEncryptCTR(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1216 static int cipherEncryptCTR( INOUT CONTEXT_INFO *contextInfoPtr,
1217 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1218 							 IN_LENGTH int length )
1219 	{
1220 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1221 	assert( isWritePtr( buffer, length ) );
1222 
1223 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1224 
1225 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RC4 )
1226 		return( cipherEncrypt( contextInfoPtr, buffer, length, CKM_RC4 ) );
1227 	return( cipherEncrypt( contextInfoPtr, buffer, length,
1228 				getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1229 							  CRYPT_MODE_CTR ) ) );
1230 	}
1231 #endif /* USE_RC4 */
1232 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherDecryptECB(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1233 static int cipherDecryptECB( INOUT CONTEXT_INFO *contextInfoPtr,
1234 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1235 							 IN_LENGTH int length )
1236 	{
1237 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1238 	assert( isWritePtr( buffer, length ) );
1239 
1240 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1241 
1242 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_3DES )
1243 		return( cipherDecrypt( contextInfoPtr, buffer, length, CKM_DES3_ECB ) );
1244 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_AES )
1245 		return( cipherDecrypt( contextInfoPtr, buffer, length, CKM_AES_ECB ) );
1246 	return( cipherDecrypt( contextInfoPtr, buffer, length,
1247 				getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1248 							  CRYPT_MODE_ECB ) ) );
1249 	}
1250 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherDecryptCBC(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1251 static int cipherDecryptCBC( INOUT CONTEXT_INFO *contextInfoPtr,
1252 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1253 							 IN_LENGTH int length )
1254 	{
1255 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1256 	assert( isWritePtr( buffer, length ) );
1257 
1258 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1259 
1260 	return( cipherDecrypt( contextInfoPtr, buffer, length,
1261 						   contextInfoPtr->capabilityInfo->paramDefaultMech ) );
1262 	}
1263 #if defined( USE_RC4 )
1264 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
cipherDecryptCTR(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH int length)1265 static int cipherDecryptCTR( INOUT CONTEXT_INFO *contextInfoPtr,
1266 							 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1267 							 IN_LENGTH int length )
1268 	{
1269 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1270 	assert( isWritePtr( buffer, length ) );
1271 
1272 	REQUIRES( length > 0 && length < MAX_INTLENGTH );
1273 
1274 	if( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RC4 )
1275 		return( cipherDecrypt( contextInfoPtr, buffer, length, CKM_RC4 ) );
1276 	return( cipherDecrypt( contextInfoPtr, buffer, length,
1277 				getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1278 							  CRYPT_MODE_CTR ) ) );
1279 	}
1280 #endif /* USE_RC4 */
1281 
1282 /****************************************************************************
1283 *																			*
1284 *								MAC Mapping Functions						*
1285 *																			*
1286 ****************************************************************************/
1287 
1288 /* MAC data.  The PKCS #11 way of handling this is rather problematic since
1289    the HMAC operation is associated with a session and not with the the HMAC
1290    object.  This means that we can only have a single HMAC operation in
1291    effect at any one time.  To protect against users starting a second
1292    HMAC/sign operation, we record the device object handle of the currently
1293    active signing object and don't allow any further signature operations to
1294    be initiated if there's an object currently in use */
1295 
1296 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
hmac(INOUT CONTEXT_INFO * contextInfoPtr,INOUT_BUFFER_FIXED (length)BYTE * buffer,IN_LENGTH_Z int length)1297 static int hmac( INOUT CONTEXT_INFO *contextInfoPtr,
1298 				 INOUT_BUFFER_FIXED( length ) BYTE *buffer,
1299 				 IN_LENGTH_Z int length )
1300 	{
1301 	CK_MECHANISM mechanism = { contextInfoPtr->capabilityInfo->paramDefaultMech,
1302 							   NULL_PTR, 0 };
1303 	CRYPT_DEVICE iCryptDevice;
1304 	PKCS11_INFO *pkcs11Info;
1305 	CK_RV status;
1306 	int cryptStatus;
1307 
1308 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1309 	assert( ( length == 0 ) || isWritePtr( buffer, length ) );
1310 
1311 	REQUIRES( length >= 0 && length < MAX_INTLENGTH );
1312 
1313 	/* Get the information for the device associated with this context */
1314 	cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1315 										&iCryptDevice, &pkcs11Info );
1316 	if( cryptStatusError( cryptStatus ) )
1317 		return( cryptStatus );
1318 
1319 	/* If we're currently in the middle of a multi-stage sign operation we
1320 	   can't start a new one.  We have to perform this tracking explicitly
1321 	   since PKCS #11 only allows one multi-stage operation per session */
1322 	if( pkcs11Info->hActiveSignObject != CK_OBJECT_NONE && \
1323 		pkcs11Info->hActiveSignObject != contextInfoPtr->deviceObject )
1324 		{
1325 		krnlReleaseObject( iCryptDevice );
1326 		return( CRYPT_ERROR_INCOMPLETE );
1327 		}
1328 
1329 	/* If we haven't initialised the MAC operation yet, start it now */
1330 	if( !( contextInfoPtr->flags & CONTEXT_FLAG_HASH_INITED ) )
1331 		{
1332 		status = C_SignInit( pkcs11Info->hSession, &mechanism,
1333 							 contextInfoPtr->deviceObject );
1334 		if( status != CKR_OK )
1335 			return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
1336 		contextInfoPtr->flags |= CONTEXT_FLAG_HASH_INITED;
1337 		pkcs11Info->hActiveSignObject = contextInfoPtr->deviceObject;
1338 		}
1339 
1340 	if( length > 0 )
1341 		status = C_SignUpdate( pkcs11Info->hSession, buffer, length  );
1342 	else
1343 		{
1344 		CK_ULONG dummy;
1345 
1346 		status = C_SignFinal( pkcs11Info->hSession,
1347 							  contextInfoPtr->ctxMAC->mac, &dummy );
1348 		pkcs11Info->hActiveSignObject = CK_OBJECT_NONE;
1349 		}
1350 	if( status != CKR_OK )
1351 		return( pkcs11MapError( status, CRYPT_ERROR_FAILED ) );
1352 
1353 	krnlReleaseObject( iCryptDevice );
1354 	return( cryptStatus );
1355 	}
1356 
1357 /****************************************************************************
1358 *																			*
1359 *						 	Device Capability Routines						*
1360 *																			*
1361 ****************************************************************************/
1362 
1363 /* Conventional encryption and MAC mechanism information */
1364 
1365 static const PKCS11_MECHANISM_INFO mechanismInfoConv[] = {
1366 	/* Conventional encryption mechanisms */
1367 	{ CKM_DES_ECB, CKM_DES_KEY_GEN, CKM_DES_CBC, CKF_NONE,
1368 	  CRYPT_ALGO_DES, CRYPT_MODE_ECB, CKK_DES,
1369 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1370 	  cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1371 	{ CKM_DES_CBC, CKM_DES_KEY_GEN, CKM_DES_CBC, CKF_NONE,
1372 	  CRYPT_ALGO_DES, CRYPT_MODE_CBC, CKK_DES,
1373 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1374 	  cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1375 	{ CKM_DES3_ECB, CKM_DES3_KEY_GEN, CKM_DES3_CBC, CKF_NONE,
1376 	  CRYPT_ALGO_3DES, CRYPT_MODE_ECB, CKK_DES3,
1377 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1378 	  cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1379 	{ CKM_DES3_CBC, CKM_DES3_KEY_GEN, CKM_DES3_CBC, CKF_NONE,
1380 	  CRYPT_ALGO_3DES, CRYPT_MODE_CBC, CKK_DES3,
1381 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1382 	  cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1383 #ifdef USE_RC4
1384 	{ CKM_RC4, CKM_RC4_KEY_GEN, CKM_RC4, CKF_NONE,
1385 	  CRYPT_ALGO_RC4, CRYPT_MODE_CTR, CKK_RC4,
1386 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1387 	  cipherEncryptCTR, cipherDecryptCTR, NULL, NULL },
1388 #endif /* USE_RC4 */
1389 	{ CKM_AES_ECB, CKM_AES_KEY_GEN, CKM_AES_CBC, CKF_NONE,
1390 	  CRYPT_ALGO_AES, CRYPT_MODE_ECB, CKK_AES,
1391 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1392 	  cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1393 	{ CKM_AES_CBC, CKM_AES_KEY_GEN, CKM_AES_CBC, CKF_NONE,
1394 	  CRYPT_ALGO_AES, CRYPT_MODE_CBC, CKK_AES,
1395 	  genericEndFunction, cipherInitKey, cipherGenerateKey,
1396 	  cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1397 
1398 	/* MAC mechanisms.  The positioning of the encrypt/decrypt functions is
1399 	   a bit odd because cryptlib treats hashing as an encrypt/decrypt
1400 	   operation while PKCS #11 treats it as a sign/verify operation, the
1401 	   function names correspond to the PKCS #11 usage but the position is
1402 	   for cryptlib usage.  In addition there aren't any HMAC key types so
1403 	   it's necessary to use CKK_GENERIC_SECRET (there's actually a bug in
1404 	   the standard around this because CKK_GENERIC_SECRET keys can't be
1405 	   used for en/decryption or sign/verify, at the moment some
1406 	   implementations allow them to be used with HMAC and some don't).  In
1407 	   order to allow for implementations that define their own HMAC keygen
1408 	   and key types, we use macros for CKM_x_HMAC_KEY_GEN and CKK_x_HMAC
1409 	   that expand either to the vendor-specific type or the generic CKM/CKK
1410 	   types */
1411 	{ CKM_SHA_1_HMAC, CKM_SHA_1_HMAC_KEY_GEN, CKM_SHA_1_HMAC, CKF_NONE,
1412 	  CRYPT_ALGO_HMAC_SHA1, CRYPT_MODE_NONE, CKK_SHA_1_HMAC,
1413 	  genericEndFunction, hmacInitKey, hmacGenerateKey,
1414 	  hmac, hmac, NULL, NULL },
1415 	{ CKM_SHA256_HMAC, CKM_SHA256_HMAC_KEY_GEN, CKM_SHA256_HMAC, CKF_NONE,
1416 	  CRYPT_ALGO_HMAC_SHA2, CRYPT_MODE_NONE, CKK_SHA256_HMAC,
1417 	  genericEndFunction, hmacInitKey, hmacGenerateKey,
1418 	  hmac, hmac, NULL, NULL },
1419 
1420 	{ CKM_NONE, CKM_NONE, CKM_NONE, CKF_NONE, CRYPT_ERROR, CRYPT_ERROR },
1421 		{ CKM_NONE, CKM_NONE, CKM_NONE, CKF_NONE, CRYPT_ERROR, CRYPT_ERROR }
1422 	};
1423 
1424 CHECK_RETVAL_PTR_NONNULL STDC_NONNULL_ARG( ( 1 ) ) \
getMechanismInfoConv(OUT_LENGTH_SHORT int * mechanismInfoSize)1425 const PKCS11_MECHANISM_INFO *getMechanismInfoConv( OUT_LENGTH_SHORT int *mechanismInfoSize )
1426 	{
1427 	assert( isWritePtr( mechanismInfoSize, sizeof( int ) ) );
1428 
1429 	*mechanismInfoSize = FAILSAFE_ARRAYSIZE( mechanismInfoConv, \
1430 											 PKCS11_MECHANISM_INFO );
1431 	return( mechanismInfoConv );
1432 	}
1433 
1434 /* Map a cryptlib conventional-encryption algorithm and mode to a PKCS #11
1435    mechanism */
1436 
getMechanism(const GETMECH_TYPE mechType,IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,IN_MODE const CRYPT_MODE_TYPE cryptMode)1437 static CK_MECHANISM_TYPE getMechanism( const GETMECH_TYPE mechType,
1438 									   IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo,
1439 									   IN_MODE const CRYPT_MODE_TYPE cryptMode )
1440 	{
1441 	int i;
1442 
1443 	REQUIRES_EXT( ( ( mechType == MECH_CONV && \
1444 					  isConvAlgo( cryptAlgo ) && \
1445 					  cryptMode > CRYPT_MODE_NONE && \
1446 					  cryptMode < CRYPT_MODE_LAST ) ||
1447 					( mechType == MECH_CONV_KEYGEN && \
1448 					  isConvAlgo( cryptAlgo ) && \
1449 					  cryptMode == CRYPT_MODE_NONE ) ||
1450 					( ( mechType == MECH_MAC || \
1451 						mechType == MECH_MAC_KEYGEN ) && \
1452 					  isMacAlgo( cryptAlgo ) && \
1453 					  cryptMode == CRYPT_MODE_NONE ) ), CKM_NONE );
1454 
1455 	/* Find a match for the algorithm type.  If it's a MAC algorithm or
1456 	   keygen mechanism, we're done */
1457 	for( i = 0; mechanismInfoConv[ i ].cryptAlgo != cryptAlgo && \
1458 				mechanismInfoConv[ i ].cryptAlgo != CRYPT_ERROR && \
1459 				i < FAILSAFE_ARRAYSIZE( mechanismInfoConv, PKCS11_MECHANISM_INFO );
1460 		 i++ );
1461 	ENSURES_EXT( ( i < FAILSAFE_ARRAYSIZE( mechanismInfoConv, PKCS11_MECHANISM_INFO ) ),
1462 				 CKM_NONE );
1463 	ENSURES_EXT( ( i < sizeof( mechanismInfoConv ) / sizeof( PKCS11_MECHANISM_INFO ) && \
1464 				   mechanismInfoConv[ i ].cryptAlgo != CRYPT_ERROR ), CKM_NONE );
1465 	if( mechType == MECH_MAC )
1466 		return( mechanismInfoConv[ i ].mechanism );
1467 	if( mechType == MECH_CONV_KEYGEN || mechType == MECH_MAC_KEYGEN )
1468 		return( mechanismInfoConv[ i ].keygenMechanism );
1469 
1470 	/* It's a conventional-encryption mechanism, we have to match the
1471 	   encryption mode as well */
1472 	ENSURES_EXT( mechType == MECH_CONV, CKM_NONE );
1473 	while( mechanismInfoConv[ i ].cryptMode != cryptMode && \
1474 		   mechanismInfoConv[ i ].cryptAlgo != CRYPT_ERROR && \
1475 		   i < FAILSAFE_ARRAYSIZE( mechanismInfoConv, PKCS11_MECHANISM_INFO ) )
1476 		i++;
1477 	ENSURES_EXT( ( i < FAILSAFE_ARRAYSIZE( mechanismInfoConv, PKCS11_MECHANISM_INFO ) ),
1478 				 CKM_NONE );
1479 	ENSURES_EXT( ( i < sizeof( mechanismInfoConv ) / sizeof( PKCS11_MECHANISM_INFO ) && \
1480 				 mechanismInfoConv[ i ].cryptAlgo != CRYPT_ERROR ), CKM_NONE );
1481 
1482 	return( mechanismInfoConv[ i ].mechanism );
1483 	}
1484 
1485 /****************************************************************************
1486 *																			*
1487 *						 	Device Access Routines							*
1488 *																			*
1489 ****************************************************************************/
1490 
1491 /* Mechanisms supported by PKCS #11 devices.  These are actually cryptlib
1492    native mechanisms (support of the various mechanisms in devices is too
1493    patchy to rely on, see for example the comments about PKCS vs.raw RSA
1494    mechanisms elsewhere), but not the full set supported by the system
1495    device since functions like private key export aren't available.  The
1496    list is sorted in order of frequency of use in order to make lookups a
1497    bit faster */
1498 
1499 static const FAR_BSS MECHANISM_FUNCTION_INFO mechanismFunctions[] = {
1500 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) exportPKCS1 },
1501 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) importPKCS1 },
1502 	{ MESSAGE_DEV_SIGN, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) signPKCS1 },
1503 	{ MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) sigcheckPKCS1 },
1504 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) exportPKCS1 },
1505 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) importPKCS1 },
1506 #ifdef USE_PGP
1507 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) exportPKCS1PGP },
1508 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) importPKCS1PGP },
1509 #endif /* USE_PGP */
1510 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) exportCMS },
1511 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) importCMS },
1512 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS5, ( MECHANISM_FUNCTION ) derivePKCS5 },
1513 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
1514 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PGP, ( MECHANISM_FUNCTION ) derivePGP },
1515 #endif /* USE_PGP || USE_PGPKEYS */
1516 #ifdef USE_SSL
1517 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_TLS, ( MECHANISM_FUNCTION ) deriveSSL },
1518 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_SSL, ( MECHANISM_FUNCTION ) deriveTLS },
1519 	{ MESSAGE_DEV_SIGN, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) signSSL },
1520 	{ MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) sigcheckSSL },
1521 #endif /* USE_SSL */
1522 #ifdef USE_CMP
1523 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_CMP, ( MECHANISM_FUNCTION ) deriveCMP },
1524 #endif /* USE_CMP */
1525 #ifdef USE_PKCS12
1526 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS12, ( MECHANISM_FUNCTION ) derivePKCS12 },
1527 #endif /* USE_PKCS12 */
1528 	{ MESSAGE_NONE, MECHANISM_NONE, NULL }, { MESSAGE_NONE, MECHANISM_NONE, NULL }
1529 	};
1530 
1531 /* Set up the function pointers to the device methods */
1532 
1533 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
setDevicePKCS11(INOUT DEVICE_INFO * deviceInfo,IN_BUFFER (nameLength)const char * name,IN_LENGTH_ATTRIBUTE const int nameLength)1534 int setDevicePKCS11( INOUT DEVICE_INFO *deviceInfo,
1535 					 IN_BUFFER( nameLength ) const char *name,
1536 					 IN_LENGTH_ATTRIBUTE const int nameLength )
1537 	{
1538 	int status;
1539 
1540 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
1541 	assert( isReadPtr( name, nameLength ) );
1542 
1543 	REQUIRES( nameLength > 0 && nameLength < MAX_ATTRIBUTE_SIZE );
1544 
1545 	status = initPKCS11Init( deviceInfo, name, nameLength );
1546 	if( cryptStatusError( status ) )
1547 		return( status );
1548 	deviceInfo->controlFunction = controlFunction;
1549 	initPKCS11Read( deviceInfo );
1550 	initPKCS11Write( deviceInfo );
1551 	deviceInfo->mechanismFunctions = mechanismFunctions;
1552 	deviceInfo->mechanismFunctionCount = \
1553 		FAILSAFE_ARRAYSIZE( mechanismFunctions, MECHANISM_FUNCTION_INFO );
1554 
1555 	return( CRYPT_OK );
1556 	}
1557 #endif /* USE_PKCS11 */
1558