1 /****************************************************************************
2 *																			*
3 *					  cryptlib Generic Crypto HW Routines					*
4 *						Copyright Peter Gutmann 1998-2009					*
5 *																			*
6 ****************************************************************************/
7 
8 #define PKC_CONTEXT		/* Indicate that we're working with PKC contexts */
9 #if defined( INC_ALL )
10   #include "crypt.h"
11   #include "context.h"
12   #include "device.h"
13   #include "hardware.h"
14   #include "dev_mech.h"
15 #else
16   #include "crypt.h"
17   #include "context/context.h"
18   #include "device/device.h"
19   #include "device/hardware.h"
20   #include "mechs/dev_mech.h"
21 #endif /* Compiler-specific includes */
22 
23 #ifdef USE_HARDWARE
24 
25 /****************************************************************************
26 *																			*
27 *						 		Utility Routines							*
28 *																			*
29 ****************************************************************************/
30 
31 /* Get access to the hardware device associated with a context */
32 
getContextDeviceInfo(const CRYPT_HANDLE iCryptContext,CRYPT_DEVICE * iCryptDevice,HARDWARE_INFO ** hwInfoPtrPtr)33 static int getContextDeviceInfo( const CRYPT_HANDLE iCryptContext,
34 								 CRYPT_DEVICE *iCryptDevice,
35 								 HARDWARE_INFO **hwInfoPtrPtr )
36 	{
37 	CRYPT_DEVICE iLocalDevice;
38 	DEVICE_INFO *deviceInfo;
39 	int status;
40 
41 	assert( isWritePtr( iCryptDevice, sizeof( CRYPT_DEVICE ) ) );
42 	assert( isWritePtr( hwInfoPtrPtr, sizeof( HARDWARE_INFO * ) ) );
43 
44 	REQUIRES( isHandleRangeValid( iCryptContext ) );
45 
46 	/* Clear return values */
47 	*iCryptDevice = CRYPT_ERROR;
48 	*hwInfoPtrPtr = NULL;
49 
50 	/* Get the the device associated with this context */
51 	status = krnlSendMessage( iCryptContext, IMESSAGE_GETDEPENDENT,
52 							  &iLocalDevice, OBJECT_TYPE_DEVICE );
53 	if( cryptStatusError( status ) )
54 		return( status );
55 
56 	/* Get the hardware information from the device information */
57 	status = krnlAcquireObject( iLocalDevice, OBJECT_TYPE_DEVICE,
58 								( void ** ) &deviceInfo,
59 								CRYPT_ERROR_SIGNALLED );
60 	if( cryptStatusError( status ) )
61 		return( status );
62 	*iCryptDevice = iLocalDevice;
63 	*hwInfoPtrPtr = deviceInfo->deviceHardware;
64 
65 	return( CRYPT_OK );
66 	}
67 
68 /* Get a reference to the cryptographic hardware object that underlies a
69    cryptlib object.  This is used to connect a template object from a
70    PKCS #15 storage object to the corresponding hardware object via the
71    storageID that's recorded in the storage object */
72 
getHardwareReference(const CRYPT_CONTEXT iCryptContext,int * keyHandle)73 static int getHardwareReference( const CRYPT_CONTEXT iCryptContext,
74 								 int *keyHandle )
75 	{
76 	MESSAGE_DATA msgData;
77 	BYTE storageID[ KEYID_SIZE + 8 ];
78 	int status;
79 
80 	assert( isWritePtr( keyHandle, sizeof( int ) ) );
81 
82 	REQUIRES( isHandleRangeValid( iCryptContext ) );
83 
84 	setMessageData( &msgData, storageID, KEYID_SIZE );
85 	status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
86 							  &msgData, CRYPT_IATTRIBUTE_DEVICESTORAGEID );
87 	if( cryptStatusOK( status ) )
88 		status = hwLookupItem( storageID, KEYID_SIZE, keyHandle );
89 	if( cryptStatusError( status ) )
90 		{
91 		/* In theory this is an internal error but in practice we shouldn't
92 		   treat this as too fatal, what it really means is that the crypto
93 		   hardware (which we don't control and therefore can't do too much
94 		   about) is out of sync with the PKCS #15 storage object.  This can
95 		   happen for example during the development process when the
96 		   hardware is reinitialised but the storage object isn't, or from
97 		   any one of a number of other circumstances beyond our control.
98 		   To deal with this we return a standard notfound error but also
99 		   output a diagnostic message for developers to let them know that
100 		   they need to check hardware/storage object synchronisation */
101 		DEBUG_PRINT(( "Object held in PKCS #15 object store doesn't "
102 					  "correspond to anything known to the crypto "
103 					  "hardware HAL" ));
104 		return( CRYPT_ERROR_NOTFOUND );
105 		}
106 
107 	return( CRYPT_OK );
108 	}
109 
110 /* Open the PKCS #15 storage object associated with this device */
111 
openStorageObject(CRYPT_KEYSET * iCryptKeyset,const CRYPT_KEYOPT_TYPE options,const CRYPT_DEVICE iCryptDevice)112 static int openStorageObject( CRYPT_KEYSET *iCryptKeyset,
113 							  const CRYPT_KEYOPT_TYPE options,
114 							  const CRYPT_DEVICE iCryptDevice )
115 	{
116 	MESSAGE_CREATEOBJECT_INFO createInfo;
117 	char storageFilePath[ MAX_PATH_LENGTH + 8 ];
118 	int storageFilePathLen, status;
119 
120 	assert( isWritePtr( iCryptKeyset, sizeof( CRYPT_KEYSET ) ) );
121 
122 	REQUIRES( options == CRYPT_KEYOPT_NONE || \
123 			  options == CRYPT_KEYOPT_CREATE );
124 	REQUIRES( isHandleRangeValid( iCryptDevice ) );
125 
126 	/* Clear return value */
127 	*iCryptKeyset = CRYPT_ERROR;
128 
129 	/* Try and open/create the PKCS #15 storage object */
130 	status = fileBuildCryptlibPath( storageFilePath, MAX_PATH_LENGTH,
131 									&storageFilePathLen, "CLKEYS", 6,
132 									BUILDPATH_GETPATH );
133 	if( cryptStatusError( status ) )
134 		return( status );
135 	setMessageCreateObjectInfo( &createInfo, CRYPT_KEYSET_FILE );
136 	if( options != CRYPT_KEYOPT_NONE )
137 		createInfo.arg2 = options;
138 	createInfo.strArg1 = storageFilePath;
139 	createInfo.strArgLen1 = storageFilePathLen;
140 	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
141 							  &createInfo, OBJECT_TYPE_KEYSET );
142 	if( cryptStatusError( status ) )
143 		return( status );
144 
145 	/* Now that we've got the storage object we have to perform a somewhat
146 	   awkward double-linked-list update of the keyset to give it the handle
147 	   of the owning device since we need to create any contexts for keys
148 	   fetched from the storage object via the hardware device rather than
149 	   the default system device.  In theory we could also do this via a new
150 	   get-owning-object message but we still need to signal to the keyset
151 	   that it's a storage object rather than a standard keyset so this
152 	   action serves a second purpose anyway and we may as well use it to
153 	   explicitly set the owning-device handle at the same time.
154 
155 	   Note that we don't set the storage object as a dependent object of
156 	   the device because it's not necessarily constant across device
157 	   sessions.  In particular if we initialise or zeroise the device then
158 	   the storage object will be reset, but there's no way to switch
159 	   dependent objects without destroying and recreating the parent.  In
160 	   addition it's not certain whether the storage-object keyset should
161 	   really be a dependent object or not, in theory it's nice because it
162 	   allows keyset-specific messages/accesses to be sent to the device and
163 	   automatically routed to the keyset (standard accesses will still go
164 	   to the device, so for example a getItem() will be handled as a
165 	   device-get rather than a keyset-get) but such unmediated access to
166 	   the underlying keyset probably isn't a good idea anyway */
167 	status = krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE,
168 							  ( MESSAGE_CAST ) &iCryptDevice,
169 							  CRYPT_IATTRIBUTE_HWSTORAGE );
170 	if( cryptStatusError( status ) )
171 		{
172 		krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
173 		return( status );
174 		}
175 	*iCryptKeyset = createInfo.cryptHandle;
176 
177 	return( CRYPT_OK );
178 	}
179 
180 /****************************************************************************
181 *																			*
182 *						 		Init/Shutdown Routines						*
183 *																			*
184 ****************************************************************************/
185 
186 /* Initialise the capability information */
187 
188 #define MAX_DEVICE_CAPABILITIES		32
189 
190 static CAPABILITY_INFO_LIST capabilityInfoList[ MAX_DEVICE_CAPABILITIES ];
191 
192 /* Initialise the cryptographic hardware and its crypto capability
193    interface */
194 
195 CHECK_RETVAL \
deviceInitHardware(void)196 int deviceInitHardware( void )
197 	{
198 	CAPABILITY_INFO *capabilityInfo;
199 	static BOOLEAN initCalled = FALSE;
200 	int noCapabilities, i, status;
201 
202 	/* If we've previously tried to initialise the hardware, don't try it
203 	   again */
204 	if( initCalled )
205 		return( CRYPT_OK );
206 	initCalled = TRUE;
207 
208 	/* Get the hardware capability information */
209 	status = hwGetCapabilities( &capabilityInfo, &noCapabilities );
210 	if( cryptStatusError( status ) )
211 		return( status );
212 	ENSURES( noCapabilities > 0 && \
213 			 noCapabilities < MAX_DEVICE_CAPABILITIES );
214 
215 	/* Build the list of available capabilities */
216 	memset( capabilityInfoList, 0,
217 			sizeof( CAPABILITY_INFO_LIST ) * MAX_DEVICE_CAPABILITIES );
218 	for( i = 0; i < noCapabilities && \
219 				capabilityInfo[ i ].cryptAlgo != CRYPT_ALGO_NONE; i++ )
220 		{
221 		REQUIRES( sanityCheckCapability( &capabilityInfo[ i ] ) );
222 
223 		capabilityInfoList[ i ].info = &capabilityInfo[ i ];
224 		capabilityInfoList[ i ].next = NULL;
225 		if( i > 0 )
226 			capabilityInfoList[ i - 1 ].next = &capabilityInfoList[ i ];
227 		}
228 	ENSURES( i < noCapabilities );
229 
230 	return( CRYPT_OK );
231 	}
232 
deviceEndHardware(void)233 void deviceEndHardware( void )
234 	{
235 	}
236 
237 /****************************************************************************
238 *																			*
239 *					Device Init/Shutdown/Device Control Routines			*
240 *																			*
241 ****************************************************************************/
242 
243 /* Close a previously-opened session with the device.  We have to have this
244    before the initialisation function since it may be called by it if the
245    initialisation process fails */
246 
shutdownFunction(DEVICE_INFO * deviceInfo)247 static void shutdownFunction( DEVICE_INFO *deviceInfo )
248 	{
249 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
250 
251 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
252 
253 	/* Shut down access to the storage object */
254 	if( hardwareInfo->iCryptKeyset != CRYPT_ERROR )
255 		{
256 		krnlSendNotifier( hardwareInfo->iCryptKeyset, IMESSAGE_DECREFCOUNT );
257 		hardwareInfo->iCryptKeyset = CRYPT_ERROR;
258 		}
259 	deviceInfo->flags &= ~( DEVICE_ACTIVE | DEVICE_LOGGEDIN );
260 	}
261 
262 /* Open a session with the device */
263 
initFunction(DEVICE_INFO * deviceInfo,const char * name,const int nameLength)264 static int initFunction( DEVICE_INFO *deviceInfo, const char *name,
265 						 const int nameLength )
266 	{
267 	CRYPT_KEYSET iCryptKeyset;
268 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
269 	int status;
270 
271 	UNUSED_ARG( name );
272 
273 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
274 
275 	/* Set up any internal objects to contain invalid handles */
276 	hardwareInfo->iCryptKeyset = CRYPT_ERROR;
277 
278 	/* Set up the device ID information */
279 	memcpy( hardwareInfo->label, "Cryptographic hardware device", 29 );
280 	hardwareInfo->labelLen = 29;
281 	deviceInfo->label = hardwareInfo->label;
282 	deviceInfo->labelLen = hardwareInfo->labelLen;
283 
284 	/* Since this is a built-in hardware device it's always present and
285 	   available */
286 	deviceInfo->flags |= DEVICE_ACTIVE | DEVICE_LOGGEDIN;
287 
288 	/* Try and open the PKCS #15 storage object.  If we can't open it it
289 	   means that either it doesn't exist (i.e. persistent key storage
290 	   isn't supported) or the device hasn't been initialised yet.  This
291 	   isn't a fatal error, although it does mean that public-key
292 	   operations will be severely restricted since these depend on storing
293 	   key metadata in the storage object */
294 	status = openStorageObject( &iCryptKeyset, CRYPT_KEYOPT_NONE,
295 								deviceInfo->objectHandle );
296 	if( cryptStatusError( status ) )
297 		return( CRYPT_OK );	/* Storage object not available */
298 	hardwareInfo->iCryptKeyset = iCryptKeyset;
299 
300 	return( CRYPT_OK );
301 	}
302 
303 /* Handle device control functions */
304 
controlFunction(DEVICE_INFO * deviceInfo,const CRYPT_ATTRIBUTE_TYPE type,const void * data,const int dataLength,MESSAGE_FUNCTION_EXTINFO * messageExtInfo)305 static int controlFunction( DEVICE_INFO *deviceInfo,
306 							const CRYPT_ATTRIBUTE_TYPE type,
307 							const void *data, const int dataLength,
308 							MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
309 	{
310 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
311 	int status;
312 
313 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
314 
315 	REQUIRES( isAttribute( type ) || isInternalAttribute( type ) );
316 
317 	UNUSED_ARG( hardwareInfo );
318 	UNUSED_ARG( messageExtInfo );
319 
320 	/* Handle user authorisation.  Since this is a built-in hardware device
321 	   it's always available for use so these are just dummy routines,
322 	   although they can be expanded to call down into the HAL for actual
323 	   authentication if any hardware with such a facility is ever used */
324 	if( type == CRYPT_DEVINFO_AUTHENT_USER || \
325 		type == CRYPT_DEVINFO_AUTHENT_SUPERVISOR )
326 		{
327 		/* Authenticate the user */
328 		/* ... */
329 
330 		/* The device is now ready for use */
331 		deviceInfo->flags |= DEVICE_LOGGEDIN;
332 		krnlSendMessage( deviceInfo->objectHandle, IMESSAGE_SETATTRIBUTE,
333 						 MESSAGE_VALUE_UNUSED, CRYPT_IATTRIBUTE_INITIALISED );
334 		return( CRYPT_OK );
335 		}
336 
337 	/* Handle authorisation value change */
338 	if( type == CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR )
339 		{
340 		/* Set SO PIN */
341 		/* ... */
342 
343 		return( CRYPT_OK );
344 		}
345 	if( type == CRYPT_DEVINFO_SET_AUTHENT_USER )
346 		{
347 		/* Set user PIN */
348 		/* ... */
349 
350 		return( CRYPT_OK );
351 		}
352 
353 	/* Handle initialisation and zeroisation */
354 	if( type == CRYPT_DEVINFO_INITIALISE || \
355 		type == CRYPT_DEVINFO_ZEROISE )
356 		{
357 		CRYPT_KEYSET iCryptKeyset;
358 
359 		/* Shut down any existing state if necessary in preparation for the
360 		   zeroise/initialise.  Since this clears all state we manually
361 		   reset the device-active flag since we're still active, just with
362 		   all information cleared */
363 		if( hardwareInfo->iCryptKeyset != CRYPT_ERROR )
364 			shutdownFunction( deviceInfo );
365 		hwInitialise();
366 		deviceInfo->flags |= DEVICE_ACTIVE;
367 
368 		/* The only real difference between a zeroise and an initialise is
369 		   that the zeroise only clears existing state and exits while the
370 		   initialise resets the state with the device ready to be used
371 		   again */
372 		if( type == CRYPT_DEVINFO_ZEROISE )
373 			{
374 			char storageFilePath[ MAX_PATH_LENGTH + 1 + 8 ];
375 			int storageFilePathLen;
376 
377 			/* Zeroise the device */
378 			status = fileBuildCryptlibPath( storageFilePath, MAX_PATH_LENGTH,
379 											&storageFilePathLen, "CLKEYS", 6,
380 											BUILDPATH_GETPATH );
381 			if( cryptStatusOK( status ) )
382 				{
383 				storageFilePath[ storageFilePathLen ] = '\0';
384 				fileErase( storageFilePath );
385 				}
386 			deviceInfo->flags &= ~DEVICE_LOGGEDIN;
387 			return( status );
388 			}
389 
390 		/* Initialise the device.  In theory we're already in the logged-in
391 		   state but if the initialise was preceded by a zeroise then this
392 		   will have been cleared, so we explicitly re-set it */
393 		status = openStorageObject( &iCryptKeyset, CRYPT_KEYOPT_CREATE,
394 									deviceInfo->objectHandle );
395 		if( cryptStatusError( status ) )
396 			return( status );
397 		hardwareInfo->iCryptKeyset = iCryptKeyset;
398 		deviceInfo->flags |= DEVICE_LOGGEDIN;
399 
400 		return( CRYPT_OK );
401 		}
402 
403 	/* Handle high-reliability time */
404 	if( type == CRYPT_IATTRIBUTE_TIME )
405 		{
406 		time_t *timePtr = ( time_t * ) data;
407 
408 		UNUSED_ARG( timePtr );
409 
410 		return( CRYPT_ERROR_NOTAVAIL );
411 		}
412 
413 	retIntError();
414 	}
415 
416 /* Get random data from the device.  The messageExtInfo parameter is used
417    to handle recursive messages sent to the system device during the
418    randomness-polling process and isn't used here */
419 
getRandomFunction(DEVICE_INFO * deviceInfo,void * buffer,const int length,MESSAGE_FUNCTION_EXTINFO * messageExtInfo)420 static int getRandomFunction( DEVICE_INFO *deviceInfo, void *buffer,
421 							  const int length,
422 							  MESSAGE_FUNCTION_EXTINFO *messageExtInfo )
423 	{
424 	UNUSED_ARG( messageExtInfo );
425 
426 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
427 	assert( isWritePtr( buffer, length ) );
428 
429 	REQUIRES( length > 0 && length < MAX_BUFFER_SIZE );
430 
431 	/* Fill the buffer with random data */
432 	return( hwGetRandom( buffer, length ) );
433 	}
434 
435 /****************************************************************************
436 *																			*
437 *						Get/Set/Delete Item Routines						*
438 *																			*
439 ****************************************************************************/
440 
441 /* Instantiate an object in a device.  This works like the create context
442    function but instantiates a cryptlib object using data already contained
443    in the device (for example a stored private key or certificate).  If the
444    value being read is a public key and there's a certificate attached then
445    the instantiated object is a native cryptlib object rather than a device
446    object with a native certificate object attached because there doesn't
447    appear to be any good reason to create the public-key object in the
448    device, and the cryptlib native object will probably be faster anyway */
449 
getItemFunction(DEVICE_INFO * deviceInfo,CRYPT_CONTEXT * iCryptContext,const KEYMGMT_ITEM_TYPE itemType,const CRYPT_KEYID_TYPE keyIDtype,const void * keyID,const int keyIDlength,void * auxInfo,int * auxInfoLength,const int flags)450 static int getItemFunction( DEVICE_INFO *deviceInfo,
451 							CRYPT_CONTEXT *iCryptContext,
452 							const KEYMGMT_ITEM_TYPE itemType,
453 							const CRYPT_KEYID_TYPE keyIDtype,
454 							const void *keyID, const int keyIDlength,
455 							void *auxInfo, int *auxInfoLength,
456 							const int flags )
457 	{
458 #if 0
459 	const CRYPT_DEVICE cryptDevice = deviceInfo->objectHandle;
460 	CRYPT_CERTIFICATE iCryptCert = CRYPT_UNUSED;
461 	const CAPABILITY_INFO *capabilityInfoPtr;
462 	HW_KEYINFO keyInfo;
463 	MESSAGE_DATA msgData;
464 	const int extraFlags = ( itemType == KEYMGMT_ITEM_PRIVATEKEY ) ? \
465 						   KEYMGMT_FLAG_DATAONLY_CERT : 0;
466 	int keyHandle, p15status, status;
467 #endif
468 	CRYPT_CONTEXT iLocalContext;
469 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
470 	MESSAGE_KEYMGMT_INFO getkeyInfo;
471 	int keyHandle, status;
472 
473 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
474 	assert( isWritePtr( iCryptContext, sizeof( CRYPT_CONTEXT ) ) );
475 	assert( isReadPtr( keyID, keyIDlength ) );
476 
477 	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
478 			  itemType == KEYMGMT_ITEM_PRIVATEKEY );
479 	REQUIRES( keyIDtype == CRYPT_KEYID_NAME || \
480 			  keyIDtype == CRYPT_KEYID_URI || \
481 			  keyIDtype == CRYPT_IKEYID_KEYID || \
482 			  keyIDtype == CRYPT_IKEYID_PGPKEYID || \
483 			  keyIDtype == CRYPT_IKEYID_ISSUERANDSERIALNUMBER );
484 	REQUIRES( auxInfo == NULL && *auxInfoLength == 0 );
485 	REQUIRES( flags >= KEYMGMT_FLAG_NONE && flags < KEYMGMT_FLAG_MAX );
486 
487 #if 1
488 	/* Redirect the fetch down to the PKCS #15 storage object, which will
489 	   create either a dummy context that we have to connect to the actual
490 	   hardware for a private-key object or a native public-key/certificate
491 	   object if it's a non-private-key item */
492 	if( hardwareInfo->iCryptKeyset == CRYPT_ERROR )
493 		return( CRYPT_ERROR_NOTINITED );
494 	setMessageKeymgmtInfo( &getkeyInfo, keyIDtype, keyID, keyIDlength,
495 						   NULL, 0, flags );
496 	status = krnlSendMessage( hardwareInfo->iCryptKeyset,
497 							  IMESSAGE_KEY_GETKEY, &getkeyInfo,
498 							  itemType );
499 	if( cryptStatusError( status ) )
500 		return( status );
501 	iLocalContext = getkeyInfo.cryptHandle;
502 
503 	/* If it's a public-key fetch, we've created a native object and we're
504 	   done */
505 	if( itemType != KEYMGMT_ITEM_PRIVATEKEY )
506 		{
507 		*iCryptContext = iLocalContext;
508 		return( CRYPT_OK );
509 		}
510 
511 	/* It was a private-key fetch, we need to connect the dummy context that
512 	   was created with the underlying hardware.  When this final step
513 	   has been completed we can move the context to the initialised state */
514 	status = getHardwareReference( iLocalContext, &keyHandle );
515 	if( cryptStatusError( status ) )
516 		{
517 		krnlSendNotifier( iLocalContext, IMESSAGE_DECREFCOUNT );
518 		return( status );
519 		}
520 	status = krnlSendMessage( iLocalContext, IMESSAGE_SETATTRIBUTE,
521 							  &keyHandle, CRYPT_IATTRIBUTE_DEVICEOBJECT );
522 	if( cryptStatusOK( status ) )
523 		{
524 		status = krnlSendMessage( iLocalContext, IMESSAGE_SETATTRIBUTE,
525 								  MESSAGE_VALUE_UNUSED,
526 								  CRYPT_IATTRIBUTE_INITIALISED );
527 		}
528 	if( cryptStatusError( status ) )
529 		{
530 		krnlSendNotifier( iLocalContext, IMESSAGE_DECREFCOUNT );
531 		return( status );
532 		}
533 #else
534 	/* As a first step we redirect the fetch down to the PKCS #15 storage
535 	   object to get any certificate that may be associated with the item.
536 	   We always do this because if we're fetching a public key then this
537 	   is all that we need and if we're fetching a private key then we'll
538 	   associate the certificate with it if it's present */
539 	if( hardwareInfo->iCryptKeyset == CRYPT_ERROR )
540 		return( CRYPT_ERROR_NOTINITED );
541 	setMessageKeymgmtInfo( &getkeyInfo, keyIDtype, keyID, keyIDlength,
542 						   NULL, 0, flags | extraFlags );
543 	p15status = krnlSendMessage( hardwareInfo->iCryptKeyset,
544 								 IMESSAGE_KEY_GETKEY, &getkeyInfo,
545 								 KEYMGMT_ITEM_PUBLICKEY );
546 	if( cryptStatusOK( p15status ) )
547 		{
548 		iCryptCert = getkeyInfo.cryptHandle;
549 
550 		/* If we were after a public key, we're done */
551 		if( itemType == KEYMGMT_ITEM_PUBLICKEY )
552 			{
553 			*iCryptContext = iCryptCert;
554 			return( CRYPT_OK );
555 			}
556 
557 		/* If we were after a private key and the keyID is one that isn't
558 		   stored locally, extract it from the returned private key */
559 		// This won't work, there's no CRYPT_IKEYID_KEYID or
560 		// CRYPT_IKEYID_PGPKEYID with the cert, only an
561 		// CRYPT_IKEYID_ISSUERANDSERIALNUMBER
562 		}
563 
564 	/* Look up the private key, which we may use directly or simply extract
565 	   the public-key components from.  If there's an error then we
566 	   preferentially return the error code from the storage object, which
567 	   is likely to be more informative than a generic CRYPT_ERROR_NOTFOUND
568 	   from the hardware lookup */
569 	status = hwLookupItemInfo( keyIDtype, keyID, keyIDlength, &keyHandle,
570 							   &keyInfo );
571 	if( cryptStatusError( status ) )
572 		return( cryptStatusError( p15status ) ? p15status : status );
573 	if( itemType == KEYMGMT_ITEM_PUBLICKEY )
574 		{
575 		MESSAGE_CREATEOBJECT_INFO createInfo;
576 
577 		/* There's no certificate present but we do have private-key
578 		   components from which we can extract the public-key portion to
579 		   create a native context instead of a device one.  This solves a
580 		   variety of problems including the fact that performing public-key
581 		   operations natively is often much faster than the time it takes
582 		   to marshall the data and get it to the crypto hardware, and that
583 		   if we do it ourselves we can defend against a variety of RSA
584 		   padding and timing attacks that have come up since the device
585 		   firmware was done */
586 		setMessageCreateObjectInfo( &createInfo, keyInfo.cryptAlgo );
587 		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
588 								  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
589 								  OBJECT_TYPE_CONTEXT );
590 		if( cryptStatusError( status ) )
591 			return( status );
592 		iLocalContext = createInfo.cryptHandle;
593 
594 		/* Send the keying information to the context.  We don't set the
595 		   action flags because there are none recorded at the hardware
596 		   level */
597 		status = setPublicComponents( createInfo.cryptHandle,
598 									  keyInfo.cryptAlgo,
599 									  &keyInfo.publicKeyInfo );
600 		if( cryptStatusError( status ) )
601 			{
602 			krnlSendNotifier( iLocalContext, IMESSAGE_DECREFCOUNT );
603 			return( status );
604 			}
605 		*iCryptContext = iLocalContext;
606 		return( CRYPT_OK );
607 		}
608 
609 	/* It's a private key, create a dummy context for the device object,
610 	   remember the device that it's contained in, and record the handle for
611 	   the device-internal key */
612 	capabilityInfoPtr = findCapabilityInfo( deviceInfo->capabilityInfoList,
613 											keyInfo.cryptAlgo );
614 	if( capabilityInfoPtr == NULL )
615 		return( CRYPT_ERROR_NOTAVAIL );
616 	status = createContextFromCapability( &iLocalContext, cryptDevice,
617 										  capabilityInfoPtr,
618 										  CREATEOBJECT_FLAG_DUMMY | \
619 										  CREATEOBJECT_FLAG_PERSISTENT );
620 	if( cryptStatusError( status ) )
621 		{
622 		if( iCryptCert != CRYPT_UNUSED )
623 			krnlSendNotifier( iCryptCert, IMESSAGE_DECREFCOUNT );
624 		return( status );
625 		}
626 	status = krnlSendMessage( iLocalContext, IMESSAGE_SETDEPENDENT,
627 							  ( MESSAGE_CAST ) &cryptDevice,
628 							  SETDEP_OPTION_INCREF );
629 	if( cryptStatusOK( status ) )
630 		status = krnlSendMessage( iLocalContext, IMESSAGE_SETATTRIBUTE,
631 								  ( MESSAGE_CAST ) &keyHandle,
632 								  CRYPT_IATTRIBUTE_DEVICEOBJECT );
633 	if( cryptStatusError( status ) )
634 		{
635 		krnlSendNotifier( iLocalContext, IMESSAGE_DECREFCOUNT );
636 		if( iCryptCert != CRYPT_UNUSED )
637 			krnlSendNotifier( iCryptCert, IMESSAGE_DECREFCOUNT );
638 		return( status );
639 		}
640 
641 	/* Set the object's label, send the keying information to the context,
642 	   and mark it as initialised (i.e. with a key loaded).  Setting the
643 	   label requires special care because the label that we're setting
644 	   matches that of an existing object, so trying to set it as a standard
645 	   CRYPT_CTXINFO_LABEL will return a CRYPT_ERROR_DUPLICATE error when
646 	   the context code checks for the existence of an existing label.  To
647 	   handle this, we use the attribute CRYPT_IATTRIBUTE_EXISTINGLABEL to
648 	   indicate that we're setting a label that matches an existing object
649 	   in the device */
650 	if( keyInfo.labelLength <= 0 )
651 		{
652 		/* If there's no label present, use a dummy value */
653 		strlcpy_s( keyInfo.label, CRYPT_MAX_TEXTSIZE, "Label-less private key" );
654 		keyInfo.labelLength = 22;
655 		}
656 	setMessageData( &msgData, keyInfo.label, keyInfo.labelLength );
657 	status = krnlSendMessage( iLocalContext, IMESSAGE_SETATTRIBUTE_S,
658 							  &msgData, CRYPT_IATTRIBUTE_EXISTINGLABEL );
659 	if( cryptStatusOK( status ) )
660 		status = setPublicComponents( iLocalContext, keyInfo.cryptAlgo,
661 									  &keyInfo.publicKeyInfo );
662 	if( cryptStatusOK( status ) )
663 		status = krnlSendMessage( iLocalContext, IMESSAGE_SETATTRIBUTE,
664 								  MESSAGE_VALUE_UNUSED,
665 								  CRYPT_IATTRIBUTE_INITIALISED );
666 	if( cryptStatusOK( status ) && ( iCryptCert != CRYPT_UNUSED ) )
667 		{
668 		/* If there's a certificate present, attach it to the context.  The
669 		   certificate is an internal object used only by the context so we
670 		   tell the kernel to mark it as owned by the context only */
671 		status = krnlSendMessage( iLocalContext, IMESSAGE_SETDEPENDENT,
672 								  ( MESSAGE_CAST ) &iCryptCert,
673 								  SETDEP_OPTION_NOINCREF );
674 		}
675 	if( cryptStatusError( status ) )
676 		{
677 		krnlSendNotifier( iLocalContext, IMESSAGE_DECREFCOUNT );
678 		if( iCryptCert != CRYPT_UNUSED )
679 			krnlSendNotifier( iCryptCert, IMESSAGE_DECREFCOUNT );
680 		}
681 #endif /* 1 */
682 
683 	*iCryptContext = iLocalContext;
684 	return( CRYPT_OK );
685 	}
686 
687 /* Add an object to a device.  This can only ever add a certificate
688    (enforced by the kernel ACLs) so we don't have to perform any
689    special-case handling */
690 
setItemFunction(DEVICE_INFO * deviceInfo,const CRYPT_HANDLE iCryptHandle)691 static int setItemFunction( DEVICE_INFO *deviceInfo,
692 							const CRYPT_HANDLE iCryptHandle )
693 	{
694 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
695 	MESSAGE_KEYMGMT_INFO setkeyInfo;
696 
697 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
698 
699 	REQUIRES( isHandleRangeValid( iCryptHandle ) );
700 
701 	/* Redirect the add down to the PKCS #15 storage object */
702 	if( hardwareInfo->iCryptKeyset == CRYPT_ERROR )
703 		return( CRYPT_ERROR_NOTINITED );
704 	setMessageKeymgmtInfo( &setkeyInfo, CRYPT_KEYID_NONE, NULL, 0,
705 						   NULL, 0, KEYMGMT_FLAG_NONE );
706 	setkeyInfo.cryptHandle = iCryptHandle;
707 	return( krnlSendMessage( hardwareInfo->iCryptKeyset,
708 							 IMESSAGE_KEY_SETKEY, &setkeyInfo,
709 							 KEYMGMT_ITEM_PUBLICKEY ) );
710 	}
711 
712 /* Delete an object in a device */
713 
deleteItemFunction(DEVICE_INFO * deviceInfo,const KEYMGMT_ITEM_TYPE itemType,const CRYPT_KEYID_TYPE keyIDtype,const void * keyID,const int keyIDlength)714 static int deleteItemFunction( DEVICE_INFO *deviceInfo,
715 							   const KEYMGMT_ITEM_TYPE itemType,
716 							   const CRYPT_KEYID_TYPE keyIDtype,
717 							   const void *keyID, const int keyIDlength )
718 	{
719 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
720 	MESSAGE_KEYMGMT_INFO getkeyInfo, deletekeyInfo;
721 	int status;
722 
723 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
724 	assert( isReadPtr( keyID, keyIDlength ) );
725 
726 	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
727 			  itemType == KEYMGMT_ITEM_PRIVATEKEY );
728 	REQUIRES( keyIDtype == CRYPT_KEYID_NAME );
729 	REQUIRES( keyIDlength > 0 && keyIDlength <= CRYPT_MAX_TEXTSIZE );
730 
731 	/* Perform the delete both from the PKCS #15 storage object and the
732 	   native storage.  This gets a bit complicated because in order to
733 	   find the hardware object we have to extract the storageID, and in
734 	   order to get that we have to instantiate a dummy private-key object
735 	   to contain it.  In addition if the object that's stored isn't a
736 	   private-key object then there's no associated cryptographic
737 	   hardware object.  To handle this we try and instantiate a dummy
738 	   private-key object in order to get the storageID.  If this succeeds,
739 	   we locate the underlying hardware object and delete it.  Finally, we
740 	   delete the PKCS #15 object, either a pure public-key/certificate
741 	   object or the private-key metadata for the cryptographic hardware
742 	   object */
743 	if( hardwareInfo->iCryptKeyset == CRYPT_ERROR )
744 		return( CRYPT_ERROR_NOTINITED );
745 	setMessageKeymgmtInfo( &getkeyInfo, keyIDtype, keyID, keyIDlength,
746 						   NULL, 0, KEYMGMT_FLAG_NONE );
747 	status = krnlSendMessage( hardwareInfo->iCryptKeyset,
748 							  IMESSAGE_KEY_GETKEY, &getkeyInfo,
749 							  KEYMGMT_ITEM_PRIVATEKEY );
750 	if( cryptStatusOK( status ) )
751 		{
752 		int keyHandle;
753 
754 		/* It's a private-key object, get its hardware reference and delete
755 		   it.  If this fails we continue anyway because we know that
756 		   there's also a PKCS #15 object to delete */
757 		status = getHardwareReference( getkeyInfo.cryptHandle, &keyHandle );
758 		if( cryptStatusOK( status ) )
759 			( void ) hwDeleteItem( keyHandle );
760 		krnlSendNotifier( getkeyInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
761 		}
762 	setMessageKeymgmtInfo( &deletekeyInfo, keyIDtype, keyID, keyIDlength,
763 						   NULL, 0, KEYMGMT_FLAG_NONE );
764 	return( krnlSendMessage( hardwareInfo->iCryptKeyset,
765 							 IMESSAGE_KEY_DELETEKEY, &deletekeyInfo,
766 							 itemType ) );
767 	}
768 
769 /* Get the sequence of certificates in a chain from a device.  Since these
770    functions operate only on certificates we can redirect them straight down
771    to the underlying storage object */
772 
getFirstItemFunction(DEVICE_INFO * deviceInfo,CRYPT_CERTIFICATE * iCertificate,int * stateInfo,const CRYPT_KEYID_TYPE keyIDtype,const void * keyID,const int keyIDlength,const KEYMGMT_ITEM_TYPE itemType,const int options)773 static int getFirstItemFunction( DEVICE_INFO *deviceInfo,
774 								 CRYPT_CERTIFICATE *iCertificate,
775 								 int *stateInfo,
776 								 const CRYPT_KEYID_TYPE keyIDtype,
777 								 const void *keyID, const int keyIDlength,
778 								 const KEYMGMT_ITEM_TYPE itemType,
779 								 const int options )
780 	{
781 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
782 	MESSAGE_KEYMGMT_INFO getnextcertInfo;
783 
784 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
785 	assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
786 	assert( isReadPtr( keyID, keyIDlength ) );
787 	assert( isWritePtr( stateInfo, sizeof( int ) ) );
788 
789 	REQUIRES( keyIDtype == CRYPT_IKEYID_KEYID );
790 	REQUIRES( keyIDlength > 4 && keyIDlength < MAX_INTLENGTH_SHORT );
791 	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY );
792 
793 	/* Clear return values */
794 	*iCertificate = CRYPT_ERROR;
795 	*stateInfo = CRYPT_ERROR;
796 
797 	/* Get the first certificate */
798 	setMessageKeymgmtInfo( &getnextcertInfo, keyIDtype, keyID, keyIDlength,
799 						   stateInfo, sizeof( int ), options );
800 	return( krnlSendMessage( hardwareInfo->iCryptKeyset,
801 							 IMESSAGE_KEY_GETFIRSTCERT, &getnextcertInfo,
802 							 KEYMGMT_ITEM_PUBLICKEY ) );
803 	}
804 
getNextItemFunction(DEVICE_INFO * deviceInfo,CRYPT_CERTIFICATE * iCertificate,int * stateInfo,const int options)805 static int getNextItemFunction( DEVICE_INFO *deviceInfo,
806 								CRYPT_CERTIFICATE *iCertificate,
807 								int *stateInfo, const int options )
808 	{
809 	HARDWARE_INFO *hardwareInfo = deviceInfo->deviceHardware;
810 	MESSAGE_KEYMGMT_INFO getnextcertInfo;
811 
812 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
813 	assert( isWritePtr( iCertificate, sizeof( CRYPT_CERTIFICATE ) ) );
814 	assert( isWritePtr( stateInfo, sizeof( int ) ) );
815 
816 	REQUIRES( isHandleRangeValid( *stateInfo ) || \
817 			  *stateInfo == CRYPT_ERROR );
818 
819 	UNUSED_ARG( hardwareInfo );
820 
821 	/* Clear return value */
822 	*iCertificate = CRYPT_ERROR;
823 
824 	/* If the previous certificate was the last one, there's nothing left to
825 	   fetch */
826 	if( *stateInfo == CRYPT_ERROR )
827 		return( CRYPT_ERROR_NOTFOUND );
828 
829 	/* Get the next certificate */
830 	setMessageKeymgmtInfo( &getnextcertInfo, CRYPT_KEYID_NONE, NULL, 0,
831 						   stateInfo, sizeof( int ), options );
832 	return( krnlSendMessage( hardwareInfo->iCryptKeyset,
833 							 IMESSAGE_KEY_GETNEXTCERT, &getnextcertInfo,
834 							 KEYMGMT_ITEM_PUBLICKEY ) );
835 	}
836 
837 /****************************************************************************
838 *																			*
839 *					Cryptographic HAL Assist Routines						*
840 *																			*
841 ****************************************************************************/
842 
843 /* The following helper routines provide common functionality needed by most
844    cryptographic HALs, which avoids having to reimplement the same code in
845    each HAL module.  These are called from the HAL to provide services such
846    as keygen assist and various context-management functions */
847 
848 /* Set up a mapping from a context to its associated information in the
849    underlying hardware.  This generates a storageID for the information and
850    records it and the hardware handle in the context.  The caller has to
851    record the storageID alongside the crypto information held by the
852    hardware for later use to look up the information */
853 
setPersonalityMapping(CONTEXT_INFO * contextInfoPtr,const int keyHandle,void * storageID,const int storageIDlength)854 int setPersonalityMapping( CONTEXT_INFO *contextInfoPtr, const int keyHandle,
855 						   void *storageID, const int storageIDlength )
856 	{
857 	CRYPT_DEVICE iCryptDevice;
858 	HARDWARE_INFO *hardwareInfo;
859 	MESSAGE_KEYMGMT_INFO setkeyInfo;
860 	MESSAGE_DATA msgData;
861 	BYTE buffer[ KEYID_SIZE + 8 ];
862 	int status;
863 
864 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
865 	assert( isWritePtr( storageID, storageIDlength ) );
866 
867 	REQUIRES( keyHandle >= 0 && keyHandle < INT_MAX );
868 	REQUIRES( storageIDlength >= 4 && storageIDlength <= KEYID_SIZE );
869 
870 	/* Set up the mapping information in the context */
871 	status = hwGetRandom( buffer, KEYID_SIZE );
872 	if( cryptStatusError( status ) )
873 		return( status );
874 	setMessageData( &msgData, buffer, KEYID_SIZE );
875 	status = krnlSendMessage( contextInfoPtr->objectHandle,
876 							  IMESSAGE_SETATTRIBUTE_S, &msgData,
877 							  CRYPT_IATTRIBUTE_DEVICESTORAGEID );
878 	if( cryptStatusOK( status ) )
879 		{
880 		status = krnlSendMessage( contextInfoPtr->objectHandle,
881 								  IMESSAGE_SETATTRIBUTE,
882 								  ( MESSAGE_CAST ) &keyHandle,
883 								  CRYPT_IATTRIBUTE_DEVICEOBJECT );
884 		}
885 	if( cryptStatusError( status ) )
886 		return( status );
887 
888 	/* Copy the storageID back to the caller */
889 	memcpy( storageID, buffer, storageIDlength );
890 
891 	/* If it's a non-PKC context then there's nothing further to do */
892 	if( contextInfoPtr->type != CONTEXT_PKC )
893 		return( CRYPT_OK );
894 
895 	/* As a variation of the above, if it's a public-key context then we
896 	   don't want to persist it to the storage object because public-key
897 	   contexts a bit of an anomaly, when generating our own keys we always
898 	   have full private keys and when obtaining public keys from an
899 	   external source they'll be in the form of certificates so there isn't
900 	   really much need for persistent raw public keys.  At the moment the
901 	   only time they're used is for the self-test, and potentially
902 	   polluting the (typically quite limited) crypto hardware storage with
903 	   unneeded public keys doesn't seem like a good idea */
904 	if( contextInfoPtr->flags & CONTEXT_FLAG_ISPUBLICKEY )
905 		return( CRYPT_OK );
906 
907 	/* It's a PKC context, prepare to persist the key metadata to the
908 	   underlying PKCS #15 object store */
909 	status = getContextDeviceInfo( contextInfoPtr->objectHandle,
910 								   &iCryptDevice, &hardwareInfo );
911 	if( cryptStatusError( status ) )
912 		return( status );
913 	if( hardwareInfo->iCryptKeyset == CRYPT_ERROR )
914 		{
915 		krnlReleaseObject( iCryptDevice );
916 		return( CRYPT_ERROR_NOTINITED );
917 		}
918 
919 	/* Since this is a dummy context that contains no actual keying
920 	   information (the key data is held in hardware) we set it as
921 	   KEYMGMT_ITEM_KEYMETADATA */
922 	setMessageKeymgmtInfo( &setkeyInfo, CRYPT_KEYID_NONE, NULL, 0, NULL, 0,
923 						   KEYMGMT_FLAG_NONE );
924 	setkeyInfo.cryptHandle = contextInfoPtr->objectHandle;
925 	status = krnlSendMessage( hardwareInfo->iCryptKeyset,
926 							  IMESSAGE_KEY_SETKEY, &setkeyInfo,
927 							  KEYMGMT_ITEM_KEYMETADATA );
928 	krnlReleaseObject( iCryptDevice );
929 
930 	return( status );
931 	}
932 
933 /* Many hardware devices have no native public/private key generation
934    support or can only generate something like the DLP x value, which is
935    just a raw string of random bits, but can't generate a full set of
936    public/private key parameters since these require complex bignum
937    operations not supported by the underlying cryptologic.  To handle this
938    we provide supplementary software support routines that generate the
939    key parameters using native contexts and bignum code and then pass them
940    back to the crypto HAL to load into the cryptlogic */
941 
generateKeyComponents(CONTEXT_INFO * staticContextInfo,PKC_INFO * contextData,const CAPABILITY_INFO * capabilityInfoPtr,const int keySizeBits)942 static int generateKeyComponents( CONTEXT_INFO *staticContextInfo,
943 								  PKC_INFO *contextData,
944 								  const CAPABILITY_INFO *capabilityInfoPtr,
945 								  const int keySizeBits )
946 	{
947 	int status;
948 
949 	assert( isWritePtr( staticContextInfo, sizeof( CONTEXT_INFO ) ) );
950 	assert( isWritePtr( contextData, sizeof( PKC_INFO ) ) );
951 	assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );
952 
953 	REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \
954 			  keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
955 
956 	/* Initialise a static context to generate the key into */
957 	status = staticInitContext( staticContextInfo, CONTEXT_PKC,
958 								capabilityInfoPtr, contextData,
959 								sizeof( PKC_INFO ), NULL );
960 	if( cryptStatusError( status ) )
961 		return( status );
962 
963 	/* Generate a key into the static context */
964 	status = capabilityInfoPtr->generateKeyFunction( staticContextInfo,
965 													 keySizeBits );
966 	if( cryptStatusError( status ) )
967 		{
968 		staticDestroyContext( staticContextInfo );
969 		return( status );
970 		}
971 
972 	return( CRYPT_OK );
973 	}
974 
rsaGenerateComponents(CRYPT_PKCINFO_RSA * rsaKeyInfo,const int keySizeBits)975 static int rsaGenerateComponents( CRYPT_PKCINFO_RSA *rsaKeyInfo,
976 								  const int keySizeBits )
977 	{
978 	CONTEXT_INFO staticContextInfo;
979 	PKC_INFO contextData, *pkcInfo = &contextData;
980 	int length, status;
981 
982 	assert( isWritePtr( rsaKeyInfo, sizeof( CRYPT_PKCINFO_RSA ) ) );
983 
984 	REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \
985 			  keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
986 
987 	/* Clear return value */
988 	cryptInitComponents( rsaKeyInfo, FALSE );
989 
990 	/* Generate the key components */
991 	status = generateKeyComponents( &staticContextInfo, &contextData,
992 									getRSACapability(), keySizeBits );
993 	if( cryptStatusError( status ) )
994 		return( status );
995 
996 	/* Extract the newly-generated key components for the caller to use */
997 	rsaKeyInfo->nLen = BN_num_bits( &pkcInfo->rsaParam_n );
998 	length = BN_bn2bin( &pkcInfo->rsaParam_n, rsaKeyInfo->n );
999 	ENSURES( length == bitsToBytes( rsaKeyInfo->nLen ) );
1000 	rsaKeyInfo->eLen = BN_num_bits( &pkcInfo->rsaParam_e );
1001 	length = BN_bn2bin( &pkcInfo->rsaParam_e, rsaKeyInfo->e );
1002 	ENSURES( length == bitsToBytes( rsaKeyInfo->eLen ) );
1003 	rsaKeyInfo->pLen = BN_num_bits( &pkcInfo->rsaParam_p );
1004 	length = BN_bn2bin( &pkcInfo->rsaParam_p, rsaKeyInfo->p );
1005 	ENSURES( length == bitsToBytes( rsaKeyInfo->pLen ) );
1006 	rsaKeyInfo->qLen = BN_num_bits( &pkcInfo->rsaParam_q );
1007 	length = BN_bn2bin( &pkcInfo->rsaParam_q, rsaKeyInfo->q );
1008 	ENSURES( length == bitsToBytes( rsaKeyInfo->qLen ) );
1009 	rsaKeyInfo->e1Len = BN_num_bits( &pkcInfo->rsaParam_exponent1 );
1010 	length = BN_bn2bin( &pkcInfo->rsaParam_exponent1, rsaKeyInfo->e1 );
1011 	ENSURES( length == bitsToBytes( rsaKeyInfo->e1Len ) );
1012 	rsaKeyInfo->e2Len = BN_num_bits( &pkcInfo->rsaParam_exponent2 );
1013 	length = BN_bn2bin( &pkcInfo->rsaParam_exponent2, rsaKeyInfo->e2 );
1014 	ENSURES( length == bitsToBytes( rsaKeyInfo->e2Len ) );
1015 	rsaKeyInfo->uLen = BN_num_bits( &pkcInfo->rsaParam_u );
1016 	length = BN_bn2bin( &pkcInfo->rsaParam_u, rsaKeyInfo->u );
1017 	ENSURES( length == bitsToBytes( rsaKeyInfo->uLen ) );
1018 	staticDestroyContext( &staticContextInfo );
1019 
1020 	return( status );
1021 	}
1022 
1023 #if defined( USE_DH ) || defined( USE_DSA ) || defined( USE_ELGAMAL )
1024 
dlpGenerateComponents(CRYPT_PKCINFO_DLP * dlpKeyInfo,const int keySizeBits,const CRYPT_ALGO_TYPE cryptAlgo)1025 static int dlpGenerateComponents( CRYPT_PKCINFO_DLP *dlpKeyInfo,
1026 								  const int keySizeBits,
1027 								  const CRYPT_ALGO_TYPE cryptAlgo )
1028 	{
1029 	CONTEXT_INFO staticContextInfo;
1030 	PKC_INFO contextData, *pkcInfo = &contextData;
1031 	int length, status;
1032 
1033 	assert( isWritePtr( dlpKeyInfo, sizeof( CRYPT_PKCINFO_DLP ) ) );
1034 
1035 	REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \
1036 			  keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
1037 	REQUIRES( cryptAlgo == CRYPT_ALGO_DH || \
1038 			  cryptAlgo == CRYPT_ALGO_DSA || \
1039 			  cryptAlgo == CRYPT_ALGO_ELGAMAL );
1040 
1041 	/* Clear return value */
1042 	cryptInitComponents( dlpKeyInfo, FALSE );
1043 
1044 	/* Generate the key components */
1045 	switch( cryptAlgo )
1046 		{
1047 #ifdef USE_DH
1048 		case CRYPT_ALGO_DH:
1049 			status = generateKeyComponents( &staticContextInfo, &contextData,
1050 											getDHCapability(), keySizeBits );
1051 			break;
1052 #endif /* USE_DH */
1053 
1054 #ifdef USE_DSA
1055 		case CRYPT_ALGO_DSA:
1056 			status = generateKeyComponents( &staticContextInfo, &contextData,
1057 											getDSACapability(), keySizeBits );
1058 			break;
1059 #endif /* USE_DSA */
1060 
1061 #ifdef USE_ELGAMAL
1062 		case CRYPT_ALGO_ELGAMAL:
1063 			status = generateKeyComponents( &staticContextInfo, &contextData,
1064 											getElgamalCapability(), keySizeBits );
1065 			break;
1066 #endif /* USE_ELGAMAL */
1067 
1068 		default:
1069 			retIntError();
1070 		}
1071 	if( cryptStatusError( status ) )
1072 		return( status );
1073 
1074 	/* Extract the newly-generated key components for the caller to use */
1075 	dlpKeyInfo->pLen = BN_num_bits( &pkcInfo->dlpParam_p );
1076 	length = BN_bn2bin( &pkcInfo->dlpParam_p, dlpKeyInfo->p );
1077 	ENSURES( length == bitsToBytes( dlpKeyInfo->pLen ) );
1078 	dlpKeyInfo->gLen = BN_num_bits( &pkcInfo->dlpParam_g );
1079 	length = BN_bn2bin( &pkcInfo->dlpParam_g, dlpKeyInfo->g );
1080 	ENSURES( length == bitsToBytes( dlpKeyInfo->gLen ) );
1081 	dlpKeyInfo->qLen = BN_num_bits( &pkcInfo->dlpParam_q );
1082 	length = BN_bn2bin( &pkcInfo->dlpParam_q, dlpKeyInfo->q );
1083 	ENSURES( length == bitsToBytes( dlpKeyInfo->qLen ) );
1084 	dlpKeyInfo->yLen = BN_num_bits( &pkcInfo->dlpParam_y );
1085 	length = BN_bn2bin( &pkcInfo->dlpParam_y, dlpKeyInfo->y );
1086 	ENSURES( length == bitsToBytes( dlpKeyInfo->yLen ) );
1087 	dlpKeyInfo->xLen = BN_num_bits( &pkcInfo->dlpParam_x );
1088 	length = BN_bn2bin( &pkcInfo->dlpParam_x, dlpKeyInfo->x );
1089 	ENSURES( length == bitsToBytes( dlpKeyInfo->xLen ) );
1090 	staticDestroyContext( &staticContextInfo );
1091 
1092 	return( status );
1093 	}
1094 #endif /* USE_DH || USE_DSA || USE_ELGAMAL */
1095 
generatePKCcomponents(CONTEXT_INFO * contextInfoPtr,void * keyInfo,const int keySizeBits)1096 int generatePKCcomponents( CONTEXT_INFO *contextInfoPtr,
1097 						   void *keyInfo, const int keySizeBits )
1098 	{
1099 	const CRYPT_ALGO_TYPE cryptAlgo = \
1100 					contextInfoPtr->capabilityInfo->cryptAlgo;
1101 	int status;
1102 
1103 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1104 
1105 	REQUIRES( keyInfo != NULL );
1106 	REQUIRES( cryptAlgo == CRYPT_ALGO_DH || \
1107 			  cryptAlgo == CRYPT_ALGO_RSA || \
1108 			  cryptAlgo == CRYPT_ALGO_DSA || \
1109 			  cryptAlgo == CRYPT_ALGO_ELGAMAL );
1110 	REQUIRES( keySizeBits >= bytesToBits( MIN_PKCSIZE ) && \
1111 			  keySizeBits <= bytesToBits( CRYPT_MAX_PKCSIZE ) );
1112 
1113 	switch( cryptAlgo )
1114 		{
1115 		case CRYPT_ALGO_RSA:
1116 			status = rsaGenerateComponents( keyInfo, keySizeBits );
1117 			break;
1118 
1119 #if defined( USE_DH ) || defined( USE_DSA ) || defined( USE_ELGAMAL )
1120 		case CRYPT_ALGO_DH:
1121 		case CRYPT_ALGO_DSA:
1122 		case CRYPT_ALGO_ELGAMAL:
1123 			status = dlpGenerateComponents( keyInfo, keySizeBits, cryptAlgo );
1124 			break;
1125 #endif /* USE_DH || USE_DSA || USE_ELGAMAL */
1126 
1127 		default:
1128 			return( CRYPT_ERROR_NOTAVAIL );
1129 		}
1130 	if( cryptStatusError( status ) )
1131 		return( status );
1132 
1133 	/* Send the public-key data (needed for certificates and the like) to
1134 	   the context */
1135 	return( setPKCinfo( contextInfoPtr, cryptAlgo, keyInfo ) );
1136 	}
1137 
1138 /* Send public-key data to the context for use with certificate objects */
1139 
setPKCinfo(CONTEXT_INFO * contextInfoPtr,const CRYPT_ALGO_TYPE cryptAlgo,const void * keyInfo)1140 int setPKCinfo( CONTEXT_INFO *contextInfoPtr,
1141 				const CRYPT_ALGO_TYPE cryptAlgo, const void *keyInfo )
1142 	{
1143 	BYTE keyDataBuffer[ ( CRYPT_MAX_PKCSIZE * 4 ) + 8 ];
1144 	MESSAGE_DATA msgData;
1145 	int keyDataSize, status;
1146 
1147 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1148 	assert( ( cryptAlgo == CRYPT_ALGO_RSA && \
1149 			  isReadPtr( keyInfo, sizeof( CRYPT_PKCINFO_RSA ) ) ) || \
1150 			( cryptAlgo != CRYPT_ALGO_RSA && \
1151 			  isReadPtr( keyInfo, sizeof( CRYPT_PKCINFO_DLP ) ) ) );
1152 
1153 	REQUIRES( cryptAlgo == CRYPT_ALGO_DH || \
1154 			  cryptAlgo == CRYPT_ALGO_RSA || \
1155 			  cryptAlgo == CRYPT_ALGO_DSA || \
1156 			  cryptAlgo == CRYPT_ALGO_ELGAMAL );
1157 
1158 	/* Send the public key data to the context.  We send the keying
1159 	   information as CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL rather than
1160 	   CRYPT_IATTRIBUTE_KEY_SPKI since the latter transitions the context
1161 	   into the high state.  We don't want to do this because we're already
1162 	   in the middle of processing a message that does this on completion,
1163 	   all that we're doing here is sending in encoded public key data for
1164 	   use by objects such as certificates */
1165 	switch( cryptAlgo )
1166 		{
1167 		case CRYPT_ALGO_RSA:
1168 			{
1169 			const CRYPT_PKCINFO_RSA *rsaKeyInfo = \
1170 						( CRYPT_PKCINFO_RSA * ) keyInfo;
1171 
1172 			if( rsaKeyInfo->isPublicKey )
1173 				contextInfoPtr->flags |= CONTEXT_FLAG_ISPUBLICKEY;
1174 			else
1175 				contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1176 			status = writeFlatPublicKey( keyDataBuffer,
1177 							CRYPT_MAX_PKCSIZE * 4, &keyDataSize,
1178 							CRYPT_ALGO_RSA, 0, rsaKeyInfo->n,
1179 							bitsToBytes( rsaKeyInfo->nLen ), rsaKeyInfo->e,
1180 							bitsToBytes( rsaKeyInfo->eLen ), NULL, 0,
1181 							NULL, 0 );
1182 			break;
1183 			}
1184 
1185 		case CRYPT_ALGO_DH:
1186 		case CRYPT_ALGO_DSA:
1187 		case CRYPT_ALGO_ELGAMAL:
1188 			{
1189 			const CRYPT_PKCINFO_DLP *dlpKeyInfo = \
1190 						( CRYPT_PKCINFO_DLP * ) keyInfo;
1191 
1192 			if( dlpKeyInfo->isPublicKey )
1193 				contextInfoPtr->flags |= CONTEXT_FLAG_ISPUBLICKEY;
1194 			else
1195 				contextInfoPtr->flags |= CONTEXT_FLAG_PERSISTENT;
1196 			status = writeFlatPublicKey( keyDataBuffer,
1197 						CRYPT_MAX_PKCSIZE * 4, &keyDataSize, cryptAlgo, 0,
1198 						dlpKeyInfo->p, bitsToBytes( dlpKeyInfo->pLen ),
1199 						dlpKeyInfo->q, bitsToBytes( dlpKeyInfo->qLen ),
1200 						dlpKeyInfo->g, bitsToBytes( dlpKeyInfo->gLen ),
1201 						dlpKeyInfo->y, bitsToBytes( dlpKeyInfo->yLen ) );
1202 			break;
1203 			}
1204 
1205 		default:
1206 			retIntError();
1207 		}
1208 	if( cryptStatusError( status ) )
1209 		return( status );
1210 	setMessageData( &msgData, keyDataBuffer, keyDataSize );
1211 	return( krnlSendMessage( contextInfoPtr->objectHandle,
1212 							 IMESSAGE_SETATTRIBUTE_S, &msgData,
1213 							 CRYPT_IATTRIBUTE_KEY_SPKI_PARTIAL ) );
1214 	}
1215 
1216 /* Send encryption/MAC keying metadata to the context */
1217 
setConvInfo(const CRYPT_CONTEXT iCryptContext,const int keySize)1218 int setConvInfo( const CRYPT_CONTEXT iCryptContext, const int keySize )
1219 	{
1220 	assert( isHandleRangeValid( iCryptContext ) );
1221 
1222 	REQUIRES( keySize >= MIN_KEYSIZE && keySize <= CRYPT_MAX_KEYSIZE );
1223 
1224 	return( krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE,
1225 							 ( MESSAGE_CAST ) &keySize,
1226 							 CRYPT_IATTRIBUTE_KEYSIZE ) );
1227 	}
1228 
1229 /* The default cleanup function, which simply frees the context-related data
1230    used by the cryptographic hardware if it's an ephemeral key */
1231 
cleanupHardwareContext(const CONTEXT_INFO * contextInfoPtr)1232 int cleanupHardwareContext( const CONTEXT_INFO *contextInfoPtr )
1233 	{
1234 	assert( isReadPtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1235 
1236 	/* If this is non-ephemeral context data then we leave it intact when
1237 	   the corresponding context is destroyed, the only way to delete it is
1238 	   with an explicit deleteItem() */
1239 	if( contextInfoPtr->flags & CONTEXT_FLAG_PERSISTENT )
1240 		return( CRYPT_OK );
1241 
1242 	/* We have to be careful about deleting the context data since it may
1243 	   not have been set up yet, for example if we're called due to a
1244 	   failure in the complete-creation/initialisation step of setting up a
1245 	   context */
1246 	if( contextInfoPtr->deviceObject != CRYPT_ERROR )
1247 		hwDeleteItem( contextInfoPtr->deviceObject );
1248 
1249 	return( CRYPT_OK );
1250 	}
1251 
1252 /****************************************************************************
1253 *																			*
1254 *						 	Device Access Routines							*
1255 *																			*
1256 ****************************************************************************/
1257 
1258 /* Mechanisms supported by the hardware.  These are actually cryptlib native
1259    mechanisms, but not the full set supported by the system device since
1260    functions like private key export aren't available.  The  list is sorted
1261    in order of frequency of use in order to make lookups a bit faster */
1262 
1263 static const FAR_BSS MECHANISM_FUNCTION_INFO mechanismFunctions[] = {
1264 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) exportPKCS1 },
1265 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1, ( MECHANISM_FUNCTION ) importPKCS1 },
1266 	{ MESSAGE_DEV_SIGN, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) signPKCS1 },
1267 	{ MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_PKCS1, ( MECHANISM_FUNCTION ) sigcheckPKCS1 },
1268 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) exportPKCS1 },
1269 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_RAW, ( MECHANISM_FUNCTION ) importPKCS1 },
1270 #ifdef USE_PGP
1271 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) exportPKCS1PGP },
1272 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_PKCS1_PGP, ( MECHANISM_FUNCTION ) importPKCS1PGP },
1273 #endif /* USE_PGP */
1274 	{ MESSAGE_DEV_EXPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) exportCMS },
1275 	{ MESSAGE_DEV_IMPORT, MECHANISM_ENC_CMS, ( MECHANISM_FUNCTION ) importCMS },
1276 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS5, ( MECHANISM_FUNCTION ) derivePKCS5 },
1277 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
1278 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PGP, ( MECHANISM_FUNCTION ) derivePGP },
1279 #endif /* USE_PGP || USE_PGPKEYS */
1280 #ifdef USE_SSL
1281 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_TLS, ( MECHANISM_FUNCTION ) deriveSSL },
1282 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_SSL, ( MECHANISM_FUNCTION ) deriveTLS },
1283 	{ MESSAGE_DEV_SIGN, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) signSSL },
1284 	{ MESSAGE_DEV_SIGCHECK, MECHANISM_SIG_SSL, ( MECHANISM_FUNCTION ) sigcheckSSL },
1285 #endif /* USE_SSL */
1286 #ifdef USE_CMP
1287 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_CMP, ( MECHANISM_FUNCTION ) deriveCMP },
1288 #endif /* USE_CMP */
1289 #ifdef USE_PKCS12
1290 	{ MESSAGE_DEV_DERIVE, MECHANISM_DERIVE_PKCS12, ( MECHANISM_FUNCTION ) derivePKCS12 },
1291 #endif /* USE_PKCS12 */
1292 	{ MESSAGE_NONE, MECHANISM_NONE, NULL }, { MESSAGE_NONE, MECHANISM_NONE, NULL }
1293 	};
1294 
1295 /* Set up the function pointers to the device methods */
1296 
1297 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
setDeviceHardware(INOUT DEVICE_INFO * deviceInfo)1298 int setDeviceHardware( INOUT DEVICE_INFO *deviceInfo )
1299 	{
1300 	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
1301 
1302 	deviceInfo->initFunction = initFunction;
1303 	deviceInfo->shutdownFunction = shutdownFunction;
1304 	deviceInfo->controlFunction = controlFunction;
1305 	deviceInfo->getItemFunction = getItemFunction;
1306 	deviceInfo->setItemFunction = setItemFunction;
1307 	deviceInfo->deleteItemFunction = deleteItemFunction;
1308 	deviceInfo->getFirstItemFunction = getFirstItemFunction;
1309 	deviceInfo->getNextItemFunction = getNextItemFunction;
1310 	deviceInfo->getRandomFunction = getRandomFunction;
1311 	deviceInfo->capabilityInfoList = capabilityInfoList;
1312 	deviceInfo->mechanismFunctions = mechanismFunctions;
1313 	deviceInfo->mechanismFunctionCount = \
1314 		FAILSAFE_ARRAYSIZE( mechanismFunctions, MECHANISM_FUNCTION_INFO );
1315 
1316 	return( CRYPT_OK );
1317 	}
1318 #endif /* USE_HARDWARE */
1319