1 /*
2  * Copyright (c) 2010 SURFnet bv
3  * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /*****************************************************************************
29  SoftHSM.cpp
30 
31  The implementation of the SoftHSM's main class
32  *****************************************************************************/
33 
34 #include "config.h"
35 #include "log.h"
36 #include "access.h"
37 #include "Configuration.h"
38 #include "SimpleConfigLoader.h"
39 #include "MutexFactory.h"
40 #include "SecureMemoryRegistry.h"
41 #include "CryptoFactory.h"
42 #include "AsymmetricAlgorithm.h"
43 #include "SymmetricAlgorithm.h"
44 #include "AESKey.h"
45 #include "DerUtil.h"
46 #include "DESKey.h"
47 #include "RNG.h"
48 #include "RSAParameters.h"
49 #include "RSAPublicKey.h"
50 #include "RSAPrivateKey.h"
51 #include "DSAParameters.h"
52 #include "DSAPublicKey.h"
53 #include "DSAPrivateKey.h"
54 #include "ECPublicKey.h"
55 #include "ECPrivateKey.h"
56 #include "ECParameters.h"
57 #include "EDPublicKey.h"
58 #include "EDPrivateKey.h"
59 #include "DHParameters.h"
60 #include "DHPublicKey.h"
61 #include "DHPrivateKey.h"
62 #include "GOSTPublicKey.h"
63 #include "GOSTPrivateKey.h"
64 #include "cryptoki.h"
65 #include "SoftHSM.h"
66 #include "osmutex.h"
67 #include "SessionManager.h"
68 #include "SessionObjectStore.h"
69 #include "HandleManager.h"
70 #include "P11Objects.h"
71 #include "odd.h"
72 
73 #if defined(WITH_OPENSSL)
74 #include "OSSLCryptoFactory.h"
75 #else
76 #include "BotanCryptoFactory.h"
77 #endif
78 
79 #include <stdlib.h>
80 #include <algorithm>
81 #include <stdexcept>
82 
83 #ifdef _WIN32
84 #include <process.h>
85 #else
86 #include <unistd.h>
87 #endif
88 
89 // Initialise the one-and-only instance
90 
91 #ifdef HAVE_CXX11
92 
93 std::unique_ptr<MutexFactory> MutexFactory::instance(nullptr);
94 std::unique_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(nullptr);
95 #if defined(WITH_OPENSSL)
96 std::unique_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(nullptr);
97 #else
98 std::unique_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(nullptr);
99 #endif
100 std::unique_ptr<SoftHSM> SoftHSM::instance(nullptr);
101 
102 #else
103 
104 std::auto_ptr<MutexFactory> MutexFactory::instance(NULL);
105 std::auto_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(NULL);
106 #if defined(WITH_OPENSSL)
107 std::auto_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(NULL);
108 #else
109 std::auto_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(NULL);
110 #endif
111 std::auto_ptr<SoftHSM> SoftHSM::instance(NULL);
112 
113 #endif
114 
newP11Object(CK_OBJECT_CLASS objClass,CK_KEY_TYPE keyType,CK_CERTIFICATE_TYPE certType,P11Object ** p11object)115 static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERTIFICATE_TYPE certType, P11Object **p11object)
116 {
117 	switch(objClass) {
118 		case CKO_DATA:
119 			*p11object = new P11DataObj();
120 			break;
121 		case CKO_CERTIFICATE:
122 			if (certType == CKC_X_509)
123 				*p11object = new P11X509CertificateObj();
124 			else if (certType == CKC_OPENPGP)
125 				*p11object = new P11OpenPGPPublicKeyObj();
126 			else
127 				return CKR_ATTRIBUTE_VALUE_INVALID;
128 			break;
129 		case CKO_PUBLIC_KEY:
130 			if (keyType == CKK_RSA)
131 				*p11object = new P11RSAPublicKeyObj();
132 			else if (keyType == CKK_DSA)
133 				*p11object = new P11DSAPublicKeyObj();
134 			else if (keyType == CKK_EC)
135 				*p11object = new P11ECPublicKeyObj();
136 			else if (keyType == CKK_DH)
137 				*p11object = new P11DHPublicKeyObj();
138 			else if (keyType == CKK_GOSTR3410)
139 				*p11object = new P11GOSTPublicKeyObj();
140 			else if (keyType == CKK_EC_EDWARDS)
141 				*p11object = new P11EDPublicKeyObj();
142 			else
143 				return CKR_ATTRIBUTE_VALUE_INVALID;
144 			break;
145 		case CKO_PRIVATE_KEY:
146 			// we need to know the type too
147 			if (keyType == CKK_RSA)
148 				*p11object = new P11RSAPrivateKeyObj();
149 			else if (keyType == CKK_DSA)
150 				*p11object = new P11DSAPrivateKeyObj();
151 			else if (keyType == CKK_EC)
152 				*p11object = new P11ECPrivateKeyObj();
153 			else if (keyType == CKK_DH)
154 				*p11object = new P11DHPrivateKeyObj();
155 			else if (keyType == CKK_GOSTR3410)
156 				*p11object = new P11GOSTPrivateKeyObj();
157 			else if (keyType == CKK_EC_EDWARDS)
158 				*p11object = new P11EDPrivateKeyObj();
159 			else
160 				return CKR_ATTRIBUTE_VALUE_INVALID;
161 			break;
162 		case CKO_SECRET_KEY:
163 			if ((keyType == CKK_GENERIC_SECRET) ||
164 			    (keyType == CKK_MD5_HMAC) ||
165 			    (keyType == CKK_SHA_1_HMAC) ||
166 			    (keyType == CKK_SHA224_HMAC) ||
167 			    (keyType == CKK_SHA256_HMAC) ||
168 			    (keyType == CKK_SHA384_HMAC) ||
169 			    (keyType == CKK_SHA512_HMAC))
170 			{
171 				P11GenericSecretKeyObj* key = new P11GenericSecretKeyObj();
172 				*p11object = key;
173 				key->setKeyType(keyType);
174 			}
175 			else if (keyType == CKK_AES)
176 			{
177 				*p11object = new P11AESSecretKeyObj();
178 			}
179 			else if ((keyType == CKK_DES) ||
180 				 (keyType == CKK_DES2) ||
181 				 (keyType == CKK_DES3))
182 			{
183 				P11DESSecretKeyObj* key = new P11DESSecretKeyObj();
184 				*p11object = key;
185 				key->setKeyType(keyType);
186 			}
187 			else if (keyType == CKK_GOST28147)
188 			{
189 				*p11object = new P11GOSTSecretKeyObj();
190 			}
191 			else
192 				return CKR_ATTRIBUTE_VALUE_INVALID;
193 			break;
194 		case CKO_DOMAIN_PARAMETERS:
195 			if (keyType == CKK_DSA)
196 				*p11object = new P11DSADomainObj();
197 			else if (keyType == CKK_DH)
198 				*p11object = new P11DHDomainObj();
199 			else
200 				return CKR_ATTRIBUTE_VALUE_INVALID;
201 			break;
202 		default:
203 			return CKR_ATTRIBUTE_VALUE_INVALID; // invalid value for a valid argument
204 	}
205 	return CKR_OK;
206 }
207 
extractObjectInformation(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_CLASS & objClass,CK_KEY_TYPE & keyType,CK_CERTIFICATE_TYPE & certType,CK_BBOOL & isOnToken,CK_BBOOL & isPrivate,bool bImplicit)208 static CK_RV extractObjectInformation(CK_ATTRIBUTE_PTR pTemplate,
209 				      CK_ULONG ulCount,
210 				      CK_OBJECT_CLASS &objClass,
211 				      CK_KEY_TYPE &keyType,
212 				      CK_CERTIFICATE_TYPE &certType,
213 				      CK_BBOOL &isOnToken,
214 				      CK_BBOOL &isPrivate,
215 				      bool bImplicit)
216 {
217 	bool bHasClass = false;
218 	bool bHasKeyType = false;
219 	bool bHasCertType = false;
220 	bool bHasPrivate = false;
221 
222 	// Extract object information
223 	for (CK_ULONG i = 0; i < ulCount; ++i)
224 	{
225 		switch (pTemplate[i].type)
226 		{
227 			case CKA_CLASS:
228 				if (pTemplate[i].ulValueLen == sizeof(CK_OBJECT_CLASS))
229 				{
230 					objClass = *(CK_OBJECT_CLASS_PTR)pTemplate[i].pValue;
231 					bHasClass = true;
232 				}
233 				break;
234 			case CKA_KEY_TYPE:
235 				if (pTemplate[i].ulValueLen == sizeof(CK_KEY_TYPE))
236 				{
237 					keyType = *(CK_KEY_TYPE*)pTemplate[i].pValue;
238 					bHasKeyType = true;
239 				}
240 				break;
241 			case CKA_CERTIFICATE_TYPE:
242 				if (pTemplate[i].ulValueLen == sizeof(CK_CERTIFICATE_TYPE))
243 				{
244 					certType = *(CK_CERTIFICATE_TYPE*)pTemplate[i].pValue;
245 					bHasCertType = true;
246 				}
247 				break;
248 			case CKA_TOKEN:
249 				if (pTemplate[i].ulValueLen == sizeof(CK_BBOOL))
250 				{
251 					isOnToken = *(CK_BBOOL*)pTemplate[i].pValue;
252 				}
253 				break;
254 			case CKA_PRIVATE:
255 				if (pTemplate[i].ulValueLen == sizeof(CK_BBOOL))
256 				{
257 					isPrivate = *(CK_BBOOL*)pTemplate[i].pValue;
258 					bHasPrivate = true;
259 				}
260 				break;
261 			default:
262 				break;
263 		}
264 	}
265 
266 	if (bImplicit)
267 	{
268 		return CKR_OK;
269 	}
270 
271 	if (!bHasClass)
272 	{
273 		return CKR_TEMPLATE_INCOMPLETE;
274 	}
275 
276 	bool bKeyTypeRequired = (objClass == CKO_PUBLIC_KEY || objClass == CKO_PRIVATE_KEY || objClass == CKO_SECRET_KEY);
277 	if (bKeyTypeRequired && !bHasKeyType)
278 	{
279 		 return CKR_TEMPLATE_INCOMPLETE;
280 	}
281 
282 	if (objClass == CKO_CERTIFICATE)
283 	{
284 		if (!bHasCertType)
285 		{
286 			return CKR_TEMPLATE_INCOMPLETE;
287 		}
288 		if (!bHasPrivate)
289 		{
290 			// Change default value for certificates
291 			isPrivate = CK_FALSE;
292 		}
293 	}
294 
295 	if (objClass == CKO_PUBLIC_KEY && !bHasPrivate)
296 	{
297 		// Change default value for public keys
298 		isPrivate = CK_FALSE;
299 	}
300 
301 	return CKR_OK;
302 }
303 
newP11Object(OSObject * object,P11Object ** p11object)304 static CK_RV newP11Object(OSObject *object, P11Object **p11object)
305 {
306 	CK_OBJECT_CLASS objClass = object->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED);
307 	CK_KEY_TYPE keyType = CKK_RSA;
308 	CK_CERTIFICATE_TYPE certType = CKC_X_509;
309 	if (object->attributeExists(CKA_KEY_TYPE))
310 		keyType = object->getUnsignedLongValue(CKA_KEY_TYPE, CKK_RSA);
311 	if (object->attributeExists(CKA_CERTIFICATE_TYPE))
312 		certType = object->getUnsignedLongValue(CKA_CERTIFICATE_TYPE, CKC_X_509);
313 	CK_RV rv = newP11Object(objClass,keyType,certType,p11object);
314 	if (rv != CKR_OK)
315 		return rv;
316 	if (!(*p11object)->init(object))
317 		return CKR_GENERAL_ERROR; // something went wrong that shouldn't have.
318 	return CKR_OK;
319 }
320 
321 #ifdef notyet
bsAttribute(CK_ATTRIBUTE_TYPE type,const ByteString & value)322 static CK_ATTRIBUTE bsAttribute(CK_ATTRIBUTE_TYPE type, const ByteString &value)
323 {
324 	CK_ATTRIBUTE attr = {type, (CK_VOID_PTR)value.const_byte_str(), value.size() };
325 	return attr;
326 }
327 #endif
328 
329 /*****************************************************************************
330  Implementation of SoftHSM class specific functions
331  *****************************************************************************/
resetMutexFactoryCallbacks()332 static void resetMutexFactoryCallbacks()
333 {
334 	// Reset MutexFactory callbacks to our versions
335 	MutexFactory::i()->setCreateMutex(OSCreateMutex);
336 	MutexFactory::i()->setDestroyMutex(OSDestroyMutex);
337 	MutexFactory::i()->setLockMutex(OSLockMutex);
338 	MutexFactory::i()->setUnlockMutex(OSUnlockMutex);
339 }
340 
341 
342 // Return the one-and-only instance
i()343 SoftHSM* SoftHSM::i()
344 {
345 	if (!instance.get())
346 	{
347 		instance.reset(new SoftHSM());
348 	}
349 	else if(instance->detectFork())
350 	{
351 		if (Configuration::i()->getBool("library.reset_on_fork", false))
352 		{
353 			/* It is important to first clear the singleton
354 			 * instance, and then fill it again, so make sure
355 			 * the old instance is first destroyed as some
356 			 * static structures are erased in the destructor.
357 			 */
358 			instance.reset(NULL);
359 			instance.reset(new SoftHSM());
360 		}
361 	}
362 
363 	return instance.get();
364 }
365 
reset()366 void SoftHSM::reset()
367 {
368 	if (instance.get())
369 		instance.reset();
370 }
371 
372 // Constructor
SoftHSM()373 SoftHSM::SoftHSM()
374 {
375 	isInitialised = false;
376 	isRemovable = false;
377 	sessionObjectStore = NULL;
378 	objectStore = NULL;
379 	slotManager = NULL;
380 	sessionManager = NULL;
381 	handleManager = NULL;
382 	resetMutexFactoryCallbacks();
383 #ifdef _WIN32
384 	forkID = _getpid();
385 #else
386 	forkID = getpid();
387 #endif
388 }
389 
390 // Destructor
~SoftHSM()391 SoftHSM::~SoftHSM()
392 {
393 	if (handleManager != NULL) delete handleManager;
394 	handleManager = NULL;
395 	if (sessionManager != NULL) delete sessionManager;
396 	sessionManager = NULL;
397 	if (slotManager != NULL) delete slotManager;
398 	slotManager = NULL;
399 	if (objectStore != NULL) delete objectStore;
400 	objectStore = NULL;
401 	if (sessionObjectStore != NULL) delete sessionObjectStore;
402 	sessionObjectStore = NULL;
403 
404 	mechanisms_table.clear();
405 	supportedMechanisms.clear();
406 
407 	isInitialised = false;
408 
409 	resetMutexFactoryCallbacks();
410 }
411 
412 /*****************************************************************************
413  Implementation of PKCS #11 functions
414  *****************************************************************************/
415 
416 // PKCS #11 initialisation function
C_Initialize(CK_VOID_PTR pInitArgs)417 CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs)
418 {
419 	CK_C_INITIALIZE_ARGS_PTR args;
420 
421 	// Check if PKCS#11 is already initialized
422 	if (isInitialised)
423 	{
424 		ERROR_MSG("SoftHSM is already initialized");
425 		return CKR_CRYPTOKI_ALREADY_INITIALIZED;
426 	}
427 
428 	// Do we have any arguments?
429 	if (pInitArgs != NULL_PTR)
430 	{
431 		args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
432 
433 		// Must be set to NULL_PTR in this version of PKCS#11
434 		if (args->pReserved != NULL_PTR)
435 		{
436 			ERROR_MSG("pReserved must be set to NULL_PTR");
437 			return CKR_ARGUMENTS_BAD;
438 		}
439 
440 		// Can we spawn our own threads?
441 		// if (args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS)
442 		// {
443 		//	DEBUG_MSG("Cannot create threads if CKF_LIBRARY_CANT_CREATE_OS_THREADS is set");
444 		//	return CKR_NEED_TO_CREATE_THREADS;
445 		// }
446 
447 		// Are we not supplied with mutex functions?
448 		if
449 		(
450 			args->CreateMutex == NULL_PTR &&
451 			args->DestroyMutex == NULL_PTR &&
452 			args->LockMutex == NULL_PTR &&
453 			args->UnlockMutex == NULL_PTR
454 		)
455 		{
456 			// Can we use our own mutex functions?
457 			if (args->flags & CKF_OS_LOCKING_OK)
458 			{
459 				// Use our own mutex functions.
460 				resetMutexFactoryCallbacks();
461 				MutexFactory::i()->enable();
462 			}
463 			else
464 			{
465 				// The external application is not using threading
466 				MutexFactory::i()->disable();
467 			}
468 		}
469 		else
470 		{
471 			// We must have all mutex functions
472 			if
473 			(
474 				args->CreateMutex == NULL_PTR ||
475 				args->DestroyMutex == NULL_PTR ||
476 				args->LockMutex == NULL_PTR ||
477 				args->UnlockMutex == NULL_PTR
478 			)
479 			{
480 				ERROR_MSG("Not all mutex functions are supplied");
481 				return CKR_ARGUMENTS_BAD;
482 			}
483 
484 			// We could use our own mutex functions if the flag is set,
485 			// but we use the external functions in both cases.
486 
487 			// Load the external mutex functions
488 			MutexFactory::i()->setCreateMutex(args->CreateMutex);
489 			MutexFactory::i()->setDestroyMutex(args->DestroyMutex);
490 			MutexFactory::i()->setLockMutex(args->LockMutex);
491 			MutexFactory::i()->setUnlockMutex(args->UnlockMutex);
492 			MutexFactory::i()->enable();
493 		}
494 	}
495 	else
496 	{
497 		// No concurrent access by multiple threads
498 		MutexFactory::i()->disable();
499 	}
500 
501 	// Initiate SecureMemoryRegistry
502 	if (SecureMemoryRegistry::i() == NULL)
503 	{
504 		ERROR_MSG("Could not load the SecureMemoryRegistry");
505 		return CKR_GENERAL_ERROR;
506 	}
507 
508 	// Build the CryptoFactory
509 	if (CryptoFactory::i() == NULL)
510 	{
511 		ERROR_MSG("Could not load the CryptoFactory");
512 		return CKR_GENERAL_ERROR;
513 	}
514 
515 #ifdef WITH_FIPS
516 	// Check the FIPS status
517 	if (!CryptoFactory::i()->getFipsSelfTestStatus())
518 	{
519 		ERROR_MSG("The FIPS self test failed");
520 		return CKR_FIPS_SELF_TEST_FAILED;
521 	}
522 #endif
523 
524 	// (Re)load the configuration
525 	if (!Configuration::i()->reload(SimpleConfigLoader::i()))
526 	{
527 		ERROR_MSG("Could not load the configuration");
528 		return CKR_GENERAL_ERROR;
529 	}
530 
531 	// Configure the log level
532 	if (!setLogLevel(Configuration::i()->getString("log.level", DEFAULT_LOG_LEVEL)))
533 	{
534 		ERROR_MSG("Could not set the log level");
535 		return CKR_GENERAL_ERROR;
536 	}
537 
538 	// Configure object store storage backend used by all tokens.
539 	if (!ObjectStoreToken::selectBackend(Configuration::i()->getString("objectstore.backend", DEFAULT_OBJECTSTORE_BACKEND)))
540 	{
541 		ERROR_MSG("Could not set the storage backend");
542 		return CKR_GENERAL_ERROR;
543 	}
544 
545 	sessionObjectStore = new SessionObjectStore();
546 
547 	// Load the object store
548 	objectStore = new ObjectStore(Configuration::i()->getString("directories.tokendir", DEFAULT_TOKENDIR));
549 	if (!objectStore->isValid())
550 	{
551 		WARNING_MSG("Could not load the object store");
552 		delete objectStore;
553 		objectStore = NULL;
554 		delete sessionObjectStore;
555 		sessionObjectStore = NULL;
556 		return CKR_GENERAL_ERROR;
557 	}
558 
559 	// Load the enabled list of algorithms
560 	prepareSupportedMecahnisms(mechanisms_table);
561 
562 	isRemovable = Configuration::i()->getBool("slots.removable", false);
563 
564 	// Load the slot manager
565 	slotManager = new SlotManager(objectStore);
566 
567 	// Load the session manager
568 	sessionManager = new SessionManager();
569 
570 	// Load the handle manager
571 	handleManager = new HandleManager();
572 
573 	// Set the state to initialised
574 	isInitialised = true;
575 
576 	return CKR_OK;
577 }
578 
579 // PKCS #11 finalisation function
C_Finalize(CK_VOID_PTR pReserved)580 CK_RV SoftHSM::C_Finalize(CK_VOID_PTR pReserved)
581 {
582 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
583 
584 	// Must be set to NULL_PTR in this version of PKCS#11
585 	if (pReserved != NULL_PTR) return CKR_ARGUMENTS_BAD;
586 
587 	if (handleManager != NULL) delete handleManager;
588 	handleManager = NULL;
589 	if (sessionManager != NULL) delete sessionManager;
590 	sessionManager = NULL;
591 	if (slotManager != NULL) delete slotManager;
592 	slotManager = NULL;
593 	if (objectStore != NULL) delete objectStore;
594 	objectStore = NULL;
595 	if (sessionObjectStore != NULL) delete sessionObjectStore;
596 	sessionObjectStore = NULL;
597 	CryptoFactory::reset();
598 	SecureMemoryRegistry::reset();
599 
600 	isInitialised = false;
601 
602 	supportedMechanisms.clear();
603 
604 	SoftHSM::reset();
605 	return CKR_OK;
606 }
607 
608 // Return information about the PKCS #11 module
C_GetInfo(CK_INFO_PTR pInfo)609 CK_RV SoftHSM::C_GetInfo(CK_INFO_PTR pInfo)
610 {
611 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
612 	if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD;
613 
614 	pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
615 	pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
616 	memset(pInfo->manufacturerID, ' ', 32);
617 	memcpy(pInfo->manufacturerID, "SoftHSM", 7);
618 	pInfo->flags = 0;
619 	memset(pInfo->libraryDescription, ' ', 32);
620 #ifdef WITH_FIPS
621 	memcpy(pInfo->libraryDescription, "Implementation of PKCS11+FIPS", 29);
622 #else
623 	memcpy(pInfo->libraryDescription, "Implementation of PKCS11", 24);
624 #endif
625 	pInfo->libraryVersion.major = VERSION_MAJOR;
626 	pInfo->libraryVersion.minor = VERSION_MINOR;
627 
628 	return CKR_OK;
629 }
630 
631 // Return a list of available slots
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)632 CK_RV SoftHSM::C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
633 {
634 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
635 
636 	return slotManager->getSlotList(objectStore, tokenPresent, pSlotList, pulCount);
637 }
638 
639 // Return information about a slot
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)640 CK_RV SoftHSM::C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
641 {
642 	CK_RV rv;
643 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
644 
645 	Slot* slot = slotManager->getSlot(slotID);
646 	if (slot == NULL)
647 	{
648 		return CKR_SLOT_ID_INVALID;
649 	}
650 
651 	rv = slot->getSlotInfo(pInfo);
652 	if (rv != CKR_OK) {
653 		return rv;
654 	}
655 
656 	if (isRemovable) {
657 		pInfo->flags |= CKF_REMOVABLE_DEVICE;
658 	}
659 
660 	return CKR_OK;
661 }
662 
663 // Return information about a token in a slot
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)664 CK_RV SoftHSM::C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
665 {
666 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
667 
668 	Slot* slot = slotManager->getSlot(slotID);
669 	if (slot == NULL)
670 	{
671 		return CKR_SLOT_ID_INVALID;
672 	}
673 
674 	Token* token = slot->getToken();
675 	if (token == NULL)
676 	{
677 		return CKR_TOKEN_NOT_PRESENT;
678 	}
679 
680 	return token->getTokenInfo(pInfo);
681 }
682 
prepareSupportedMecahnisms(std::map<std::string,CK_MECHANISM_TYPE> & t)683 void SoftHSM::prepareSupportedMecahnisms(std::map<std::string, CK_MECHANISM_TYPE> &t)
684 {
685 #ifndef WITH_FIPS
686 	t["CKM_MD5"]			= CKM_MD5;
687 #endif
688 	t["CKM_SHA_1"]			= CKM_SHA_1;
689 	t["CKM_SHA224"]			= CKM_SHA224;
690 	t["CKM_SHA256"]			= CKM_SHA256;
691 	t["CKM_SHA384"]			= CKM_SHA384;
692 	t["CKM_SHA512"]			= CKM_SHA512;
693 #ifndef WITH_FIPS
694 	t["CKM_MD5_HMAC"]		= CKM_MD5_HMAC;
695 #endif
696 	t["CKM_SHA_1_HMAC"]		= CKM_SHA_1_HMAC;
697 	t["CKM_SHA224_HMAC"]		= CKM_SHA224_HMAC;
698 	t["CKM_SHA256_HMAC"]		= CKM_SHA256_HMAC;
699 	t["CKM_SHA384_HMAC"]		= CKM_SHA384_HMAC;
700 	t["CKM_SHA512_HMAC"]		= CKM_SHA512_HMAC;
701 	t["CKM_RSA_PKCS_KEY_PAIR_GEN"]	= CKM_RSA_PKCS_KEY_PAIR_GEN;
702 	t["CKM_RSA_PKCS"]		= CKM_RSA_PKCS;
703 	t["CKM_RSA_X_509"]		= CKM_RSA_X_509;
704 #ifndef WITH_FIPS
705 	t["CKM_MD5_RSA_PKCS"]		= CKM_MD5_RSA_PKCS;
706 #endif
707 	t["CKM_SHA1_RSA_PKCS"]		= CKM_SHA1_RSA_PKCS;
708 	t["CKM_RSA_PKCS_OAEP"]		= CKM_RSA_PKCS_OAEP;
709 	t["CKM_SHA224_RSA_PKCS"]	= CKM_SHA224_RSA_PKCS;
710 	t["CKM_SHA256_RSA_PKCS"]	= CKM_SHA256_RSA_PKCS;
711 	t["CKM_SHA384_RSA_PKCS"]	= CKM_SHA384_RSA_PKCS;
712 	t["CKM_SHA512_RSA_PKCS"]	= CKM_SHA512_RSA_PKCS;
713 #ifdef WITH_RAW_PSS
714 	t["CKM_RSA_PKCS_PSS"]		= CKM_RSA_PKCS_PSS;
715 #endif
716 	t["CKM_SHA1_RSA_PKCS_PSS"]	= CKM_SHA1_RSA_PKCS_PSS;
717 	t["CKM_SHA224_RSA_PKCS_PSS"]	= CKM_SHA224_RSA_PKCS_PSS;
718 	t["CKM_SHA256_RSA_PKCS_PSS"]	= CKM_SHA256_RSA_PKCS_PSS;
719 	t["CKM_SHA384_RSA_PKCS_PSS"]	= CKM_SHA384_RSA_PKCS_PSS;
720 	t["CKM_SHA512_RSA_PKCS_PSS"]	= CKM_SHA512_RSA_PKCS_PSS;
721 	t["CKM_GENERIC_SECRET_KEY_GEN"]	= CKM_GENERIC_SECRET_KEY_GEN;
722 #ifndef WITH_FIPS
723 	t["CKM_DES_KEY_GEN"]		= CKM_DES_KEY_GEN;
724 #endif
725 	t["CKM_DES2_KEY_GEN"]		= CKM_DES2_KEY_GEN;
726 	t["CKM_DES3_KEY_GEN"]		= CKM_DES3_KEY_GEN;
727 #ifndef WITH_FIPS
728 	t["CKM_DES_ECB"]		= CKM_DES_ECB;
729 	t["CKM_DES_CBC"]		= CKM_DES_CBC;
730 	t["CKM_DES_CBC_PAD"]		= CKM_DES_CBC_PAD;
731 	t["CKM_DES_ECB_ENCRYPT_DATA"]	= CKM_DES_ECB_ENCRYPT_DATA;
732 	t["CKM_DES_CBC_ENCRYPT_DATA"]	= CKM_DES_CBC_ENCRYPT_DATA;
733 #endif
734 	t["CKM_DES3_ECB"]		= CKM_DES3_ECB;
735 	t["CKM_DES3_CBC"]		= CKM_DES3_CBC;
736 	t["CKM_DES3_CBC_PAD"]		= CKM_DES3_CBC_PAD;
737 	t["CKM_DES3_ECB_ENCRYPT_DATA"]	= CKM_DES3_ECB_ENCRYPT_DATA;
738 	t["CKM_DES3_CBC_ENCRYPT_DATA"]	= CKM_DES3_CBC_ENCRYPT_DATA;
739 	t["CKM_DES3_CMAC"]		= CKM_DES3_CMAC;
740 	t["CKM_AES_KEY_GEN"]		= CKM_AES_KEY_GEN;
741 	t["CKM_AES_ECB"]		= CKM_AES_ECB;
742 	t["CKM_AES_CBC"]		= CKM_AES_CBC;
743 	t["CKM_AES_CBC_PAD"]		= CKM_AES_CBC_PAD;
744 	t["CKM_AES_CTR"]		= CKM_AES_CTR;
745 	t["CKM_AES_GCM"]		= CKM_AES_GCM;
746 	t["CKM_AES_KEY_WRAP"]		= CKM_AES_KEY_WRAP;
747 #ifdef HAVE_AES_KEY_WRAP_PAD
748 	t["CKM_AES_KEY_WRAP_PAD"]	= CKM_AES_KEY_WRAP_PAD;
749 #endif
750 	t["CKM_AES_ECB_ENCRYPT_DATA"]	= CKM_AES_ECB_ENCRYPT_DATA;
751 	t["CKM_AES_CBC_ENCRYPT_DATA"]	= CKM_AES_CBC_ENCRYPT_DATA;
752 	t["CKM_AES_CMAC"]		= CKM_AES_CMAC;
753 	t["CKM_DSA_PARAMETER_GEN"]	= CKM_DSA_PARAMETER_GEN;
754 	t["CKM_DSA_KEY_PAIR_GEN"]	= CKM_DSA_KEY_PAIR_GEN;
755 	t["CKM_DSA"]			= CKM_DSA;
756 	t["CKM_DSA_SHA1"]		= CKM_DSA_SHA1;
757 	t["CKM_DSA_SHA224"]		= CKM_DSA_SHA224;
758 	t["CKM_DSA_SHA256"]		= CKM_DSA_SHA256;
759 	t["CKM_DSA_SHA384"]		= CKM_DSA_SHA384;
760 	t["CKM_DSA_SHA512"]		= CKM_DSA_SHA512;
761 	t["CKM_DH_PKCS_KEY_PAIR_GEN"]	= CKM_DH_PKCS_KEY_PAIR_GEN;
762 	t["CKM_DH_PKCS_PARAMETER_GEN"]	= CKM_DH_PKCS_PARAMETER_GEN;
763 	t["CKM_DH_PKCS_DERIVE"]		= CKM_DH_PKCS_DERIVE;
764 #ifdef WITH_ECC
765 	t["CKM_EC_KEY_PAIR_GEN"]	= CKM_EC_KEY_PAIR_GEN;
766 	t["CKM_ECDSA"]			= CKM_ECDSA;
767 #endif
768 #if defined(WITH_ECC) || defined(WITH_EDDSA)
769 	t["CKM_ECDH1_DERIVE"]		= CKM_ECDH1_DERIVE;
770 #endif
771 #ifdef WITH_GOST
772 	t["CKM_GOSTR3411"]		= CKM_GOSTR3411;
773 	t["CKM_GOSTR3411_HMAC"]		= CKM_GOSTR3411_HMAC;
774 	t["CKM_GOSTR3410_KEY_PAIR_GEN"]	= CKM_GOSTR3410_KEY_PAIR_GEN;
775 	t["CKM_GOSTR3410"]		= CKM_GOSTR3410;
776 	t["CKM_GOSTR3410_WITH_GOSTR3411"] = CKM_GOSTR3410_WITH_GOSTR3411;
777 #endif
778 #ifdef WITH_EDDSA
779 	t["CKM_EC_EDWARDS_KEY_PAIR_GEN"] = CKM_EC_EDWARDS_KEY_PAIR_GEN;
780 	t["CKM_EDDSA"]			= CKM_EDDSA;
781 #endif
782 
783 	supportedMechanisms.clear();
784 	for (auto it = t.begin(); it != t.end(); ++it)
785 	{
786 		supportedMechanisms.push_back(it->second);
787 	}
788 
789 	/* Check configuration for supported algorithms */
790 	std::string mechs = Configuration::i()->getString("slots.mechanisms", "ALL");
791 	if (mechs != "ALL")
792 	{
793 		bool negative = (mechs[0] == '-');
794 		if (!negative)
795 		{
796 			/* For positive list, we remove everything */
797 			supportedMechanisms.clear();
798 		}
799 		size_t pos = 0, prev = 0;
800 		std::string token;
801 		do
802 		{
803 			pos = mechs.find(",", prev);
804 			if (pos == std::string::npos) pos = mechs.length();
805 			token = mechs.substr(prev, pos - prev);
806 			CK_MECHANISM_TYPE mechanism;
807 			try
808 			{
809 				mechanism = t.at(token);
810 				if (!negative)
811 					supportedMechanisms.push_back(mechanism);
812 				else
813 					supportedMechanisms.remove(mechanism);
814 			}
815 			catch (const std::out_of_range& e)
816 			{
817 				WARNING_MSG("Unknown mechanism provided: %s", token.c_str());
818 			}
819 			prev = pos + 1;
820 		}
821 		while (pos < mechs.length() && prev < mechs.length());
822 	}
823 
824 	nrSupportedMechanisms = supportedMechanisms.size();
825 }
826 
827 // Return the list of supported mechanisms for a given slot
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)828 CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount)
829 {
830 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
831 	if (pulCount == NULL_PTR) return CKR_ARGUMENTS_BAD;
832 
833 	Slot* slot = slotManager->getSlot(slotID);
834 	if (slot == NULL)
835 	{
836 		return CKR_SLOT_ID_INVALID;
837 	}
838 
839 	if (pMechanismList == NULL_PTR)
840 	{
841 		*pulCount = nrSupportedMechanisms;
842 
843 		return CKR_OK;
844 	}
845 
846 	if (*pulCount < nrSupportedMechanisms)
847 	{
848 		*pulCount = nrSupportedMechanisms;
849 
850 		return CKR_BUFFER_TOO_SMALL;
851 	}
852 
853 	*pulCount = nrSupportedMechanisms;
854 
855 	int i = 0;
856 	auto it = supportedMechanisms.cbegin();
857 	for (; it != supportedMechanisms.cend(); it++, i++)
858 	{
859 		pMechanismList[i] = *it;
860 	}
861 
862 	return CKR_OK;
863 }
864 
865 // Return more information about a mechanism for a given slot
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)866 CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo)
867 {
868 	unsigned long rsaMinSize, rsaMaxSize;
869 	unsigned long dsaMinSize, dsaMaxSize;
870 	unsigned long dhMinSize, dhMaxSize;
871 #ifdef WITH_ECC
872 	unsigned long ecdsaMinSize, ecdsaMaxSize;
873 #endif
874 #if defined(WITH_ECC) || defined(WITH_EDDSA)
875 	unsigned long ecdhMinSize = 0, ecdhMaxSize = 0;
876 	unsigned long eddsaMinSize = 0, eddsaMaxSize = 0;
877 #endif
878 
879 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
880 	if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD;
881 
882 	Slot* slot = slotManager->getSlot(slotID);
883 	if (slot == NULL)
884 	{
885 		return CKR_SLOT_ID_INVALID;
886 	}
887 
888 	AsymmetricAlgorithm* rsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
889 	if (rsa != NULL)
890 	{
891 		rsaMinSize = rsa->getMinKeySize();
892 		rsaMaxSize = rsa->getMaxKeySize();
893 	}
894 	else
895 	{
896 		return CKR_GENERAL_ERROR;
897 	}
898 	CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
899 
900 	AsymmetricAlgorithm* dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
901 	if (dsa != NULL)
902 	{
903 		dsaMinSize = dsa->getMinKeySize();
904 		// Limitation in PKCS#11
905 		if (dsaMinSize < 512)
906 		{
907 			dsaMinSize = 512;
908 		}
909 
910 		dsaMaxSize = dsa->getMaxKeySize();
911 		// Limitation in PKCS#11
912 		if (dsaMaxSize > 1024)
913 		{
914 			dsaMaxSize = 1024;
915 		}
916 	}
917 	else
918 	{
919 		return CKR_GENERAL_ERROR;
920 	}
921 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
922 
923 	AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
924 	if (dh != NULL)
925 	{
926 		dhMinSize = dh->getMinKeySize();
927 		dhMaxSize = dh->getMaxKeySize();
928 	}
929 	else
930 	{
931 		return CKR_GENERAL_ERROR;
932 	}
933 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
934 
935 #ifdef WITH_ECC
936 	AsymmetricAlgorithm* ecdsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
937 	if (ecdsa != NULL)
938 	{
939 		ecdsaMinSize = ecdsa->getMinKeySize();
940 		ecdsaMaxSize = ecdsa->getMaxKeySize();
941 	}
942 	else
943 	{
944 		return CKR_GENERAL_ERROR;
945 	}
946 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdsa);
947 
948 	AsymmetricAlgorithm* ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
949 	if (ecdh != NULL)
950 	{
951 		ecdhMinSize = ecdh->getMinKeySize();
952 		ecdhMaxSize = ecdh->getMaxKeySize();
953 	}
954 	else
955 	{
956 		return CKR_GENERAL_ERROR;
957 	}
958 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
959 #endif
960 
961 #ifdef WITH_EDDSA
962 	AsymmetricAlgorithm* eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
963 	if (eddsa != NULL)
964 	{
965 		eddsaMinSize = eddsa->getMinKeySize();
966 		eddsaMaxSize = eddsa->getMaxKeySize();
967 	}
968 	else
969 	{
970 		return CKR_GENERAL_ERROR;
971 	}
972 	CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
973 #endif
974 	switch (type)
975 	{
976 #ifndef WITH_FIPS
977 		case CKM_MD5:
978 #endif
979 		case CKM_SHA_1:
980 		case CKM_SHA224:
981 		case CKM_SHA256:
982 		case CKM_SHA384:
983 		case CKM_SHA512:
984 			// Key size is not in use
985 			pInfo->ulMinKeySize = 0;
986 			pInfo->ulMaxKeySize = 0;
987 			pInfo->flags = CKF_DIGEST;
988 			break;
989 #ifndef WITH_FIPS
990 		case CKM_MD5_HMAC:
991 			pInfo->ulMinKeySize = 16;
992 			pInfo->ulMaxKeySize = 512;
993 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
994 			break;
995 #endif
996 		case CKM_SHA_1_HMAC:
997 			pInfo->ulMinKeySize = 20;
998 			pInfo->ulMaxKeySize = 512;
999 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1000 			break;
1001 		case CKM_SHA224_HMAC:
1002 			pInfo->ulMinKeySize = 28;
1003 			pInfo->ulMaxKeySize = 512;
1004 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1005 			break;
1006 		case CKM_SHA256_HMAC:
1007 			pInfo->ulMinKeySize = 32;
1008 			pInfo->ulMaxKeySize = 512;
1009 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1010 			break;
1011 		case CKM_SHA384_HMAC:
1012 			pInfo->ulMinKeySize = 48;
1013 			pInfo->ulMaxKeySize = 512;
1014 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1015 			break;
1016 		case CKM_SHA512_HMAC:
1017 			pInfo->ulMinKeySize = 64;
1018 			pInfo->ulMaxKeySize = 512;
1019 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1020 			break;
1021 		case CKM_RSA_PKCS_KEY_PAIR_GEN:
1022 			pInfo->ulMinKeySize = rsaMinSize;
1023 			pInfo->ulMaxKeySize = rsaMaxSize;
1024 			pInfo->flags = CKF_GENERATE_KEY_PAIR;
1025 			break;
1026 		case CKM_RSA_PKCS:
1027 			pInfo->ulMinKeySize = rsaMinSize;
1028 			pInfo->ulMaxKeySize = rsaMaxSize;
1029 			pInfo->flags = CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
1030 			break;
1031 		case CKM_RSA_X_509:
1032 			pInfo->ulMinKeySize = rsaMinSize;
1033 			pInfo->ulMaxKeySize = rsaMaxSize;
1034 			pInfo->flags = CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT;
1035 			break;
1036 #ifndef WITH_FIPS
1037 		case CKM_MD5_RSA_PKCS:
1038 #endif
1039 		case CKM_SHA1_RSA_PKCS:
1040 		case CKM_SHA224_RSA_PKCS:
1041 		case CKM_SHA256_RSA_PKCS:
1042 		case CKM_SHA384_RSA_PKCS:
1043 		case CKM_SHA512_RSA_PKCS:
1044 #ifdef WITH_RAW_PSS
1045 		case CKM_RSA_PKCS_PSS:
1046 #endif
1047 		case CKM_SHA1_RSA_PKCS_PSS:
1048 		case CKM_SHA224_RSA_PKCS_PSS:
1049 		case CKM_SHA256_RSA_PKCS_PSS:
1050 		case CKM_SHA384_RSA_PKCS_PSS:
1051 		case CKM_SHA512_RSA_PKCS_PSS:
1052 			pInfo->ulMinKeySize = rsaMinSize;
1053 			pInfo->ulMaxKeySize = rsaMaxSize;
1054 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1055 			break;
1056 		case CKM_RSA_PKCS_OAEP:
1057 			pInfo->ulMinKeySize = rsaMinSize;
1058 			pInfo->ulMaxKeySize = rsaMaxSize;
1059 			pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
1060 			break;
1061 		case CKM_GENERIC_SECRET_KEY_GEN:
1062 			pInfo->ulMinKeySize = 1;
1063 			pInfo->ulMaxKeySize = 0x80000000;
1064 			pInfo->flags = CKF_GENERATE;
1065 			break;
1066 #ifndef WITH_FIPS
1067 		case CKM_DES_KEY_GEN:
1068 #endif
1069 		case CKM_DES2_KEY_GEN:
1070 		case CKM_DES3_KEY_GEN:
1071 			// Key size is not in use
1072 			pInfo->ulMinKeySize = 0;
1073 			pInfo->ulMaxKeySize = 0;
1074 			pInfo->flags = CKF_GENERATE;
1075 			break;
1076 #ifndef WITH_FIPS
1077 		case CKM_DES_ECB:
1078 		case CKM_DES_CBC:
1079 		case CKM_DES_CBC_PAD:
1080 #endif
1081 		case CKM_DES3_CBC:
1082 			pInfo->flags = CKF_WRAP;
1083 			// falls through
1084 		case CKM_DES3_ECB:
1085 		case CKM_DES3_CBC_PAD:
1086 			// Key size is not in use
1087 			pInfo->ulMinKeySize = 0;
1088 			pInfo->ulMaxKeySize = 0;
1089 			pInfo->flags |= CKF_ENCRYPT | CKF_DECRYPT;
1090 			break;
1091 		case CKM_DES3_CMAC:
1092 			// Key size is not in use
1093 			pInfo->ulMinKeySize = 0;
1094 			pInfo->ulMaxKeySize = 0;
1095 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1096 			break;
1097 		case CKM_AES_KEY_GEN:
1098 			pInfo->ulMinKeySize = 16;
1099 			pInfo->ulMaxKeySize = 32;
1100 			pInfo->flags = CKF_GENERATE;
1101 			break;
1102 		case CKM_AES_CBC:
1103 			pInfo->flags = CKF_WRAP;
1104 			// falls through
1105 		case CKM_AES_ECB:
1106 		case CKM_AES_CBC_PAD:
1107 		case CKM_AES_CTR:
1108 		case CKM_AES_GCM:
1109 			pInfo->ulMinKeySize = 16;
1110 			pInfo->ulMaxKeySize = 32;
1111 			pInfo->flags |= CKF_ENCRYPT | CKF_DECRYPT;
1112 			break;
1113 		case CKM_AES_KEY_WRAP:
1114 			pInfo->ulMinKeySize = 16;
1115 			pInfo->ulMaxKeySize = 0x80000000;
1116 			pInfo->flags = CKF_WRAP | CKF_UNWRAP;
1117 			break;
1118 #ifdef HAVE_AES_KEY_WRAP_PAD
1119 		case CKM_AES_KEY_WRAP_PAD:
1120 			pInfo->ulMinKeySize = 1;
1121 			pInfo->ulMaxKeySize = 0x80000000;
1122 			pInfo->flags = CKF_WRAP | CKF_UNWRAP;
1123 			break;
1124 #endif
1125 #ifndef WITH_FIPS
1126 		case CKM_DES_ECB_ENCRYPT_DATA:
1127 		case CKM_DES_CBC_ENCRYPT_DATA:
1128 #endif
1129 		case CKM_DES3_ECB_ENCRYPT_DATA:
1130 		case CKM_DES3_CBC_ENCRYPT_DATA:
1131 		case CKM_AES_ECB_ENCRYPT_DATA:
1132 		case CKM_AES_CBC_ENCRYPT_DATA:
1133 			// Key size is not in use
1134 			pInfo->ulMinKeySize = 0;
1135 			pInfo->ulMaxKeySize = 0;
1136 			pInfo->flags = CKF_DERIVE;
1137 			break;
1138 		case CKM_AES_CMAC:
1139 			pInfo->ulMinKeySize = 16;
1140 			pInfo->ulMaxKeySize = 32;
1141 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1142 			break;
1143 		case CKM_DSA_PARAMETER_GEN:
1144 			pInfo->ulMinKeySize = dsaMinSize;
1145 			pInfo->ulMaxKeySize = dsaMaxSize;
1146 			pInfo->flags = CKF_GENERATE;
1147 			break;
1148 		case CKM_DSA_KEY_PAIR_GEN:
1149 			pInfo->ulMinKeySize = dsaMinSize;
1150 			pInfo->ulMaxKeySize = dsaMaxSize;
1151 			pInfo->flags = CKF_GENERATE_KEY_PAIR;
1152 			break;
1153 		case CKM_DSA:
1154 		case CKM_DSA_SHA1:
1155 		case CKM_DSA_SHA224:
1156 		case CKM_DSA_SHA256:
1157 		case CKM_DSA_SHA384:
1158 		case CKM_DSA_SHA512:
1159 			pInfo->ulMinKeySize = dsaMinSize;
1160 			pInfo->ulMaxKeySize = dsaMaxSize;
1161 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1162 			break;
1163 		case CKM_DH_PKCS_KEY_PAIR_GEN:
1164 			pInfo->ulMinKeySize = dhMinSize;
1165 			pInfo->ulMaxKeySize = dhMaxSize;
1166 			pInfo->flags = CKF_GENERATE_KEY_PAIR;
1167 			break;
1168 		case CKM_DH_PKCS_PARAMETER_GEN:
1169 			pInfo->ulMinKeySize = dhMinSize;
1170 			pInfo->ulMaxKeySize = dhMaxSize;
1171 			pInfo->flags = CKF_GENERATE;
1172 			break;
1173 		case CKM_DH_PKCS_DERIVE:
1174 			pInfo->ulMinKeySize = dhMinSize;
1175 			pInfo->ulMaxKeySize = dhMaxSize;
1176 			pInfo->flags = CKF_DERIVE;
1177 			break;
1178 #ifdef WITH_ECC
1179 		case CKM_EC_KEY_PAIR_GEN:
1180 			pInfo->ulMinKeySize = ecdsaMinSize;
1181 			pInfo->ulMaxKeySize = ecdsaMaxSize;
1182 #define CKF_EC_COMMOM	(CKF_EC_F_P | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS)
1183 			pInfo->flags = CKF_GENERATE_KEY_PAIR | CKF_EC_COMMOM;
1184 			break;
1185 		case CKM_ECDSA:
1186 			pInfo->ulMinKeySize = ecdsaMinSize;
1187 			pInfo->ulMaxKeySize = ecdsaMaxSize;
1188 			pInfo->flags = CKF_SIGN | CKF_VERIFY | CKF_EC_COMMOM;
1189 			break;
1190 #endif
1191 #if defined(WITH_ECC) || defined(WITH_EDDSA)
1192 		case CKM_ECDH1_DERIVE:
1193 			pInfo->ulMinKeySize = ecdhMinSize ? ecdhMinSize : eddsaMinSize;
1194 			pInfo->ulMaxKeySize = ecdhMaxSize ? ecdhMaxSize : eddsaMaxSize;
1195 			pInfo->flags = CKF_DERIVE;
1196 			break;
1197 #endif
1198 #ifdef WITH_GOST
1199 		case CKM_GOSTR3411:
1200 			// Key size is not in use
1201 			pInfo->ulMinKeySize = 0;
1202 			pInfo->ulMaxKeySize = 0;
1203 			pInfo->flags = CKF_DIGEST;
1204 			break;
1205 		case CKM_GOSTR3411_HMAC:
1206 			// Key size is not in use
1207 			pInfo->ulMinKeySize = 32;
1208 			pInfo->ulMaxKeySize = 512;
1209 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1210 			break;
1211 		case CKM_GOSTR3410_KEY_PAIR_GEN:
1212 			// Key size is not in use
1213 			pInfo->ulMinKeySize = 0;
1214 			pInfo->ulMaxKeySize = 0;
1215 			pInfo->flags = CKF_GENERATE_KEY_PAIR;
1216 			break;
1217 		case CKM_GOSTR3410:
1218 			// Key size is not in use
1219 			pInfo->ulMinKeySize = 0;
1220 			pInfo->ulMaxKeySize = 0;
1221 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1222 			break;
1223 		case CKM_GOSTR3410_WITH_GOSTR3411:
1224 			// Key size is not in use
1225 			pInfo->ulMinKeySize = 0;
1226 			pInfo->ulMaxKeySize = 0;
1227 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1228 			break;
1229 #endif
1230 #ifdef WITH_EDDSA
1231 		case CKM_EC_EDWARDS_KEY_PAIR_GEN:
1232 			pInfo->ulMinKeySize = eddsaMinSize;
1233 			pInfo->ulMaxKeySize = eddsaMaxSize;
1234 			pInfo->flags = CKF_GENERATE_KEY_PAIR;
1235 			break;
1236 		case CKM_EDDSA:
1237 			pInfo->ulMinKeySize = eddsaMinSize;
1238 			pInfo->ulMaxKeySize = eddsaMaxSize;
1239 			pInfo->flags = CKF_SIGN | CKF_VERIFY;
1240 			break;
1241 #endif
1242 		default:
1243 			DEBUG_MSG("The selected mechanism is not supported");
1244 			return CKR_MECHANISM_INVALID;
1245 			break;
1246 	}
1247 
1248 	return CKR_OK;
1249 }
1250 
1251 // Initialise the token in the specified slot
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)1252 CK_RV SoftHSM::C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel)
1253 {
1254 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1255 
1256 	Slot* slot = slotManager->getSlot(slotID);
1257 	if (slot == NULL)
1258 	{
1259 		return CKR_SLOT_ID_INVALID;
1260 	}
1261 
1262 	// Check if any session is open with this token.
1263 	if (sessionManager->haveSession(slotID))
1264 	{
1265 		return CKR_SESSION_EXISTS;
1266 	}
1267 
1268 	// Check the PIN
1269 	if (pPin == NULL_PTR) return CKR_ARGUMENTS_BAD;
1270 	if (ulPinLen < MIN_PIN_LEN || ulPinLen > MAX_PIN_LEN) return CKR_PIN_INCORRECT;
1271 
1272 	ByteString soPIN(pPin, ulPinLen);
1273 
1274 	return slot->initToken(soPIN, pLabel);
1275 }
1276 
1277 // Initialise the user PIN
C_InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1278 CK_RV SoftHSM::C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
1279 {
1280 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1281 
1282 	// Get the session
1283 	Session* session = (Session*)handleManager->getSession(hSession);
1284 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1285 
1286 	// The SO must be logged in
1287 	if (session->getState() != CKS_RW_SO_FUNCTIONS) return CKR_USER_NOT_LOGGED_IN;
1288 
1289 	// Get the token
1290 	Token* token = session->getToken();
1291 	if (token == NULL) return CKR_GENERAL_ERROR;
1292 
1293 	// Check the PIN
1294 	if (pPin == NULL_PTR) return CKR_ARGUMENTS_BAD;
1295 	if (ulPinLen < MIN_PIN_LEN || ulPinLen > MAX_PIN_LEN) return CKR_PIN_LEN_RANGE;
1296 
1297 	ByteString userPIN(pPin, ulPinLen);
1298 
1299 	return token->initUserPIN(userPIN);
1300 }
1301 
1302 // Change the PIN
C_SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewLen)1303 CK_RV SoftHSM::C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
1304 {
1305 	CK_RV rv = CKR_OK;
1306 
1307 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1308 
1309 	// Get the session
1310 	Session* session = (Session*)handleManager->getSession(hSession);
1311 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1312 
1313 	// Check the new PINs
1314 	if (pOldPin == NULL_PTR) return CKR_ARGUMENTS_BAD;
1315 	if (pNewPin == NULL_PTR) return CKR_ARGUMENTS_BAD;
1316 	if (ulNewLen < MIN_PIN_LEN || ulNewLen > MAX_PIN_LEN) return CKR_PIN_LEN_RANGE;
1317 
1318 	ByteString oldPIN(pOldPin, ulOldLen);
1319 	ByteString newPIN(pNewPin, ulNewLen);
1320 
1321 	// Get the token
1322 	Token* token = session->getToken();
1323 	if (token == NULL) return CKR_GENERAL_ERROR;
1324 
1325 	switch (session->getState())
1326 	{
1327 		case CKS_RW_PUBLIC_SESSION:
1328 		case CKS_RW_USER_FUNCTIONS:
1329 			rv = token->setUserPIN(oldPIN, newPIN);
1330 			break;
1331 		case CKS_RW_SO_FUNCTIONS:
1332 			rv = token->setSOPIN(oldPIN, newPIN);
1333 			break;
1334 		default:
1335 			return CKR_SESSION_READ_ONLY;
1336 	}
1337 
1338 	return rv;
1339 }
1340 
1341 // Open a new session to the specified slot
C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY notify,CK_SESSION_HANDLE_PTR phSession)1342 CK_RV SoftHSM::C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession)
1343 {
1344 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1345 
1346 	Slot* slot = slotManager->getSlot(slotID);
1347 
1348 	CK_RV rv = sessionManager->openSession(slot, flags, pApplication, notify, phSession);
1349 	if (rv != CKR_OK)
1350 		return rv;
1351 
1352 	// Get a pointer to the session object and store it in the handle manager.
1353 	Session* session = sessionManager->getSession(*phSession);
1354 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1355 	*phSession = handleManager->addSession(slotID,session);
1356 
1357 	return CKR_OK;
1358 }
1359 
1360 // Close the given session
C_CloseSession(CK_SESSION_HANDLE hSession)1361 CK_RV SoftHSM::C_CloseSession(CK_SESSION_HANDLE hSession)
1362 {
1363 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1364 
1365 	// Get the session
1366 	Session* session = (Session*)handleManager->getSession(hSession);
1367 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1368 
1369 	// Tell the handle manager the session has been closed.
1370 	handleManager->sessionClosed(hSession);
1371 
1372 
1373 	// Tell the session object store that the session has closed.
1374 	sessionObjectStore->sessionClosed(hSession);
1375 
1376 	// Tell the session manager the session has been closed.
1377 	return sessionManager->closeSession(session->getHandle());
1378 }
1379 
1380 // Close all open sessions
C_CloseAllSessions(CK_SLOT_ID slotID)1381 CK_RV SoftHSM::C_CloseAllSessions(CK_SLOT_ID slotID)
1382 {
1383 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1384 
1385 	// Get the slot
1386 	Slot* slot = slotManager->getSlot(slotID);
1387 	if (slot == NULL) return CKR_SLOT_ID_INVALID;
1388 
1389 	// Get the token
1390 	Token* token = slot->getToken();
1391 	if (token == NULL) return CKR_TOKEN_NOT_PRESENT;
1392 
1393 	// Tell the handle manager all sessions were closed for the given slotID.
1394 	// The handle manager should then remove all session and object handles for this slot.
1395 	handleManager->allSessionsClosed(slotID);
1396 
1397 	// Tell the session object store that all sessions were closed for the given slotID.
1398 	// The session object store should then remove all session objects for this slot.
1399 	sessionObjectStore->allSessionsClosed(slotID);
1400 
1401 	// Finally tell the session manager tho close all sessions for the given slot.
1402 	// This will also trigger a logout on the associated token to occur.
1403 	return sessionManager->closeAllSessions(slot);
1404 }
1405 
1406 // Retrieve information about the specified session
C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)1407 CK_RV SoftHSM::C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
1408 {
1409 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1410 
1411 	// Get the session
1412 	Session* session = (Session*)handleManager->getSession(hSession);
1413 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1414 
1415 	return session->getInfo(pInfo);
1416 }
1417 
1418 // Determine the state of a running operation in a session
C_GetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG_PTR)1419 CK_RV SoftHSM::C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pOperationState*/, CK_ULONG_PTR /*pulOperationStateLen*/)
1420 {
1421 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1422 
1423 	// Get the session
1424 	Session* session = (Session*)handleManager->getSession(hSession);
1425 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1426 
1427 	return CKR_FUNCTION_NOT_SUPPORTED;
1428 }
1429 
1430 // Set the operation sate in a session
C_SetOperationState(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_OBJECT_HANDLE,CK_OBJECT_HANDLE)1431 CK_RV SoftHSM::C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pOperationState*/, CK_ULONG /*ulOperationStateLen*/, CK_OBJECT_HANDLE /*hEncryptionKey*/, CK_OBJECT_HANDLE /*hAuthenticationKey*/)
1432 {
1433 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1434 
1435 	// Get the session
1436 	Session* session = (Session*)handleManager->getSession(hSession);
1437 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1438 
1439 	return CKR_FUNCTION_NOT_SUPPORTED;
1440 }
1441 
1442 // Login on the token in the specified session
C_Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1443 CK_RV SoftHSM::C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
1444 {
1445 	CK_RV rv = CKR_OK;
1446 
1447 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1448 
1449 	// Get the session
1450 	Session* session = (Session*)handleManager->getSession(hSession);
1451 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1452 
1453 	// Get the PIN
1454 	if (pPin == NULL_PTR) return CKR_ARGUMENTS_BAD;
1455 	ByteString pin(pPin, ulPinLen);
1456 
1457 	// Get the token
1458 	Token* token = session->getToken();
1459 	if (token == NULL) return CKR_GENERAL_ERROR;
1460 
1461 	switch (userType)
1462 	{
1463 		case CKU_SO:
1464 			// There cannot exist a R/O session on this slot
1465 			if (sessionManager->haveROSession(session->getSlot()->getSlotID())) return CKR_SESSION_READ_ONLY_EXISTS;
1466 
1467 			// Login
1468 			rv = token->loginSO(pin);
1469 			break;
1470 		case CKU_USER:
1471 			// Login
1472 			rv = token->loginUser(pin);
1473 			break;
1474 		case CKU_CONTEXT_SPECIFIC:
1475 			// Check if re-authentication is required
1476 			if (!session->getReAuthentication()) return CKR_OPERATION_NOT_INITIALIZED;
1477 
1478 			// Re-authenticate
1479 			rv = token->reAuthenticate(pin);
1480 			if (rv == CKR_OK) session->setReAuthentication(false);
1481 			break;
1482 		default:
1483 			return CKR_USER_TYPE_INVALID;
1484 	}
1485 
1486 	return rv;
1487 }
1488 
1489 // Log out of the token in the specified session
C_Logout(CK_SESSION_HANDLE hSession)1490 CK_RV SoftHSM::C_Logout(CK_SESSION_HANDLE hSession)
1491 {
1492 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1493 
1494 	// Get the session
1495 	Session* session = (Session*)handleManager->getSession(hSession);
1496 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1497 
1498 	// Get the token
1499 	Token* token = session->getToken();
1500 	if (token == NULL) return CKR_GENERAL_ERROR;
1501 
1502 	// Logout
1503 	token->logout();
1504 
1505 	// [PKCS#11 v2.40, C_Logout] When logout is successful...
1506 	// a. Any of the application's handles to private objects become invalid.
1507 	// b. Even if a user is later logged back into the token those handles remain invalid.
1508 	// c. All private session objects from sessions belonging to the application are destroyed.
1509 
1510 	// Have the handle manager remove all handles pointing to private objects for this slot.
1511 	CK_SLOT_ID slotID = session->getSlot()->getSlotID();
1512 	handleManager->tokenLoggedOut(slotID);
1513 	sessionObjectStore->tokenLoggedOut(slotID);
1514 
1515 	return CKR_OK;
1516 }
1517 
1518 // Create a new object on the token in the specified session using the given attribute template
C_CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)1519 CK_RV SoftHSM::C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
1520 {
1521 	return this->CreateObject(hSession,pTemplate,ulCount,phObject,OBJECT_OP_CREATE);
1522 }
1523 
1524 // Create a copy of the object with the specified handle
C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)1525 CK_RV SoftHSM::C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject)
1526 {
1527 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1528 
1529 	if (pTemplate == NULL_PTR) return CKR_ARGUMENTS_BAD;
1530 	if (phNewObject == NULL_PTR) return CKR_ARGUMENTS_BAD;
1531 	*phNewObject = CK_INVALID_HANDLE;
1532 
1533 	// Get the session
1534 	Session* session = (Session*)handleManager->getSession(hSession);
1535 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1536 
1537 	// Get the slot
1538 	Slot* slot = session->getSlot();
1539 	if (slot == NULL_PTR) return CKR_GENERAL_ERROR;
1540 
1541 	// Get the token
1542 	Token* token = session->getToken();
1543 	if (token == NULL_PTR) return CKR_GENERAL_ERROR;
1544 
1545 	// Check the object handle.
1546 	OSObject *object = (OSObject *)handleManager->getObject(hObject);
1547 	if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1548 
1549 	CK_BBOOL wasOnToken = object->getBooleanValue(CKA_TOKEN, false);
1550 	CK_BBOOL wasPrivate = object->getBooleanValue(CKA_PRIVATE, true);
1551 
1552 	// Check read user credentials
1553 	CK_RV rv = haveRead(session->getState(), wasOnToken, wasPrivate);
1554 	if (rv != CKR_OK)
1555 	{
1556 		if (rv == CKR_USER_NOT_LOGGED_IN)
1557 			INFO_MSG("User is not authorized");
1558 
1559 		return rv;
1560 	}
1561 
1562 	// Check if the object is copyable
1563 	CK_BBOOL isCopyable = object->getBooleanValue(CKA_COPYABLE, true);
1564 	if (!isCopyable) return CKR_ACTION_PROHIBITED;
1565 
1566 	// Extract critical information from the template
1567 	CK_BBOOL isOnToken = wasOnToken;
1568 	CK_BBOOL isPrivate = wasPrivate;
1569 
1570 	for (CK_ULONG i = 0; i < ulCount; i++)
1571 	{
1572 		if ((pTemplate[i].type == CKA_TOKEN) && (pTemplate[i].ulValueLen == sizeof(CK_BBOOL)))
1573 		{
1574 			isOnToken = *(CK_BBOOL*)pTemplate[i].pValue;
1575 			continue;
1576 		}
1577 		if ((pTemplate[i].type == CKA_PRIVATE) && (pTemplate[i].ulValueLen == sizeof(CK_BBOOL)))
1578 		{
1579 			isPrivate = *(CK_BBOOL*)pTemplate[i].pValue;
1580 			continue;
1581 		}
1582 	}
1583 
1584 	// Check privacy does not downgrade
1585 	if (wasPrivate && !isPrivate) return CKR_TEMPLATE_INCONSISTENT;
1586 
1587 	// Check write user credentials
1588 	rv = haveWrite(session->getState(), isOnToken, isPrivate);
1589 	if (rv != CKR_OK)
1590 	{
1591 		if (rv == CKR_USER_NOT_LOGGED_IN)
1592 			INFO_MSG("User is not authorized");
1593 		if (rv == CKR_SESSION_READ_ONLY)
1594 			INFO_MSG("Session is read-only");
1595 
1596 		return rv;
1597 	}
1598 
1599 	// Create the object in session or on the token
1600 	OSObject *newobject = NULL_PTR;
1601 	if (isOnToken)
1602 	{
1603 		newobject = (OSObject*) token->createObject();
1604 	}
1605 	else
1606 	{
1607 		newobject = sessionObjectStore->createObject(slot->getSlotID(), hSession, isPrivate != CK_FALSE);
1608 	}
1609 	if (newobject == NULL) return CKR_GENERAL_ERROR;
1610 
1611 	// Copy attributes from object class (CKA_CLASS=0 so the first)
1612 	if (!newobject->startTransaction())
1613 	{
1614 		newobject->destroyObject();
1615 		return CKR_FUNCTION_FAILED;
1616 	}
1617 
1618 	CK_ATTRIBUTE_TYPE attrType = CKA_CLASS;
1619 	do
1620 	{
1621 		if (!object->attributeExists(attrType))
1622 		{
1623 			rv = CKR_FUNCTION_FAILED;
1624 			break;
1625 		}
1626 
1627 		OSAttribute attr = object->getAttribute(attrType);
1628 
1629 		// Upgrade privacy has to encrypt byte strings
1630 		if (!wasPrivate && isPrivate &&
1631 		    attr.isByteStringAttribute() &&
1632 		    attr.getByteStringValue().size() != 0)
1633 		{
1634 			ByteString value;
1635 			if (!token->encrypt(attr.getByteStringValue(), value) ||
1636 			    !newobject->setAttribute(attrType, value))
1637 			{
1638 				rv = CKR_FUNCTION_FAILED;
1639 				break;
1640 			}
1641 		}
1642 		else
1643 		{
1644 			if (!newobject->setAttribute(attrType, attr))
1645 			{
1646 				rv = CKR_FUNCTION_FAILED;
1647 				break;
1648 			}
1649 		}
1650 		attrType = object->nextAttributeType(attrType);
1651 	}
1652 	while (attrType != CKA_CLASS);
1653 
1654 	if (rv != CKR_OK)
1655 	{
1656 		newobject->abortTransaction();
1657 	}
1658 	else if (!newobject->commitTransaction())
1659 	{
1660 		rv = CKR_FUNCTION_FAILED;
1661 	}
1662 
1663 	if (rv != CKR_OK)
1664 	{
1665 		newobject->destroyObject();
1666 		return rv;
1667 	}
1668 
1669 	// Get the new P11 object
1670 	P11Object* newp11object = NULL;
1671 	rv = newP11Object(newobject,&newp11object);
1672 	if (rv != CKR_OK)
1673 	{
1674 		newobject->destroyObject();
1675 		return rv;
1676 	}
1677 
1678 	// Apply the template
1679 	rv = newp11object->saveTemplate(token, isPrivate != CK_FALSE, pTemplate, ulCount, OBJECT_OP_COPY);
1680 	delete newp11object;
1681 
1682 	if (rv != CKR_OK)
1683 	{
1684 		newobject->destroyObject();
1685 		return rv;
1686 	}
1687 
1688 	// Set handle
1689 	if (isOnToken)
1690 	{
1691 		*phNewObject = handleManager->addTokenObject(slot->getSlotID(), isPrivate != CK_FALSE, newobject);
1692 	}
1693 	else
1694 	{
1695 		*phNewObject = handleManager->addSessionObject(slot->getSlotID(), hSession, isPrivate != CK_FALSE, newobject);
1696 	}
1697 
1698 	return CKR_OK;
1699 }
1700 
1701 // Destroy the specified object
C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)1702 CK_RV SoftHSM::C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
1703 {
1704 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1705 
1706 	// Get the session
1707 	Session* session = (Session*)handleManager->getSession(hSession);
1708 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1709 
1710 	// Get the token
1711 	Token* token = session->getToken();
1712 	if (token == NULL_PTR) return CKR_GENERAL_ERROR;
1713 
1714 	// Check the object handle.
1715 	OSObject *object = (OSObject *)handleManager->getObject(hObject);
1716 	if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1717 
1718 	CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
1719 	CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
1720 
1721 	// Check user credentials
1722 	CK_RV rv = haveWrite(session->getState(), isOnToken, isPrivate);
1723 	if (rv != CKR_OK)
1724 	{
1725 		if (rv == CKR_USER_NOT_LOGGED_IN)
1726 			INFO_MSG("User is not authorized");
1727 		if (rv == CKR_SESSION_READ_ONLY)
1728 			INFO_MSG("Session is read-only");
1729 
1730 		return rv;
1731 	}
1732 
1733 	// Check if the object is destroyable
1734 	CK_BBOOL isDestroyable = object->getBooleanValue(CKA_DESTROYABLE, true);
1735 	if (!isDestroyable) return CKR_ACTION_PROHIBITED;
1736 
1737 	// Tell the handleManager to forget about the object.
1738 	handleManager->destroyObject(hObject);
1739 
1740 	// Destroy the object
1741 	if (!object->destroyObject())
1742 		return CKR_FUNCTION_FAILED;
1743 
1744 	return CKR_OK;
1745 }
1746 
1747 // Determine the size of the specified object
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)1748 CK_RV SoftHSM::C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize)
1749 {
1750 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1751 
1752 	if (pulSize == NULL) return CKR_ARGUMENTS_BAD;
1753 
1754 	// Get the session
1755 	Session* session = (Session*)handleManager->getSession(hSession);
1756 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1757 
1758 	// Get the token
1759 	Token* token = session->getToken();
1760 	if (token == NULL_PTR) return CKR_GENERAL_ERROR;
1761 
1762 	// Check the object handle.
1763 	OSObject *object = (OSObject *)handleManager->getObject(hObject);
1764 	if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1765 
1766 	*pulSize = CK_UNAVAILABLE_INFORMATION;
1767 
1768 	return CKR_OK;
1769 }
1770 
1771 // Retrieve the specified attributes for the given object
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1772 CK_RV SoftHSM::C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
1773 {
1774 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1775 
1776 	if (pTemplate == NULL) return CKR_ARGUMENTS_BAD;
1777 
1778 	// Get the session
1779 	Session* session = (Session*)handleManager->getSession(hSession);
1780 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1781 
1782 	// Get the token
1783 	Token* token = session->getToken();
1784 	if (token == NULL) return CKR_GENERAL_ERROR;
1785 
1786 	// Check the object handle.
1787 	OSObject *object = (OSObject *)handleManager->getObject(hObject);
1788 	if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1789 
1790 	CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
1791 	CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
1792 
1793 	// Check read user credentials
1794 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
1795 	if (rv != CKR_OK)
1796 	{
1797 		if (rv == CKR_USER_NOT_LOGGED_IN)
1798 			INFO_MSG("User is not authorized");
1799 
1800 		// CKR_USER_NOT_LOGGED_IN is not a valid return code for this function,
1801 		// so we use CKR_GENERAL_ERROR.
1802 		return CKR_GENERAL_ERROR;
1803 	}
1804 
1805 	// Wrap a P11Object around the OSObject so we can access the attributes in the
1806 	// context of the object in which it is defined.
1807 	P11Object* p11object = NULL;
1808 	rv = newP11Object(object,&p11object);
1809 	if (rv != CKR_OK)
1810 		return rv;
1811 
1812 	// Ask the P11Object to fill the template with attribute values.
1813 	rv = p11object->loadTemplate(token, pTemplate,ulCount);
1814 	delete p11object;
1815 	return rv;
1816 }
1817 
1818 // Change or set the value of the specified attributes on the specified object
C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1819 CK_RV SoftHSM::C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
1820 {
1821 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1822 
1823 	if (pTemplate == NULL) return CKR_ARGUMENTS_BAD;
1824 
1825 	// Get the session
1826 	Session* session = (Session*)handleManager->getSession(hSession);
1827 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1828 
1829 	// Get the token
1830 	Token* token = session->getToken();
1831 	if (token == NULL) return CKR_GENERAL_ERROR;
1832 
1833 	// Check the object handle.
1834 	OSObject *object = (OSObject *)handleManager->getObject(hObject);
1835 	if (object == NULL_PTR || !object->isValid()) return CKR_OBJECT_HANDLE_INVALID;
1836 
1837 	CK_BBOOL isOnToken = object->getBooleanValue(CKA_TOKEN, false);
1838 	CK_BBOOL isPrivate = object->getBooleanValue(CKA_PRIVATE, true);
1839 
1840 	// Check user credentials
1841 	CK_RV rv = haveWrite(session->getState(), isOnToken, isPrivate);
1842 	if (rv != CKR_OK)
1843 	{
1844 		if (rv == CKR_USER_NOT_LOGGED_IN)
1845 			INFO_MSG("User is not authorized");
1846 		if (rv == CKR_SESSION_READ_ONLY)
1847 			INFO_MSG("Session is read-only");
1848 
1849 		return rv;
1850 	}
1851 
1852 	// Check if the object is modifiable
1853 	CK_BBOOL isModifiable = object->getBooleanValue(CKA_MODIFIABLE, true);
1854 	if (!isModifiable) return CKR_ACTION_PROHIBITED;
1855 
1856 	// Wrap a P11Object around the OSObject so we can access the attributes in the
1857 	// context of the object in which it is defined.
1858 	P11Object* p11object = NULL;
1859 	rv = newP11Object(object,&p11object);
1860 	if (rv != CKR_OK)
1861 		return rv;
1862 
1863 	// Ask the P11Object to save the template with attribute values.
1864 	rv = p11object->saveTemplate(token, isPrivate != CK_FALSE, pTemplate,ulCount,OBJECT_OP_SET);
1865 	delete p11object;
1866 	return rv;
1867 }
1868 
1869 // Initialise object search in the specified session using the specified attribute template as search parameters
C_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1870 CK_RV SoftHSM::C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
1871 {
1872 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
1873 	if (pTemplate == NULL_PTR && ulCount != 0) return CKR_ARGUMENTS_BAD;
1874 
1875 	// Get the session
1876 	Session* session = (Session*)handleManager->getSession(hSession);
1877 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
1878 
1879 	// Get the slot
1880 	Slot* slot = session->getSlot();
1881 	if (slot == NULL_PTR) return CKR_GENERAL_ERROR;
1882 
1883 	// Determine whether we have a public session or not.
1884 	bool isPublicSession;
1885 	switch (session->getState()) {
1886 		case CKS_RO_USER_FUNCTIONS:
1887 		case CKS_RW_USER_FUNCTIONS:
1888 			isPublicSession = false;
1889 			break;
1890 		default:
1891 			isPublicSession = true;
1892 	}
1893 
1894 	// Get the token
1895 	Token* token = session->getToken();
1896 	if (token == NULL_PTR) return CKR_GENERAL_ERROR;
1897 
1898 	// Check if we have another operation
1899 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
1900 
1901 	session->setOpType(SESSION_OP_FIND);
1902 	FindOperation *findOp = FindOperation::create();
1903 
1904 	// Check if we are out of memory
1905 	if (findOp == NULL_PTR) return CKR_HOST_MEMORY;
1906 
1907 	std::set<OSObject*> allObjects;
1908 	token->getObjects(allObjects);
1909 	sessionObjectStore->getObjects(slot->getSlotID(),allObjects);
1910 
1911 	std::set<CK_OBJECT_HANDLE> handles;
1912 	std::set<OSObject*>::iterator it;
1913 	for (it=allObjects.begin(); it != allObjects.end(); ++it)
1914 	{
1915 		// Refresh object and check if it is valid
1916 		if (!(*it)->isValid()) {
1917 			DEBUG_MSG("Object is not valid, skipping");
1918 			continue;
1919 		}
1920 
1921 		// Determine if the object has CKA_PRIVATE set to CK_TRUE
1922 		bool isPrivateObject = (*it)->getBooleanValue(CKA_PRIVATE, true);
1923 
1924 		// If the object is private, and we are in a public session then skip it !
1925 		if (isPublicSession && isPrivateObject)
1926 			continue; // skip object
1927 
1928 		// Perform the actual attribute matching.
1929 		bool bAttrMatch = true; // We let an empty template match everything.
1930 		for (CK_ULONG i=0; i<ulCount; ++i)
1931 		{
1932 			bAttrMatch = false;
1933 
1934 			if (!(*it)->attributeExists(pTemplate[i].type))
1935 				break;
1936 
1937 			OSAttribute attr = (*it)->getAttribute(pTemplate[i].type);
1938 
1939 			if (attr.isBooleanAttribute())
1940 			{
1941 				if (sizeof(CK_BBOOL) != pTemplate[i].ulValueLen)
1942 					break;
1943 				bool bTemplateValue = (*(CK_BBOOL*)pTemplate[i].pValue == CK_TRUE);
1944 				if (attr.getBooleanValue() != bTemplateValue)
1945 					break;
1946 			}
1947 			else
1948 			{
1949 				if (attr.isUnsignedLongAttribute())
1950 				{
1951 					if (sizeof(CK_ULONG) != pTemplate[i].ulValueLen)
1952 						break;
1953 					CK_ULONG ulTemplateValue = *(CK_ULONG_PTR)pTemplate[i].pValue;
1954 					if (attr.getUnsignedLongValue() != ulTemplateValue)
1955 						break;
1956 				}
1957 				else
1958 				{
1959 					if (attr.isByteStringAttribute())
1960 					{
1961 						ByteString bsAttrValue;
1962 						if (isPrivateObject && attr.getByteStringValue().size() != 0)
1963 						{
1964 							if (!token->decrypt(attr.getByteStringValue(), bsAttrValue))
1965 							{
1966 								delete findOp;
1967 								return CKR_GENERAL_ERROR;
1968 							}
1969 						}
1970 						else
1971 							bsAttrValue = attr.getByteStringValue();
1972 
1973 						if (bsAttrValue.size() != pTemplate[i].ulValueLen)
1974 							break;
1975 						if (pTemplate[i].ulValueLen != 0)
1976 						{
1977 							ByteString bsTemplateValue((const unsigned char*)pTemplate[i].pValue, pTemplate[i].ulValueLen);
1978 							if (bsAttrValue != bsTemplateValue)
1979 								break;
1980 						}
1981 					}
1982 					else
1983 						break;
1984 				}
1985 			}
1986 			// The attribute matched !
1987 			bAttrMatch = true;
1988 		}
1989 
1990 		if (bAttrMatch)
1991 		{
1992 			CK_SLOT_ID slotID = slot->getSlotID();
1993 			bool isOnToken = (*it)->getBooleanValue(CKA_TOKEN, false);
1994 			bool isPrivate = (*it)->getBooleanValue(CKA_PRIVATE, true);
1995 			// Create an object handle for every returned object.
1996 			CK_OBJECT_HANDLE hObject;
1997 			if (isOnToken)
1998 				hObject = handleManager->addTokenObject(slotID,isPrivate,*it);
1999 			else
2000 				hObject = handleManager->addSessionObject(slotID,hSession,isPrivate,*it);
2001 			if (hObject == CK_INVALID_HANDLE)
2002 			{
2003 				delete findOp;
2004 				return CKR_GENERAL_ERROR;
2005 			}
2006 			handles.insert(hObject);
2007 		}
2008 	}
2009 
2010 	// Storing the object handles for the find will protect the library
2011 	// whenever a stale object handle is used to access the library.
2012 	findOp->setHandles(handles);
2013 
2014 	session->setFindOp(findOp);
2015 
2016 	return CKR_OK;
2017 }
2018 
2019 // Continue the search for objects in the specified session
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)2020 CK_RV SoftHSM::C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
2021 {
2022 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2023 	if (phObject == NULL_PTR) return CKR_ARGUMENTS_BAD;
2024 	if (pulObjectCount == NULL_PTR) return CKR_ARGUMENTS_BAD;
2025 
2026 	// Get the session
2027 	Session* session = (Session*)handleManager->getSession(hSession);
2028 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2029 
2030 	// Check if we are doing the correct operation
2031 	if (session->getOpType() != SESSION_OP_FIND) return CKR_OPERATION_NOT_INITIALIZED;
2032 
2033 	// return the object handles that have been added to the find operation.
2034 	FindOperation *findOp = session->getFindOp();
2035 	if (findOp == NULL) return CKR_GENERAL_ERROR;
2036 
2037 	// Ask the find operation to retrieve the object handles
2038 	*pulObjectCount = findOp->retrieveHandles(phObject,ulMaxObjectCount);
2039 
2040 	// Erase the object handles from the find operation.
2041 	findOp->eraseHandles(0,*pulObjectCount);
2042 
2043 	return CKR_OK;
2044 }
2045 
2046 // Finish searching for objects
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)2047 CK_RV SoftHSM::C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
2048 {
2049 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2050 
2051 	// Get the session
2052 	Session* session = (Session*)handleManager->getSession(hSession);
2053 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2054 
2055 	// Check if we are doing the correct operation
2056 	if (session->getOpType() != SESSION_OP_FIND) return CKR_OPERATION_NOT_INITIALIZED;
2057 
2058 	session->resetOp();
2059 	return CKR_OK;
2060 }
2061 
2062 // Encrypt*/Decrypt*() is for Symmetrical ciphers too
isSymMechanism(CK_MECHANISM_PTR pMechanism)2063 static bool isSymMechanism(CK_MECHANISM_PTR pMechanism)
2064 {
2065 	if (pMechanism == NULL_PTR) return false;
2066 
2067 	switch(pMechanism->mechanism) {
2068 		case CKM_DES_ECB:
2069 		case CKM_DES_CBC:
2070 		case CKM_DES_CBC_PAD:
2071 		case CKM_DES3_ECB:
2072 		case CKM_DES3_CBC:
2073 		case CKM_DES3_CBC_PAD:
2074 		case CKM_AES_ECB:
2075 		case CKM_AES_CBC:
2076 		case CKM_AES_CBC_PAD:
2077 		case CKM_AES_CTR:
2078 		case CKM_AES_GCM:
2079 			return true;
2080 		default:
2081 			return false;
2082 	}
2083 }
2084 
2085 // SymAlgorithm version of C_EncryptInit
SymEncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2086 CK_RV SoftHSM::SymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2087 {
2088 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2089 
2090 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
2091 
2092 	// Get the session
2093 	Session* session = (Session*)handleManager->getSession(hSession);
2094 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2095 
2096 	// Check if we have another operation
2097 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
2098 
2099 	// Get the token
2100 	Token* token = session->getToken();
2101 	if (token == NULL) return CKR_GENERAL_ERROR;
2102 
2103 	// Check the key handle.
2104 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
2105 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2106 
2107 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
2108 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
2109 
2110 	// Check read user credentials
2111 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
2112 	if (rv != CKR_OK)
2113 	{
2114 		if (rv == CKR_USER_NOT_LOGGED_IN)
2115 			INFO_MSG("User is not authorized");
2116 
2117 		return rv;
2118 	}
2119 
2120 	// Check if key can be used for encryption
2121 	if (!key->getBooleanValue(CKA_ENCRYPT, false))
2122 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
2123 
2124 	// Check if the specified mechanism is allowed for the key
2125 	if (!isMechanismPermitted(key, pMechanism))
2126 		return CKR_MECHANISM_INVALID;
2127 
2128 	// Get key info
2129 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
2130 
2131 	// Get the symmetric algorithm matching the mechanism
2132 	SymAlgo::Type algo = SymAlgo::Unknown;
2133 	SymMode::Type mode = SymMode::Unknown;
2134 	bool padding = false;
2135 	ByteString iv;
2136 	size_t bb = 8;
2137 	size_t counterBits = 0;
2138 	ByteString aad;
2139 	size_t tagBytes = 0;
2140 	switch(pMechanism->mechanism) {
2141 #ifndef WITH_FIPS
2142 		case CKM_DES_ECB:
2143 			if (keyType != CKK_DES)
2144 				return CKR_KEY_TYPE_INCONSISTENT;
2145 			algo = SymAlgo::DES;
2146 			mode = SymMode::ECB;
2147 			bb = 7;
2148 			break;
2149 		case CKM_DES_CBC:
2150 			if (keyType != CKK_DES)
2151 				return CKR_KEY_TYPE_INCONSISTENT;
2152 			algo = SymAlgo::DES;
2153 			mode = SymMode::CBC;
2154 			if (pMechanism->pParameter == NULL_PTR ||
2155 			    pMechanism->ulParameterLen == 0)
2156 			{
2157 				DEBUG_MSG("CBC mode requires an init vector");
2158 				return CKR_ARGUMENTS_BAD;
2159 			}
2160 			iv.resize(pMechanism->ulParameterLen);
2161 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2162 			bb = 7;
2163 			break;
2164 		case CKM_DES_CBC_PAD:
2165 			if (keyType != CKK_DES)
2166 				return CKR_KEY_TYPE_INCONSISTENT;
2167 			algo = SymAlgo::DES;
2168 			mode = SymMode::CBC;
2169 			padding = true;
2170 			if (pMechanism->pParameter == NULL_PTR ||
2171 			    pMechanism->ulParameterLen == 0)
2172 			{
2173 				DEBUG_MSG("CBC mode requires an init vector");
2174 				return CKR_ARGUMENTS_BAD;
2175 			}
2176 			iv.resize(pMechanism->ulParameterLen);
2177 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2178 			bb = 7;
2179 			break;
2180 #endif
2181 		case CKM_DES3_ECB:
2182 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2183 				return CKR_KEY_TYPE_INCONSISTENT;
2184 			algo = SymAlgo::DES3;
2185 			mode = SymMode::ECB;
2186 			bb = 7;
2187 			break;
2188 		case CKM_DES3_CBC:
2189 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2190 				return CKR_KEY_TYPE_INCONSISTENT;
2191 			algo = SymAlgo::DES3;
2192 			mode = SymMode::CBC;
2193 			if (pMechanism->pParameter == NULL_PTR ||
2194 			    pMechanism->ulParameterLen == 0)
2195 			{
2196 				DEBUG_MSG("CBC mode requires an init vector");
2197 				return CKR_ARGUMENTS_BAD;
2198 			}
2199 			iv.resize(pMechanism->ulParameterLen);
2200 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2201 			bb = 7;
2202 			break;
2203 		case CKM_DES3_CBC_PAD:
2204 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2205 				return CKR_KEY_TYPE_INCONSISTENT;
2206 			algo = SymAlgo::DES3;
2207 			mode = SymMode::CBC;
2208 			padding = true;
2209 			if (pMechanism->pParameter == NULL_PTR ||
2210 			    pMechanism->ulParameterLen == 0)
2211 			{
2212 				DEBUG_MSG("CBC mode requires an init vector");
2213 				return CKR_ARGUMENTS_BAD;
2214 			}
2215 			iv.resize(pMechanism->ulParameterLen);
2216 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2217 			bb = 7;
2218 			break;
2219 		case CKM_AES_ECB:
2220 			if (keyType != CKK_AES)
2221 				return CKR_KEY_TYPE_INCONSISTENT;
2222 			algo = SymAlgo::AES;
2223 			mode = SymMode::ECB;
2224 			break;
2225 		case CKM_AES_CBC:
2226 			if (keyType != CKK_AES)
2227 				return CKR_KEY_TYPE_INCONSISTENT;
2228 			algo = SymAlgo::AES;
2229 			mode = SymMode::CBC;
2230 			if (pMechanism->pParameter == NULL_PTR ||
2231 			    pMechanism->ulParameterLen == 0)
2232 			{
2233 				DEBUG_MSG("CBC mode requires an init vector");
2234 				return CKR_ARGUMENTS_BAD;
2235 			}
2236 			iv.resize(pMechanism->ulParameterLen);
2237 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2238 			break;
2239 		case CKM_AES_CBC_PAD:
2240 			if (keyType != CKK_AES)
2241 				return CKR_KEY_TYPE_INCONSISTENT;
2242 			algo = SymAlgo::AES;
2243 			mode = SymMode::CBC;
2244 			padding = true;
2245 			if (pMechanism->pParameter == NULL_PTR ||
2246 			    pMechanism->ulParameterLen == 0)
2247 			{
2248 				DEBUG_MSG("CBC mode requires an init vector");
2249 				return CKR_ARGUMENTS_BAD;
2250 			}
2251 			iv.resize(pMechanism->ulParameterLen);
2252 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2253 			break;
2254 		case CKM_AES_CTR:
2255 			if (keyType != CKK_AES)
2256 				return CKR_KEY_TYPE_INCONSISTENT;
2257 			algo = SymAlgo::AES;
2258 			mode = SymMode::CTR;
2259 			if (pMechanism->pParameter == NULL_PTR ||
2260 			    pMechanism->ulParameterLen != sizeof(CK_AES_CTR_PARAMS))
2261 			{
2262 				DEBUG_MSG("CTR mode requires a counter block");
2263 				return CKR_ARGUMENTS_BAD;
2264 			}
2265 			counterBits = CK_AES_CTR_PARAMS_PTR(pMechanism->pParameter)->ulCounterBits;
2266 			if (counterBits == 0 || counterBits > 128)
2267 			{
2268 				DEBUG_MSG("Invalid ulCounterBits");
2269 				return CKR_MECHANISM_PARAM_INVALID;
2270 			}
2271 			iv.resize(16);
2272 			memcpy(&iv[0], CK_AES_CTR_PARAMS_PTR(pMechanism->pParameter)->cb, 16);
2273 			break;
2274 		case CKM_AES_GCM:
2275 			if (keyType != CKK_AES)
2276 				return CKR_KEY_TYPE_INCONSISTENT;
2277 			algo = SymAlgo::AES;
2278 			mode = SymMode::GCM;
2279 			if (pMechanism->pParameter == NULL_PTR ||
2280 			    pMechanism->ulParameterLen != sizeof(CK_GCM_PARAMS))
2281 			{
2282 				DEBUG_MSG("GCM mode requires parameters");
2283 				return CKR_ARGUMENTS_BAD;
2284 			}
2285 			iv.resize(CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulIvLen);
2286 			memcpy(&iv[0], CK_GCM_PARAMS_PTR(pMechanism->pParameter)->pIv, CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulIvLen);
2287 			aad.resize(CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulAADLen);
2288 			memcpy(&aad[0], CK_GCM_PARAMS_PTR(pMechanism->pParameter)->pAAD, CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulAADLen);
2289 			tagBytes = CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulTagBits;
2290 			if (tagBytes > 128 || tagBytes % 8 != 0)
2291 			{
2292 				DEBUG_MSG("Invalid ulTagBits value");
2293 				return CKR_ARGUMENTS_BAD;
2294 			}
2295 			tagBytes = tagBytes / 8;
2296 			break;
2297 		default:
2298 			return CKR_MECHANISM_INVALID;
2299 	}
2300 	SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
2301 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
2302 
2303 	SymmetricKey* secretkey = new SymmetricKey();
2304 
2305 	if (getSymmetricKey(secretkey, token, key) != CKR_OK)
2306 	{
2307 		cipher->recycleKey(secretkey);
2308 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
2309 		return CKR_GENERAL_ERROR;
2310 	}
2311 
2312 	// adjust key bit length
2313 	secretkey->setBitLen(secretkey->getKeyBits().size() * bb);
2314 
2315 	// Initialize encryption
2316 	if (!cipher->encryptInit(secretkey, mode, iv, padding, counterBits, aad, tagBytes))
2317 	{
2318 		cipher->recycleKey(secretkey);
2319 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
2320 		return CKR_MECHANISM_INVALID;
2321 	}
2322 
2323 	session->setOpType(SESSION_OP_ENCRYPT);
2324 	session->setSymmetricCryptoOp(cipher);
2325 	session->setAllowMultiPartOp(true);
2326 	session->setAllowSinglePartOp(true);
2327 	session->setSymmetricKey(secretkey);
2328 
2329 	return CKR_OK;
2330 }
2331 
2332 // AsymAlgorithm version of C_EncryptInit
AsymEncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2333 CK_RV SoftHSM::AsymEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2334 {
2335 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2336 
2337 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
2338 
2339 	// Get the session
2340 	Session* session = (Session*)handleManager->getSession(hSession);
2341 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2342 
2343 	// Check if we have another operation
2344 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
2345 
2346 	// Get the token
2347 	Token* token = session->getToken();
2348 	if (token == NULL) return CKR_GENERAL_ERROR;
2349 
2350 	// Check the key handle.
2351 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
2352 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2353 
2354 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
2355 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
2356 
2357 	// Check read user credentials
2358 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
2359 	if (rv != CKR_OK)
2360 	{
2361 		if (rv == CKR_USER_NOT_LOGGED_IN)
2362 			INFO_MSG("User is not authorized");
2363 
2364 		return rv;
2365 	}
2366 
2367 	// Check if key can be used for encryption
2368 	if (!key->getBooleanValue(CKA_ENCRYPT, false))
2369 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
2370 
2371 	// Get key info
2372 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
2373 
2374 	// Get the asymmetric algorithm matching the mechanism
2375 	AsymMech::Type mechanism;
2376 	bool isRSA = false;
2377 	switch(pMechanism->mechanism) {
2378 		case CKM_RSA_PKCS:
2379 			if (keyType != CKK_RSA)
2380 				return CKR_KEY_TYPE_INCONSISTENT;
2381 			mechanism = AsymMech::RSA_PKCS;
2382 			isRSA = true;
2383 			break;
2384 		case CKM_RSA_X_509:
2385 			if (keyType != CKK_RSA)
2386 				return CKR_KEY_TYPE_INCONSISTENT;
2387 			mechanism = AsymMech::RSA;
2388 			isRSA = true;
2389 			break;
2390 		case CKM_RSA_PKCS_OAEP:
2391 			if (keyType != CKK_RSA)
2392 				return CKR_KEY_TYPE_INCONSISTENT;
2393 			rv = MechParamCheckRSAPKCSOAEP(pMechanism);
2394 			if (rv != CKR_OK)
2395 				return rv;
2396 
2397 			mechanism = AsymMech::RSA_PKCS_OAEP;
2398 			isRSA = true;
2399 			break;
2400 		default:
2401 			return CKR_MECHANISM_INVALID;
2402 	}
2403 
2404 	AsymmetricAlgorithm* asymCrypto = NULL;
2405 	PublicKey* publicKey = NULL;
2406 	if (isRSA)
2407 	{
2408 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
2409 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
2410 
2411 		publicKey = asymCrypto->newPublicKey();
2412 		if (publicKey == NULL)
2413 		{
2414 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
2415 			return CKR_HOST_MEMORY;
2416 		}
2417 
2418 		if (getRSAPublicKey((RSAPublicKey*)publicKey, token, key) != CKR_OK)
2419 		{
2420 			asymCrypto->recyclePublicKey(publicKey);
2421 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
2422 			return CKR_GENERAL_ERROR;
2423 		}
2424 	}
2425 	else
2426 	{
2427 		return CKR_MECHANISM_INVALID;
2428         }
2429 
2430 	session->setOpType(SESSION_OP_ENCRYPT);
2431 	session->setAsymmetricCryptoOp(asymCrypto);
2432 	session->setMechanism(mechanism);
2433 	session->setAllowMultiPartOp(false);
2434 	session->setAllowSinglePartOp(true);
2435 	session->setPublicKey(publicKey);
2436 
2437 	return CKR_OK;
2438 }
2439 
2440 // Initialise encryption using the specified object and mechanism
C_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2441 CK_RV SoftHSM::C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2442 {
2443 	if (isSymMechanism(pMechanism))
2444 		return SymEncryptInit(hSession, pMechanism, hKey);
2445 	else
2446 		return AsymEncryptInit(hSession, pMechanism, hKey);
2447 }
2448 
2449 // SymAlgorithm version of C_Encrypt
SymEncrypt(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2450 static CK_RV SymEncrypt(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2451 {
2452 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
2453 	if (cipher == NULL || !session->getAllowSinglePartOp())
2454 	{
2455 		session->resetOp();
2456 		return CKR_OPERATION_NOT_INITIALIZED;
2457 	}
2458 
2459 	// Check data size
2460 	CK_ULONG maxSize = ulDataLen + cipher->getTagBytes();
2461 	if (cipher->isBlockCipher())
2462 	{
2463 		CK_ULONG remainder = ulDataLen % cipher->getBlockSize();
2464 		if (cipher->getPaddingMode() == false && remainder != 0)
2465 		{
2466 			session->resetOp();
2467 			return CKR_DATA_LEN_RANGE;
2468 		}
2469 
2470 		// Round up to block size
2471 		if (remainder != 0)
2472 		{
2473 			maxSize = ulDataLen + cipher->getBlockSize() - remainder;
2474 		}
2475 		else if (cipher->getPaddingMode() == true)
2476 		{
2477 			maxSize = ulDataLen + cipher->getBlockSize();
2478 		}
2479 	}
2480 	if (!cipher->checkMaximumBytes(ulDataLen))
2481 	{
2482 		session->resetOp();
2483 		return CKR_DATA_LEN_RANGE;
2484 	}
2485 
2486 	if (pEncryptedData == NULL_PTR)
2487 	{
2488 		*pulEncryptedDataLen = maxSize;
2489 		return CKR_OK;
2490 	}
2491 
2492 	// Check buffer size
2493 	if (*pulEncryptedDataLen < maxSize)
2494 	{
2495 		*pulEncryptedDataLen = maxSize;
2496 		return CKR_BUFFER_TOO_SMALL;
2497 	}
2498 
2499 	// Get the data
2500 	ByteString data(pData, ulDataLen);
2501 	ByteString encryptedData;
2502 
2503 	// Encrypt the data
2504 	if (!cipher->encryptUpdate(data, encryptedData))
2505 	{
2506 		session->resetOp();
2507 		return CKR_GENERAL_ERROR;
2508 	}
2509 
2510 	// Finalize encryption
2511 	ByteString encryptedFinal;
2512 	if (!cipher->encryptFinal(encryptedFinal))
2513 	{
2514 		session->resetOp();
2515 		return CKR_GENERAL_ERROR;
2516 	}
2517 	encryptedData += encryptedFinal;
2518 	encryptedData.resize(maxSize);
2519 
2520 	memcpy(pEncryptedData, encryptedData.byte_str(), encryptedData.size());
2521 	*pulEncryptedDataLen = encryptedData.size();
2522 
2523 	session->resetOp();
2524 	return CKR_OK;
2525 }
2526 
2527 // AsymAlgorithm version of C_Encrypt
AsymEncrypt(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2528 static CK_RV AsymEncrypt(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2529 {
2530 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
2531 	AsymMech::Type mechanism = session->getMechanism();
2532 	PublicKey* publicKey = session->getPublicKey();
2533 	if (asymCrypto == NULL || !session->getAllowSinglePartOp() || publicKey == NULL)
2534 	{
2535 		session->resetOp();
2536 		return CKR_OPERATION_NOT_INITIALIZED;
2537 	}
2538 
2539 	// Size of the encrypted data
2540 	CK_ULONG size = publicKey->getOutputLength();
2541 
2542 	if (pEncryptedData == NULL_PTR)
2543 	{
2544 		*pulEncryptedDataLen = size;
2545 		return CKR_OK;
2546 	}
2547 
2548 	// Check buffer size
2549 	if (*pulEncryptedDataLen < size)
2550 	{
2551 		*pulEncryptedDataLen = size;
2552 		return CKR_BUFFER_TOO_SMALL;
2553 	}
2554 
2555 	// Get the data
2556 	ByteString data;
2557 	ByteString encryptedData;
2558 
2559 	// We must allow input length <= k and therfore need to prepend the data with zeroes.
2560 	if (mechanism == AsymMech::RSA) {
2561 		data.wipe(size-ulDataLen);
2562 	}
2563 
2564 	data += ByteString(pData, ulDataLen);
2565 
2566 	// Encrypt the data
2567 	if (!asymCrypto->encrypt(publicKey,data,encryptedData,mechanism))
2568 	{
2569 		session->resetOp();
2570 		return CKR_GENERAL_ERROR;
2571 	}
2572 
2573 	// Check size
2574 	if (encryptedData.size() != size)
2575 	{
2576 		ERROR_MSG("The size of the encrypted data differs from the size of the mechanism");
2577 		session->resetOp();
2578 		return CKR_GENERAL_ERROR;
2579 	}
2580 	memcpy(pEncryptedData, encryptedData.byte_str(), size);
2581 	*pulEncryptedDataLen = size;
2582 
2583 	session->resetOp();
2584 	return CKR_OK;
2585 }
2586 
2587 // Perform a single operation encryption operation in the specified session
C_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2588 CK_RV SoftHSM::C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2589 {
2590 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2591 
2592 	if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
2593 	if (pulEncryptedDataLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
2594 
2595 	// Get the session
2596 	Session* session = (Session*)handleManager->getSession(hSession);
2597 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2598 
2599 	// Check if we are doing the correct operation
2600 	if (session->getOpType() != SESSION_OP_ENCRYPT)
2601 		return CKR_OPERATION_NOT_INITIALIZED;
2602 
2603 	if (session->getSymmetricCryptoOp() != NULL)
2604 		return SymEncrypt(session, pData, ulDataLen,
2605 				  pEncryptedData, pulEncryptedDataLen);
2606 	else
2607 		return AsymEncrypt(session, pData, ulDataLen,
2608 				   pEncryptedData, pulEncryptedDataLen);
2609 }
2610 
2611 // SymAlgorithm version of C_EncryptUpdate
SymEncryptUpdate(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2612 static CK_RV SymEncryptUpdate(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2613 {
2614 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
2615 	if (cipher == NULL || !session->getAllowMultiPartOp())
2616 	{
2617 		session->resetOp();
2618 		return CKR_OPERATION_NOT_INITIALIZED;
2619 	}
2620 
2621 	// Check data size
2622 	size_t blockSize = cipher->getBlockSize();
2623 	size_t remainingSize = cipher->getBufferSize();
2624 	CK_ULONG maxSize = ulDataLen + remainingSize;
2625 	if (cipher->isBlockCipher())
2626 	{
2627 		int nrOfBlocks = (ulDataLen + remainingSize) / blockSize;
2628 		maxSize = nrOfBlocks * blockSize;
2629 	}
2630 	if (!cipher->checkMaximumBytes(ulDataLen))
2631 	{
2632 		session->resetOp();
2633 		return CKR_DATA_LEN_RANGE;
2634 	}
2635 
2636 	// Check data size
2637 	if (pEncryptedData == NULL_PTR)
2638 	{
2639 		*pulEncryptedDataLen = maxSize;
2640 		return CKR_OK;
2641 	}
2642 
2643 	// Check output buffer size
2644 	if (*pulEncryptedDataLen < maxSize)
2645 	{
2646 		DEBUG_MSG("ulDataLen: %#5x  output buffer size: %#5x  blockSize: %#3x  remainingSize: %#4x  maxSize: %#5x",
2647 			  ulDataLen, *pulEncryptedDataLen, blockSize, remainingSize, maxSize);
2648 		*pulEncryptedDataLen = maxSize;
2649 		return CKR_BUFFER_TOO_SMALL;
2650 	}
2651 
2652 	// Get the data
2653 	ByteString data(pData, ulDataLen);
2654 	ByteString encryptedData;
2655 
2656 	// Encrypt the data
2657 	if (!cipher->encryptUpdate(data, encryptedData))
2658 	{
2659 		session->resetOp();
2660 		return CKR_GENERAL_ERROR;
2661 	}
2662 	DEBUG_MSG("ulDataLen: %#5x  output buffer size: %#5x  blockSize: %#3x  remainingSize: %#4x  maxSize: %#5x  encryptedData.size(): %#5x",
2663 		  ulDataLen, *pulEncryptedDataLen, blockSize, remainingSize, maxSize, encryptedData.size());
2664 
2665 	// Check output size from crypto. Unrecoverable error if to large.
2666 	if (*pulEncryptedDataLen < encryptedData.size())
2667 	{
2668 		session->resetOp();
2669 		ERROR_MSG("EncryptUpdate returning too much data. Length of output data buffer is %i but %i bytes was returned by the encrypt.",
2670 			  *pulEncryptedDataLen, encryptedData.size());
2671 		return CKR_GENERAL_ERROR;
2672 	}
2673 
2674 	if (encryptedData.size() > 0)
2675 	{
2676 		memcpy(pEncryptedData, encryptedData.byte_str(), encryptedData.size());
2677 	}
2678 	*pulEncryptedDataLen = encryptedData.size();
2679 
2680 	return CKR_OK;
2681 }
2682 
2683 // Feed data to the running encryption operation in a session
C_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2684 CK_RV SoftHSM::C_EncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2685 {
2686 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2687 
2688 	if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
2689 	if (pulEncryptedDataLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
2690 
2691 	// Get the session
2692 	Session* session = (Session*)handleManager->getSession(hSession);
2693 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2694 
2695 	// Check if we are doing the correct operation
2696 	if (session->getOpType() != SESSION_OP_ENCRYPT)
2697 		return CKR_OPERATION_NOT_INITIALIZED;
2698 
2699 	if (session->getSymmetricCryptoOp() != NULL)
2700 		return SymEncryptUpdate(session, pData, ulDataLen,
2701 				  pEncryptedData, pulEncryptedDataLen);
2702 	else
2703 		return CKR_FUNCTION_NOT_SUPPORTED;
2704 }
2705 
2706 // SymAlgorithm version of C_EncryptFinal
SymEncryptFinal(Session * session,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2707 static CK_RV SymEncryptFinal(Session* session, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2708 {
2709 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
2710 	if (cipher == NULL || !session->getAllowMultiPartOp())
2711 	{
2712 		session->resetOp();
2713 		return CKR_OPERATION_NOT_INITIALIZED;
2714 	}
2715 
2716 	// Check data size
2717 	size_t remainingSize = cipher->getBufferSize() + cipher->getTagBytes();
2718 	CK_ULONG size = remainingSize;
2719 	if (cipher->isBlockCipher())
2720 	{
2721 		size_t blockSize = cipher->getBlockSize();
2722 		bool isPadding = cipher->getPaddingMode();
2723 		if ((remainingSize % blockSize) != 0 && !isPadding)
2724 		{
2725 			session->resetOp();
2726 			DEBUG_MSG("Remaining buffer size is not an integral of the block size. Block size: %#2x  Remaining size: %#2x",
2727 				  blockSize, remainingSize);
2728 			return CKR_DATA_LEN_RANGE;
2729 		}
2730 		// when padding: an integral of the block size that is longer than the remaining data.
2731 		size = isPadding ? ((remainingSize + blockSize) / blockSize) * blockSize : remainingSize;
2732 	}
2733 
2734 	// Give required output buffer size.
2735 	if (pEncryptedData == NULL_PTR)
2736 	{
2737 		*pulEncryptedDataLen = size;
2738 		return CKR_OK;
2739 	}
2740 
2741 	// Check output buffer size
2742 	if (*pulEncryptedDataLen < size)
2743 	{
2744 		DEBUG_MSG("output buffer size: %#5x  size: %#5x",
2745 			  *pulEncryptedDataLen, size);
2746 		*pulEncryptedDataLen = size;
2747 		return CKR_BUFFER_TOO_SMALL;
2748 	}
2749 
2750 	// Finalize encryption
2751 	ByteString encryptedFinal;
2752 	if (!cipher->encryptFinal(encryptedFinal))
2753 	{
2754 		session->resetOp();
2755 		return CKR_GENERAL_ERROR;
2756 	}
2757 	DEBUG_MSG("output buffer size: %#2x  size: %#2x  encryptedFinal.size(): %#2x",
2758 		  *pulEncryptedDataLen, size, encryptedFinal.size());
2759 
2760 	// Check output size from crypto. Unrecoverable error if to large.
2761 	if (*pulEncryptedDataLen < encryptedFinal.size())
2762 	{
2763 		session->resetOp();
2764 		ERROR_MSG("EncryptFinal returning too much data. Length of output data buffer is %i but %i bytes was returned by the encrypt.",
2765 			  *pulEncryptedDataLen, encryptedFinal.size());
2766 		return CKR_GENERAL_ERROR;
2767 	}
2768 
2769 	if (encryptedFinal.size() > 0)
2770 	{
2771 		memcpy(pEncryptedData, encryptedFinal.byte_str(), encryptedFinal.size());
2772 	}
2773 	*pulEncryptedDataLen = encryptedFinal.size();
2774 
2775 	session->resetOp();
2776 	return CKR_OK;
2777 }
2778 
2779 // Finalise the encryption operation
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)2780 CK_RV SoftHSM::C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
2781 {
2782 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2783 
2784 	// Get the session
2785 	Session* session = (Session*)handleManager->getSession(hSession);
2786 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2787 
2788 	// Github issue #469, check NULL_PTR on pulEncryptedDataLen
2789 	if (pulEncryptedDataLen == NULL)
2790 	{
2791 		session->resetOp();
2792 		return CKR_ARGUMENTS_BAD;
2793 	}
2794 
2795 	// Check if we are doing the correct operation
2796 	if (session->getOpType() != SESSION_OP_ENCRYPT) return CKR_OPERATION_NOT_INITIALIZED;
2797 
2798 	if (session->getSymmetricCryptoOp() != NULL)
2799 		return SymEncryptFinal(session, pEncryptedData, pulEncryptedDataLen);
2800 	else
2801 		return CKR_FUNCTION_NOT_SUPPORTED;
2802 }
2803 
2804 // SymAlgorithm version of C_DecryptInit
SymDecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)2805 CK_RV SoftHSM::SymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
2806 {
2807 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
2808 
2809 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
2810 
2811 	// Get the session
2812 	Session* session = (Session*)handleManager->getSession(hSession);
2813 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
2814 
2815 	// Get the token
2816 	Token* token = session->getToken();
2817 	if (token == NULL) return CKR_GENERAL_ERROR;
2818 
2819 	// Check if we have another operation
2820 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
2821 
2822 	// Check the key handle.
2823 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
2824 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
2825 
2826 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
2827 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
2828 
2829 	// Check read user credentials
2830 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
2831 	if (rv != CKR_OK)
2832 	{
2833 		if (rv == CKR_USER_NOT_LOGGED_IN)
2834 			INFO_MSG("User is not authorized");
2835 
2836 		return rv;
2837 	}
2838 
2839 	// Check if key can be used for decryption
2840 	if (!key->getBooleanValue(CKA_DECRYPT, false))
2841 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
2842 
2843 
2844 	// Check if the specified mechanism is allowed for the key
2845 	if (!isMechanismPermitted(key, pMechanism))
2846 		return CKR_MECHANISM_INVALID;
2847 
2848 	// Get key info
2849 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
2850 
2851 	// Get the symmetric algorithm matching the mechanism
2852 	SymAlgo::Type algo = SymAlgo::Unknown;
2853 	SymMode::Type mode = SymMode::Unknown;
2854 	bool padding = false;
2855 	ByteString iv;
2856 	size_t bb = 8;
2857 	size_t counterBits = 0;
2858 	ByteString aad;
2859 	size_t tagBytes = 0;
2860 	switch(pMechanism->mechanism) {
2861 #ifndef WITH_FIPS
2862 		case CKM_DES_ECB:
2863 			if (keyType != CKK_DES)
2864 				return CKR_KEY_TYPE_INCONSISTENT;
2865 			algo = SymAlgo::DES;
2866 			mode = SymMode::ECB;
2867 			bb = 7;
2868 			break;
2869 		case CKM_DES_CBC:
2870 			if (keyType != CKK_DES)
2871 				return CKR_KEY_TYPE_INCONSISTENT;
2872 			algo = SymAlgo::DES;
2873 			mode = SymMode::CBC;
2874 			if (pMechanism->pParameter == NULL_PTR ||
2875 			    pMechanism->ulParameterLen == 0)
2876 			{
2877 				DEBUG_MSG("CBC mode requires an init vector");
2878 				return CKR_ARGUMENTS_BAD;
2879 			}
2880 			iv.resize(pMechanism->ulParameterLen);
2881 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2882 			bb = 7;
2883 			break;
2884 		case CKM_DES_CBC_PAD:
2885 			if (keyType != CKK_DES)
2886 				return CKR_KEY_TYPE_INCONSISTENT;
2887 			algo = SymAlgo::DES;
2888 			mode = SymMode::CBC;
2889 			padding = true;
2890 			if (pMechanism->pParameter == NULL_PTR ||
2891 			    pMechanism->ulParameterLen == 0)
2892 			{
2893 				DEBUG_MSG("CBC mode requires an init vector");
2894 				return CKR_ARGUMENTS_BAD;
2895 			}
2896 			iv.resize(pMechanism->ulParameterLen);
2897 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2898 			bb = 7;
2899 			break;
2900 #endif
2901 		case CKM_DES3_ECB:
2902 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2903 				return CKR_KEY_TYPE_INCONSISTENT;
2904 			algo = SymAlgo::DES3;
2905 			mode = SymMode::ECB;
2906 			bb = 7;
2907 			break;
2908 		case CKM_DES3_CBC:
2909 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2910 				return CKR_KEY_TYPE_INCONSISTENT;
2911 			algo = SymAlgo::DES3;
2912 			mode = SymMode::CBC;
2913 			if (pMechanism->pParameter == NULL_PTR ||
2914 			    pMechanism->ulParameterLen == 0)
2915 			{
2916 				DEBUG_MSG("CBC mode requires an init vector");
2917 				return CKR_ARGUMENTS_BAD;
2918 			}
2919 			iv.resize(pMechanism->ulParameterLen);
2920 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2921 			bb = 7;
2922 			break;
2923 		case CKM_DES3_CBC_PAD:
2924 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
2925 				return CKR_KEY_TYPE_INCONSISTENT;
2926 			algo = SymAlgo::DES3;
2927 			mode = SymMode::CBC;
2928 			padding = true;
2929 			if (pMechanism->pParameter == NULL_PTR ||
2930 			    pMechanism->ulParameterLen == 0)
2931 			{
2932 				DEBUG_MSG("CBC mode requires an init vector");
2933 				return CKR_ARGUMENTS_BAD;
2934 			}
2935 			iv.resize(pMechanism->ulParameterLen);
2936 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2937 			bb = 7;
2938 			break;
2939 		case CKM_AES_ECB:
2940 			if (keyType != CKK_AES)
2941 				return CKR_KEY_TYPE_INCONSISTENT;
2942 			algo = SymAlgo::AES;
2943 			mode = SymMode::ECB;
2944 			break;
2945 		case CKM_AES_CBC:
2946 			if (keyType != CKK_AES)
2947 				return CKR_KEY_TYPE_INCONSISTENT;
2948 			algo = SymAlgo::AES;
2949 			mode = SymMode::CBC;
2950 			if (pMechanism->pParameter == NULL_PTR ||
2951 			    pMechanism->ulParameterLen == 0)
2952 			{
2953 				DEBUG_MSG("CBC mode requires an init vector");
2954 				return CKR_ARGUMENTS_BAD;
2955 			}
2956 			iv.resize(pMechanism->ulParameterLen);
2957 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2958 			break;
2959 		case CKM_AES_CBC_PAD:
2960 			if (keyType != CKK_AES)
2961 				return CKR_KEY_TYPE_INCONSISTENT;
2962 			algo = SymAlgo::AES;
2963 			mode = SymMode::CBC;
2964 			padding = true;
2965 			if (pMechanism->pParameter == NULL_PTR ||
2966 			    pMechanism->ulParameterLen == 0)
2967 			{
2968 				DEBUG_MSG("CBC mode requires an init vector");
2969 				return CKR_ARGUMENTS_BAD;
2970 			}
2971 			iv.resize(pMechanism->ulParameterLen);
2972 			memcpy(&iv[0], pMechanism->pParameter, pMechanism->ulParameterLen);
2973 			break;
2974 		case CKM_AES_CTR:
2975 			if (keyType != CKK_AES)
2976 				return CKR_KEY_TYPE_INCONSISTENT;
2977 			algo = SymAlgo::AES;
2978 			mode = SymMode::CTR;
2979 			if (pMechanism->pParameter == NULL_PTR ||
2980 			    pMechanism->ulParameterLen != sizeof(CK_AES_CTR_PARAMS))
2981 			{
2982 				DEBUG_MSG("CTR mode requires a counter block");
2983 				return CKR_ARGUMENTS_BAD;
2984 			}
2985 			counterBits = CK_AES_CTR_PARAMS_PTR(pMechanism->pParameter)->ulCounterBits;
2986 			if (counterBits == 0 || counterBits > 128)
2987 			{
2988 				DEBUG_MSG("Invalid ulCounterBits");
2989 				return CKR_MECHANISM_PARAM_INVALID;
2990 			}
2991 			iv.resize(16);
2992 			memcpy(&iv[0], CK_AES_CTR_PARAMS_PTR(pMechanism->pParameter)->cb, 16);
2993 			break;
2994 		case CKM_AES_GCM:
2995 			if (keyType != CKK_AES)
2996 				return CKR_KEY_TYPE_INCONSISTENT;
2997 			algo = SymAlgo::AES;
2998 			mode = SymMode::GCM;
2999 			if (pMechanism->pParameter == NULL_PTR ||
3000 			    pMechanism->ulParameterLen != sizeof(CK_GCM_PARAMS))
3001 			{
3002 				DEBUG_MSG("GCM mode requires parameters");
3003 				return CKR_ARGUMENTS_BAD;
3004 			}
3005 			iv.resize(CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulIvLen);
3006 			memcpy(&iv[0], CK_GCM_PARAMS_PTR(pMechanism->pParameter)->pIv, CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulIvLen);
3007 			aad.resize(CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulAADLen);
3008 			memcpy(&aad[0], CK_GCM_PARAMS_PTR(pMechanism->pParameter)->pAAD, CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulAADLen);
3009 			tagBytes = CK_GCM_PARAMS_PTR(pMechanism->pParameter)->ulTagBits;
3010 			if (tagBytes > 128 || tagBytes % 8 != 0)
3011 			{
3012 				DEBUG_MSG("Invalid ulTagBits value");
3013 				return CKR_ARGUMENTS_BAD;
3014 			}
3015 			tagBytes = tagBytes / 8;
3016 			break;
3017 		default:
3018 			return CKR_MECHANISM_INVALID;
3019 	}
3020 	SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
3021 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
3022 
3023 	SymmetricKey* secretkey = new SymmetricKey();
3024 
3025 	if (getSymmetricKey(secretkey, token, key) != CKR_OK)
3026 	{
3027 		cipher->recycleKey(secretkey);
3028 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
3029 		return CKR_GENERAL_ERROR;
3030 	}
3031 
3032 	// adjust key bit length
3033 	secretkey->setBitLen(secretkey->getKeyBits().size() * bb);
3034 
3035 	// Initialize decryption
3036 	if (!cipher->decryptInit(secretkey, mode, iv, padding, counterBits, aad, tagBytes))
3037 	{
3038 		cipher->recycleKey(secretkey);
3039 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
3040 		return CKR_MECHANISM_INVALID;
3041 	}
3042 
3043 	session->setOpType(SESSION_OP_DECRYPT);
3044 	session->setSymmetricCryptoOp(cipher);
3045 	session->setAllowMultiPartOp(true);
3046 	session->setAllowSinglePartOp(true);
3047 	session->setSymmetricKey(secretkey);
3048 
3049 	return CKR_OK;
3050 }
3051 
3052 // AsymAlgorithm version of C_DecryptInit
AsymDecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)3053 CK_RV SoftHSM::AsymDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
3054 {
3055 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3056 
3057 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
3058 
3059 	// Get the session
3060 	Session* session = (Session*)handleManager->getSession(hSession);
3061 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3062 
3063 	// Get the token
3064 	Token* token = session->getToken();
3065 	if (token == NULL) return CKR_GENERAL_ERROR;
3066 
3067 	// Check if we have another operation
3068 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
3069 
3070 	// Check the key handle.
3071 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
3072 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
3073 
3074 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
3075 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
3076 
3077 	// Check read user credentials
3078 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
3079 	if (rv != CKR_OK)
3080 	{
3081 		if (rv == CKR_USER_NOT_LOGGED_IN)
3082 			INFO_MSG("User is not authorized");
3083 
3084 		return rv;
3085 	}
3086 
3087 	// Check if key can be used for decryption
3088 	if (!key->getBooleanValue(CKA_DECRYPT, false))
3089 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
3090 
3091 	// Check if the specified mechanism is allowed for the key
3092 	if (!isMechanismPermitted(key, pMechanism))
3093 		return CKR_MECHANISM_INVALID;
3094 
3095 	// Get key info
3096 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
3097 
3098 	// Get the asymmetric algorithm matching the mechanism
3099 	AsymMech::Type mechanism = AsymMech::Unknown;
3100 	bool isRSA = false;
3101 	switch(pMechanism->mechanism) {
3102 		case CKM_RSA_PKCS:
3103 			if (keyType != CKK_RSA)
3104 				return CKR_KEY_TYPE_INCONSISTENT;
3105 			mechanism = AsymMech::RSA_PKCS;
3106 			isRSA = true;
3107 			break;
3108 		case CKM_RSA_X_509:
3109 			if (keyType != CKK_RSA)
3110 				return CKR_KEY_TYPE_INCONSISTENT;
3111 			mechanism = AsymMech::RSA;
3112 			isRSA = true;
3113 			break;
3114 		case CKM_RSA_PKCS_OAEP:
3115 			if (keyType != CKK_RSA)
3116 				return CKR_KEY_TYPE_INCONSISTENT;
3117 			if (pMechanism->pParameter == NULL_PTR ||
3118 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS))
3119 			{
3120 				DEBUG_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS");
3121 				return CKR_ARGUMENTS_BAD;
3122 			}
3123 			if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1)
3124 			{
3125 				DEBUG_MSG("hashAlg must be CKM_SHA_1");
3126 				return CKR_ARGUMENTS_BAD;
3127 			}
3128 			if (CK_RSA_PKCS_OAEP_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1)
3129 			{
3130 				DEBUG_MSG("mgf must be CKG_MGF1_SHA1");
3131 				return CKR_ARGUMENTS_BAD;
3132 			}
3133 
3134 			mechanism = AsymMech::RSA_PKCS_OAEP;
3135 			isRSA = true;
3136 			break;
3137 		default:
3138 			return CKR_MECHANISM_INVALID;
3139 	}
3140 
3141 	AsymmetricAlgorithm* asymCrypto = NULL;
3142 	PrivateKey* privateKey = NULL;
3143 	if (isRSA)
3144 	{
3145 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
3146 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
3147 
3148 		privateKey = asymCrypto->newPrivateKey();
3149 		if (privateKey == NULL)
3150 		{
3151 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
3152 			return CKR_HOST_MEMORY;
3153 		}
3154 
3155 		if (getRSAPrivateKey((RSAPrivateKey*)privateKey, token, key) != CKR_OK)
3156 		{
3157 			asymCrypto->recyclePrivateKey(privateKey);
3158 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
3159 			return CKR_GENERAL_ERROR;
3160 		}
3161 	}
3162 	else
3163 	{
3164 		return CKR_MECHANISM_INVALID;
3165         }
3166 
3167 	// Check if re-authentication is required
3168 	if (key->getBooleanValue(CKA_ALWAYS_AUTHENTICATE, false))
3169 	{
3170 		session->setReAuthentication(true);
3171 	}
3172 
3173 	session->setOpType(SESSION_OP_DECRYPT);
3174 	session->setAsymmetricCryptoOp(asymCrypto);
3175 	session->setMechanism(mechanism);
3176 	session->setAllowMultiPartOp(false);
3177 	session->setAllowSinglePartOp(true);
3178 	session->setPrivateKey(privateKey);
3179 
3180 	return CKR_OK;
3181 }
3182 
3183 // Initialise decryption using the specified object
C_DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)3184 CK_RV SoftHSM::C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
3185 {
3186 	if (isSymMechanism(pMechanism))
3187 		return SymDecryptInit(hSession, pMechanism, hKey);
3188 	else
3189 		return AsymDecryptInit(hSession, pMechanism, hKey);
3190 }
3191 
3192 // SymAlgorithm version of C_Decrypt
SymDecrypt(Session * session,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)3193 static CK_RV SymDecrypt(Session* session, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
3194 {
3195 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
3196 	if (cipher == NULL || !session->getAllowSinglePartOp())
3197 	{
3198 		session->resetOp();
3199 		return CKR_OPERATION_NOT_INITIALIZED;
3200 	}
3201 
3202 	// Check encrypted data size
3203 	if (cipher->isBlockCipher() && ulEncryptedDataLen % cipher->getBlockSize() != 0)
3204 	{
3205 		session->resetOp();
3206 		return CKR_ENCRYPTED_DATA_LEN_RANGE;
3207 	}
3208 	if (!cipher->checkMaximumBytes(ulEncryptedDataLen))
3209 	{
3210 		session->resetOp();
3211 		return CKR_ENCRYPTED_DATA_LEN_RANGE;
3212 	}
3213 
3214 	if (pData == NULL_PTR)
3215 	{
3216 		*pulDataLen = ulEncryptedDataLen;
3217 		return CKR_OK;
3218 	}
3219 
3220 	// Check buffer size
3221 	if (*pulDataLen < ulEncryptedDataLen)
3222 	{
3223 		*pulDataLen = ulEncryptedDataLen;
3224 		return CKR_BUFFER_TOO_SMALL;
3225 	}
3226 
3227 	// Get the data
3228 	ByteString encryptedData(pEncryptedData, ulEncryptedDataLen);
3229 	ByteString data;
3230 
3231 	// Decrypt the data
3232 	if (!cipher->decryptUpdate(encryptedData,data))
3233 	{
3234 		session->resetOp();
3235 		return CKR_GENERAL_ERROR;
3236 	}
3237 
3238 	// Finalize decryption
3239 	ByteString dataFinal;
3240 	if (!cipher->decryptFinal(dataFinal))
3241 	{
3242 		session->resetOp();
3243 		return CKR_GENERAL_ERROR;
3244 	}
3245 	data += dataFinal;
3246 	if (data.size() > ulEncryptedDataLen)
3247 	{
3248 		data.resize(ulEncryptedDataLen);
3249 	}
3250 
3251 	if (data.size() != 0)
3252 	{
3253 		memcpy(pData, data.byte_str(), data.size());
3254 	}
3255 	*pulDataLen = data.size();
3256 
3257 	session->resetOp();
3258 	return CKR_OK;
3259 
3260 }
3261 
3262 // AsymAlgorithm version of C_Decrypt
AsymDecrypt(Session * session,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)3263 static CK_RV AsymDecrypt(Session* session, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
3264 {
3265 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
3266 	AsymMech::Type mechanism = session->getMechanism();
3267 	PrivateKey* privateKey = session->getPrivateKey();
3268 	if (asymCrypto == NULL || !session->getAllowSinglePartOp() || privateKey == NULL)
3269 	{
3270 		session->resetOp();
3271 		return CKR_OPERATION_NOT_INITIALIZED;
3272 	}
3273 
3274 	// Check if re-authentication is required
3275 	if (session->getReAuthentication())
3276 	{
3277 		session->resetOp();
3278 		return CKR_USER_NOT_LOGGED_IN;
3279 	}
3280 
3281 	// Size of the data
3282 	CK_ULONG size = privateKey->getOutputLength();
3283 	if (pData == NULL_PTR)
3284 	{
3285 		*pulDataLen = size;
3286 		return CKR_OK;
3287 	}
3288 
3289 	// Check buffer size
3290 	if (*pulDataLen < size)
3291 	{
3292 		*pulDataLen = size;
3293 		return CKR_BUFFER_TOO_SMALL;
3294 	}
3295 
3296 	// Get the data
3297 	ByteString encryptedData(pEncryptedData, ulEncryptedDataLen);
3298 	ByteString data;
3299 
3300 	// Decrypt the data
3301 	if (!asymCrypto->decrypt(privateKey,encryptedData,data,mechanism))
3302 	{
3303 		session->resetOp();
3304 		return CKR_GENERAL_ERROR;
3305 	}
3306 
3307 	// Check size
3308 	if (data.size() > size)
3309 	{
3310 		ERROR_MSG("The size of the decrypted data exceeds the size of the mechanism");
3311 		session->resetOp();
3312 		return CKR_GENERAL_ERROR;
3313 	}
3314 	if (data.size() != 0)
3315 	{
3316 		memcpy(pData, data.byte_str(), data.size());
3317 	}
3318 	*pulDataLen = data.size();
3319 
3320 	session->resetOp();
3321 	return CKR_OK;
3322 
3323 }
3324 
3325 // Perform a single operation decryption in the given session
C_Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)3326 CK_RV SoftHSM::C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
3327 {
3328 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3329 
3330 	if (pEncryptedData == NULL_PTR) return CKR_ARGUMENTS_BAD;
3331 	if (pulDataLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
3332 
3333 	// Get the session
3334 	Session* session = (Session*)handleManager->getSession(hSession);
3335 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3336 
3337 	// Check if we are doing the correct operation
3338 	if (session->getOpType() != SESSION_OP_DECRYPT)
3339 		return CKR_OPERATION_NOT_INITIALIZED;
3340 
3341 	if (session->getSymmetricCryptoOp() != NULL)
3342 		return SymDecrypt(session, pEncryptedData, ulEncryptedDataLen,
3343 				  pData, pulDataLen);
3344 	else
3345 		return AsymDecrypt(session, pEncryptedData, ulEncryptedDataLen,
3346 				   pData, pulDataLen);
3347 }
3348 
3349 // SymAlgorithm version of C_DecryptUpdate
SymDecryptUpdate(Session * session,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pDataLen)3350 static CK_RV SymDecryptUpdate(Session* session, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen)
3351 {
3352 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
3353 	if (cipher == NULL || !session->getAllowMultiPartOp())
3354 	{
3355 		session->resetOp();
3356 		return CKR_OPERATION_NOT_INITIALIZED;
3357 	}
3358 
3359 	// Check encrypted data size
3360 	size_t blockSize = cipher->getBlockSize();
3361 	size_t remainingSize = cipher->getBufferSize();
3362 	CK_ULONG maxSize = ulEncryptedDataLen + remainingSize;
3363 	if (cipher->isBlockCipher())
3364 	{
3365 		// There must always be one block left in padding mode if next operation is DecryptFinal.
3366 		// To guarantee that one byte is removed in padding mode when the number of blocks is calculated.
3367 		size_t paddingAdjustByte = cipher->getPaddingMode() ? 1 : 0;
3368 		int nrOfBlocks = (ulEncryptedDataLen + remainingSize - paddingAdjustByte) / blockSize;
3369 		maxSize = nrOfBlocks * blockSize;
3370 	}
3371 	if (!cipher->checkMaximumBytes(ulEncryptedDataLen))
3372 	{
3373 		session->resetOp();
3374 		return CKR_ENCRYPTED_DATA_LEN_RANGE;
3375 	}
3376 
3377 	// Give required output buffer size.
3378 	if (pData == NULL_PTR)
3379 	{
3380 		*pDataLen = maxSize;
3381 		return CKR_OK;
3382 	}
3383 
3384 	// Check output buffer size
3385 	if (*pDataLen < maxSize)
3386 	{
3387 		DEBUG_MSG("Output buffer too short   ulEncryptedDataLen: %#5x  output buffer size: %#5x  blockSize: %#3x  remainingSize: %#4x  maxSize: %#5x",
3388 			  ulEncryptedDataLen, *pDataLen, blockSize, remainingSize, maxSize);
3389 		*pDataLen = maxSize;
3390 		return CKR_BUFFER_TOO_SMALL;
3391 	}
3392 
3393 	// Get the data
3394 	ByteString data(pEncryptedData, ulEncryptedDataLen);
3395 	ByteString decryptedData;
3396 
3397 	// Encrypt the data
3398 	if (!cipher->decryptUpdate(data, decryptedData))
3399 	{
3400 		session->resetOp();
3401 		return CKR_GENERAL_ERROR;
3402 	}
3403 	DEBUG_MSG("ulEncryptedDataLen: %#5x  output buffer size: %#5x  blockSize: %#3x  remainingSize: %#4x  maxSize: %#5x  decryptedData.size(): %#5x",
3404 		  ulEncryptedDataLen, *pDataLen, blockSize, remainingSize, maxSize, decryptedData.size());
3405 
3406 	// Check output size from crypto. Unrecoverable error if to large.
3407 	if (*pDataLen < decryptedData.size())
3408 	{
3409 		session->resetOp();
3410 		ERROR_MSG("DecryptUpdate returning too much data. Length of output data buffer is %i but %i bytes was returned by the decrypt.",
3411 				*pDataLen, decryptedData.size());
3412 		return CKR_GENERAL_ERROR;
3413 	}
3414 
3415 	if (decryptedData.size() > 0)
3416 	{
3417 		memcpy(pData, decryptedData.byte_str(), decryptedData.size());
3418 	}
3419 	*pDataLen = decryptedData.size();
3420 
3421 	return CKR_OK;
3422 }
3423 
3424 
3425 // Feed data to the running decryption operation in a session
C_DecryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pDataLen)3426 CK_RV SoftHSM::C_DecryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen)
3427 {
3428 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3429 
3430 	if (pEncryptedData == NULL_PTR) return CKR_ARGUMENTS_BAD;
3431 	if (pDataLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
3432 
3433 	// Get the session
3434 	Session* session = (Session*)handleManager->getSession(hSession);
3435 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3436 
3437 	// Check if we are doing the correct operation
3438 	if (session->getOpType() != SESSION_OP_DECRYPT)
3439 		return CKR_OPERATION_NOT_INITIALIZED;
3440 
3441 	if (session->getSymmetricCryptoOp() != NULL)
3442 		return SymDecryptUpdate(session, pEncryptedData, ulEncryptedDataLen,
3443 				  pData, pDataLen);
3444 	else
3445 		return CKR_FUNCTION_NOT_SUPPORTED;
3446 }
3447 
SymDecryptFinal(Session * session,CK_BYTE_PTR pDecryptedData,CK_ULONG_PTR pulDecryptedDataLen)3448 static CK_RV SymDecryptFinal(Session* session, CK_BYTE_PTR pDecryptedData, CK_ULONG_PTR pulDecryptedDataLen)
3449 {
3450 	SymmetricAlgorithm* cipher = session->getSymmetricCryptoOp();
3451 	if (cipher == NULL || !session->getAllowMultiPartOp())
3452 	{
3453 		session->resetOp();
3454 		return CKR_OPERATION_NOT_INITIALIZED;
3455 	}
3456 
3457 	// Check encrypted data size
3458 	size_t remainingSize = cipher->getBufferSize();
3459 	CK_ULONG size = remainingSize;
3460 	if (cipher->isBlockCipher())
3461 	{
3462 		size_t blockSize = cipher->getBlockSize();
3463 		if (remainingSize % blockSize != 0)
3464 		{
3465 			session->resetOp();
3466 			DEBUG_MSG("Remaining data length is not an integral of the block size. Block size: %#2x  Remaining size: %#2x",
3467 				   blockSize, remainingSize);
3468 			return CKR_ENCRYPTED_DATA_LEN_RANGE;
3469 		}
3470 		// It is at least one padding byte. If no padding the all remains will be returned.
3471 		size_t paddingAdjustByte = cipher->getPaddingMode() ? 1 : 0;
3472 		size = remainingSize - paddingAdjustByte;
3473 	}
3474 
3475 	// Give required output buffer size.
3476 	if (pDecryptedData == NULL_PTR)
3477 	{
3478 		*pulDecryptedDataLen = size;
3479 		return CKR_OK;
3480 	}
3481 
3482 	// Check output buffer size
3483 	if (*pulDecryptedDataLen < size)
3484 	{
3485 		DEBUG_MSG("output buffer size: %#5x  size: %#5x",
3486 			  *pulDecryptedDataLen, size);
3487 		*pulDecryptedDataLen = size;
3488 		return CKR_BUFFER_TOO_SMALL;
3489 	}
3490 
3491 	// Finalize decryption
3492 	ByteString decryptedFinal;
3493 	if (!cipher->decryptFinal(decryptedFinal))
3494 	{
3495 		session->resetOp();
3496 		return CKR_GENERAL_ERROR;
3497 	}
3498 	DEBUG_MSG("output buffer size: %#2x  size: %#2x  decryptedFinal.size(): %#2x",
3499 		  *pulDecryptedDataLen, size, decryptedFinal.size());
3500 
3501 	// Check output size from crypto. Unrecoverable error if to large.
3502 	if (*pulDecryptedDataLen < decryptedFinal.size())
3503 	{
3504 		session->resetOp();
3505 		ERROR_MSG("DecryptFinal returning too much data. Length of output data buffer is %i but %i bytes was returned by the encrypt.",
3506 			  *pulDecryptedDataLen, decryptedFinal.size());
3507 		return CKR_GENERAL_ERROR;
3508 	}
3509 
3510 	if (decryptedFinal.size() > 0)
3511 	{
3512 		memcpy(pDecryptedData, decryptedFinal.byte_str(), decryptedFinal.size());
3513 	}
3514 	*pulDecryptedDataLen = decryptedFinal.size();
3515 
3516 	session->resetOp();
3517 	return CKR_OK;
3518 }
3519 
3520 // Finalise the decryption operation
C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG_PTR pDataLen)3521 CK_RV SoftHSM::C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen)
3522 {
3523 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3524 
3525 	// Get the session
3526 	Session* session = (Session*)handleManager->getSession(hSession);
3527 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3528 
3529 	// Github issue #469, check NULL_PTR on pDataLen
3530 	if (pDataLen == NULL)
3531 	{
3532 		session->resetOp();
3533 		return CKR_ARGUMENTS_BAD;
3534 	}
3535 
3536 	// Check if we are doing the correct operation
3537 	if (session->getOpType() != SESSION_OP_DECRYPT) return CKR_OPERATION_NOT_INITIALIZED;
3538 
3539 	if (session->getSymmetricCryptoOp() != NULL)
3540 		return SymDecryptFinal(session, pData, pDataLen);
3541 	else
3542 		return CKR_FUNCTION_NOT_SUPPORTED;
3543 }
3544 
3545 // Initialise digesting using the specified mechanism in the specified session
C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)3546 CK_RV SoftHSM::C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
3547 {
3548 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3549 
3550 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
3551 
3552 	// Get the session
3553 	Session* session = (Session*)handleManager->getSession(hSession);
3554 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3555 
3556 	// Check if we have another operation
3557 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
3558 
3559 	// Get the mechanism
3560 	HashAlgo::Type algo = HashAlgo::Unknown;
3561 	switch(pMechanism->mechanism) {
3562 #ifndef WITH_FIPS
3563 		case CKM_MD5:
3564 			algo = HashAlgo::MD5;
3565 			break;
3566 #endif
3567 		case CKM_SHA_1:
3568 			algo = HashAlgo::SHA1;
3569 			break;
3570 		case CKM_SHA224:
3571 			algo = HashAlgo::SHA224;
3572 			break;
3573 		case CKM_SHA256:
3574 			algo = HashAlgo::SHA256;
3575 			break;
3576 		case CKM_SHA384:
3577 			algo = HashAlgo::SHA384;
3578 			break;
3579 		case CKM_SHA512:
3580 			algo = HashAlgo::SHA512;
3581 			break;
3582 #ifdef WITH_GOST
3583 		case CKM_GOSTR3411:
3584 			algo = HashAlgo::GOST;
3585 			break;
3586 #endif
3587 		default:
3588 			return CKR_MECHANISM_INVALID;
3589 	}
3590 	HashAlgorithm* hash = CryptoFactory::i()->getHashAlgorithm(algo);
3591 	if (hash == NULL) return CKR_MECHANISM_INVALID;
3592 
3593 	// Initialize hashing
3594 	if (hash->hashInit() == false)
3595 	{
3596 		CryptoFactory::i()->recycleHashAlgorithm(hash);
3597 		return CKR_GENERAL_ERROR;
3598 	}
3599 
3600 	session->setOpType(SESSION_OP_DIGEST);
3601 	session->setDigestOp(hash);
3602 	session->setHashAlgo(algo);
3603 
3604 	return CKR_OK;
3605 }
3606 
3607 // Digest the specified data in a one-pass operation and return the resulting digest
C_Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)3608 CK_RV SoftHSM::C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
3609 {
3610 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3611 
3612 	if (pulDigestLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
3613 	if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
3614 
3615 	// Get the session
3616 	Session* session = (Session*)handleManager->getSession(hSession);
3617 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3618 
3619 	// Check if we are doing the correct operation
3620 	if (session->getOpType() != SESSION_OP_DIGEST) return CKR_OPERATION_NOT_INITIALIZED;
3621 
3622 	// Return size
3623 	CK_ULONG size = session->getDigestOp()->getHashSize();
3624 	if (pDigest == NULL_PTR)
3625 	{
3626 		*pulDigestLen = size;
3627 		return CKR_OK;
3628 	}
3629 
3630 	// Check buffer size
3631 	if (*pulDigestLen < size)
3632 	{
3633 		*pulDigestLen = size;
3634 		return CKR_BUFFER_TOO_SMALL;
3635 	}
3636 
3637 	// Get the data
3638 	ByteString data(pData, ulDataLen);
3639 
3640 	// Digest the data
3641 	if (session->getDigestOp()->hashUpdate(data) == false)
3642 	{
3643 		session->resetOp();
3644 		return CKR_GENERAL_ERROR;
3645 	}
3646 
3647 	// Get the digest
3648 	ByteString digest;
3649 	if (session->getDigestOp()->hashFinal(digest) == false)
3650 	{
3651 		session->resetOp();
3652 		return CKR_GENERAL_ERROR;
3653 	}
3654 
3655 	// Check size
3656 	if (digest.size() != size)
3657 	{
3658 		ERROR_MSG("The size of the digest differ from the size of the mechanism");
3659 		session->resetOp();
3660 		return CKR_GENERAL_ERROR;
3661 	}
3662 	memcpy(pDigest, digest.byte_str(), size);
3663 	*pulDigestLen = size;
3664 
3665 	session->resetOp();
3666 
3667 	return CKR_OK;
3668 }
3669 
3670 // Update a running digest operation
C_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)3671 CK_RV SoftHSM::C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
3672 {
3673 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3674 
3675 	if (pPart == NULL_PTR) return CKR_ARGUMENTS_BAD;
3676 
3677 	// Get the session
3678 	Session* session = (Session*)handleManager->getSession(hSession);
3679 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3680 
3681 	// Check if we are doing the correct operation
3682 	if (session->getOpType() != SESSION_OP_DIGEST) return CKR_OPERATION_NOT_INITIALIZED;
3683 
3684 	// Get the data
3685 	ByteString data(pPart, ulPartLen);
3686 
3687 	// Digest the data
3688 	if (session->getDigestOp()->hashUpdate(data) == false)
3689 	{
3690 		session->resetOp();
3691 		return CKR_GENERAL_ERROR;
3692 	}
3693 
3694 	return CKR_OK;
3695 }
3696 
3697 // Update a running digest operation by digesting a secret key with the specified handle
C_DigestKey(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)3698 CK_RV SoftHSM::C_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
3699 {
3700 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3701 
3702 	// Get the session
3703 	Session* session = (Session*)handleManager->getSession(hSession);
3704 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3705 
3706 	// Check if we are doing the correct operation
3707 	if (session->getOpType() != SESSION_OP_DIGEST) return CKR_OPERATION_NOT_INITIALIZED;
3708 
3709 	// Get the token
3710 	Token* token = session->getToken();
3711 	if (token == NULL) return CKR_GENERAL_ERROR;
3712 
3713 	// Check the key handle.
3714 	OSObject *key = (OSObject *)handleManager->getObject(hObject);
3715 	if (key == NULL_PTR || !key->isValid()) return CKR_KEY_HANDLE_INVALID;
3716 
3717 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
3718 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
3719 
3720 	// Check read user credentials
3721 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
3722 	if (rv != CKR_OK)
3723 	{
3724 		if (rv == CKR_USER_NOT_LOGGED_IN)
3725 			INFO_MSG("User is not authorized");
3726 
3727 		// CKR_USER_NOT_LOGGED_IN is not a valid return code for this function,
3728 		// so we use CKR_GENERAL_ERROR.
3729 		return CKR_GENERAL_ERROR;
3730 	}
3731 
3732 	// Whitelist
3733 	HashAlgo::Type algo = session->getHashAlgo();
3734 	if (algo != HashAlgo::SHA1 &&
3735 	    algo != HashAlgo::SHA224 &&
3736 	    algo != HashAlgo::SHA256 &&
3737 	    algo != HashAlgo::SHA384 &&
3738 	    algo != HashAlgo::SHA512)
3739 	{
3740 		// Parano...
3741 		if (!key->getBooleanValue(CKA_EXTRACTABLE, false))
3742 			return CKR_KEY_INDIGESTIBLE;
3743 		if (key->getBooleanValue(CKA_SENSITIVE, false))
3744 			return CKR_KEY_INDIGESTIBLE;
3745 	}
3746 
3747 	// Get value
3748 	if (!key->attributeExists(CKA_VALUE))
3749 		return CKR_KEY_INDIGESTIBLE;
3750 	ByteString keybits;
3751 	if (isPrivate)
3752 	{
3753 		if (!token->decrypt(key->getByteStringValue(CKA_VALUE), keybits))
3754 			return CKR_GENERAL_ERROR;
3755 	}
3756 	else
3757 	{
3758 		keybits = key->getByteStringValue(CKA_VALUE);
3759 	}
3760 
3761 	// Digest the value
3762 	if (session->getDigestOp()->hashUpdate(keybits) == false)
3763 	{
3764 		session->resetOp();
3765 		return CKR_GENERAL_ERROR;
3766 	}
3767 
3768 	return CKR_OK;
3769 }
3770 
3771 // Finalise the digest operation in the specified session and return the digest
C_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)3772 CK_RV SoftHSM::C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
3773 {
3774 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3775 
3776 	if (pulDigestLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
3777 
3778 	// Get the session
3779 	Session* session = (Session*)handleManager->getSession(hSession);
3780 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3781 
3782 	// Check if we are doing the correct operation
3783 	if (session->getOpType() != SESSION_OP_DIGEST) return CKR_OPERATION_NOT_INITIALIZED;
3784 
3785 	// Return size
3786 	CK_ULONG size = session->getDigestOp()->getHashSize();
3787 	if (pDigest == NULL_PTR)
3788 	{
3789 		*pulDigestLen = size;
3790 		return CKR_OK;
3791 	}
3792 
3793 	// Check buffer size
3794 	if (*pulDigestLen < size)
3795 	{
3796 		*pulDigestLen = size;
3797 		return CKR_BUFFER_TOO_SMALL;
3798 	}
3799 
3800 	// Get the digest
3801 	ByteString digest;
3802 	if (session->getDigestOp()->hashFinal(digest) == false)
3803 	{
3804 		session->resetOp();
3805 		return CKR_GENERAL_ERROR;
3806 	}
3807 
3808 	// Check size
3809 	if (digest.size() != size)
3810 	{
3811 		ERROR_MSG("The size of the digest differ from the size of the mechanism");
3812 		session->resetOp();
3813 		return CKR_GENERAL_ERROR;
3814 	}
3815 	memcpy(pDigest, digest.byte_str(), size);
3816 	*pulDigestLen = size;
3817 
3818 	session->resetOp();
3819 
3820 	return CKR_OK;
3821 }
3822 
3823 // Sign*/Verify*() is for MACs too
isMacMechanism(CK_MECHANISM_PTR pMechanism)3824 static bool isMacMechanism(CK_MECHANISM_PTR pMechanism)
3825 {
3826 	if (pMechanism == NULL_PTR) return false;
3827 
3828 	switch(pMechanism->mechanism) {
3829 		case CKM_MD5_HMAC:
3830 		case CKM_SHA_1_HMAC:
3831 		case CKM_SHA224_HMAC:
3832 		case CKM_SHA256_HMAC:
3833 		case CKM_SHA384_HMAC:
3834 		case CKM_SHA512_HMAC:
3835 #ifdef WITH_GOST
3836 		case CKM_GOSTR3411_HMAC:
3837 #endif
3838 		case CKM_DES3_CMAC:
3839 		case CKM_AES_CMAC:
3840 			return true;
3841 		default:
3842 			return false;
3843 	}
3844 }
3845 
3846 // MacAlgorithm version of C_SignInit
MacSignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)3847 CK_RV SoftHSM::MacSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
3848 {
3849 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
3850 
3851 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
3852 
3853 	// Get the session
3854 	Session* session = (Session*)handleManager->getSession(hSession);
3855 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
3856 
3857 	// Check if we have another operation
3858 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
3859 
3860 	// Get the token
3861 	Token* token = session->getToken();
3862 	if (token == NULL) return CKR_GENERAL_ERROR;
3863 
3864 	// Check the key handle.
3865 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
3866 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
3867 
3868 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
3869 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
3870 
3871 	// Check read user credentials
3872 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
3873 	if (rv != CKR_OK)
3874 	{
3875 		if (rv == CKR_USER_NOT_LOGGED_IN)
3876 			INFO_MSG("User is not authorized");
3877 
3878 		return rv;
3879 	}
3880 
3881 	// Check if key can be used for signing
3882 	if (!key->getBooleanValue(CKA_SIGN, false))
3883 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
3884 
3885 	// Check if the specified mechanism is allowed for the key
3886 	if (!isMechanismPermitted(key, pMechanism))
3887 		return CKR_MECHANISM_INVALID;
3888 
3889 	// Get key info
3890 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
3891 
3892 	// Get the MAC algorithm matching the mechanism
3893 	// Also check mechanism constraints
3894 	MacAlgo::Type algo = MacAlgo::Unknown;
3895 	size_t bb = 8;
3896 	size_t minSize = 0;
3897 	switch(pMechanism->mechanism) {
3898 #ifndef WITH_FIPS
3899 		case CKM_MD5_HMAC:
3900 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_MD5_HMAC)
3901 				return CKR_KEY_TYPE_INCONSISTENT;
3902 			minSize = 16;
3903 			algo = MacAlgo::HMAC_MD5;
3904 			break;
3905 #endif
3906 		case CKM_SHA_1_HMAC:
3907 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA_1_HMAC)
3908 				return CKR_KEY_TYPE_INCONSISTENT;
3909 			minSize = 20;
3910 			algo = MacAlgo::HMAC_SHA1;
3911 			break;
3912 		case CKM_SHA224_HMAC:
3913 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA224_HMAC)
3914 				return CKR_KEY_TYPE_INCONSISTENT;
3915 			minSize = 28;
3916 			algo = MacAlgo::HMAC_SHA224;
3917 			break;
3918 		case CKM_SHA256_HMAC:
3919 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA256_HMAC)
3920 				return CKR_KEY_TYPE_INCONSISTENT;
3921 			minSize = 32;
3922 			algo = MacAlgo::HMAC_SHA256;
3923 			break;
3924 		case CKM_SHA384_HMAC:
3925 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA384_HMAC)
3926 				return CKR_KEY_TYPE_INCONSISTENT;
3927 			minSize = 48;
3928 			algo = MacAlgo::HMAC_SHA384;
3929 			break;
3930 		case CKM_SHA512_HMAC:
3931 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA512_HMAC)
3932 				return CKR_KEY_TYPE_INCONSISTENT;
3933 			minSize = 64;
3934 			algo = MacAlgo::HMAC_SHA512;
3935 			break;
3936 #ifdef WITH_GOST
3937 		case CKM_GOSTR3411_HMAC:
3938 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_GOST28147)
3939 				return CKR_KEY_TYPE_INCONSISTENT;
3940 			minSize = 32;
3941 			algo = MacAlgo::HMAC_GOST;
3942 			break;
3943 #endif
3944 		case CKM_DES3_CMAC:
3945 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
3946 				return CKR_KEY_TYPE_INCONSISTENT;
3947 			algo = MacAlgo::CMAC_DES;
3948 			bb = 7;
3949 			break;
3950 		case CKM_AES_CMAC:
3951 			if (keyType != CKK_AES)
3952 				return CKR_KEY_TYPE_INCONSISTENT;
3953 			algo = MacAlgo::CMAC_AES;
3954 			break;
3955 		default:
3956 			return CKR_MECHANISM_INVALID;
3957 	}
3958 	MacAlgorithm* mac = CryptoFactory::i()->getMacAlgorithm(algo);
3959 	if (mac == NULL) return CKR_MECHANISM_INVALID;
3960 
3961 	SymmetricKey* privkey = new SymmetricKey();
3962 
3963 	if (getSymmetricKey(privkey, token, key) != CKR_OK)
3964 	{
3965 		mac->recycleKey(privkey);
3966 		CryptoFactory::i()->recycleMacAlgorithm(mac);
3967 		return CKR_GENERAL_ERROR;
3968 	}
3969 
3970 	// Adjust key bit length
3971 	privkey->setBitLen(privkey->getKeyBits().size() * bb);
3972 
3973 	// Check key size
3974 	if (privkey->getBitLen() < (minSize*8))
3975 	{
3976 		mac->recycleKey(privkey);
3977 		CryptoFactory::i()->recycleMacAlgorithm(mac);
3978 		return CKR_KEY_SIZE_RANGE;
3979 	}
3980 
3981 	// Initialize signing
3982 	if (!mac->signInit(privkey))
3983 	{
3984 		mac->recycleKey(privkey);
3985 		CryptoFactory::i()->recycleMacAlgorithm(mac);
3986 		return CKR_MECHANISM_INVALID;
3987 	}
3988 
3989 	session->setOpType(SESSION_OP_SIGN);
3990 	session->setMacOp(mac);
3991 	session->setAllowMultiPartOp(true);
3992 	session->setAllowSinglePartOp(true);
3993 	session->setSymmetricKey(privkey);
3994 
3995 	return CKR_OK;
3996 }
3997 
3998 // AsymmetricAlgorithm version of C_SignInit
AsymSignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)3999 CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4000 {
4001 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4002 
4003 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
4004 
4005 	// Get the session
4006 	Session* session = (Session*)handleManager->getSession(hSession);
4007 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4008 
4009 	// Check if we have another operation
4010 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
4011 
4012 	// Get the token
4013 	Token* token = session->getToken();
4014 	if (token == NULL) return CKR_GENERAL_ERROR;
4015 
4016 	// Check the key handle.
4017 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
4018 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
4019 
4020 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
4021 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
4022 
4023 	// Check read user credentials
4024 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
4025 	if (rv != CKR_OK)
4026 	{
4027 		if (rv == CKR_USER_NOT_LOGGED_IN)
4028 			INFO_MSG("User is not authorized");
4029 
4030 		return rv;
4031 	}
4032 
4033 	// Check if key can be used for signing
4034 	if (!key->getBooleanValue(CKA_SIGN, false))
4035 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
4036 
4037 	// Check if the specified mechanism is allowed for the key
4038 	if (!isMechanismPermitted(key, pMechanism))
4039 		return CKR_MECHANISM_INVALID;
4040 
4041 	// Get the asymmetric algorithm matching the mechanism
4042 	AsymMech::Type mechanism = AsymMech::Unknown;
4043 	void* param = NULL;
4044 	size_t paramLen = 0;
4045 	RSA_PKCS_PSS_PARAMS pssParam;
4046 	bool bAllowMultiPartOp;
4047 	bool isRSA = false;
4048 	bool isDSA = false;
4049 #ifdef WITH_ECC
4050 	bool isECDSA = false;
4051 #endif
4052 #ifdef WITH_EDDSA
4053 	bool isEDDSA = false;
4054 #endif
4055 	switch(pMechanism->mechanism) {
4056 		case CKM_RSA_PKCS:
4057 			mechanism = AsymMech::RSA_PKCS;
4058 			bAllowMultiPartOp = false;
4059 			isRSA = true;
4060 			break;
4061 		case CKM_RSA_X_509:
4062 			mechanism = AsymMech::RSA;
4063 			bAllowMultiPartOp = false;
4064 			isRSA = true;
4065 			break;
4066 #ifndef WITH_FIPS
4067 		case CKM_MD5_RSA_PKCS:
4068 			mechanism = AsymMech::RSA_MD5_PKCS;
4069 			bAllowMultiPartOp = true;
4070 			isRSA = true;
4071 			break;
4072 #endif
4073 		case CKM_SHA1_RSA_PKCS:
4074 			mechanism = AsymMech::RSA_SHA1_PKCS;
4075 			bAllowMultiPartOp = true;
4076 			isRSA = true;
4077 			break;
4078 		case CKM_SHA224_RSA_PKCS:
4079 			mechanism = AsymMech::RSA_SHA224_PKCS;
4080 			bAllowMultiPartOp = true;
4081 			isRSA = true;
4082 			break;
4083 		case CKM_SHA256_RSA_PKCS:
4084 			mechanism = AsymMech::RSA_SHA256_PKCS;
4085 			bAllowMultiPartOp = true;
4086 			isRSA = true;
4087 			break;
4088 		case CKM_SHA384_RSA_PKCS:
4089 			mechanism = AsymMech::RSA_SHA384_PKCS;
4090 			bAllowMultiPartOp = true;
4091 			isRSA = true;
4092 			break;
4093 		case CKM_SHA512_RSA_PKCS:
4094 			mechanism = AsymMech::RSA_SHA512_PKCS;
4095 			bAllowMultiPartOp = true;
4096 			isRSA = true;
4097 			break;
4098 #ifdef WITH_RAW_PSS
4099 		case CKM_RSA_PKCS_PSS:
4100 			if (pMechanism->pParameter == NULL_PTR ||
4101 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS))
4102 			{
4103 				ERROR_MSG("Invalid RSA-PSS parameters");
4104 				return CKR_ARGUMENTS_BAD;
4105 			}
4106 			mechanism = AsymMech::RSA_PKCS_PSS;
4107 			unsigned long allowedMgf;
4108 
4109 			switch(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
4110 				case CKM_SHA_1:
4111 					pssParam.hashAlg = HashAlgo::SHA1;
4112 					pssParam.mgf = AsymRSAMGF::MGF1_SHA1;
4113 					allowedMgf = CKG_MGF1_SHA1;
4114 					break;
4115 				case CKM_SHA224:
4116 					pssParam.hashAlg = HashAlgo::SHA224;
4117 					pssParam.mgf = AsymRSAMGF::MGF1_SHA224;
4118 					allowedMgf = CKG_MGF1_SHA224;
4119 					break;
4120 				case CKM_SHA256:
4121 					pssParam.hashAlg = HashAlgo::SHA256;
4122 					pssParam.mgf = AsymRSAMGF::MGF1_SHA256;
4123 					allowedMgf = CKG_MGF1_SHA256;
4124 					break;
4125 				case CKM_SHA384:
4126 					pssParam.hashAlg = HashAlgo::SHA384;
4127 					pssParam.mgf = AsymRSAMGF::MGF1_SHA384;
4128 					allowedMgf = CKG_MGF1_SHA384;
4129 					break;
4130 				case CKM_SHA512:
4131 					pssParam.hashAlg = HashAlgo::SHA512;
4132 					pssParam.mgf = AsymRSAMGF::MGF1_SHA512;
4133 					allowedMgf = CKG_MGF1_SHA512;
4134 					break;
4135 				default:
4136 					ERROR_MSG("Invalid RSA-PSS hash");
4137 					return CKR_ARGUMENTS_BAD;
4138 			}
4139 
4140 			if (CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != allowedMgf) {
4141 				ERROR_MSG("Hash and MGF don't match");
4142 				return CKR_ARGUMENTS_BAD;
4143 			}
4144 
4145 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4146 			param = &pssParam;
4147 			paramLen = sizeof(pssParam);
4148 			bAllowMultiPartOp = false;
4149 			isRSA = true;
4150 			break;
4151 #endif
4152 		case CKM_SHA1_RSA_PKCS_PSS:
4153 			if (pMechanism->pParameter == NULL_PTR ||
4154 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4155 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1 ||
4156 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1)
4157 			{
4158 				ERROR_MSG("Invalid parameters");
4159 				return CKR_ARGUMENTS_BAD;
4160 			}
4161 			mechanism = AsymMech::RSA_SHA1_PKCS_PSS;
4162 			pssParam.hashAlg = HashAlgo::SHA1;
4163 			pssParam.mgf = AsymRSAMGF::MGF1_SHA1;
4164 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4165 			param = &pssParam;
4166 			paramLen = sizeof(pssParam);
4167 			bAllowMultiPartOp = true;
4168 			isRSA = true;
4169 			break;
4170 		case CKM_SHA224_RSA_PKCS_PSS:
4171 			if (pMechanism->pParameter == NULL_PTR ||
4172 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4173 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA224 ||
4174 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA224)
4175 			{
4176 				ERROR_MSG("Invalid parameters");
4177 				return CKR_ARGUMENTS_BAD;
4178 			}
4179 			mechanism = AsymMech::RSA_SHA224_PKCS_PSS;
4180 			pssParam.hashAlg = HashAlgo::SHA224;
4181 			pssParam.mgf = AsymRSAMGF::MGF1_SHA224;
4182 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4183 			param = &pssParam;
4184 			paramLen = sizeof(pssParam);
4185 			bAllowMultiPartOp = true;
4186 			isRSA = true;
4187 			break;
4188 		case CKM_SHA256_RSA_PKCS_PSS:
4189 			if (pMechanism->pParameter == NULL_PTR ||
4190 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4191 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256 ||
4192 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256)
4193 			{
4194 				ERROR_MSG("Invalid parameters");
4195 				return CKR_ARGUMENTS_BAD;
4196 			}
4197 			mechanism = AsymMech::RSA_SHA256_PKCS_PSS;
4198 			pssParam.hashAlg = HashAlgo::SHA256;
4199 			pssParam.mgf = AsymRSAMGF::MGF1_SHA256;
4200 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4201 			param = &pssParam;
4202 			paramLen = sizeof(pssParam);
4203 			bAllowMultiPartOp = true;
4204 			isRSA = true;
4205 			break;
4206 		case CKM_SHA384_RSA_PKCS_PSS:
4207 			if (pMechanism->pParameter == NULL_PTR ||
4208 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4209 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384 ||
4210 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384)
4211 			{
4212 				ERROR_MSG("Invalid parameters");
4213 				return CKR_ARGUMENTS_BAD;
4214 			}
4215 			mechanism = AsymMech::RSA_SHA384_PKCS_PSS;
4216 			pssParam.hashAlg = HashAlgo::SHA384;
4217 			pssParam.mgf = AsymRSAMGF::MGF1_SHA384;
4218 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4219 			param = &pssParam;
4220 			paramLen = sizeof(pssParam);
4221 			bAllowMultiPartOp = true;
4222 			isRSA = true;
4223 			break;
4224 		case CKM_SHA512_RSA_PKCS_PSS:
4225 			if (pMechanism->pParameter == NULL_PTR ||
4226 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
4227 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512 ||
4228 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512)
4229 			{
4230 				ERROR_MSG("Invalid parameters");
4231 				return CKR_ARGUMENTS_BAD;
4232 			}
4233 			mechanism = AsymMech::RSA_SHA512_PKCS_PSS;
4234 			pssParam.hashAlg = HashAlgo::SHA512;
4235 			pssParam.mgf = AsymRSAMGF::MGF1_SHA512;
4236 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
4237 			param = &pssParam;
4238 			paramLen = sizeof(pssParam);
4239 			bAllowMultiPartOp = true;
4240 			isRSA = true;
4241 			break;
4242 		case CKM_DSA:
4243 			mechanism = AsymMech::DSA;
4244 			bAllowMultiPartOp = false;
4245 			isDSA = true;
4246 			break;
4247 		case CKM_DSA_SHA1:
4248 			mechanism = AsymMech::DSA_SHA1;
4249 			bAllowMultiPartOp = true;
4250 			isDSA = true;
4251 			break;
4252 		case CKM_DSA_SHA224:
4253 			mechanism = AsymMech::DSA_SHA224;
4254 			bAllowMultiPartOp = true;
4255 			isDSA = true;
4256 			break;
4257 		case CKM_DSA_SHA256:
4258 			mechanism = AsymMech::DSA_SHA256;
4259 			bAllowMultiPartOp = true;
4260 			isDSA = true;
4261 			break;
4262 		case CKM_DSA_SHA384:
4263 			mechanism = AsymMech::DSA_SHA384;
4264 			bAllowMultiPartOp = true;
4265 			isDSA = true;
4266 			break;
4267 		case CKM_DSA_SHA512:
4268 			mechanism = AsymMech::DSA_SHA512;
4269 			bAllowMultiPartOp = true;
4270 			isDSA = true;
4271 			break;
4272 #ifdef WITH_ECC
4273 		case CKM_ECDSA:
4274 			mechanism = AsymMech::ECDSA;
4275 			bAllowMultiPartOp = false;
4276 			isECDSA = true;
4277 			break;
4278 #endif
4279 #ifdef WITH_GOST
4280 		case CKM_GOSTR3410:
4281 			mechanism = AsymMech::GOST;
4282 			bAllowMultiPartOp = false;
4283 			break;
4284 		case CKM_GOSTR3410_WITH_GOSTR3411:
4285 			mechanism = AsymMech::GOST_GOST;
4286 			bAllowMultiPartOp = true;
4287 			break;
4288 #endif
4289 #ifdef WITH_EDDSA
4290 		case CKM_EDDSA:
4291 			mechanism = AsymMech::EDDSA;
4292 			bAllowMultiPartOp = false;
4293 			isEDDSA = true;
4294 			break;
4295 #endif
4296 		default:
4297 			return CKR_MECHANISM_INVALID;
4298 	}
4299 
4300 	AsymmetricAlgorithm* asymCrypto = NULL;
4301 	PrivateKey* privateKey = NULL;
4302 	if (isRSA)
4303 	{
4304 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
4305 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
4306 
4307 		privateKey = asymCrypto->newPrivateKey();
4308 		if (privateKey == NULL)
4309 		{
4310 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4311 			return CKR_HOST_MEMORY;
4312 		}
4313 
4314 		if (getRSAPrivateKey((RSAPrivateKey*)privateKey, token, key) != CKR_OK)
4315 		{
4316 			asymCrypto->recyclePrivateKey(privateKey);
4317 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4318 			return CKR_GENERAL_ERROR;
4319 		}
4320 	}
4321 	else if (isDSA)
4322 	{
4323 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
4324 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
4325 
4326 		privateKey = asymCrypto->newPrivateKey();
4327 		if (privateKey == NULL)
4328 		{
4329 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4330 			return CKR_HOST_MEMORY;
4331 		}
4332 
4333 		if (getDSAPrivateKey((DSAPrivateKey*)privateKey, token, key) != CKR_OK)
4334 		{
4335 			asymCrypto->recyclePrivateKey(privateKey);
4336 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4337 			return CKR_GENERAL_ERROR;
4338 		}
4339         }
4340 #ifdef WITH_ECC
4341 	else if (isECDSA)
4342 	{
4343 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
4344 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
4345 
4346 		privateKey = asymCrypto->newPrivateKey();
4347 		if (privateKey == NULL)
4348 		{
4349 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4350 			return CKR_HOST_MEMORY;
4351 		}
4352 
4353 		if (getECPrivateKey((ECPrivateKey*)privateKey, token, key) != CKR_OK)
4354 		{
4355 			asymCrypto->recyclePrivateKey(privateKey);
4356 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4357 			return CKR_GENERAL_ERROR;
4358 		}
4359 	}
4360 #endif
4361 #ifdef WITH_EDDSA
4362 	else if (isEDDSA)
4363 	{
4364 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
4365 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
4366 
4367 		privateKey = asymCrypto->newPrivateKey();
4368 		if (privateKey == NULL)
4369 		{
4370 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4371 			return CKR_HOST_MEMORY;
4372 		}
4373 
4374 		if (getEDPrivateKey((EDPrivateKey*)privateKey, token, key) != CKR_OK)
4375 		{
4376 			asymCrypto->recyclePrivateKey(privateKey);
4377 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4378 			return CKR_GENERAL_ERROR;
4379 		}
4380 	}
4381 #endif
4382 	else
4383 	{
4384 #ifdef WITH_GOST
4385 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
4386 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
4387 
4388 		privateKey = asymCrypto->newPrivateKey();
4389 		if (privateKey == NULL)
4390 		{
4391 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4392 			return CKR_HOST_MEMORY;
4393 		}
4394 
4395 		if (getGOSTPrivateKey((GOSTPrivateKey*)privateKey, token, key) != CKR_OK)
4396 		{
4397 			asymCrypto->recyclePrivateKey(privateKey);
4398 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4399 			return CKR_GENERAL_ERROR;
4400 		}
4401 #else
4402 		return CKR_MECHANISM_INVALID;
4403 #endif
4404         }
4405 
4406 	// Initialize signing
4407 	if (bAllowMultiPartOp && !asymCrypto->signInit(privateKey,mechanism,param,paramLen))
4408 	{
4409 		asymCrypto->recyclePrivateKey(privateKey);
4410 		CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
4411 		return CKR_MECHANISM_INVALID;
4412 	}
4413 
4414 	// Check if re-authentication is required
4415 	if (key->getBooleanValue(CKA_ALWAYS_AUTHENTICATE, false))
4416 	{
4417 		session->setReAuthentication(true);
4418 	}
4419 
4420 	session->setOpType(SESSION_OP_SIGN);
4421 	session->setAsymmetricCryptoOp(asymCrypto);
4422 	session->setMechanism(mechanism);
4423 	session->setParameters(param, paramLen);
4424 	session->setAllowMultiPartOp(bAllowMultiPartOp);
4425 	session->setAllowSinglePartOp(true);
4426 	session->setPrivateKey(privateKey);
4427 
4428 	return CKR_OK;
4429 }
4430 
4431 // Initialise a signing operation using the specified key and mechanism
C_SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)4432 CK_RV SoftHSM::C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4433 {
4434 	if (isMacMechanism(pMechanism))
4435 		return MacSignInit(hSession, pMechanism, hKey);
4436 	else
4437 		return AsymSignInit(hSession, pMechanism, hKey);
4438 }
4439 
4440 // MacAlgorithm version of C_Sign
MacSign(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4441 static CK_RV MacSign(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4442 {
4443 	MacAlgorithm* mac = session->getMacOp();
4444 	if (mac == NULL || !session->getAllowSinglePartOp())
4445 	{
4446 		session->resetOp();
4447 		return CKR_OPERATION_NOT_INITIALIZED;
4448 	}
4449 
4450 	// Size of the signature
4451 	CK_ULONG size = mac->getMacSize();
4452 	if (pSignature == NULL_PTR)
4453 	{
4454 		*pulSignatureLen = size;
4455 		return CKR_OK;
4456 	}
4457 
4458 	// Check buffer size
4459 	if (*pulSignatureLen < size)
4460 	{
4461 		*pulSignatureLen = size;
4462 		return CKR_BUFFER_TOO_SMALL;
4463 	}
4464 
4465 	// Get the data
4466 	ByteString data(pData, ulDataLen);
4467 
4468 	// Sign the data
4469 	if (!mac->signUpdate(data))
4470 	{
4471 		session->resetOp();
4472 		return CKR_GENERAL_ERROR;
4473 	}
4474 
4475 	// Get the signature
4476 	ByteString signature;
4477 	if (!mac->signFinal(signature))
4478 	{
4479 		session->resetOp();
4480 		return CKR_GENERAL_ERROR;
4481 	}
4482 
4483 	// Check size
4484 	if (signature.size() != size)
4485 	{
4486 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
4487 		session->resetOp();
4488 		return CKR_GENERAL_ERROR;
4489 	}
4490 	memcpy(pSignature, signature.byte_str(), size);
4491 	*pulSignatureLen = size;
4492 
4493 	session->resetOp();
4494 	return CKR_OK;
4495 }
4496 
4497 // AsymmetricAlgorithm version of C_Sign
AsymSign(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4498 static CK_RV AsymSign(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4499 {
4500 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
4501 	AsymMech::Type mechanism = session->getMechanism();
4502 	PrivateKey* privateKey = session->getPrivateKey();
4503 	size_t paramLen;
4504 	void* param = session->getParameters(paramLen);
4505 	if (asymCrypto == NULL || !session->getAllowSinglePartOp() || privateKey == NULL)
4506 	{
4507 		session->resetOp();
4508 		return CKR_OPERATION_NOT_INITIALIZED;
4509 	}
4510 
4511 	// Check if re-authentication is required
4512 	if (session->getReAuthentication())
4513 	{
4514 		session->resetOp();
4515 		return CKR_USER_NOT_LOGGED_IN;
4516 	}
4517 
4518 	// Size of the signature
4519 	CK_ULONG size = privateKey->getOutputLength();
4520 	if (pSignature == NULL_PTR)
4521 	{
4522 		*pulSignatureLen = size;
4523 		return CKR_OK;
4524 	}
4525 
4526 	// Check buffer size
4527 	if (*pulSignatureLen < size)
4528 	{
4529 		*pulSignatureLen = size;
4530 		return CKR_BUFFER_TOO_SMALL;
4531 	}
4532 
4533 	// Get the data
4534 	ByteString data;
4535 
4536 	// We must allow input length <= k and therfore need to prepend the data with zeroes.
4537 	if (mechanism == AsymMech::RSA) {
4538 		data.wipe(size-ulDataLen);
4539 	}
4540 
4541 	data += ByteString(pData, ulDataLen);
4542 	ByteString signature;
4543 
4544 	// Sign the data
4545 	if (session->getAllowMultiPartOp())
4546 	{
4547 		if (!asymCrypto->signUpdate(data) ||
4548 		    !asymCrypto->signFinal(signature))
4549 		{
4550 			session->resetOp();
4551 			return CKR_GENERAL_ERROR;
4552 		}
4553 	}
4554 	else if (!asymCrypto->sign(privateKey,data,signature,mechanism,param,paramLen))
4555 	{
4556 		session->resetOp();
4557 		return CKR_GENERAL_ERROR;
4558 	}
4559 
4560 	// Check size
4561 	if (signature.size() != size)
4562 	{
4563 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
4564 		session->resetOp();
4565 		return CKR_GENERAL_ERROR;
4566 	}
4567 	memcpy(pSignature, signature.byte_str(), size);
4568 	*pulSignatureLen = size;
4569 
4570 	session->resetOp();
4571 	return CKR_OK;
4572 }
4573 
4574 // Sign the data in a single pass operation
C_Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4575 CK_RV SoftHSM::C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4576 {
4577 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4578 
4579 	if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
4580 	if (pulSignatureLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
4581 
4582 	// Get the session
4583 	Session* session = (Session*)handleManager->getSession(hSession);
4584 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4585 
4586 	// Check if we are doing the correct operation
4587 	if (session->getOpType() != SESSION_OP_SIGN)
4588 		return CKR_OPERATION_NOT_INITIALIZED;
4589 
4590 	if (session->getMacOp() != NULL)
4591 		return MacSign(session, pData, ulDataLen,
4592 			       pSignature, pulSignatureLen);
4593 	else
4594 		return AsymSign(session, pData, ulDataLen,
4595 				pSignature, pulSignatureLen);
4596 }
4597 
4598 // MacAlgorithm version of C_SignUpdate
MacSignUpdate(Session * session,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)4599 static CK_RV MacSignUpdate(Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
4600 {
4601 	MacAlgorithm* mac = session->getMacOp();
4602 	if (mac == NULL || !session->getAllowMultiPartOp())
4603 	{
4604 		session->resetOp();
4605 		return CKR_OPERATION_NOT_INITIALIZED;
4606 	}
4607 
4608 	// Get the part
4609 	ByteString part(pPart, ulPartLen);
4610 
4611 	// Sign the data
4612 	if (!mac->signUpdate(part))
4613 	{
4614 		session->resetOp();
4615 		return CKR_GENERAL_ERROR;
4616 	}
4617 
4618 	session->setAllowSinglePartOp(false);
4619 	return CKR_OK;
4620 }
4621 
4622 // AsymmetricAlgorithm version of C_SignUpdate
AsymSignUpdate(Session * session,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)4623 static CK_RV AsymSignUpdate(Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
4624 {
4625 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
4626 	if (asymCrypto == NULL || !session->getAllowMultiPartOp())
4627 	{
4628 		session->resetOp();
4629 		return CKR_OPERATION_NOT_INITIALIZED;
4630 	}
4631 
4632 	// Check if re-authentication is required
4633 	if (session->getReAuthentication())
4634 	{
4635 		session->resetOp();
4636 		return CKR_USER_NOT_LOGGED_IN;
4637 	}
4638 
4639 	// Get the part
4640 	ByteString part(pPart, ulPartLen);
4641 
4642 	// Sign the data
4643 	if (!asymCrypto->signUpdate(part))
4644 	{
4645 		session->resetOp();
4646 		return CKR_GENERAL_ERROR;
4647 	}
4648 
4649 	session->setAllowSinglePartOp(false);
4650 	return CKR_OK;
4651 }
4652 
4653 // Update a running signing operation with additional data
C_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)4654 CK_RV SoftHSM::C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
4655 {
4656 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4657 
4658 	if (pPart == NULL_PTR) return CKR_ARGUMENTS_BAD;
4659 
4660 	// Get the session
4661 	Session* session = (Session*)handleManager->getSession(hSession);
4662 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4663 
4664 	// Check if we are doing the correct operation
4665 	if (session->getOpType() != SESSION_OP_SIGN)
4666 		return CKR_OPERATION_NOT_INITIALIZED;
4667 
4668 	if (session->getMacOp() != NULL)
4669 		return MacSignUpdate(session, pPart, ulPartLen);
4670 	else
4671 		return AsymSignUpdate(session, pPart, ulPartLen);
4672 }
4673 
4674 // MacAlgorithm version of C_SignFinal
MacSignFinal(Session * session,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4675 static CK_RV MacSignFinal(Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4676 {
4677 	MacAlgorithm* mac = session->getMacOp();
4678 	if (mac == NULL)
4679 	{
4680 		session->resetOp();
4681 		return CKR_OPERATION_NOT_INITIALIZED;
4682 	}
4683 
4684 	// Size of the signature
4685 	CK_ULONG size = mac->getMacSize();
4686 	if (pSignature == NULL_PTR)
4687 	{
4688 		*pulSignatureLen = size;
4689 		return CKR_OK;
4690 	}
4691 
4692 	// Check buffer size
4693 	if (*pulSignatureLen < size)
4694 	{
4695 		*pulSignatureLen = size;
4696 		return CKR_BUFFER_TOO_SMALL;
4697 	}
4698 
4699 	// Get the signature
4700 	ByteString signature;
4701 	if (!mac->signFinal(signature))
4702 	{
4703 		session->resetOp();
4704 		return CKR_GENERAL_ERROR;
4705 	}
4706 
4707 	// Check size
4708 	if (signature.size() != size)
4709 	{
4710 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
4711 		session->resetOp();
4712 		return CKR_GENERAL_ERROR;
4713 	}
4714 	memcpy(pSignature, signature.byte_str(), size);
4715 	*pulSignatureLen = size;
4716 
4717 	session->resetOp();
4718 	return CKR_OK;
4719 }
4720 
4721 // AsymmetricAlgorithm version of C_SignFinal
AsymSignFinal(Session * session,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4722 static CK_RV AsymSignFinal(Session* session, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4723 {
4724 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
4725 	PrivateKey* privateKey = session->getPrivateKey();
4726 	if (asymCrypto == NULL || privateKey == NULL)
4727 	{
4728 		session->resetOp();
4729 		return CKR_OPERATION_NOT_INITIALIZED;
4730 	}
4731 
4732 	// Check if re-authentication is required
4733 	if (session->getReAuthentication())
4734 	{
4735 		session->resetOp();
4736 		return CKR_USER_NOT_LOGGED_IN;
4737 	}
4738 
4739 	// Size of the signature
4740 	CK_ULONG size = privateKey->getOutputLength();
4741 	if (pSignature == NULL_PTR)
4742 	{
4743 		*pulSignatureLen = size;
4744 		return CKR_OK;
4745 	}
4746 
4747 	// Check buffer size
4748 	if (*pulSignatureLen < size)
4749 	{
4750 		*pulSignatureLen = size;
4751 		return CKR_BUFFER_TOO_SMALL;
4752 	}
4753 
4754 	// Get the signature
4755 	ByteString signature;
4756 	if (!asymCrypto->signFinal(signature))
4757 	{
4758 		session->resetOp();
4759 		return CKR_GENERAL_ERROR;
4760 	}
4761 
4762 	// Check size
4763 	if (signature.size() != size)
4764 	{
4765 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
4766 		session->resetOp();
4767 		return CKR_GENERAL_ERROR;
4768 	}
4769 	memcpy(pSignature, signature.byte_str(), size);
4770 	*pulSignatureLen = size;
4771 
4772 	session->resetOp();
4773 	return CKR_OK;
4774 }
4775 
4776 // Finalise a running signing operation and return the signature
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)4777 CK_RV SoftHSM::C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
4778 {
4779 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4780 
4781 	if (pulSignatureLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
4782 
4783 	// Get the session
4784 	Session* session = (Session*)handleManager->getSession(hSession);
4785 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4786 
4787 	// Check if we are doing the correct operation
4788 	if (session->getOpType() != SESSION_OP_SIGN || !session->getAllowMultiPartOp())
4789 		return CKR_OPERATION_NOT_INITIALIZED;
4790 
4791 	if (session->getMacOp() != NULL)
4792 		return MacSignFinal(session, pSignature, pulSignatureLen);
4793 	else
4794 		return AsymSignFinal(session, pSignature, pulSignatureLen);
4795 }
4796 
4797 // Initialise a signing operation that allows recovery of the signed data
C_SignRecoverInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR,CK_OBJECT_HANDLE)4798 CK_RV SoftHSM::C_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR /*pMechanism*/, CK_OBJECT_HANDLE /*hKey*/)
4799 {
4800 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4801 
4802 	// Get the session
4803 	Session* session = (Session*)handleManager->getSession(hSession);
4804 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4805 
4806 	// Check if we have another operation
4807 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
4808 
4809 	return CKR_FUNCTION_NOT_SUPPORTED;
4810 }
4811 
4812 // Perform a single part signing operation that allows recovery of the signed data
C_SignRecover(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)4813 CK_RV SoftHSM::C_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pData*/, CK_ULONG /*ulDataLen*/, CK_BYTE_PTR /*pSignature*/, CK_ULONG_PTR /*pulSignatureLen*/)
4814 {
4815 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4816 
4817 	// Get the session
4818 	Session* session = (Session*)handleManager->getSession(hSession);
4819 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4820 
4821 	return CKR_FUNCTION_NOT_SUPPORTED;
4822 }
4823 
4824 // MacAlgorithm version of C_VerifyInit
MacVerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)4825 CK_RV SoftHSM::MacVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4826 {
4827 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4828 
4829 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
4830 
4831 	// Get the session
4832 	Session* session = (Session*)handleManager->getSession(hSession);
4833 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4834 
4835 	// Check if we have another operation
4836 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
4837 
4838 	// Get the token
4839 	Token* token = session->getToken();
4840 	if (token == NULL) return CKR_GENERAL_ERROR;
4841 
4842 	// Check the key handle.
4843 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
4844 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
4845 
4846 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
4847 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
4848 
4849 	// Check read user credentials
4850 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
4851 	if (rv != CKR_OK)
4852 	{
4853 		if (rv == CKR_USER_NOT_LOGGED_IN)
4854 			INFO_MSG("User is not authorized");
4855 
4856 		return rv;
4857 	}
4858 
4859 	// Check if key can be used for verifying
4860 	if (!key->getBooleanValue(CKA_VERIFY, false))
4861 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
4862 
4863 	// Check if the specified mechanism is allowed for the key
4864 	if (!isMechanismPermitted(key, pMechanism))
4865 		return CKR_MECHANISM_INVALID;
4866 
4867 	// Get key info
4868 	CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
4869 
4870 	// Get the MAC algorithm matching the mechanism
4871 	// Also check mechanism constraints
4872 	MacAlgo::Type algo = MacAlgo::Unknown;
4873 	size_t bb = 8;
4874 	size_t minSize = 0;
4875 	switch(pMechanism->mechanism) {
4876 #ifndef WITH_FIPS
4877 		case CKM_MD5_HMAC:
4878 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_MD5_HMAC)
4879 				return CKR_KEY_TYPE_INCONSISTENT;
4880 			minSize = 16;
4881 			algo = MacAlgo::HMAC_MD5;
4882 			break;
4883 #endif
4884 		case CKM_SHA_1_HMAC:
4885 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA_1_HMAC)
4886 				return CKR_KEY_TYPE_INCONSISTENT;
4887 			minSize = 20;
4888 			algo = MacAlgo::HMAC_SHA1;
4889 			break;
4890 		case CKM_SHA224_HMAC:
4891 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA224_HMAC)
4892 				return CKR_KEY_TYPE_INCONSISTENT;
4893 			minSize = 28;
4894 			algo = MacAlgo::HMAC_SHA224;
4895 			break;
4896 		case CKM_SHA256_HMAC:
4897 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA256_HMAC)
4898 				return CKR_KEY_TYPE_INCONSISTENT;
4899 			minSize = 32;
4900 			algo = MacAlgo::HMAC_SHA256;
4901 			break;
4902 		case CKM_SHA384_HMAC:
4903 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA384_HMAC)
4904 				return CKR_KEY_TYPE_INCONSISTENT;
4905 			minSize = 48;
4906 			algo = MacAlgo::HMAC_SHA384;
4907 			break;
4908 		case CKM_SHA512_HMAC:
4909 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_SHA512_HMAC)
4910 				return CKR_KEY_TYPE_INCONSISTENT;
4911 			minSize = 64;
4912 			algo = MacAlgo::HMAC_SHA512;
4913 			break;
4914 #ifdef WITH_GOST
4915 		case CKM_GOSTR3411_HMAC:
4916 			if (keyType != CKK_GENERIC_SECRET && keyType != CKK_GOST28147)
4917 				return CKR_KEY_TYPE_INCONSISTENT;
4918 			minSize = 32;
4919 			algo = MacAlgo::HMAC_GOST;
4920 			break;
4921 #endif
4922 		case CKM_DES3_CMAC:
4923 			if (keyType != CKK_DES2 && keyType != CKK_DES3)
4924 				return CKR_KEY_TYPE_INCONSISTENT;
4925 			algo = MacAlgo::CMAC_DES;
4926 			bb = 7;
4927 			break;
4928 		case CKM_AES_CMAC:
4929 			if (keyType != CKK_AES)
4930 				return CKR_KEY_TYPE_INCONSISTENT;
4931 			algo = MacAlgo::CMAC_AES;
4932 			break;
4933 		default:
4934 			return CKR_MECHANISM_INVALID;
4935 	}
4936 	MacAlgorithm* mac = CryptoFactory::i()->getMacAlgorithm(algo);
4937 	if (mac == NULL) return CKR_MECHANISM_INVALID;
4938 
4939 	SymmetricKey* pubkey = new SymmetricKey();
4940 
4941 	if (getSymmetricKey(pubkey, token, key) != CKR_OK)
4942 	{
4943 		mac->recycleKey(pubkey);
4944 		CryptoFactory::i()->recycleMacAlgorithm(mac);
4945 		return CKR_GENERAL_ERROR;
4946 	}
4947 
4948 	// Adjust key bit length
4949 	pubkey->setBitLen(pubkey->getKeyBits().size() * bb);
4950 
4951 	// Check key size
4952 	if (pubkey->getBitLen() < (minSize*8))
4953 	{
4954 		mac->recycleKey(pubkey);
4955 		CryptoFactory::i()->recycleMacAlgorithm(mac);
4956 		return CKR_KEY_SIZE_RANGE;
4957 	}
4958 
4959 	// Initialize verifying
4960 	if (!mac->verifyInit(pubkey))
4961 	{
4962 		mac->recycleKey(pubkey);
4963 		CryptoFactory::i()->recycleMacAlgorithm(mac);
4964 		return CKR_MECHANISM_INVALID;
4965 	}
4966 
4967 	session->setOpType(SESSION_OP_VERIFY);
4968 	session->setMacOp(mac);
4969 	session->setAllowMultiPartOp(true);
4970 	session->setAllowSinglePartOp(true);
4971 	session->setSymmetricKey(pubkey);
4972 
4973 	return CKR_OK;
4974 }
4975 
4976 // AsymmetricAlgorithm version of C_VerifyInit
AsymVerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)4977 CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
4978 {
4979 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
4980 
4981 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
4982 
4983 	// Get the session
4984 	Session* session = (Session*)handleManager->getSession(hSession);
4985 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
4986 
4987 	// Check if we have another operation
4988 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
4989 
4990 	// Get the token
4991 	Token* token = session->getToken();
4992 	if (token == NULL) return CKR_GENERAL_ERROR;
4993 
4994 	// Check the key handle.
4995 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
4996 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
4997 
4998 	CK_BBOOL isOnToken = key->getBooleanValue(CKA_TOKEN, false);
4999 	CK_BBOOL isPrivate = key->getBooleanValue(CKA_PRIVATE, true);
5000 
5001 	// Check read user credentials
5002 	CK_RV rv = haveRead(session->getState(), isOnToken, isPrivate);
5003 	if (rv != CKR_OK)
5004 	{
5005 		if (rv == CKR_USER_NOT_LOGGED_IN)
5006 			INFO_MSG("User is not authorized");
5007 
5008 		return rv;
5009 	}
5010 
5011 	// Check if key can be used for verifying
5012 	if (!key->getBooleanValue(CKA_VERIFY, false))
5013 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
5014 
5015 	// Check if the specified mechanism is allowed for the key
5016 	if (!isMechanismPermitted(key, pMechanism))
5017 		return CKR_MECHANISM_INVALID;
5018 
5019 	// Get the asymmetric algorithm matching the mechanism
5020 	AsymMech::Type mechanism = AsymMech::Unknown;
5021 	void* param = NULL;
5022 	size_t paramLen = 0;
5023 	RSA_PKCS_PSS_PARAMS pssParam;
5024 	bool bAllowMultiPartOp;
5025 	bool isRSA = false;
5026 	bool isDSA = false;
5027 #ifdef WITH_ECC
5028 	bool isECDSA = false;
5029 #endif
5030 #ifdef WITH_EDDSA
5031 	bool isEDDSA = false;
5032 #endif
5033 	switch(pMechanism->mechanism) {
5034 		case CKM_RSA_PKCS:
5035 			mechanism = AsymMech::RSA_PKCS;
5036 			bAllowMultiPartOp = false;
5037 			isRSA = true;
5038 			break;
5039 		case CKM_RSA_X_509:
5040 			mechanism = AsymMech::RSA;
5041 			bAllowMultiPartOp = false;
5042 			isRSA = true;
5043 			break;
5044 #ifndef WITH_FIPS
5045 		case CKM_MD5_RSA_PKCS:
5046 			mechanism = AsymMech::RSA_MD5_PKCS;
5047 			bAllowMultiPartOp = true;
5048 			isRSA = true;
5049 			break;
5050 #endif
5051 		case CKM_SHA1_RSA_PKCS:
5052 			mechanism = AsymMech::RSA_SHA1_PKCS;
5053 			bAllowMultiPartOp = true;
5054 			isRSA = true;
5055 			break;
5056 		case CKM_SHA224_RSA_PKCS:
5057 			mechanism = AsymMech::RSA_SHA224_PKCS;
5058 			bAllowMultiPartOp = true;
5059 			isRSA = true;
5060 			break;
5061 		case CKM_SHA256_RSA_PKCS:
5062 			mechanism = AsymMech::RSA_SHA256_PKCS;
5063 			bAllowMultiPartOp = true;
5064 			isRSA = true;
5065 			break;
5066 		case CKM_SHA384_RSA_PKCS:
5067 			mechanism = AsymMech::RSA_SHA384_PKCS;
5068 			bAllowMultiPartOp = true;
5069 			isRSA = true;
5070 			break;
5071 		case CKM_SHA512_RSA_PKCS:
5072 			mechanism = AsymMech::RSA_SHA512_PKCS;
5073 			bAllowMultiPartOp = true;
5074 			isRSA = true;
5075 			break;
5076 #ifdef WITH_RAW_PSS
5077 		case CKM_RSA_PKCS_PSS:
5078 			if (pMechanism->pParameter == NULL_PTR ||
5079 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS))
5080 			{
5081 				ERROR_MSG("Invalid parameters");
5082 				return CKR_ARGUMENTS_BAD;
5083 			}
5084 			mechanism = AsymMech::RSA_PKCS_PSS;
5085 
5086 			unsigned long expectedMgf;
5087 			switch(CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg) {
5088 				case CKM_SHA_1:
5089 					pssParam.hashAlg = HashAlgo::SHA1;
5090 					pssParam.mgf = AsymRSAMGF::MGF1_SHA1;
5091 					expectedMgf = CKG_MGF1_SHA1;
5092 					break;
5093 				case CKM_SHA224:
5094 					pssParam.hashAlg = HashAlgo::SHA224;
5095 					pssParam.mgf = AsymRSAMGF::MGF1_SHA224;
5096 					expectedMgf = CKG_MGF1_SHA224;
5097 					break;
5098 				case CKM_SHA256:
5099 					pssParam.hashAlg = HashAlgo::SHA256;
5100 					pssParam.mgf = AsymRSAMGF::MGF1_SHA256;
5101 					expectedMgf = CKG_MGF1_SHA256;
5102 					break;
5103 				case CKM_SHA384:
5104 					pssParam.hashAlg = HashAlgo::SHA384;
5105 					pssParam.mgf = AsymRSAMGF::MGF1_SHA384;
5106 					expectedMgf = CKG_MGF1_SHA384;
5107 					break;
5108 				case CKM_SHA512:
5109 					pssParam.hashAlg = HashAlgo::SHA512;
5110 					pssParam.mgf = AsymRSAMGF::MGF1_SHA512;
5111 					expectedMgf = CKG_MGF1_SHA512;
5112 					break;
5113 				default:
5114 					return CKR_ARGUMENTS_BAD;
5115 			}
5116 
5117 			if (CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != expectedMgf) {
5118 				return CKR_ARGUMENTS_BAD;
5119 			}
5120 
5121 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5122 			param = &pssParam;
5123 			paramLen = sizeof(pssParam);
5124 			bAllowMultiPartOp = false;
5125 			isRSA = true;
5126 			break;
5127 #endif
5128 		case CKM_SHA1_RSA_PKCS_PSS:
5129 			if (pMechanism->pParameter == NULL_PTR ||
5130 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
5131 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA_1 ||
5132 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA1)
5133 			{
5134 				ERROR_MSG("Invalid parameters");
5135 				return CKR_ARGUMENTS_BAD;
5136 			}
5137 			mechanism = AsymMech::RSA_SHA1_PKCS_PSS;
5138 			pssParam.hashAlg = HashAlgo::SHA1;
5139 			pssParam.mgf = AsymRSAMGF::MGF1_SHA1;
5140 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5141 			param = &pssParam;
5142 			paramLen = sizeof(pssParam);
5143 			bAllowMultiPartOp = true;
5144 			isRSA = true;
5145 			break;
5146 		case CKM_SHA224_RSA_PKCS_PSS:
5147 			if (pMechanism->pParameter == NULL_PTR ||
5148 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
5149 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA224 ||
5150 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA224)
5151 			{
5152 				ERROR_MSG("Invalid parameters");
5153 				return CKR_ARGUMENTS_BAD;
5154 			}
5155 			mechanism = AsymMech::RSA_SHA224_PKCS_PSS;
5156 			pssParam.hashAlg = HashAlgo::SHA224;
5157 			pssParam.mgf = AsymRSAMGF::MGF1_SHA224;
5158 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5159 			param = &pssParam;
5160 			paramLen = sizeof(pssParam);
5161 			bAllowMultiPartOp = true;
5162 			isRSA = true;
5163 			break;
5164 		case CKM_SHA256_RSA_PKCS_PSS:
5165 			if (pMechanism->pParameter == NULL_PTR ||
5166 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
5167 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA256 ||
5168 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA256)
5169 			{
5170 				ERROR_MSG("Invalid parameters");
5171 				return CKR_ARGUMENTS_BAD;
5172 			}
5173 			mechanism = AsymMech::RSA_SHA256_PKCS_PSS;
5174 			pssParam.hashAlg = HashAlgo::SHA256;
5175 			pssParam.mgf = AsymRSAMGF::MGF1_SHA256;
5176 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5177 			param = &pssParam;
5178 			paramLen = sizeof(pssParam);
5179 			bAllowMultiPartOp = true;
5180 			isRSA = true;
5181 			break;
5182 		case CKM_SHA384_RSA_PKCS_PSS:
5183 			if (pMechanism->pParameter == NULL_PTR ||
5184 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
5185 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA384 ||
5186 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA384)
5187 			{
5188 				ERROR_MSG("Invalid parameters");
5189 				return CKR_ARGUMENTS_BAD;
5190 			}
5191 			mechanism = AsymMech::RSA_SHA384_PKCS_PSS;
5192 			pssParam.hashAlg = HashAlgo::SHA384;
5193 			pssParam.mgf = AsymRSAMGF::MGF1_SHA384;
5194 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5195 			param = &pssParam;
5196 			paramLen = sizeof(pssParam);
5197 			bAllowMultiPartOp = true;
5198 			isRSA = true;
5199 			break;
5200 		case CKM_SHA512_RSA_PKCS_PSS:
5201 			if (pMechanism->pParameter == NULL_PTR ||
5202 			    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) ||
5203 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->hashAlg != CKM_SHA512 ||
5204 			    CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->mgf != CKG_MGF1_SHA512)
5205 			{
5206 				ERROR_MSG("Invalid parameters");
5207 				return CKR_ARGUMENTS_BAD;
5208 			}
5209 			mechanism = AsymMech::RSA_SHA512_PKCS_PSS;
5210 			pssParam.hashAlg = HashAlgo::SHA512;
5211 			pssParam.mgf = AsymRSAMGF::MGF1_SHA512;
5212 			pssParam.sLen = CK_RSA_PKCS_PSS_PARAMS_PTR(pMechanism->pParameter)->sLen;
5213 			param = &pssParam;
5214 			paramLen = sizeof(pssParam);
5215 			bAllowMultiPartOp = true;
5216 			isRSA = true;
5217 			break;
5218 		case CKM_DSA:
5219 			mechanism = AsymMech::DSA;
5220 			bAllowMultiPartOp = false;
5221 			isDSA = true;
5222 			break;
5223 		case CKM_DSA_SHA1:
5224 			mechanism = AsymMech::DSA_SHA1;
5225 			bAllowMultiPartOp = true;
5226 			isDSA = true;
5227 			break;
5228 		case CKM_DSA_SHA224:
5229 			mechanism = AsymMech::DSA_SHA224;
5230 			bAllowMultiPartOp = true;
5231 			isDSA = true;
5232 			break;
5233 		case CKM_DSA_SHA256:
5234 			mechanism = AsymMech::DSA_SHA256;
5235 			bAllowMultiPartOp = true;
5236 			isDSA = true;
5237 			break;
5238 		case CKM_DSA_SHA384:
5239 			mechanism = AsymMech::DSA_SHA384;
5240 			bAllowMultiPartOp = true;
5241 			isDSA = true;
5242 			break;
5243 		case CKM_DSA_SHA512:
5244 			mechanism = AsymMech::DSA_SHA512;
5245 			bAllowMultiPartOp = true;
5246 			isDSA = true;
5247 			break;
5248 #ifdef WITH_ECC
5249 		case CKM_ECDSA:
5250 			mechanism = AsymMech::ECDSA;
5251 			bAllowMultiPartOp = false;
5252 			isECDSA = true;
5253 			break;
5254 #endif
5255 #ifdef WITH_GOST
5256 		case CKM_GOSTR3410:
5257 			mechanism = AsymMech::GOST;
5258 			bAllowMultiPartOp = false;
5259 			break;
5260 		case CKM_GOSTR3410_WITH_GOSTR3411:
5261 			mechanism = AsymMech::GOST_GOST;
5262 			bAllowMultiPartOp = true;
5263 			break;
5264 #endif
5265 #ifdef WITH_EDDSA
5266 		case CKM_EDDSA:
5267 			mechanism = AsymMech::EDDSA;
5268 			bAllowMultiPartOp = false;
5269 			isEDDSA = true;
5270 			break;
5271 #endif
5272 		default:
5273 			return CKR_MECHANISM_INVALID;
5274 	}
5275 
5276 	AsymmetricAlgorithm* asymCrypto = NULL;
5277 	PublicKey* publicKey = NULL;
5278 	if (isRSA)
5279 	{
5280 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
5281 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
5282 
5283 		publicKey = asymCrypto->newPublicKey();
5284 		if (publicKey == NULL)
5285 		{
5286 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5287 			return CKR_HOST_MEMORY;
5288 		}
5289 
5290 		if (getRSAPublicKey((RSAPublicKey*)publicKey, token, key) != CKR_OK)
5291 		{
5292 			asymCrypto->recyclePublicKey(publicKey);
5293 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5294 			return CKR_GENERAL_ERROR;
5295 		}
5296 	}
5297 	else if (isDSA)
5298 	{
5299 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
5300 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
5301 
5302 		publicKey = asymCrypto->newPublicKey();
5303 		if (publicKey == NULL)
5304 		{
5305 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5306 			return CKR_HOST_MEMORY;
5307 		}
5308 
5309 		if (getDSAPublicKey((DSAPublicKey*)publicKey, token, key) != CKR_OK)
5310 		{
5311 			asymCrypto->recyclePublicKey(publicKey);
5312 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5313 			return CKR_GENERAL_ERROR;
5314 		}
5315         }
5316 #ifdef WITH_ECC
5317 	else if (isECDSA)
5318 	{
5319 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
5320 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
5321 
5322 		publicKey = asymCrypto->newPublicKey();
5323 		if (publicKey == NULL)
5324 		{
5325 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5326 			return CKR_HOST_MEMORY;
5327 		}
5328 
5329 		if (getECPublicKey((ECPublicKey*)publicKey, token, key) != CKR_OK)
5330 		{
5331 			asymCrypto->recyclePublicKey(publicKey);
5332 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5333 			return CKR_GENERAL_ERROR;
5334 		}
5335 	}
5336 #endif
5337 #ifdef WITH_EDDSA
5338 	else if (isEDDSA)
5339 	{
5340 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
5341 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
5342 
5343 		publicKey = asymCrypto->newPublicKey();
5344 		if (publicKey == NULL)
5345 		{
5346 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5347 			return CKR_HOST_MEMORY;
5348 		}
5349 
5350 		if (getEDPublicKey((EDPublicKey*)publicKey, token, key) != CKR_OK)
5351 		{
5352 			asymCrypto->recyclePublicKey(publicKey);
5353 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5354 			return CKR_GENERAL_ERROR;
5355 		}
5356 	}
5357 #endif
5358 	else
5359 	{
5360 #ifdef WITH_GOST
5361 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
5362 		if (asymCrypto == NULL) return CKR_MECHANISM_INVALID;
5363 
5364 		publicKey = asymCrypto->newPublicKey();
5365 		if (publicKey == NULL)
5366 		{
5367 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5368 			return CKR_HOST_MEMORY;
5369 		}
5370 
5371 		if (getGOSTPublicKey((GOSTPublicKey*)publicKey, token, key) != CKR_OK)
5372 		{
5373 			asymCrypto->recyclePublicKey(publicKey);
5374 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5375 			return CKR_GENERAL_ERROR;
5376 		}
5377 #else
5378 		return CKR_MECHANISM_INVALID;
5379 #endif
5380         }
5381 
5382 	// Initialize verifying
5383 	if (bAllowMultiPartOp && !asymCrypto->verifyInit(publicKey,mechanism,param,paramLen))
5384 	{
5385 		asymCrypto->recyclePublicKey(publicKey);
5386 		CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
5387 		return CKR_MECHANISM_INVALID;
5388 	}
5389 
5390 	session->setOpType(SESSION_OP_VERIFY);
5391 	session->setAsymmetricCryptoOp(asymCrypto);
5392 	session->setMechanism(mechanism);
5393 	session->setParameters(param, paramLen);
5394 	session->setAllowMultiPartOp(bAllowMultiPartOp);
5395 	session->setAllowSinglePartOp(true);
5396 	session->setPublicKey(publicKey);
5397 
5398 	return CKR_OK;
5399 }
5400 
5401 // Initialise a verification operation using the specified key and mechanism
C_VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)5402 CK_RV SoftHSM::C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
5403 {
5404 	if (isMacMechanism(pMechanism))
5405 		return MacVerifyInit(hSession, pMechanism, hKey);
5406 	else
5407 		return AsymVerifyInit(hSession, pMechanism, hKey);
5408 }
5409 
5410 // MacAlgorithm version of C_Verify
MacVerify(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5411 static CK_RV MacVerify(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5412 {
5413 	MacAlgorithm* mac = session->getMacOp();
5414 	if (mac == NULL || !session->getAllowSinglePartOp())
5415 	{
5416 		session->resetOp();
5417 		return CKR_OPERATION_NOT_INITIALIZED;
5418 	}
5419 
5420 	// Size of the signature
5421 	CK_ULONG size = mac->getMacSize();
5422 
5423 	// Check buffer size
5424 	if (ulSignatureLen != size)
5425 	{
5426 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
5427 		session->resetOp();
5428 		return CKR_SIGNATURE_LEN_RANGE;
5429 	}
5430 
5431 	// Get the data
5432 	ByteString data(pData, ulDataLen);
5433 
5434 	// Verify the data
5435 	if (!mac->verifyUpdate(data))
5436 	{
5437 		session->resetOp();
5438 		return CKR_GENERAL_ERROR;
5439 	}
5440 
5441 	// Get the signature
5442 	ByteString signature(pSignature, ulSignatureLen);
5443 
5444 	// Verify the signature
5445 	if (!mac->verifyFinal(signature))
5446 	{
5447 		session->resetOp();
5448 		return CKR_SIGNATURE_INVALID;
5449 	}
5450 
5451 	session->resetOp();
5452 	return CKR_OK;
5453 }
5454 
5455 // AsymmetricAlgorithm version of C_Verify
AsymVerify(Session * session,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5456 static CK_RV AsymVerify(Session* session, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5457 {
5458 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
5459 	AsymMech::Type mechanism = session->getMechanism();
5460 	PublicKey* publicKey = session->getPublicKey();
5461 	size_t paramLen;
5462 	void* param = session->getParameters(paramLen);
5463 	if (asymCrypto == NULL || !session->getAllowSinglePartOp() || publicKey == NULL)
5464 	{
5465 		session->resetOp();
5466 		return CKR_OPERATION_NOT_INITIALIZED;
5467 	}
5468 
5469 	// Size of the signature
5470 	CK_ULONG size = publicKey->getOutputLength();
5471 
5472 	// Check buffer size
5473 	if (ulSignatureLen != size)
5474 	{
5475 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
5476 		session->resetOp();
5477 		return CKR_SIGNATURE_LEN_RANGE;
5478 	}
5479 
5480 	// Get the data
5481 	ByteString data;
5482 
5483 	// We must allow input length <= k and therfore need to prepend the data with zeroes.
5484 	if (mechanism == AsymMech::RSA) {
5485 		data.wipe(size-ulDataLen);
5486 	}
5487 
5488 	data += ByteString(pData, ulDataLen);
5489 	ByteString signature(pSignature, ulSignatureLen);
5490 
5491 	// Verify the data
5492 	if (session->getAllowMultiPartOp())
5493 	{
5494 		if (!asymCrypto->verifyUpdate(data) ||
5495 		    !asymCrypto->verifyFinal(signature))
5496 		{
5497 			session->resetOp();
5498 			return CKR_SIGNATURE_INVALID;
5499 		}
5500 	}
5501 	else if (!asymCrypto->verify(publicKey,data,signature,mechanism,param,paramLen))
5502 	{
5503 		session->resetOp();
5504 		return CKR_SIGNATURE_INVALID;
5505 	}
5506 
5507 	session->resetOp();
5508 	return CKR_OK;
5509 }
5510 
5511 // Perform a single pass verification operation
C_Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5512 CK_RV SoftHSM::C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5513 {
5514 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5515 
5516 	if (pData == NULL_PTR) return CKR_ARGUMENTS_BAD;
5517 	if (pSignature == NULL_PTR) return CKR_ARGUMENTS_BAD;
5518 
5519 	// Get the session
5520 	Session* session = (Session*)handleManager->getSession(hSession);
5521 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5522 
5523 	// Check if we are doing the correct operation
5524 	if (session->getOpType() != SESSION_OP_VERIFY)
5525 		return CKR_OPERATION_NOT_INITIALIZED;
5526 
5527 	if (session->getMacOp() != NULL)
5528 		return MacVerify(session, pData, ulDataLen,
5529 				 pSignature, ulSignatureLen);
5530 	else
5531 		return AsymVerify(session, pData, ulDataLen,
5532 				  pSignature, ulSignatureLen);
5533 }
5534 
5535 // MacAlgorithm version of C_VerifyUpdate
MacVerifyUpdate(Session * session,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)5536 static CK_RV MacVerifyUpdate(Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
5537 {
5538 	MacAlgorithm* mac = session->getMacOp();
5539 	if (mac == NULL || !session->getAllowMultiPartOp())
5540 	{
5541 		session->resetOp();
5542 		return CKR_OPERATION_NOT_INITIALIZED;
5543 	}
5544 
5545 	// Get the part
5546 	ByteString part(pPart, ulPartLen);
5547 
5548 	// Verify the data
5549 	if (!mac->verifyUpdate(part))
5550 	{
5551 		// verifyUpdate can't fail for a logical reason, so we assume total breakdown.
5552 		session->resetOp();
5553 		return CKR_GENERAL_ERROR;
5554 	}
5555 
5556 	session->setAllowSinglePartOp(false);
5557 	return CKR_OK;
5558 }
5559 
5560 // AsymmetricAlgorithm version of C_VerifyUpdate
AsymVerifyUpdate(Session * session,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)5561 static CK_RV AsymVerifyUpdate(Session* session, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
5562 {
5563 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
5564 	if (asymCrypto == NULL || !session->getAllowMultiPartOp())
5565 	{
5566 		session->resetOp();
5567 		return CKR_OPERATION_NOT_INITIALIZED;
5568 	}
5569 
5570 	// Get the part
5571 	ByteString part(pPart, ulPartLen);
5572 
5573 	// Verify the data
5574 	if (!asymCrypto->verifyUpdate(part))
5575 	{
5576 		// verifyUpdate can't fail for a logical reason, so we assume total breakdown.
5577 		session->resetOp();
5578 		return CKR_GENERAL_ERROR;
5579 	}
5580 
5581 	session->setAllowSinglePartOp(false);
5582 	return CKR_OK;
5583 }
5584 
5585 // Update a running verification operation with additional data
C_VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)5586 CK_RV SoftHSM::C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
5587 {
5588 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5589 
5590 	if (pPart == NULL_PTR) return CKR_ARGUMENTS_BAD;
5591 
5592 	// Get the session
5593 	Session* session = (Session*)handleManager->getSession(hSession);
5594 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5595 
5596 	// Check if we are doing the correct operation
5597 	if (session->getOpType() != SESSION_OP_VERIFY)
5598 		return CKR_OPERATION_NOT_INITIALIZED;
5599 
5600 	if (session->getMacOp() != NULL)
5601 		return MacVerifyUpdate(session, pPart, ulPartLen);
5602 	else
5603 		return AsymVerifyUpdate(session, pPart, ulPartLen);
5604 }
5605 
5606 // MacAlgorithm version of C_SignFinal
MacVerifyFinal(Session * session,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5607 static CK_RV MacVerifyFinal(Session* session, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5608 {
5609 	MacAlgorithm* mac = session->getMacOp();
5610 	if (mac == NULL)
5611 	{
5612 		session->resetOp();
5613 		return CKR_OPERATION_NOT_INITIALIZED;
5614 	}
5615 
5616 	// Size of the signature
5617 	CK_ULONG size = mac->getMacSize();
5618 
5619 	// Check buffer size
5620 	if (ulSignatureLen != size)
5621 	{
5622 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
5623 		session->resetOp();
5624 		return CKR_SIGNATURE_LEN_RANGE;
5625 	}
5626 
5627 	// Get the signature
5628 	ByteString signature(pSignature, ulSignatureLen);
5629 
5630 	// Verify the data
5631 	if (!mac->verifyFinal(signature))
5632 	{
5633 		session->resetOp();
5634 		return CKR_SIGNATURE_INVALID;
5635 	}
5636 
5637 	session->resetOp();
5638 	return CKR_OK;
5639 }
5640 
5641 // AsymmetricAlgorithm version of C_VerifyFinal
AsymVerifyFinal(Session * session,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5642 static CK_RV AsymVerifyFinal(Session* session, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5643 {
5644 	AsymmetricAlgorithm* asymCrypto = session->getAsymmetricCryptoOp();
5645 	PublicKey* publicKey = session->getPublicKey();
5646 	if (asymCrypto == NULL || publicKey == NULL)
5647 	{
5648 		session->resetOp();
5649 		return CKR_OPERATION_NOT_INITIALIZED;
5650 	}
5651 
5652 	// Size of the signature
5653 	CK_ULONG size = publicKey->getOutputLength();
5654 
5655 	// Check buffer size
5656 	if (ulSignatureLen != size)
5657 	{
5658 		ERROR_MSG("The size of the signature differs from the size of the mechanism");
5659 		session->resetOp();
5660 		return CKR_SIGNATURE_LEN_RANGE;
5661 	}
5662 
5663 	// Get the data
5664 	ByteString signature(pSignature, ulSignatureLen);
5665 
5666 	// Verify the data
5667 	if (!asymCrypto->verifyFinal(signature))
5668 	{
5669 		session->resetOp();
5670 		return CKR_SIGNATURE_INVALID;
5671 	}
5672 
5673 	session->resetOp();
5674 	return CKR_OK;
5675 }
5676 
5677 // Finalise the verification operation and check the signature
C_VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)5678 CK_RV SoftHSM::C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
5679 {
5680 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5681 
5682 	if (pSignature == NULL_PTR) return CKR_ARGUMENTS_BAD;
5683 
5684 	// Get the session
5685 	Session* session = (Session*)handleManager->getSession(hSession);
5686 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5687 
5688 	// Check if we are doing the correct operation
5689 	if (session->getOpType() != SESSION_OP_VERIFY || !session->getAllowMultiPartOp())
5690 		return CKR_OPERATION_NOT_INITIALIZED;
5691 
5692 	if (session->getMacOp() != NULL)
5693 		return MacVerifyFinal(session, pSignature, ulSignatureLen);
5694 	else
5695 		return AsymVerifyFinal(session, pSignature, ulSignatureLen);
5696 }
5697 
5698 // Initialise a verification operation the allows recovery of the signed data from the signature
C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR,CK_OBJECT_HANDLE)5699 CK_RV SoftHSM::C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR /*pMechanism*/, CK_OBJECT_HANDLE /*hKey*/)
5700 {
5701 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5702 
5703 	// Get the session
5704 	Session* session = (Session*)handleManager->getSession(hSession);
5705 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5706 
5707 	// Check if we have another operation
5708 	if (session->getOpType() != SESSION_OP_NONE) return CKR_OPERATION_ACTIVE;
5709 
5710 	return CKR_FUNCTION_NOT_SUPPORTED;
5711 }
5712 
5713 // Perform a single part verification operation and recover the signed data
C_VerifyRecover(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)5714 CK_RV SoftHSM::C_VerifyRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pSignature*/, CK_ULONG /*ulSignatureLen*/, CK_BYTE_PTR /*pData*/, CK_ULONG_PTR /*pulDataLen*/)
5715 {
5716 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5717 
5718 	// Get the session
5719 	Session* session = (Session*)handleManager->getSession(hSession);
5720 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5721 
5722 	return CKR_FUNCTION_NOT_SUPPORTED;
5723 }
5724 
5725 // Update a running multi-part encryption and digesting operation
C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)5726 CK_RV SoftHSM::C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pPart*/, CK_ULONG /*ulPartLen*/, CK_BYTE_PTR /*pEncryptedPart*/, CK_ULONG_PTR /*pulEncryptedPartLen*/)
5727 {
5728 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5729 
5730 	// Get the session
5731 	Session* session = (Session*)handleManager->getSession(hSession);
5732 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5733 
5734 	return CKR_FUNCTION_NOT_SUPPORTED;
5735 }
5736 
5737 // Update a running multi-part decryption and digesting operation
C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)5738 CK_RV SoftHSM::C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pPart*/, CK_ULONG /*ulPartLen*/, CK_BYTE_PTR /*pDecryptedPart*/, CK_ULONG_PTR /*pulDecryptedPartLen*/)
5739 {
5740 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5741 
5742 	// Get the session
5743 	Session* session = (Session*)handleManager->getSession(hSession);
5744 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5745 
5746 	return CKR_FUNCTION_NOT_SUPPORTED;
5747 }
5748 
5749 // Update a running multi-part signing and encryption operation
C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)5750 CK_RV SoftHSM::C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pPart*/, CK_ULONG /*ulPartLen*/, CK_BYTE_PTR /*pEncryptedPart*/, CK_ULONG_PTR /*pulEncryptedPartLen*/)
5751 {
5752 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5753 
5754 	// Get the session
5755 	Session* session = (Session*)handleManager->getSession(hSession);
5756 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5757 
5758 	return CKR_FUNCTION_NOT_SUPPORTED;
5759 }
5760 
5761 // Update a running multi-part decryption and verification operation
C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR,CK_ULONG,CK_BYTE_PTR,CK_ULONG_PTR)5762 CK_RV SoftHSM::C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR /*pEncryptedPart*/, CK_ULONG /*ulEncryptedPartLen*/, CK_BYTE_PTR /*pPart*/, CK_ULONG_PTR /*pulPartLen*/)
5763 {
5764 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5765 
5766 	// Get the session
5767 	Session* session = (Session*)handleManager->getSession(hSession);
5768 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5769 
5770 	return CKR_FUNCTION_NOT_SUPPORTED;
5771 }
5772 
5773 // Generate a secret key or a domain parameter set using the specified mechanism
C_GenerateKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)5774 CK_RV SoftHSM::C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
5775 {
5776 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5777 
5778 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
5779 	if (pTemplate == NULL_PTR && ulCount != 0) return CKR_ARGUMENTS_BAD;
5780 	if (phKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
5781 
5782 	// Get the session
5783 	Session* session = (Session*)handleManager->getSession(hSession);
5784 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5785 
5786 	// Check the mechanism, only accept DSA and DH parameters
5787 	// and symmetric ciphers
5788 	CK_OBJECT_CLASS objClass;
5789 	CK_KEY_TYPE keyType;
5790 	switch (pMechanism->mechanism)
5791 	{
5792 		case CKM_DSA_PARAMETER_GEN:
5793 			objClass = CKO_DOMAIN_PARAMETERS;
5794 			keyType = CKK_DSA;
5795 			break;
5796 		case CKM_DH_PKCS_PARAMETER_GEN:
5797 			objClass = CKO_DOMAIN_PARAMETERS;
5798 			keyType = CKK_DH;
5799 			break;
5800 #ifndef WITH_FIPS
5801 		case CKM_DES_KEY_GEN:
5802 			objClass = CKO_SECRET_KEY;
5803 			keyType = CKK_DES;
5804 			break;
5805 #endif
5806 		case CKM_DES2_KEY_GEN:
5807 			objClass = CKO_SECRET_KEY;
5808 			keyType = CKK_DES2;
5809 			break;
5810 		case CKM_DES3_KEY_GEN:
5811 			objClass = CKO_SECRET_KEY;
5812 			keyType = CKK_DES3;
5813 			break;
5814 		case CKM_AES_KEY_GEN:
5815 			objClass = CKO_SECRET_KEY;
5816 			keyType = CKK_AES;
5817 			break;
5818 		case CKM_GENERIC_SECRET_KEY_GEN:
5819 			objClass = CKO_SECRET_KEY;
5820 			keyType = CKK_GENERIC_SECRET;
5821 			break;
5822 		default:
5823 			return CKR_MECHANISM_INVALID;
5824 	}
5825 
5826 	// Extract information from the template that is needed to create the object.
5827 	CK_BBOOL isOnToken = CK_FALSE;
5828 	CK_BBOOL isPrivate = CK_TRUE;
5829 	CK_CERTIFICATE_TYPE dummy;
5830 	bool isImplicit = true;
5831 	extractObjectInformation(pTemplate, ulCount, objClass, keyType, dummy, isOnToken, isPrivate, isImplicit);
5832 
5833 	// Report errors and/or unexpected usage.
5834 	if (objClass != CKO_SECRET_KEY && objClass != CKO_DOMAIN_PARAMETERS)
5835 		return CKR_ATTRIBUTE_VALUE_INVALID;
5836 	if (pMechanism->mechanism == CKM_DSA_PARAMETER_GEN &&
5837 	    (objClass != CKO_DOMAIN_PARAMETERS || keyType != CKK_DSA))
5838 		return CKR_TEMPLATE_INCONSISTENT;
5839 	if (pMechanism->mechanism == CKM_DH_PKCS_PARAMETER_GEN &&
5840 	    (objClass != CKO_DOMAIN_PARAMETERS || keyType != CKK_DH))
5841 		return CKR_TEMPLATE_INCONSISTENT;
5842 	if (pMechanism->mechanism == CKM_DES_KEY_GEN &&
5843 	    (objClass != CKO_SECRET_KEY || keyType != CKK_DES))
5844 		return CKR_TEMPLATE_INCONSISTENT;
5845 	if (pMechanism->mechanism == CKM_DES2_KEY_GEN &&
5846 	    (objClass != CKO_SECRET_KEY || keyType != CKK_DES2))
5847 		return CKR_TEMPLATE_INCONSISTENT;
5848 	if (pMechanism->mechanism == CKM_DES3_KEY_GEN &&
5849 	    (objClass != CKO_SECRET_KEY || keyType != CKK_DES3))
5850 		return CKR_TEMPLATE_INCONSISTENT;
5851 	if (pMechanism->mechanism == CKM_AES_KEY_GEN &&
5852 	    (objClass != CKO_SECRET_KEY || keyType != CKK_AES))
5853 		return CKR_TEMPLATE_INCONSISTENT;
5854 	if (pMechanism->mechanism == CKM_GENERIC_SECRET_KEY_GEN &&
5855 	    (objClass != CKO_SECRET_KEY || keyType != CKK_GENERIC_SECRET))
5856 		return CKR_TEMPLATE_INCONSISTENT;
5857 
5858 	// Check authorization
5859 	CK_RV rv = haveWrite(session->getState(), isOnToken, isPrivate);
5860 	if (rv != CKR_OK)
5861 	{
5862 		if (rv == CKR_USER_NOT_LOGGED_IN)
5863 			INFO_MSG("User is not authorized");
5864 		if (rv == CKR_SESSION_READ_ONLY)
5865 			INFO_MSG("Session is read-only");
5866 
5867 		return rv;
5868 	}
5869 
5870 	// Generate DSA domain parameters
5871 	if (pMechanism->mechanism == CKM_DSA_PARAMETER_GEN)
5872 	{
5873 		return this->generateDSAParameters(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5874 	}
5875 
5876 	// Generate DH domain parameters
5877 	if (pMechanism->mechanism == CKM_DH_PKCS_PARAMETER_GEN)
5878 	{
5879 		return this->generateDHParameters(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5880 	}
5881 
5882 	// Generate DES secret key
5883 	if (pMechanism->mechanism == CKM_DES_KEY_GEN)
5884 	{
5885 		return this->generateDES(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5886 	}
5887 
5888 	// Generate DES2 secret key
5889 	if (pMechanism->mechanism == CKM_DES2_KEY_GEN)
5890 	{
5891 		return this->generateDES2(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5892 	}
5893 
5894 	// Generate DES3 secret key
5895 	if (pMechanism->mechanism == CKM_DES3_KEY_GEN)
5896 	{
5897 		return this->generateDES3(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5898 	}
5899 
5900 	// Generate AES secret key
5901 	if (pMechanism->mechanism == CKM_AES_KEY_GEN)
5902 	{
5903 		return this->generateAES(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5904 	}
5905 
5906 	// Generate generic secret key
5907 	if (pMechanism->mechanism == CKM_GENERIC_SECRET_KEY_GEN)
5908 	{
5909 		return this->generateGeneric(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate);
5910 	}
5911 
5912 	return CKR_GENERAL_ERROR;
5913 }
5914 
5915 // Generate a key-pair using the specified mechanism
C_GenerateKeyPair(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey)5916 CK_RV SoftHSM::C_GenerateKeyPair
5917 (
5918 	CK_SESSION_HANDLE hSession,
5919 	CK_MECHANISM_PTR pMechanism,
5920 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
5921 	CK_ULONG ulPublicKeyAttributeCount,
5922 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
5923 	CK_ULONG ulPrivateKeyAttributeCount,
5924 	CK_OBJECT_HANDLE_PTR phPublicKey,
5925 	CK_OBJECT_HANDLE_PTR phPrivateKey
5926 )
5927 {
5928 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
5929 
5930 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
5931 	if (pPublicKeyTemplate == NULL_PTR && ulPublicKeyAttributeCount != 0) return CKR_ARGUMENTS_BAD;
5932 	if (pPrivateKeyTemplate == NULL_PTR && ulPrivateKeyAttributeCount != 0) return CKR_ARGUMENTS_BAD;
5933 	if (phPublicKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
5934 	if (phPrivateKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
5935 
5936 	// Get the session
5937 	Session* session = (Session*)handleManager->getSession(hSession);
5938 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
5939 
5940 	// Check the mechanism, only accept RSA, DSA, EC and DH key pair generation.
5941 	CK_KEY_TYPE keyType;
5942 	switch (pMechanism->mechanism)
5943 	{
5944 		case CKM_RSA_PKCS_KEY_PAIR_GEN:
5945 			keyType = CKK_RSA;
5946 			break;
5947 		case CKM_DSA_KEY_PAIR_GEN:
5948 			keyType = CKK_DSA;
5949 			break;
5950 		case CKM_DH_PKCS_KEY_PAIR_GEN:
5951 			keyType = CKK_DH;
5952 			break;
5953 #ifdef WITH_ECC
5954 		case CKM_EC_KEY_PAIR_GEN:
5955 			keyType = CKK_EC;
5956 			break;
5957 #endif
5958 #ifdef WITH_GOST
5959 		case CKM_GOSTR3410_KEY_PAIR_GEN:
5960 			keyType = CKK_GOSTR3410;
5961 			break;
5962 #endif
5963 #ifdef WITH_EDDSA
5964 		case CKM_EC_EDWARDS_KEY_PAIR_GEN:
5965 			keyType = CKK_EC_EDWARDS;
5966 			break;
5967 #endif
5968 		default:
5969 			return CKR_MECHANISM_INVALID;
5970 	}
5971 	CK_CERTIFICATE_TYPE dummy;
5972 
5973 	// Extract information from the public key template that is needed to create the object.
5974 	CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
5975 	CK_BBOOL ispublicKeyToken = CK_FALSE;
5976 	CK_BBOOL ispublicKeyPrivate = CK_FALSE;
5977 	bool isPublicKeyImplicit = true;
5978 	extractObjectInformation(pPublicKeyTemplate, ulPublicKeyAttributeCount, publicKeyClass, keyType, dummy, ispublicKeyToken, ispublicKeyPrivate, isPublicKeyImplicit);
5979 
5980 	// Report errors caused by accidental template mix-ups in the application using this cryptoki lib.
5981 	if (publicKeyClass != CKO_PUBLIC_KEY)
5982 		return CKR_ATTRIBUTE_VALUE_INVALID;
5983 	if (pMechanism->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN && keyType != CKK_RSA)
5984 		return CKR_TEMPLATE_INCONSISTENT;
5985 	if (pMechanism->mechanism == CKM_DSA_KEY_PAIR_GEN && keyType != CKK_DSA)
5986 		return CKR_TEMPLATE_INCONSISTENT;
5987 	if (pMechanism->mechanism == CKM_EC_KEY_PAIR_GEN && keyType != CKK_EC)
5988 		return CKR_TEMPLATE_INCONSISTENT;
5989 	if (pMechanism->mechanism == CKM_DH_PKCS_KEY_PAIR_GEN && keyType != CKK_DH)
5990 		return CKR_TEMPLATE_INCONSISTENT;
5991 	if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410)
5992 		return CKR_TEMPLATE_INCONSISTENT;
5993 	if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS)
5994 		return CKR_TEMPLATE_INCONSISTENT;
5995 
5996 	// Extract information from the private key template that is needed to create the object.
5997 	CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
5998 	CK_BBOOL isprivateKeyToken = CK_FALSE;
5999 	CK_BBOOL isprivateKeyPrivate = CK_TRUE;
6000 	bool isPrivateKeyImplicit = true;
6001 	extractObjectInformation(pPrivateKeyTemplate, ulPrivateKeyAttributeCount, privateKeyClass, keyType, dummy, isprivateKeyToken, isprivateKeyPrivate, isPrivateKeyImplicit);
6002 
6003 	// Report errors caused by accidental template mix-ups in the application using this cryptoki lib.
6004 	if (privateKeyClass != CKO_PRIVATE_KEY)
6005 		return CKR_ATTRIBUTE_VALUE_INVALID;
6006 	if (pMechanism->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN && keyType != CKK_RSA)
6007 		return CKR_TEMPLATE_INCONSISTENT;
6008 	if (pMechanism->mechanism == CKM_DSA_KEY_PAIR_GEN && keyType != CKK_DSA)
6009 		return CKR_TEMPLATE_INCONSISTENT;
6010 	if (pMechanism->mechanism == CKM_EC_KEY_PAIR_GEN && keyType != CKK_EC)
6011 		return CKR_TEMPLATE_INCONSISTENT;
6012 	if (pMechanism->mechanism == CKM_DH_PKCS_KEY_PAIR_GEN && keyType != CKK_DH)
6013 		return CKR_TEMPLATE_INCONSISTENT;
6014 	if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410)
6015 		return CKR_TEMPLATE_INCONSISTENT;
6016 	if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS)
6017 		return CKR_TEMPLATE_INCONSISTENT;
6018 
6019 	// Check user credentials
6020 	CK_RV rv = haveWrite(session->getState(), ispublicKeyToken || isprivateKeyToken, ispublicKeyPrivate || isprivateKeyPrivate);
6021 	if (rv != CKR_OK)
6022 	{
6023 		if (rv == CKR_USER_NOT_LOGGED_IN)
6024 			INFO_MSG("User is not authorized");
6025 		if (rv == CKR_SESSION_READ_ONLY)
6026 			INFO_MSG("Session is read-only");
6027 
6028 		return rv;
6029 	}
6030 
6031 	// Generate RSA keys
6032 	if (pMechanism->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN)
6033 	{
6034 			return this->generateRSA(hSession,
6035 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6036 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6037 									 phPublicKey, phPrivateKey,
6038 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6039 	}
6040 
6041 	// Generate DSA keys
6042 	if (pMechanism->mechanism == CKM_DSA_KEY_PAIR_GEN)
6043 	{
6044 			return this->generateDSA(hSession,
6045 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6046 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6047 									 phPublicKey, phPrivateKey,
6048 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6049 	}
6050 
6051 	// Generate EC keys
6052 	if (pMechanism->mechanism == CKM_EC_KEY_PAIR_GEN)
6053 	{
6054 			return this->generateEC(hSession,
6055 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6056 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6057 									 phPublicKey, phPrivateKey,
6058 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6059 	}
6060 
6061 	// Generate DH keys
6062 	if (pMechanism->mechanism == CKM_DH_PKCS_KEY_PAIR_GEN)
6063 	{
6064 			return this->generateDH(hSession,
6065 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6066 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6067 									 phPublicKey, phPrivateKey,
6068 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6069 	}
6070 
6071 	// Generate GOST keys
6072 	if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN)
6073 	{
6074 			return this->generateGOST(hSession,
6075 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6076 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6077 									 phPublicKey, phPrivateKey,
6078 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6079 	}
6080 
6081 	// Generate EDDSA keys
6082 	if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN)
6083 	{
6084 			return this->generateED(hSession,
6085 									 pPublicKeyTemplate, ulPublicKeyAttributeCount,
6086 									 pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
6087 									 phPublicKey, phPrivateKey,
6088 									 ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate);
6089 	}
6090 
6091 	return CKR_GENERAL_ERROR;
6092 }
6093 
6094 // Internal: Wrap blob using symmetric key
WrapKeySym(CK_MECHANISM_PTR pMechanism,Token * token,OSObject * wrapKey,ByteString & keydata,ByteString & wrapped)6095 CK_RV SoftHSM::WrapKeySym
6096 (
6097 	CK_MECHANISM_PTR pMechanism,
6098 	Token* token,
6099 	OSObject* wrapKey,
6100 	ByteString& keydata,
6101 	ByteString& wrapped
6102 )
6103 {
6104 	// Get the symmetric algorithm matching the mechanism
6105 	SymAlgo::Type algo = SymAlgo::Unknown;
6106 	SymWrap::Type mode = SymWrap::Unknown;
6107 	size_t bb = 8;
6108 #ifdef HAVE_AES_KEY_WRAP
6109 	CK_ULONG wrappedlen = keydata.size();
6110 
6111 	// [PKCS#11 v2.40, 2.14.3 AES Key Wrap]
6112 	// A key whose length is not a multiple of the AES Key Wrap block
6113 	// size (8 bytes) will be zero padded to fit.
6114 	CK_ULONG alignment = wrappedlen % 8;
6115 	if (alignment != 0)
6116 	{
6117 		keydata.resize(wrappedlen + 8 - alignment);
6118 		memset(&keydata[wrappedlen], 0, 8 - alignment);
6119 		wrappedlen = keydata.size();
6120 	}
6121 #endif
6122 	switch(pMechanism->mechanism) {
6123 #ifdef HAVE_AES_KEY_WRAP
6124 		case CKM_AES_KEY_WRAP:
6125 			if ((wrappedlen < 16) || ((wrappedlen % 8) != 0))
6126 				return CKR_KEY_SIZE_RANGE;
6127 			algo = SymAlgo::AES;
6128 			mode = SymWrap::AES_KEYWRAP;
6129 			break;
6130 #endif
6131 #ifdef HAVE_AES_KEY_WRAP_PAD
6132 		case CKM_AES_KEY_WRAP_PAD:
6133 			algo = SymAlgo::AES;
6134 			mode = SymWrap::AES_KEYWRAP_PAD;
6135 			break;
6136 #endif
6137 		case CKM_AES_CBC:
6138 			algo = SymAlgo::AES;
6139 			break;
6140 		case CKM_DES3_CBC:
6141 			algo = SymAlgo::DES3;
6142 			break;
6143 		default:
6144 			return CKR_MECHANISM_INVALID;
6145 	}
6146 	SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
6147 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
6148 
6149 	SymmetricKey* wrappingkey = new SymmetricKey();
6150 
6151 	if (getSymmetricKey(wrappingkey, token, wrapKey) != CKR_OK)
6152 	{
6153 		cipher->recycleKey(wrappingkey);
6154 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6155 		return CKR_GENERAL_ERROR;
6156 	}
6157 
6158 	// adjust key bit length
6159 	wrappingkey->setBitLen(wrappingkey->getKeyBits().size() * bb);
6160 
6161 	ByteString iv;
6162 	ByteString encryptedFinal;
6163 
6164 	if (pMechanism->mechanism == CKM_AES_CBC) {
6165 		iv.resize(16);
6166 		memcpy(&iv[0], pMechanism->pParameter, 16);
6167 	} else if (pMechanism->mechanism == CKM_DES3_CBC){
6168 		iv.resize(8);
6169 		memcpy(&iv[0], pMechanism->pParameter, 8);
6170 	}
6171 	switch(pMechanism->mechanism) {
6172 
6173 		case CKM_AES_CBC:
6174 		case CKM_DES3_CBC:
6175 			if (!cipher->encryptInit(wrappingkey, SymMode::CBC, iv, false))
6176 			{
6177 				cipher->recycleKey(wrappingkey);
6178 				CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6179 				return CKR_MECHANISM_INVALID;
6180 			}
6181 			if (!cipher->encryptUpdate(keydata, wrapped))
6182 			{
6183 				cipher->recycleKey(wrappingkey);
6184 				CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6185 				return CKR_GENERAL_ERROR;
6186 			}
6187 			// Finalize encryption
6188 			if (!cipher->encryptFinal(encryptedFinal))
6189 			{
6190 				cipher->recycleKey(wrappingkey);
6191 				CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6192 				return CKR_GENERAL_ERROR;
6193 			}
6194 			wrapped += encryptedFinal;
6195 			break;
6196 		default:
6197 			// Wrap the key
6198 			if (!cipher->wrapKey(wrappingkey, mode, keydata, wrapped))
6199 			{
6200 				cipher->recycleKey(wrappingkey);
6201 				CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6202 				return CKR_GENERAL_ERROR;
6203 			}
6204 	}
6205 
6206 	cipher->recycleKey(wrappingkey);
6207 	CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6208 	return CKR_OK;
6209 }
6210 
6211 // Internal: Wrap blob using asymmetric key
WrapKeyAsym(CK_MECHANISM_PTR pMechanism,Token * token,OSObject * wrapKey,ByteString & keydata,ByteString & wrapped)6212 CK_RV SoftHSM::WrapKeyAsym
6213 (
6214 	CK_MECHANISM_PTR pMechanism,
6215 	Token* token,
6216 	OSObject* wrapKey,
6217 	ByteString& keydata,
6218 	ByteString& wrapped
6219 )
6220 {
6221 	const size_t bb = 8;
6222 	AsymAlgo::Type algo = AsymAlgo::Unknown;
6223 	AsymMech::Type mech = AsymMech::Unknown;
6224 
6225 	CK_ULONG modulus_length;
6226 	switch(pMechanism->mechanism) {
6227 		case CKM_RSA_PKCS:
6228 		case CKM_RSA_PKCS_OAEP:
6229 			algo = AsymAlgo::RSA;
6230 			if (!wrapKey->attributeExists(CKA_MODULUS_BITS))
6231 				return CKR_GENERAL_ERROR;
6232 			modulus_length = wrapKey->getUnsignedLongValue(CKA_MODULUS_BITS, 0);
6233 			// adjust key bit length
6234 			modulus_length /= bb;
6235 			break;
6236 
6237 		default:
6238 			return CKR_MECHANISM_INVALID;
6239 	}
6240 
6241 	switch(pMechanism->mechanism) {
6242 		case CKM_RSA_PKCS:
6243 			mech = AsymMech::RSA_PKCS;
6244 			// RFC 3447 section 7.2.1
6245 			if (keydata.size() > modulus_length - 11)
6246 				return CKR_KEY_SIZE_RANGE;
6247 			break;
6248 
6249 		case CKM_RSA_PKCS_OAEP:
6250 			mech = AsymMech::RSA_PKCS_OAEP;
6251 			// SHA-1 is the only supported option
6252 			// PKCS#11 2.40 draft 2 section 2.1.8: input length <= k-2-2hashLen
6253 			if (keydata.size() > modulus_length - 2 - 2 * 160 / 8)
6254 				return CKR_KEY_SIZE_RANGE;
6255 			break;
6256 
6257 		default:
6258 			return CKR_MECHANISM_INVALID;
6259 	}
6260 
6261 	AsymmetricAlgorithm* cipher = CryptoFactory::i()->getAsymmetricAlgorithm(algo);
6262 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
6263 
6264 	PublicKey* publicKey = cipher->newPublicKey();
6265 	if (publicKey == NULL)
6266 	{
6267 		CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6268 		return CKR_HOST_MEMORY;
6269 	}
6270 
6271 	switch(pMechanism->mechanism) {
6272 		case CKM_RSA_PKCS:
6273 		case CKM_RSA_PKCS_OAEP:
6274 			if (getRSAPublicKey((RSAPublicKey*)publicKey, token, wrapKey) != CKR_OK)
6275 			{
6276 				cipher->recyclePublicKey(publicKey);
6277 				CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6278 				return CKR_GENERAL_ERROR;
6279 			}
6280 			break;
6281 
6282 		default:
6283 			return CKR_MECHANISM_INVALID;
6284 	}
6285 	// Wrap the key
6286 	if (!cipher->wrapKey(publicKey, keydata, wrapped, mech))
6287 	{
6288 		cipher->recyclePublicKey(publicKey);
6289 		CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6290 		return CKR_GENERAL_ERROR;
6291 	}
6292 
6293 	cipher->recyclePublicKey(publicKey);
6294 	CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6295 
6296 	return CKR_OK;
6297 }
6298 
6299 
6300 // Wrap the specified key using the specified wrapping key and mechanism
C_WrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hWrappingKey,CK_OBJECT_HANDLE hKey,CK_BYTE_PTR pWrappedKey,CK_ULONG_PTR pulWrappedKeyLen)6301 CK_RV SoftHSM::C_WrapKey
6302 (
6303 	CK_SESSION_HANDLE hSession,
6304 	CK_MECHANISM_PTR pMechanism,
6305 	CK_OBJECT_HANDLE hWrappingKey,
6306 	CK_OBJECT_HANDLE hKey,
6307 	CK_BYTE_PTR pWrappedKey,
6308 	CK_ULONG_PTR pulWrappedKeyLen
6309 )
6310 {
6311 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
6312 
6313 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
6314 	if (pulWrappedKeyLen == NULL_PTR) return CKR_ARGUMENTS_BAD;
6315 
6316 	// Get the session
6317 	Session* session = (Session*)handleManager->getSession(hSession);
6318 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
6319 
6320 	CK_RV rv;
6321 	// Check the mechanism, only accept advanced AES key wrapping and RSA
6322 	switch(pMechanism->mechanism)
6323 	{
6324 #ifdef HAVE_AES_KEY_WRAP
6325 		case CKM_AES_KEY_WRAP:
6326 #endif
6327 #ifdef HAVE_AES_KEY_WRAP_PAD
6328 		case CKM_AES_KEY_WRAP_PAD:
6329 #endif
6330 		case CKM_RSA_PKCS:
6331 			// Does not handle optional init vector
6332 			if (pMechanism->pParameter != NULL_PTR ||
6333                             pMechanism->ulParameterLen != 0)
6334 				return CKR_ARGUMENTS_BAD;
6335 			break;
6336 		case CKM_RSA_PKCS_OAEP:
6337 			rv = MechParamCheckRSAPKCSOAEP(pMechanism);
6338 			if (rv != CKR_OK)
6339 				return rv;
6340 			break;
6341 		case CKM_AES_CBC:
6342 			if (pMechanism->pParameter == NULL_PTR ||
6343                             pMechanism->ulParameterLen != 16)
6344                                 return CKR_ARGUMENTS_BAD;
6345                         break;
6346 		default:
6347 			return CKR_MECHANISM_INVALID;
6348 	}
6349 
6350 	// Get the token
6351 	Token* token = session->getToken();
6352 	if (token == NULL) return CKR_GENERAL_ERROR;
6353 
6354 	// Check the wrapping key handle.
6355 	OSObject *wrapKey = (OSObject *)handleManager->getObject(hWrappingKey);
6356 	if (wrapKey == NULL_PTR || !wrapKey->isValid()) return CKR_WRAPPING_KEY_HANDLE_INVALID;
6357 
6358 	CK_BBOOL isWrapKeyOnToken = wrapKey->getBooleanValue(CKA_TOKEN, false);
6359 	CK_BBOOL isWrapKeyPrivate = wrapKey->getBooleanValue(CKA_PRIVATE, true);
6360 
6361 	// Check user credentials for the wrapping key
6362 	rv = haveRead(session->getState(), isWrapKeyOnToken, isWrapKeyPrivate);
6363 	if (rv != CKR_OK)
6364 	{
6365 		if (rv == CKR_USER_NOT_LOGGED_IN)
6366 			INFO_MSG("User is not authorized");
6367 
6368 		return rv;
6369 	}
6370 
6371 	// Check wrapping key class and type
6372 	if ((pMechanism->mechanism == CKM_AES_KEY_WRAP || pMechanism->mechanism == CKM_AES_KEY_WRAP_PAD) && wrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_SECRET_KEY)
6373 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6374 	if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && wrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_PUBLIC_KEY)
6375 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6376 	if (pMechanism->mechanism == CKM_AES_KEY_WRAP && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
6377 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6378 	if (pMechanism->mechanism == CKM_AES_KEY_WRAP_PAD && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
6379 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6380 	if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_RSA)
6381 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6382 	if (pMechanism->mechanism == CKM_AES_CBC && wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
6383 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6384 	if (pMechanism->mechanism == CKM_DES3_CBC && (wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_DES2 ||
6385 		wrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_DES3))
6386 		return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
6387 
6388 	// Check if the wrapping key can be used for wrapping
6389 	if (wrapKey->getBooleanValue(CKA_WRAP, false) == false)
6390 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
6391 
6392 	// Check if the specified mechanism is allowed for the wrapping key
6393 	if (!isMechanismPermitted(wrapKey, pMechanism))
6394 		return CKR_MECHANISM_INVALID;
6395 
6396 	// Check the to be wrapped key handle.
6397 	OSObject *key = (OSObject *)handleManager->getObject(hKey);
6398 	if (key == NULL_PTR || !key->isValid()) return CKR_KEY_HANDLE_INVALID;
6399 
6400 	CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
6401 	CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
6402 
6403 	// Check user credentials for the to be wrapped key
6404 	rv = haveRead(session->getState(), isKeyOnToken, isKeyPrivate);
6405 	if (rv != CKR_OK)
6406 	{
6407 		if (rv == CKR_USER_NOT_LOGGED_IN)
6408 			INFO_MSG("User is not authorized");
6409 
6410 		return rv;
6411 	}
6412 
6413 	// Check if the to be wrapped key can be wrapped
6414 	if (key->getBooleanValue(CKA_EXTRACTABLE, false) == false)
6415 		return CKR_KEY_UNEXTRACTABLE;
6416 	if (key->getBooleanValue(CKA_WRAP_WITH_TRUSTED, false) && wrapKey->getBooleanValue(CKA_TRUSTED, false) == false)
6417 		return CKR_KEY_NOT_WRAPPABLE;
6418 
6419 	// Check the class
6420 	CK_OBJECT_CLASS keyClass = key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED);
6421 	if (keyClass != CKO_SECRET_KEY && keyClass != CKO_PRIVATE_KEY)
6422 		return CKR_KEY_NOT_WRAPPABLE;
6423 	// CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP can be used only on SECRET keys: PKCS#11 2.40 draft 2 section 2.1.6 PKCS #1 v1.5 RSA & section 2.1.8 PKCS #1 RSA OAEP
6424 	if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && keyClass != CKO_SECRET_KEY)
6425 		return CKR_KEY_NOT_WRAPPABLE;
6426 
6427 	// Verify the wrap template attribute
6428 	if (wrapKey->attributeExists(CKA_WRAP_TEMPLATE))
6429 	{
6430 		OSAttribute attr = wrapKey->getAttribute(CKA_WRAP_TEMPLATE);
6431 
6432 		if (attr.isAttributeMapAttribute())
6433 		{
6434 			typedef std::map<CK_ATTRIBUTE_TYPE,OSAttribute> attrmap_type;
6435 
6436 			const attrmap_type& map = attr.getAttributeMapValue();
6437 
6438 			for (attrmap_type::const_iterator it = map.begin(); it != map.end(); ++it)
6439 			{
6440 				if (!key->attributeExists(it->first))
6441 				{
6442 					return CKR_KEY_NOT_WRAPPABLE;
6443 				}
6444 
6445 				OSAttribute keyAttr = key->getAttribute(it->first);
6446 				ByteString v1, v2;
6447 				if (!keyAttr.peekValue(v1) || !it->second.peekValue(v2) || (v1 != v2))
6448 				{
6449 					return CKR_KEY_NOT_WRAPPABLE;
6450 				}
6451 			}
6452 		}
6453 	}
6454 
6455 	// Get the key data to encrypt
6456 	ByteString keydata;
6457 	if (keyClass == CKO_SECRET_KEY)
6458 	{
6459 		if (isKeyPrivate)
6460 		{
6461 			bool bOK = token->decrypt(key->getByteStringValue(CKA_VALUE), keydata);
6462 			if (!bOK) return CKR_GENERAL_ERROR;
6463 		}
6464 		else
6465 		{
6466 			keydata = key->getByteStringValue(CKA_VALUE);
6467 		}
6468 	}
6469 	else
6470 	{
6471 		CK_KEY_TYPE keyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
6472 		AsymAlgo::Type alg = AsymAlgo::Unknown;
6473 		switch (keyType) {
6474 			case CKK_RSA:
6475 				alg = AsymAlgo::RSA;
6476 				break;
6477 			case CKK_DSA:
6478 				alg = AsymAlgo::DSA;
6479 				break;
6480 			case CKK_DH:
6481 				alg = AsymAlgo::DH;
6482 				break;
6483 #ifdef WITH_ECC
6484 			case CKK_EC:
6485 				// can be ecdh too but it doesn't matter
6486 				alg = AsymAlgo::ECDSA;
6487 				break;
6488 #endif
6489 #ifdef WITH_EDDSA
6490 			// Not yet
6491 #endif
6492 #ifdef WITH_GOST
6493 			case CKK_GOSTR3410:
6494 				alg = AsymAlgo::GOST;
6495 				break;
6496 #endif
6497 			default:
6498 				return CKR_KEY_NOT_WRAPPABLE;
6499 		}
6500 		AsymmetricAlgorithm* asymCrypto = NULL;
6501 		PrivateKey* privateKey = NULL;
6502 		asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(alg);
6503 		if (asymCrypto == NULL)
6504 			return CKR_GENERAL_ERROR;
6505 		privateKey = asymCrypto->newPrivateKey();
6506 		if (privateKey == NULL)
6507 		{
6508 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
6509 			return CKR_HOST_MEMORY;
6510 		}
6511 		switch (keyType) {
6512 			case CKK_RSA:
6513 				rv = getRSAPrivateKey((RSAPrivateKey*)privateKey, token, key);
6514 				break;
6515 			case CKK_DSA:
6516 				rv = getDSAPrivateKey((DSAPrivateKey*)privateKey, token, key);
6517 				break;
6518 			case CKK_DH:
6519 				rv = getDHPrivateKey((DHPrivateKey*)privateKey, token, key);
6520 				break;
6521 #ifdef WITH_ECC
6522 			case CKK_EC:
6523 				rv = getECPrivateKey((ECPrivateKey*)privateKey, token, key);
6524 				break;
6525 #endif
6526 #ifdef WITH_GOST
6527 			case CKK_GOSTR3410:
6528 				rv = getGOSTPrivateKey((GOSTPrivateKey*)privateKey, token, key);
6529 				break;
6530 #endif
6531 		}
6532 		if (rv != CKR_OK)
6533 		{
6534 			asymCrypto->recyclePrivateKey(privateKey);
6535 			CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
6536 			return CKR_GENERAL_ERROR;
6537 		}
6538 		keydata = privateKey->PKCS8Encode();
6539 		asymCrypto->recyclePrivateKey(privateKey);
6540 		CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto);
6541 	}
6542 	if (keydata.size() == 0)
6543 		return CKR_KEY_NOT_WRAPPABLE;
6544 
6545 	keyClass = wrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED);
6546 	ByteString wrapped;
6547 	if (keyClass == CKO_SECRET_KEY)
6548 		rv = SoftHSM::WrapKeySym(pMechanism, token, wrapKey, keydata, wrapped);
6549 	else
6550 		rv = SoftHSM::WrapKeyAsym(pMechanism, token, wrapKey, keydata, wrapped);
6551 	if (rv != CKR_OK)
6552 		return rv;
6553 
6554 	if (pWrappedKey != NULL) {
6555 		if (*pulWrappedKeyLen >= wrapped.size())
6556 			memcpy(pWrappedKey, wrapped.byte_str(), wrapped.size());
6557 		else
6558 			rv = CKR_BUFFER_TOO_SMALL;
6559 	}
6560 
6561 	*pulWrappedKeyLen = wrapped.size();
6562 	return rv;
6563 }
6564 
6565 // Internal: Unwrap blob using symmetric key
UnwrapKeySym(CK_MECHANISM_PTR pMechanism,ByteString & wrapped,Token * token,OSObject * unwrapKey,ByteString & keydata)6566 CK_RV SoftHSM::UnwrapKeySym
6567 (
6568 	CK_MECHANISM_PTR pMechanism,
6569 	ByteString& wrapped,
6570 	Token* token,
6571 	OSObject* unwrapKey,
6572 	ByteString& keydata
6573 )
6574 {
6575 	// Get the symmetric algorithm matching the mechanism
6576 	SymAlgo::Type algo = SymAlgo::Unknown;
6577 	SymWrap::Type mode = SymWrap::Unknown;
6578 	size_t bb = 8;
6579 	switch(pMechanism->mechanism) {
6580 #ifdef HAVE_AES_KEY_WRAP
6581 		case CKM_AES_KEY_WRAP:
6582 			algo = SymAlgo::AES;
6583 			mode = SymWrap::AES_KEYWRAP;
6584 			break;
6585 #endif
6586 #ifdef HAVE_AES_KEY_WRAP_PAD
6587 		case CKM_AES_KEY_WRAP_PAD:
6588 			algo = SymAlgo::AES;
6589 			mode = SymWrap::AES_KEYWRAP_PAD;
6590 			break;
6591 #endif
6592 		default:
6593 			return CKR_MECHANISM_INVALID;
6594 	}
6595 	SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
6596 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
6597 
6598 	SymmetricKey* unwrappingkey = new SymmetricKey();
6599 
6600 	if (getSymmetricKey(unwrappingkey, token, unwrapKey) != CKR_OK)
6601 	{
6602 		cipher->recycleKey(unwrappingkey);
6603 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6604 		return CKR_GENERAL_ERROR;
6605 	}
6606 
6607 	// adjust key bit length
6608 	unwrappingkey->setBitLen(unwrappingkey->getKeyBits().size() * bb);
6609 
6610 	// Unwrap the key
6611 	CK_RV rv = CKR_OK;
6612 	if (!cipher->unwrapKey(unwrappingkey, mode, wrapped, keydata))
6613 		rv = CKR_GENERAL_ERROR;
6614 	cipher->recycleKey(unwrappingkey);
6615 	CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
6616 	return rv;
6617 }
6618 
6619 // Internal: Unwrap blob using asymmetric key
UnwrapKeyAsym(CK_MECHANISM_PTR pMechanism,ByteString & wrapped,Token * token,OSObject * unwrapKey,ByteString & keydata)6620 CK_RV SoftHSM::UnwrapKeyAsym
6621 (
6622 	CK_MECHANISM_PTR pMechanism,
6623 	ByteString& wrapped,
6624 	Token* token,
6625 	OSObject* unwrapKey,
6626 	ByteString& keydata
6627 )
6628 {
6629 	// Get the symmetric algorithm matching the mechanism
6630 	AsymAlgo::Type algo = AsymAlgo::Unknown;
6631 	AsymMech::Type mode = AsymMech::Unknown;
6632 	switch(pMechanism->mechanism) {
6633 		case CKM_RSA_PKCS:
6634 			algo = AsymAlgo::RSA;
6635 			mode = AsymMech::RSA_PKCS;
6636 			break;
6637 
6638 		case CKM_RSA_PKCS_OAEP:
6639 			algo = AsymAlgo::RSA;
6640 			mode = AsymMech::RSA_PKCS_OAEP;
6641 			break;
6642 
6643 		default:
6644 			return CKR_MECHANISM_INVALID;
6645 	}
6646 	AsymmetricAlgorithm* cipher = CryptoFactory::i()->getAsymmetricAlgorithm(algo);
6647 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
6648 
6649 	PrivateKey* unwrappingkey = cipher->newPrivateKey();
6650 	if (unwrappingkey == NULL)
6651 	{
6652 		CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6653 		return CKR_HOST_MEMORY;
6654 	}
6655 
6656 	switch(pMechanism->mechanism) {
6657 		case CKM_RSA_PKCS:
6658 		case CKM_RSA_PKCS_OAEP:
6659 			if (getRSAPrivateKey((RSAPrivateKey*)unwrappingkey, token, unwrapKey) != CKR_OK)
6660 			{
6661 				cipher->recyclePrivateKey(unwrappingkey);
6662 				CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6663 				return CKR_GENERAL_ERROR;
6664 			}
6665 			break;
6666 
6667 		default:
6668 			return CKR_MECHANISM_INVALID;
6669 	}
6670 
6671 	// Unwrap the key
6672 	CK_RV rv = CKR_OK;
6673 	if (!cipher->unwrapKey(unwrappingkey, wrapped, keydata, mode))
6674 		rv = CKR_GENERAL_ERROR;
6675 	cipher->recyclePrivateKey(unwrappingkey);
6676 	CryptoFactory::i()->recycleAsymmetricAlgorithm(cipher);
6677 	return rv;
6678 }
6679 
6680 // Unwrap the specified key using the specified unwrapping key
C_UnwrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hUnwrappingKey,CK_BYTE_PTR pWrappedKey,CK_ULONG ulWrappedKeyLen,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR hKey)6681 CK_RV SoftHSM::C_UnwrapKey
6682 (
6683 	CK_SESSION_HANDLE hSession,
6684 	CK_MECHANISM_PTR pMechanism,
6685 	CK_OBJECT_HANDLE hUnwrappingKey,
6686 	CK_BYTE_PTR pWrappedKey,
6687 	CK_ULONG ulWrappedKeyLen,
6688 	CK_ATTRIBUTE_PTR pTemplate,
6689 	CK_ULONG ulCount,
6690 	CK_OBJECT_HANDLE_PTR hKey
6691 )
6692 {
6693 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
6694 
6695 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
6696 	if (pWrappedKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
6697 	if (pTemplate == NULL_PTR) return CKR_ARGUMENTS_BAD;
6698 	if (hKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
6699 
6700 	// Get the session
6701 	Session* session = (Session*)handleManager->getSession(hSession);
6702 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
6703 
6704 	CK_RV rv;
6705 	// Check the mechanism
6706 	switch(pMechanism->mechanism)
6707 	{
6708 #ifdef HAVE_AES_KEY_WRAP
6709 		case CKM_AES_KEY_WRAP:
6710 			if ((ulWrappedKeyLen < 24) || ((ulWrappedKeyLen % 8) != 0))
6711 				return CKR_WRAPPED_KEY_LEN_RANGE;
6712 			// Does not handle optional init vector
6713 			if (pMechanism->pParameter != NULL_PTR ||
6714                             pMechanism->ulParameterLen != 0)
6715 				return CKR_ARGUMENTS_BAD;
6716 			break;
6717 #endif
6718 #ifdef HAVE_AES_KEY_WRAP_PAD
6719 		case CKM_AES_KEY_WRAP_PAD:
6720 			if ((ulWrappedKeyLen < 16) || ((ulWrappedKeyLen % 8) != 0))
6721 				return CKR_WRAPPED_KEY_LEN_RANGE;
6722 			// Does not handle optional init vector
6723 			if (pMechanism->pParameter != NULL_PTR ||
6724                             pMechanism->ulParameterLen != 0)
6725 				return CKR_ARGUMENTS_BAD;
6726 			break;
6727 #endif
6728 		case CKM_RSA_PKCS:
6729 			// Input length checks needs to be done later when unwrapping key is known
6730 			break;
6731 		case CKM_RSA_PKCS_OAEP:
6732 			rv = MechParamCheckRSAPKCSOAEP(pMechanism);
6733 			if (rv != CKR_OK)
6734 				return rv;
6735 			break;
6736 
6737 		default:
6738 			return CKR_MECHANISM_INVALID;
6739 	}
6740 
6741 	// Get the token
6742 	Token* token = session->getToken();
6743 	if (token == NULL) return CKR_GENERAL_ERROR;
6744 
6745 	// Check the unwrapping key handle.
6746 	OSObject *unwrapKey = (OSObject *)handleManager->getObject(hUnwrappingKey);
6747 	if (unwrapKey == NULL_PTR || !unwrapKey->isValid()) return CKR_UNWRAPPING_KEY_HANDLE_INVALID;
6748 
6749 	CK_BBOOL isUnwrapKeyOnToken = unwrapKey->getBooleanValue(CKA_TOKEN, false);
6750 	CK_BBOOL isUnwrapKeyPrivate = unwrapKey->getBooleanValue(CKA_PRIVATE, true);
6751 
6752 	// Check user credentials
6753 	rv = haveRead(session->getState(), isUnwrapKeyOnToken, isUnwrapKeyPrivate);
6754 	if (rv != CKR_OK)
6755 	{
6756 		if (rv == CKR_USER_NOT_LOGGED_IN)
6757 			INFO_MSG("User is not authorized");
6758 
6759 		return rv;
6760 	}
6761 
6762 	// Check unwrapping key class and type
6763 	if ((pMechanism->mechanism == CKM_AES_KEY_WRAP || pMechanism->mechanism == CKM_AES_KEY_WRAP_PAD) && unwrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_SECRET_KEY)
6764 		return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6765 	if (pMechanism->mechanism == CKM_AES_KEY_WRAP && unwrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
6766 		return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6767 	if (pMechanism->mechanism == CKM_AES_KEY_WRAP_PAD && unwrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_AES)
6768 		return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6769 	if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && unwrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_PRIVATE_KEY)
6770 		return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6771 	if ((pMechanism->mechanism == CKM_RSA_PKCS || pMechanism->mechanism == CKM_RSA_PKCS_OAEP) && unwrapKey->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_RSA)
6772 		return CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6773 
6774 	// Check if the unwrapping key can be used for unwrapping
6775 	if (unwrapKey->getBooleanValue(CKA_UNWRAP, false) == false)
6776 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
6777 
6778 	// Check if the specified mechanism is allowed for the unwrap key
6779 	if (!isMechanismPermitted(unwrapKey, pMechanism))
6780 		return CKR_MECHANISM_INVALID;
6781 
6782 	// Extract information from the template that is needed to create the object.
6783 	CK_OBJECT_CLASS objClass;
6784 	CK_KEY_TYPE keyType;
6785 	CK_BBOOL isOnToken = CK_FALSE;
6786 	CK_BBOOL isPrivate = CK_TRUE;
6787 	CK_CERTIFICATE_TYPE dummy;
6788 	bool isImplicit = false;
6789 	rv = extractObjectInformation(pTemplate, ulCount, objClass, keyType, dummy, isOnToken, isPrivate, isImplicit);
6790 	if (rv != CKR_OK)
6791 	{
6792 		ERROR_MSG("Mandatory attribute not present in template");
6793 		return rv;
6794 	}
6795 
6796 	// Report errors and/or unexpected usage.
6797 	if (objClass != CKO_SECRET_KEY && objClass != CKO_PRIVATE_KEY)
6798 		return CKR_ATTRIBUTE_VALUE_INVALID;
6799 	// Key type will be handled at object creation
6800 
6801 	// Check authorization
6802 	rv = haveWrite(session->getState(), isOnToken, isPrivate);
6803 	if (rv != CKR_OK)
6804 	{
6805 		if (rv == CKR_USER_NOT_LOGGED_IN)
6806 			INFO_MSG("User is not authorized");
6807 		if (rv == CKR_SESSION_READ_ONLY)
6808 			INFO_MSG("Session is read-only");
6809 
6810 		return rv;
6811 	}
6812 
6813 	// Build unwrapped key template
6814 	const CK_ULONG maxAttribs = 32;
6815 	CK_ATTRIBUTE secretAttribs[maxAttribs] = {
6816 		{ CKA_CLASS, &objClass, sizeof(objClass) },
6817 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
6818 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
6819 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) }
6820 	};
6821 	CK_ULONG secretAttribsCount = 4;
6822 
6823 	// Add the additional
6824 	if (ulCount > (maxAttribs - secretAttribsCount))
6825 		return CKR_TEMPLATE_INCONSISTENT;
6826 	for (CK_ULONG i = 0; i < ulCount; ++i)
6827 	{
6828 		switch (pTemplate[i].type)
6829 		{
6830 			case CKA_CLASS:
6831 			case CKA_TOKEN:
6832 			case CKA_PRIVATE:
6833 			case CKA_KEY_TYPE:
6834 				continue;
6835 			default:
6836 				secretAttribs[secretAttribsCount++] = pTemplate[i];
6837 		}
6838 	}
6839 
6840 	// Apply the unwrap template
6841 	if (unwrapKey->attributeExists(CKA_UNWRAP_TEMPLATE))
6842 	{
6843 		OSAttribute unwrapAttr = unwrapKey->getAttribute(CKA_UNWRAP_TEMPLATE);
6844 
6845 		if (unwrapAttr.isAttributeMapAttribute())
6846 		{
6847 			typedef std::map<CK_ATTRIBUTE_TYPE,OSAttribute> attrmap_type;
6848 
6849 			const attrmap_type& map = unwrapAttr.getAttributeMapValue();
6850 
6851 			for (attrmap_type::const_iterator it = map.begin(); it != map.end(); ++it)
6852 			{
6853 				CK_ATTRIBUTE* attr = NULL;
6854 				for (CK_ULONG i = 0; i < secretAttribsCount; ++i)
6855 				{
6856 					if (it->first == secretAttribs[i].type)
6857 					{
6858 						if (attr != NULL)
6859 						{
6860 							return CKR_TEMPLATE_INCONSISTENT;
6861 						}
6862 						attr = &secretAttribs[i];
6863 						ByteString value;
6864 						it->second.peekValue(value);
6865 						if (attr->ulValueLen != value.size())
6866 						{
6867 							return CKR_TEMPLATE_INCONSISTENT;
6868 						}
6869 						if (memcmp(attr->pValue, value.const_byte_str(), value.size()) != 0)
6870 						{
6871 							return CKR_TEMPLATE_INCONSISTENT;
6872 						}
6873 					}
6874 				}
6875 				if (attr == NULL)
6876 				{
6877 					return CKR_TEMPLATE_INCONSISTENT;
6878 				}
6879 			}
6880 		}
6881 	}
6882 
6883 	*hKey = CK_INVALID_HANDLE;
6884 
6885 	// Unwrap the key
6886 	ByteString wrapped(pWrappedKey, ulWrappedKeyLen);
6887 	ByteString keydata;
6888 	if (unwrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_SECRET_KEY)
6889 		rv = UnwrapKeySym(pMechanism, wrapped, token, unwrapKey, keydata);
6890 	else if (unwrapKey->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_PRIVATE_KEY)
6891 		rv = UnwrapKeyAsym(pMechanism, wrapped, token, unwrapKey, keydata);
6892 	else
6893 		rv = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT;
6894 	if (rv != CKR_OK)
6895 		return rv;
6896 
6897 	// Create the secret object using C_CreateObject
6898 	rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, hKey, OBJECT_OP_UNWRAP);
6899 
6900 	// Store the attributes that are being supplied
6901 	if (rv == CKR_OK)
6902 	{
6903 		OSObject* osobject = (OSObject*)handleManager->getObject(*hKey);
6904 		if (osobject == NULL_PTR || !osobject->isValid())
6905 			rv = CKR_FUNCTION_FAILED;
6906 		if (osobject->startTransaction())
6907 		{
6908 			bool bOK = true;
6909 
6910 			// Common Attributes
6911 			bOK = bOK && osobject->setAttribute(CKA_LOCAL, false);
6912 
6913 			// Common Secret Key Attributes
6914 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE, false);
6915 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, false);
6916 
6917 			// Secret Attributes
6918 			if (objClass == CKO_SECRET_KEY)
6919 			{
6920 				ByteString value;
6921 				if (isPrivate)
6922 					token->encrypt(keydata, value);
6923 				else
6924 					value = keydata;
6925 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
6926 			}
6927 			else if (keyType == CKK_RSA)
6928 			{
6929 				bOK = bOK && setRSAPrivateKey(osobject, keydata, token, isPrivate != CK_FALSE);
6930 			}
6931 			else if (keyType == CKK_DSA)
6932 			{
6933 				bOK = bOK && setDSAPrivateKey(osobject, keydata, token, isPrivate != CK_FALSE);
6934 			}
6935 			else if (keyType == CKK_DH)
6936 			{
6937 				bOK = bOK && setDHPrivateKey(osobject, keydata, token, isPrivate != CK_FALSE);
6938 			}
6939 #ifdef WITH_ECC
6940 			else if (keyType == CKK_EC)
6941 			{
6942 				bOK = bOK && setECPrivateKey(osobject, keydata, token, isPrivate != CK_FALSE);
6943 			}
6944 #endif
6945 #ifdef WITH_GOST
6946 			else if (keyType == CKK_GOSTR3410)
6947 			{
6948 				bOK = bOK && setGOSTPrivateKey(osobject, keydata, token, isPrivate != CK_FALSE);
6949 			}
6950 #endif
6951 			else
6952 				bOK = false;
6953 
6954 			if (bOK)
6955 				bOK = osobject->commitTransaction();
6956 			else
6957 				osobject->abortTransaction();
6958 
6959 			if (!bOK)
6960 				rv = CKR_FUNCTION_FAILED;
6961 		}
6962 		else
6963 			rv = CKR_FUNCTION_FAILED;
6964 	}
6965 
6966 	// Remove secret that may have been created already when the function fails.
6967 	if (rv != CKR_OK)
6968 	{
6969 		if (*hKey != CK_INVALID_HANDLE)
6970 		{
6971 			OSObject* obj = (OSObject*)handleManager->getObject(*hKey);
6972 			handleManager->destroyObject(*hKey);
6973 			if (obj) obj->destroyObject();
6974 			*hKey = CK_INVALID_HANDLE;
6975 		}
6976 
6977 	}
6978 
6979 	return rv;
6980 }
6981 
6982 // Derive a key from the specified base key
C_DeriveKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey)6983 CK_RV SoftHSM::C_DeriveKey
6984 (
6985 	CK_SESSION_HANDLE hSession,
6986 	CK_MECHANISM_PTR pMechanism,
6987 	CK_OBJECT_HANDLE hBaseKey,
6988 	CK_ATTRIBUTE_PTR pTemplate,
6989 	CK_ULONG ulCount,
6990 	CK_OBJECT_HANDLE_PTR phKey
6991 )
6992 {
6993 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
6994 
6995 	if (pMechanism == NULL_PTR) return CKR_ARGUMENTS_BAD;
6996 	if (pTemplate == NULL_PTR) return CKR_ARGUMENTS_BAD;
6997 	if (phKey == NULL_PTR) return CKR_ARGUMENTS_BAD;
6998 
6999 	// Get the session
7000 	Session* session = (Session*)handleManager->getSession(hSession);
7001 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
7002 
7003 	// Check the mechanism, only accept DH and ECDH derive
7004 	switch (pMechanism->mechanism)
7005 	{
7006 		case CKM_DH_PKCS_DERIVE:
7007 #if defined(WITH_ECC) || defined(WITH_EDDSA)
7008 		case CKM_ECDH1_DERIVE:
7009 #endif
7010 #ifndef WITH_FIPS
7011 		case CKM_DES_ECB_ENCRYPT_DATA:
7012 		case CKM_DES_CBC_ENCRYPT_DATA:
7013 #endif
7014 		case CKM_DES3_ECB_ENCRYPT_DATA:
7015 		case CKM_DES3_CBC_ENCRYPT_DATA:
7016 		case CKM_AES_ECB_ENCRYPT_DATA:
7017 		case CKM_AES_CBC_ENCRYPT_DATA:
7018 			break;
7019 
7020 		default:
7021 			ERROR_MSG("Invalid mechanism");
7022 			return CKR_MECHANISM_INVALID;
7023 	}
7024 
7025 	// Get the token
7026 	Token* token = session->getToken();
7027 	if (token == NULL) return CKR_GENERAL_ERROR;
7028 
7029 	// Check the key handle.
7030 	OSObject *key = (OSObject *)handleManager->getObject(hBaseKey);
7031 	if (key == NULL_PTR || !key->isValid()) return CKR_OBJECT_HANDLE_INVALID;
7032 
7033 	CK_BBOOL isKeyOnToken = key->getBooleanValue(CKA_TOKEN, false);
7034 	CK_BBOOL isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, true);
7035 
7036 	// Check user credentials
7037 	CK_RV rv = haveRead(session->getState(), isKeyOnToken, isKeyPrivate);
7038 	if (rv != CKR_OK)
7039 	{
7040 		if (rv == CKR_USER_NOT_LOGGED_IN)
7041 			INFO_MSG("User is not authorized");
7042 
7043 		return rv;
7044 	}
7045 
7046 	// Check if key can be used for derive
7047 	if (!key->getBooleanValue(CKA_DERIVE, false))
7048 		return CKR_KEY_FUNCTION_NOT_PERMITTED;
7049 
7050 	// Check if the specified mechanism is allowed for the key
7051 	if (!isMechanismPermitted(key, pMechanism))
7052 		return CKR_MECHANISM_INVALID;
7053 
7054 	// Extract information from the template that is needed to create the object.
7055 	CK_OBJECT_CLASS objClass;
7056 	CK_KEY_TYPE keyType;
7057 	CK_BBOOL isOnToken = CK_FALSE;
7058 	CK_BBOOL isPrivate = CK_TRUE;
7059 	CK_CERTIFICATE_TYPE dummy;
7060 	bool isImplicit = false;
7061 	rv = extractObjectInformation(pTemplate, ulCount, objClass, keyType, dummy, isOnToken, isPrivate, isImplicit);
7062 	if (rv != CKR_OK)
7063 	{
7064 		ERROR_MSG("Mandatory attribute not present in template");
7065 		return rv;
7066 	}
7067 
7068 	// Report errors and/or unexpected usage.
7069 	if (objClass != CKO_SECRET_KEY)
7070 		return CKR_ATTRIBUTE_VALUE_INVALID;
7071 	if (keyType != CKK_GENERIC_SECRET &&
7072 	    keyType != CKK_DES &&
7073 	    keyType != CKK_DES2 &&
7074 	    keyType != CKK_DES3 &&
7075 	    keyType != CKK_AES)
7076 		return CKR_TEMPLATE_INCONSISTENT;
7077 
7078 	// Check authorization
7079 	rv = haveWrite(session->getState(), isOnToken, isPrivate);
7080 	if (rv != CKR_OK)
7081 	{
7082 		if (rv == CKR_USER_NOT_LOGGED_IN)
7083 			INFO_MSG("User is not authorized");
7084 		if (rv == CKR_SESSION_READ_ONLY)
7085 			INFO_MSG("Session is read-only");
7086 
7087 		return rv;
7088 	}
7089 
7090 	// Derive DH secret
7091 	if (pMechanism->mechanism == CKM_DH_PKCS_DERIVE)
7092 	{
7093 		// Check key class and type
7094 		if (key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_PRIVATE_KEY)
7095 			return CKR_KEY_TYPE_INCONSISTENT;
7096 		if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_DH)
7097 			return CKR_KEY_TYPE_INCONSISTENT;
7098 
7099 		return this->deriveDH(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate);
7100 	}
7101 
7102 #if defined(WITH_ECC) || defined(WITH_EDDSA)
7103 	// Derive ECDH secret
7104 	if (pMechanism->mechanism == CKM_ECDH1_DERIVE)
7105 	{
7106 		// Check key class and type
7107 		if (key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_PRIVATE_KEY)
7108 			return CKR_KEY_TYPE_INCONSISTENT;
7109 #ifdef WITH_ECC
7110 		else if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) == CKK_EC)
7111 			return this->deriveECDH(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate);
7112 #endif
7113 #ifdef WITH_EDDSA
7114 		else if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) == CKK_EC_EDWARDS)
7115 			return this->deriveEDDSA(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate);
7116 #endif
7117 		else
7118 			return CKR_KEY_TYPE_INCONSISTENT;
7119 	}
7120 #endif
7121 
7122 	// Derive symmetric secret
7123 	if (pMechanism->mechanism == CKM_DES_ECB_ENCRYPT_DATA ||
7124 	    pMechanism->mechanism == CKM_DES_CBC_ENCRYPT_DATA ||
7125 	    pMechanism->mechanism == CKM_DES3_ECB_ENCRYPT_DATA ||
7126 	    pMechanism->mechanism == CKM_DES3_CBC_ENCRYPT_DATA ||
7127 	    pMechanism->mechanism == CKM_AES_ECB_ENCRYPT_DATA ||
7128 	    pMechanism->mechanism == CKM_AES_CBC_ENCRYPT_DATA)
7129 	{
7130 		// Check key class and type
7131 		CK_KEY_TYPE baseKeyType = key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED);
7132 		if (key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_SECRET_KEY)
7133 			return CKR_KEY_TYPE_INCONSISTENT;
7134 		if (pMechanism->mechanism == CKM_DES_ECB_ENCRYPT_DATA &&
7135 		    baseKeyType != CKK_DES)
7136 			return CKR_KEY_TYPE_INCONSISTENT;
7137 		if (pMechanism->mechanism == CKM_DES_CBC_ENCRYPT_DATA &&
7138 		    baseKeyType != CKK_DES)
7139 			return CKR_KEY_TYPE_INCONSISTENT;
7140 		if (pMechanism->mechanism == CKM_DES3_ECB_ENCRYPT_DATA &&
7141 		    baseKeyType != CKK_DES2 && baseKeyType != CKK_DES3)
7142 			return CKR_KEY_TYPE_INCONSISTENT;
7143 		if (pMechanism->mechanism == CKM_DES3_CBC_ENCRYPT_DATA &&
7144 		    baseKeyType != CKK_DES2 && baseKeyType != CKK_DES3)
7145 			return CKR_KEY_TYPE_INCONSISTENT;
7146 		if (pMechanism->mechanism == CKM_AES_ECB_ENCRYPT_DATA &&
7147 		    baseKeyType != CKK_AES)
7148 			return CKR_KEY_TYPE_INCONSISTENT;
7149 		if (pMechanism->mechanism == CKM_AES_CBC_ENCRYPT_DATA &&
7150 		    baseKeyType != CKK_AES)
7151 			return CKR_KEY_TYPE_INCONSISTENT;
7152 
7153 		return this->deriveSymmetric(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate);
7154 	}
7155 
7156 	return CKR_MECHANISM_INVALID;
7157 }
7158 
7159 // Seed the random number generator with new data
C_SeedRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSeed,CK_ULONG ulSeedLen)7160 CK_RV SoftHSM::C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
7161 {
7162 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
7163 
7164 	if (pSeed == NULL_PTR) return CKR_ARGUMENTS_BAD;
7165 
7166 	// Get the session
7167 	Session* session = (Session*)handleManager->getSession(hSession);
7168 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
7169 
7170 	// Get the RNG
7171 	RNG* rng = CryptoFactory::i()->getRNG();
7172 	if (rng == NULL) return CKR_GENERAL_ERROR;
7173 
7174 	// Seed the RNG
7175 	ByteString seed(pSeed, ulSeedLen);
7176 	rng->seed(seed);
7177 
7178 	return CKR_OK;
7179 }
7180 
7181 // Generate the specified amount of random data
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pRandomData,CK_ULONG ulRandomLen)7182 CK_RV SoftHSM::C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
7183 {
7184 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
7185 
7186 	if (pRandomData == NULL_PTR) return CKR_ARGUMENTS_BAD;
7187 
7188 	// Get the session
7189 	Session* session = (Session*)handleManager->getSession(hSession);
7190 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
7191 
7192 	// Get the RNG
7193 	RNG* rng = CryptoFactory::i()->getRNG();
7194 	if (rng == NULL) return CKR_GENERAL_ERROR;
7195 
7196 	// Generate random data
7197 	ByteString randomData;
7198 	if (!rng->generateRandom(randomData, ulRandomLen)) return CKR_GENERAL_ERROR;
7199 
7200 	// Return random data
7201 	if (ulRandomLen != 0)
7202 	{
7203 		memcpy(pRandomData, randomData.byte_str(), ulRandomLen);
7204 	}
7205 
7206 	return CKR_OK;
7207 }
7208 
7209 // Legacy function
C_GetFunctionStatus(CK_SESSION_HANDLE hSession)7210 CK_RV SoftHSM::C_GetFunctionStatus(CK_SESSION_HANDLE hSession)
7211 {
7212 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
7213 
7214 	// Get the session
7215 	Session* session = (Session*)handleManager->getSession(hSession);
7216 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
7217 
7218 	return CKR_FUNCTION_NOT_PARALLEL;
7219 }
7220 
7221 // Legacy function
C_CancelFunction(CK_SESSION_HANDLE hSession)7222 CK_RV SoftHSM::C_CancelFunction(CK_SESSION_HANDLE hSession)
7223 {
7224 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
7225 
7226 	// Get the session
7227 	Session* session = (Session*)handleManager->getSession(hSession);
7228 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
7229 
7230 	return CKR_FUNCTION_NOT_PARALLEL;
7231 }
7232 
7233 // Wait or poll for a slot event on the specified slot
C_WaitForSlotEvent(CK_FLAGS flags,CK_SLOT_ID_PTR,CK_VOID_PTR)7234 CK_RV SoftHSM::C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR /*pSlot*/, CK_VOID_PTR /*pReserved*/)
7235 {
7236 	if (!(flags & CKF_DONT_BLOCK)) return CKR_FUNCTION_NOT_SUPPORTED;
7237 
7238 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
7239 
7240 	// SoftHSM slots don't change after it's initialised. With the
7241 	// exception of when a slot is initialised and then getSlotList() is
7242 	// called. However, at this point the caller has been updated with the
7243 	// new slot list already so no event needs to be triggered.
7244 	return CKR_NO_EVENT;
7245 }
7246 
generateGeneric(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)7247 CK_RV SoftHSM::generateGeneric
7248 (CK_SESSION_HANDLE hSession,
7249 	CK_ATTRIBUTE_PTR pTemplate,
7250 	CK_ULONG ulCount,
7251 	CK_OBJECT_HANDLE_PTR phKey,
7252 	CK_BBOOL isOnToken,
7253 	CK_BBOOL isPrivate)
7254 {
7255 	*phKey = CK_INVALID_HANDLE;
7256 
7257 	// Get the session
7258 	Session* session = (Session*)handleManager->getSession(hSession);
7259 	if (session == NULL)
7260 		return CKR_SESSION_HANDLE_INVALID;
7261 
7262 	// Get the token
7263 	Token* token = session->getToken();
7264 	if (token == NULL)
7265 		return CKR_GENERAL_ERROR;
7266 
7267 	// Extract desired parameter information
7268 	size_t keyLen = 0;
7269 	bool checkValue = true;
7270 	for (CK_ULONG i = 0; i < ulCount; i++)
7271 	{
7272 		switch (pTemplate[i].type)
7273 		{
7274 			case CKA_VALUE_LEN:
7275 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
7276 				{
7277 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
7278 					return CKR_ATTRIBUTE_VALUE_INVALID;
7279 				}
7280 				keyLen = *(CK_ULONG*)pTemplate[i].pValue;
7281 				break;
7282 			case CKA_CHECK_VALUE:
7283 				if (pTemplate[i].ulValueLen > 0)
7284 				{
7285 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
7286 					return CKR_ATTRIBUTE_VALUE_INVALID;
7287 				}
7288 				checkValue = false;
7289 				break;
7290 			default:
7291 				break;
7292 		}
7293 	}
7294 
7295 	// CKA_VALUE_LEN must be specified
7296 	if (keyLen == 0)
7297 	{
7298 		INFO_MSG("Missing CKA_VALUE_LEN in pTemplate");
7299 		return CKR_TEMPLATE_INCOMPLETE;
7300 	}
7301 
7302 	// Check keyLen
7303 	if (keyLen < 1 || keyLen > 0x8000000)
7304 	{
7305 		INFO_MSG("bad generic key length");
7306 		return CKR_ATTRIBUTE_VALUE_INVALID;
7307 	}
7308 
7309 	// Generate the secret key
7310 	RNG* rng = CryptoFactory::i()->getRNG();
7311 	if (rng == NULL) return CKR_GENERAL_ERROR;
7312 	ByteString key;
7313 	if (!rng->generateRandom(key, keyLen)) return CKR_GENERAL_ERROR;
7314 
7315         CK_RV rv = CKR_OK;
7316 
7317 	// Create the secret key object using C_CreateObject
7318 	const CK_ULONG maxAttribs = 32;
7319 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
7320 	CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
7321 	CK_ATTRIBUTE keyAttribs[maxAttribs] = {
7322 		{ CKA_CLASS, &objClass, sizeof(objClass) },
7323 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
7324 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
7325 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
7326 	};
7327 	CK_ULONG keyAttribsCount = 4;
7328 
7329 	// Add the additional
7330 	if (ulCount > (maxAttribs - keyAttribsCount))
7331 		rv = CKR_TEMPLATE_INCONSISTENT;
7332 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
7333 	{
7334 		switch (pTemplate[i].type)
7335 		{
7336 			case CKA_CLASS:
7337 			case CKA_TOKEN:
7338 			case CKA_PRIVATE:
7339 			case CKA_KEY_TYPE:
7340 			case CKA_CHECK_VALUE:
7341 				continue;
7342 			default:
7343 				keyAttribs[keyAttribsCount++] = pTemplate[i];
7344 				break;
7345 		}
7346 	}
7347 
7348 	if (rv == CKR_OK)
7349 		rv = CreateObject(hSession, keyAttribs, keyAttribsCount, phKey, OBJECT_OP_GENERATE);
7350 
7351 	// Store the attributes that are being supplied
7352 	if (rv == CKR_OK)
7353 	{
7354 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
7355 		if (osobject == NULL_PTR || !osobject->isValid()) {
7356 			rv = CKR_FUNCTION_FAILED;
7357 		} else if (osobject->startTransaction()) {
7358 			bool bOK = true;
7359 
7360 			// Common Attributes
7361 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
7362 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_GENERIC_SECRET_KEY_GEN;
7363 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
7364 
7365 			// Common Secret Key Attributes
7366 			bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
7367 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
7368 			bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
7369 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
7370 
7371 			// Generic Secret Key Attributes
7372 			ByteString value;
7373 			ByteString kcv;
7374 			SymmetricKey symKey;
7375 			symKey.setKeyBits(key);
7376 			symKey.setBitLen(keyLen);
7377 			if (isPrivate)
7378 			{
7379 				token->encrypt(symKey.getKeyBits(), value);
7380 				token->encrypt(symKey.getKeyCheckValue(), kcv);
7381 			}
7382 			else
7383 			{
7384 				value = symKey.getKeyBits();
7385 				kcv = symKey.getKeyCheckValue();
7386 			}
7387 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
7388 			if (checkValue)
7389 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
7390 
7391 			if (bOK)
7392 				bOK = osobject->commitTransaction();
7393 			else
7394 				osobject->abortTransaction();
7395 
7396 			if (!bOK)
7397 				rv = CKR_FUNCTION_FAILED;
7398 		} else
7399 			rv = CKR_FUNCTION_FAILED;
7400 	}
7401 
7402 	// Clean up
7403 	// Remove the key that may have been created already when the function fails.
7404 	if (rv != CKR_OK)
7405 	{
7406 		if (*phKey != CK_INVALID_HANDLE)
7407 		{
7408 			OSObject* oskey = (OSObject*)handleManager->getObject(*phKey);
7409 			handleManager->destroyObject(*phKey);
7410 			if (oskey) oskey->destroyObject();
7411 			*phKey = CK_INVALID_HANDLE;
7412 		}
7413 	}
7414 
7415 	return rv;
7416 }
7417 
7418 // Generate an AES secret key
generateAES(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)7419 CK_RV SoftHSM::generateAES
7420 (CK_SESSION_HANDLE hSession,
7421 	CK_ATTRIBUTE_PTR pTemplate,
7422 	CK_ULONG ulCount,
7423 	CK_OBJECT_HANDLE_PTR phKey,
7424 	CK_BBOOL isOnToken,
7425 	CK_BBOOL isPrivate)
7426 {
7427 	*phKey = CK_INVALID_HANDLE;
7428 
7429 	// Get the session
7430 	Session* session = (Session*)handleManager->getSession(hSession);
7431 	if (session == NULL)
7432 		return CKR_SESSION_HANDLE_INVALID;
7433 
7434 	// Get the token
7435 	Token* token = session->getToken();
7436 	if (token == NULL)
7437 		return CKR_GENERAL_ERROR;
7438 
7439 	// Extract desired parameter information
7440 	size_t keyLen = 0;
7441 	bool checkValue = true;
7442 	for (CK_ULONG i = 0; i < ulCount; i++)
7443 	{
7444 		switch (pTemplate[i].type)
7445 		{
7446 			case CKA_VALUE_LEN:
7447 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
7448 				{
7449 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
7450 					return CKR_ATTRIBUTE_VALUE_INVALID;
7451 				}
7452 				keyLen = *(CK_ULONG*)pTemplate[i].pValue;
7453 				break;
7454 			case CKA_CHECK_VALUE:
7455 				if (pTemplate[i].ulValueLen > 0)
7456 				{
7457 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
7458 					return CKR_ATTRIBUTE_VALUE_INVALID;
7459 				}
7460 				checkValue = false;
7461 				break;
7462 			default:
7463 				break;
7464 		}
7465 	}
7466 
7467 	// CKA_VALUE_LEN must be specified
7468 	if (keyLen == 0)
7469 	{
7470 		INFO_MSG("Missing CKA_VALUE_LEN in pTemplate");
7471 		return CKR_TEMPLATE_INCOMPLETE;
7472 	}
7473 
7474 	// keyLen must be 16, 24, or 32
7475 	if (keyLen != 16 && keyLen != 24 && keyLen != 32)
7476 	{
7477 		INFO_MSG("bad AES key length");
7478 		return CKR_ATTRIBUTE_VALUE_INVALID;
7479 	}
7480 
7481 	// Generate the secret key
7482 	AESKey* key = new AESKey(keyLen * 8);
7483 	SymmetricAlgorithm* aes = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES);
7484 	if (aes == NULL)
7485 	{
7486 		ERROR_MSG("Could not get SymmetricAlgorithm");
7487 		delete key;
7488 		return CKR_GENERAL_ERROR;
7489 	}
7490 	RNG* rng = CryptoFactory::i()->getRNG();
7491 	if (rng == NULL)
7492 	{
7493 		ERROR_MSG("Could not get RNG");
7494 		aes->recycleKey(key);
7495 		CryptoFactory::i()->recycleSymmetricAlgorithm(aes);
7496 		return CKR_GENERAL_ERROR;
7497 	}
7498 	if (!aes->generateKey(*key, rng))
7499 	{
7500 		ERROR_MSG("Could not generate AES secret key");
7501 		aes->recycleKey(key);
7502 		CryptoFactory::i()->recycleSymmetricAlgorithm(aes);
7503 		return CKR_GENERAL_ERROR;
7504 	}
7505 
7506 	CK_RV rv = CKR_OK;
7507 
7508 	// Create the secret key object using C_CreateObject
7509 	const CK_ULONG maxAttribs = 32;
7510 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
7511 	CK_KEY_TYPE keyType = CKK_AES;
7512 	CK_ATTRIBUTE keyAttribs[maxAttribs] = {
7513 		{ CKA_CLASS, &objClass, sizeof(objClass) },
7514 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
7515 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
7516 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
7517 	};
7518 	CK_ULONG keyAttribsCount = 4;
7519 
7520 	// Add the additional
7521 	if (ulCount > (maxAttribs - keyAttribsCount))
7522 		rv = CKR_TEMPLATE_INCONSISTENT;
7523 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
7524 	{
7525 		switch (pTemplate[i].type)
7526 		{
7527 			case CKA_CLASS:
7528 			case CKA_TOKEN:
7529 			case CKA_PRIVATE:
7530 			case CKA_KEY_TYPE:
7531 			case CKA_CHECK_VALUE:
7532 				continue;
7533 		default:
7534 			keyAttribs[keyAttribsCount++] = pTemplate[i];
7535 		}
7536 	}
7537 
7538 	if (rv == CKR_OK)
7539 		rv = this->CreateObject(hSession, keyAttribs, keyAttribsCount, phKey,OBJECT_OP_GENERATE);
7540 
7541 	// Store the attributes that are being supplied
7542 	if (rv == CKR_OK)
7543 	{
7544 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
7545 		if (osobject == NULL_PTR || !osobject->isValid()) {
7546 			rv = CKR_FUNCTION_FAILED;
7547 		} else if (osobject->startTransaction()) {
7548 			bool bOK = true;
7549 
7550 			// Common Attributes
7551 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
7552 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_AES_KEY_GEN;
7553 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
7554 
7555 			// Common Secret Key Attributes
7556 			bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
7557 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
7558 			bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
7559 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
7560 
7561 			// AES Secret Key Attributes
7562 			ByteString value;
7563 			ByteString kcv;
7564 			if (isPrivate)
7565 			{
7566 				token->encrypt(key->getKeyBits(), value);
7567 				token->encrypt(key->getKeyCheckValue(), kcv);
7568 			}
7569 			else
7570 			{
7571 				value = key->getKeyBits();
7572 				kcv = key->getKeyCheckValue();
7573 			}
7574 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
7575 			if (checkValue)
7576 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
7577 
7578 			if (bOK)
7579 				bOK = osobject->commitTransaction();
7580 			else
7581 				osobject->abortTransaction();
7582 
7583 			if (!bOK)
7584 				rv = CKR_FUNCTION_FAILED;
7585 		} else
7586 			rv = CKR_FUNCTION_FAILED;
7587 	}
7588 
7589 	// Clean up
7590 	aes->recycleKey(key);
7591 	CryptoFactory::i()->recycleSymmetricAlgorithm(aes);
7592 
7593 	// Remove the key that may have been created already when the function fails.
7594 	if (rv != CKR_OK)
7595 	{
7596 		if (*phKey != CK_INVALID_HANDLE)
7597 		{
7598 			OSObject* oskey = (OSObject*)handleManager->getObject(*phKey);
7599 			handleManager->destroyObject(*phKey);
7600 			if (oskey) oskey->destroyObject();
7601 			*phKey = CK_INVALID_HANDLE;
7602 		}
7603 	}
7604 
7605 	return rv;
7606 }
7607 
7608 // Generate a DES secret key
generateDES(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)7609 CK_RV SoftHSM::generateDES
7610 (CK_SESSION_HANDLE hSession,
7611 	CK_ATTRIBUTE_PTR pTemplate,
7612 	CK_ULONG ulCount,
7613 	CK_OBJECT_HANDLE_PTR phKey,
7614 	CK_BBOOL isOnToken,
7615 	CK_BBOOL isPrivate)
7616 {
7617 	*phKey = CK_INVALID_HANDLE;
7618 
7619 	// Get the session
7620 	Session* session = (Session*)handleManager->getSession(hSession);
7621 	if (session == NULL)
7622 		return CKR_SESSION_HANDLE_INVALID;
7623 
7624 	// Get the token
7625 	Token* token = session->getToken();
7626 	if (token == NULL)
7627 		return CKR_GENERAL_ERROR;
7628 
7629 	// Extract desired parameter information
7630 	bool checkValue = true;
7631 	for (CK_ULONG i = 0; i < ulCount; i++)
7632 	{
7633 		switch (pTemplate[i].type)
7634 		{
7635 			case CKA_CHECK_VALUE:
7636 				if (pTemplate[i].ulValueLen > 0)
7637 				{
7638 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
7639 					return CKR_ATTRIBUTE_VALUE_INVALID;
7640 				}
7641 				checkValue = false;
7642 				break;
7643 			default:
7644 				break;
7645 		}
7646 	}
7647 
7648 	// Generate the secret key
7649 	DESKey* key = new DESKey(56);
7650 	SymmetricAlgorithm* des = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::DES);
7651 	if (des == NULL)
7652 	{
7653 		ERROR_MSG("Could not get SymmetricAlgorithm");
7654 		delete key;
7655 		return CKR_GENERAL_ERROR;
7656 	}
7657 	RNG* rng = CryptoFactory::i()->getRNG();
7658 	if (rng == NULL)
7659 	{
7660 		ERROR_MSG("Could not get RNG");
7661 		des->recycleKey(key);
7662 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7663 		return CKR_GENERAL_ERROR;
7664 	}
7665 	if (!des->generateKey(*key, rng))
7666 	{
7667 		ERROR_MSG("Could not generate DES secret key");
7668 		des->recycleKey(key);
7669 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7670 		return CKR_GENERAL_ERROR;
7671 	}
7672 
7673 	CK_RV rv = CKR_OK;
7674 
7675 	// Create the secret key object using C_CreateObject
7676 	const CK_ULONG maxAttribs = 32;
7677 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
7678 	CK_KEY_TYPE keyType = CKK_DES;
7679 	CK_ATTRIBUTE keyAttribs[maxAttribs] = {
7680 		{ CKA_CLASS, &objClass, sizeof(objClass) },
7681 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
7682 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
7683 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
7684 	};
7685 	CK_ULONG keyAttribsCount = 4;
7686 
7687 	// Add the additional
7688 	if (ulCount > (maxAttribs - keyAttribsCount))
7689 		rv = CKR_TEMPLATE_INCONSISTENT;
7690 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
7691 	{
7692 		switch (pTemplate[i].type)
7693 		{
7694 			case CKA_CLASS:
7695 			case CKA_TOKEN:
7696 			case CKA_PRIVATE:
7697 			case CKA_KEY_TYPE:
7698 			case CKA_CHECK_VALUE:
7699 				continue;
7700 		default:
7701 			keyAttribs[keyAttribsCount++] = pTemplate[i];
7702 		}
7703 	}
7704 
7705 	if (rv == CKR_OK)
7706 		rv = this->CreateObject(hSession, keyAttribs, keyAttribsCount, phKey,OBJECT_OP_GENERATE);
7707 
7708 	// Store the attributes that are being supplied
7709 	if (rv == CKR_OK)
7710 	{
7711 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
7712 		if (osobject == NULL_PTR || !osobject->isValid()) {
7713 			rv = CKR_FUNCTION_FAILED;
7714 		} else if (osobject->startTransaction()) {
7715 			bool bOK = true;
7716 
7717 			// Common Attributes
7718 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
7719 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DES_KEY_GEN;
7720 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
7721 
7722 			// Common Secret Key Attributes
7723 			bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
7724 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
7725 			bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
7726 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
7727 
7728 			// DES Secret Key Attributes
7729 			ByteString value;
7730 			ByteString kcv;
7731 			if (isPrivate)
7732 			{
7733 				token->encrypt(key->getKeyBits(), value);
7734 				token->encrypt(key->getKeyCheckValue(), kcv);
7735 			}
7736 			else
7737 			{
7738 				value = key->getKeyBits();
7739 				kcv = key->getKeyCheckValue();
7740 			}
7741 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
7742 			if (checkValue)
7743 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
7744 
7745 			if (bOK)
7746 				bOK = osobject->commitTransaction();
7747 			else
7748 				osobject->abortTransaction();
7749 
7750 			if (!bOK)
7751 				rv = CKR_FUNCTION_FAILED;
7752 		} else
7753 			rv = CKR_FUNCTION_FAILED;
7754 	}
7755 
7756 	// Clean up
7757 	des->recycleKey(key);
7758 	CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7759 
7760 	// Remove the key that may have been created already when the function fails.
7761 	if (rv != CKR_OK)
7762 	{
7763 		if (*phKey != CK_INVALID_HANDLE)
7764 		{
7765 			OSObject* oskey = (OSObject*)handleManager->getObject(*phKey);
7766 			handleManager->destroyObject(*phKey);
7767 			if (oskey) oskey->destroyObject();
7768 			*phKey = CK_INVALID_HANDLE;
7769 		}
7770 	}
7771 
7772 	return rv;
7773 }
7774 
7775 // Generate a DES2 secret key
generateDES2(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)7776 CK_RV SoftHSM::generateDES2
7777 (CK_SESSION_HANDLE hSession,
7778 	CK_ATTRIBUTE_PTR pTemplate,
7779 	CK_ULONG ulCount,
7780 	CK_OBJECT_HANDLE_PTR phKey,
7781 	CK_BBOOL isOnToken,
7782 	CK_BBOOL isPrivate)
7783 {
7784 	*phKey = CK_INVALID_HANDLE;
7785 
7786 	// Get the session
7787 	Session* session = (Session*)handleManager->getSession(hSession);
7788 	if (session == NULL)
7789 		return CKR_SESSION_HANDLE_INVALID;
7790 
7791 	// Get the token
7792 	Token* token = session->getToken();
7793 	if (token == NULL)
7794 		return CKR_GENERAL_ERROR;
7795 
7796 	// Extract desired parameter information
7797 	bool checkValue = true;
7798 	for (CK_ULONG i = 0; i < ulCount; i++)
7799 	{
7800 		switch (pTemplate[i].type)
7801 		{
7802 			case CKA_CHECK_VALUE:
7803 				if (pTemplate[i].ulValueLen > 0)
7804 				{
7805 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
7806 					return CKR_ATTRIBUTE_VALUE_INVALID;
7807 				}
7808 				checkValue = false;
7809 				break;
7810 			default:
7811 				break;
7812 		}
7813 	}
7814 
7815 	// Generate the secret key
7816 	DESKey* key = new DESKey(112);
7817 	SymmetricAlgorithm* des = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::DES3);
7818 	if (des == NULL)
7819 	{
7820 		ERROR_MSG("Could not get SymmetricAlgorith");
7821 		delete key;
7822 		return CKR_GENERAL_ERROR;
7823 	}
7824 	RNG* rng = CryptoFactory::i()->getRNG();
7825 	if (rng == NULL)
7826 	{
7827 		ERROR_MSG("Could not get RNG");
7828 		des->recycleKey(key);
7829 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7830 		return CKR_GENERAL_ERROR;
7831 	}
7832 	if (!des->generateKey(*key, rng))
7833 	{
7834 		ERROR_MSG("Could not generate DES secret key");
7835 		des->recycleKey(key);
7836 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7837 		return CKR_GENERAL_ERROR;
7838 	}
7839 
7840 	CK_RV rv = CKR_OK;
7841 
7842 	// Create the secret key object using C_CreateObject
7843 	const CK_ULONG maxAttribs = 32;
7844 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
7845 	CK_KEY_TYPE keyType = CKK_DES2;
7846 	CK_ATTRIBUTE keyAttribs[maxAttribs] = {
7847 		{ CKA_CLASS, &objClass, sizeof(objClass) },
7848 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
7849 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
7850 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
7851 	};
7852 	CK_ULONG keyAttribsCount = 4;
7853 
7854 	// Add the additional
7855 	if (ulCount > (maxAttribs - keyAttribsCount))
7856 		rv = CKR_TEMPLATE_INCONSISTENT;
7857 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
7858 	{
7859 		switch (pTemplate[i].type)
7860 		{
7861 			case CKA_CLASS:
7862 			case CKA_TOKEN:
7863 			case CKA_PRIVATE:
7864 			case CKA_KEY_TYPE:
7865 			case CKA_CHECK_VALUE:
7866 				continue;
7867 		default:
7868 			keyAttribs[keyAttribsCount++] = pTemplate[i];
7869 		}
7870 	}
7871 
7872 	if (rv == CKR_OK)
7873 		rv = this->CreateObject(hSession, keyAttribs, keyAttribsCount, phKey,OBJECT_OP_GENERATE);
7874 
7875 	// Store the attributes that are being supplied
7876 	if (rv == CKR_OK)
7877 	{
7878 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
7879 		if (osobject == NULL_PTR || !osobject->isValid()) {
7880 			rv = CKR_FUNCTION_FAILED;
7881 		} else if (osobject->startTransaction()) {
7882 			bool bOK = true;
7883 
7884 			// Common Attributes
7885 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
7886 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DES2_KEY_GEN;
7887 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
7888 
7889 			// Common Secret Key Attributes
7890 			bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
7891 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
7892 			bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
7893 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
7894 
7895 			// DES Secret Key Attributes
7896 			ByteString value;
7897 			ByteString kcv;
7898 			if (isPrivate)
7899 			{
7900 				token->encrypt(key->getKeyBits(), value);
7901 				token->encrypt(key->getKeyCheckValue(), kcv);
7902 			}
7903 			else
7904 			{
7905 				value = key->getKeyBits();
7906 				kcv = key->getKeyCheckValue();
7907 			}
7908 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
7909 			if (checkValue)
7910 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
7911 
7912 			if (bOK)
7913 				bOK = osobject->commitTransaction();
7914 			else
7915 				osobject->abortTransaction();
7916 
7917 			if (!bOK)
7918 				rv = CKR_FUNCTION_FAILED;
7919 		} else
7920 			rv = CKR_FUNCTION_FAILED;
7921 	}
7922 
7923 	// Clean up
7924 	des->recycleKey(key);
7925 	CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7926 
7927 	// Remove the key that may have been created already when the function fails.
7928 	if (rv != CKR_OK)
7929 	{
7930 		if (*phKey != CK_INVALID_HANDLE)
7931 		{
7932 			OSObject* oskey = (OSObject*)handleManager->getObject(*phKey);
7933 			handleManager->destroyObject(*phKey);
7934 			if (oskey) oskey->destroyObject();
7935 			*phKey = CK_INVALID_HANDLE;
7936 		}
7937 	}
7938 
7939 	return rv;
7940 }
7941 
7942 // Generate a DES3 secret key
generateDES3(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)7943 CK_RV SoftHSM::generateDES3
7944 (CK_SESSION_HANDLE hSession,
7945 	CK_ATTRIBUTE_PTR pTemplate,
7946 	CK_ULONG ulCount,
7947 	CK_OBJECT_HANDLE_PTR phKey,
7948 	CK_BBOOL isOnToken,
7949 	CK_BBOOL isPrivate)
7950 {
7951 	*phKey = CK_INVALID_HANDLE;
7952 
7953 	// Get the session
7954 	Session* session = (Session*)handleManager->getSession(hSession);
7955 	if (session == NULL)
7956 		return CKR_SESSION_HANDLE_INVALID;
7957 
7958 	// Get the token
7959 	Token* token = session->getToken();
7960 	if (token == NULL)
7961 		return CKR_GENERAL_ERROR;
7962 
7963 	// Extract desired parameter information
7964 	bool checkValue = true;
7965 	for (CK_ULONG i = 0; i < ulCount; i++)
7966 	{
7967 		switch (pTemplate[i].type)
7968 		{
7969 			case CKA_CHECK_VALUE:
7970 				if (pTemplate[i].ulValueLen > 0)
7971 				{
7972 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
7973 					return CKR_ATTRIBUTE_VALUE_INVALID;
7974 				}
7975 				checkValue = false;
7976 				break;
7977 			default:
7978 				break;
7979 		}
7980 	}
7981 
7982 	// Generate the secret key
7983 	DESKey* key = new DESKey(168);
7984 	SymmetricAlgorithm* des = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::DES3);
7985 	if (des == NULL)
7986 	{
7987 		ERROR_MSG("Could not get SymmetricAlgorithm");
7988 		delete key;
7989 		return CKR_GENERAL_ERROR;
7990 	}
7991 	RNG* rng = CryptoFactory::i()->getRNG();
7992 	if (rng == NULL)
7993 	{
7994 		ERROR_MSG("Could not get RNG");
7995 		des->recycleKey(key);
7996 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
7997 		return CKR_GENERAL_ERROR;
7998 	}
7999 	if (!des->generateKey(*key, rng))
8000 	{
8001 		ERROR_MSG("Could not generate DES secret key");
8002 		des->recycleKey(key);
8003 		CryptoFactory::i()->recycleSymmetricAlgorithm(des);
8004 		return CKR_GENERAL_ERROR;
8005 	}
8006 
8007 	CK_RV rv = CKR_OK;
8008 
8009 	// Create the secret key object using C_CreateObject
8010 	const CK_ULONG maxAttribs = 32;
8011 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
8012 	CK_KEY_TYPE keyType = CKK_DES3;
8013 	CK_ATTRIBUTE keyAttribs[maxAttribs] = {
8014 		{ CKA_CLASS, &objClass, sizeof(objClass) },
8015 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
8016 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
8017 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
8018 	};
8019 	CK_ULONG keyAttribsCount = 4;
8020 
8021 	// Add the additional
8022 	if (ulCount > (maxAttribs - keyAttribsCount))
8023 		rv = CKR_TEMPLATE_INCONSISTENT;
8024 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
8025 	{
8026 		switch (pTemplate[i].type)
8027 		{
8028 			case CKA_CLASS:
8029 			case CKA_TOKEN:
8030 			case CKA_PRIVATE:
8031 			case CKA_KEY_TYPE:
8032 			case CKA_CHECK_VALUE:
8033 				continue;
8034 		default:
8035 			keyAttribs[keyAttribsCount++] = pTemplate[i];
8036 		}
8037 	}
8038 
8039 	if (rv == CKR_OK)
8040 		rv = this->CreateObject(hSession, keyAttribs, keyAttribsCount, phKey,OBJECT_OP_GENERATE);
8041 
8042 	// Store the attributes that are being supplied
8043 	if (rv == CKR_OK)
8044 	{
8045 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
8046 		if (osobject == NULL_PTR || !osobject->isValid()) {
8047 			rv = CKR_FUNCTION_FAILED;
8048 		} else if (osobject->startTransaction()) {
8049 			bool bOK = true;
8050 
8051 			// Common Attributes
8052 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8053 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DES3_KEY_GEN;
8054 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8055 
8056 			// Common Secret Key Attributes
8057 			bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
8058 			bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
8059 			bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
8060 			bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
8061 
8062 			// DES Secret Key Attributes
8063 			ByteString value;
8064 			ByteString kcv;
8065 			if (isPrivate)
8066 			{
8067 				token->encrypt(key->getKeyBits(), value);
8068 				token->encrypt(key->getKeyCheckValue(), kcv);
8069 			}
8070 			else
8071 			{
8072 				value = key->getKeyBits();
8073 				kcv = key->getKeyCheckValue();
8074 			}
8075 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
8076 			if (checkValue)
8077 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
8078 
8079 			if (bOK)
8080 				bOK = osobject->commitTransaction();
8081 			else
8082 				osobject->abortTransaction();
8083 
8084 			if (!bOK)
8085 				rv = CKR_FUNCTION_FAILED;
8086 		} else
8087 			rv = CKR_FUNCTION_FAILED;
8088 	}
8089 
8090 	// Clean up
8091 	des->recycleKey(key);
8092 	CryptoFactory::i()->recycleSymmetricAlgorithm(des);
8093 
8094 	// Remove the key that may have been created already when the function fails.
8095 	if (rv != CKR_OK)
8096 	{
8097 		if (*phKey != CK_INVALID_HANDLE)
8098 		{
8099 			OSObject* oskey = (OSObject*)handleManager->getObject(*phKey);
8100 			handleManager->destroyObject(*phKey);
8101 			if (oskey) oskey->destroyObject();
8102 			*phKey = CK_INVALID_HANDLE;
8103 		}
8104 	}
8105 
8106 	return rv;
8107 }
8108 
8109 // Generate an RSA key pair
generateRSA(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)8110 CK_RV SoftHSM::generateRSA
8111 (CK_SESSION_HANDLE hSession,
8112 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
8113 	CK_ULONG ulPublicKeyAttributeCount,
8114 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
8115 	CK_ULONG ulPrivateKeyAttributeCount,
8116 	CK_OBJECT_HANDLE_PTR phPublicKey,
8117 	CK_OBJECT_HANDLE_PTR phPrivateKey,
8118 	CK_BBOOL isPublicKeyOnToken,
8119 	CK_BBOOL isPublicKeyPrivate,
8120 	CK_BBOOL isPrivateKeyOnToken,
8121 	CK_BBOOL isPrivateKeyPrivate
8122 )
8123 {
8124 	*phPublicKey = CK_INVALID_HANDLE;
8125 	*phPrivateKey = CK_INVALID_HANDLE;
8126 
8127 	// Get the session
8128 	Session* session = (Session*)handleManager->getSession(hSession);
8129 	if (session == NULL)
8130 		return CKR_SESSION_HANDLE_INVALID;
8131 
8132 	// Get the token
8133 	Token* token = session->getToken();
8134 	if (token == NULL)
8135 		return CKR_GENERAL_ERROR;
8136 
8137 	// Extract desired key information: bitlen and public exponent
8138 	size_t bitLen = 0;
8139 	ByteString exponent("010001");
8140 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
8141 	{
8142 		switch (pPublicKeyTemplate[i].type)
8143 		{
8144 			case CKA_MODULUS_BITS:
8145 				if (pPublicKeyTemplate[i].ulValueLen != sizeof(CK_ULONG))
8146 				{
8147 					INFO_MSG("CKA_MODULUS_BITS does not have the size of CK_ULONG");
8148 					return CKR_ATTRIBUTE_VALUE_INVALID;
8149 				}
8150 				bitLen = *(CK_ULONG*)pPublicKeyTemplate[i].pValue;
8151 				break;
8152 			case CKA_PUBLIC_EXPONENT:
8153 				exponent = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
8154 				break;
8155 			default:
8156 				break;
8157 		}
8158 	}
8159 
8160 	// CKA_MODULUS_BITS must be specified to be able to generate a key pair.
8161 	if (bitLen == 0) {
8162 		INFO_MSG("Missing CKA_MODULUS_BITS in pPublicKeyTemplate");
8163 		return CKR_TEMPLATE_INCOMPLETE;
8164 	}
8165 
8166 	// Set the parameters
8167 	RSAParameters p;
8168 	p.setE(exponent);
8169 	p.setBitLength(bitLen);
8170 
8171 	// Generate key pair
8172 	AsymmetricKeyPair* kp = NULL;
8173 	AsymmetricAlgorithm* rsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
8174 	if (rsa == NULL)
8175 		return CKR_GENERAL_ERROR;
8176 	if (!rsa->generateKeyPair(&kp, &p))
8177 	{
8178 		ERROR_MSG("Could not generate key pair");
8179 		CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
8180 		return CKR_GENERAL_ERROR;
8181 	}
8182 
8183 	RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
8184 	RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
8185 
8186 	CK_RV rv = CKR_OK;
8187 
8188 	// Create a public key using C_CreateObject
8189 	if (rv == CKR_OK)
8190 	{
8191 		const CK_ULONG maxAttribs = 32;
8192 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
8193 		CK_KEY_TYPE publicKeyType = CKK_RSA;
8194 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
8195 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
8196 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
8197 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
8198 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
8199 		};
8200 		CK_ULONG publicKeyAttribsCount = 4;
8201 
8202 		// Add the additional
8203 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
8204 			rv = CKR_TEMPLATE_INCONSISTENT;
8205 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
8206 		{
8207 			switch (pPublicKeyTemplate[i].type)
8208 			{
8209 				case CKA_CLASS:
8210 				case CKA_TOKEN:
8211 				case CKA_PRIVATE:
8212 				case CKA_KEY_TYPE:
8213 				case CKA_PUBLIC_EXPONENT:
8214 					continue;
8215 				default:
8216 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
8217 			}
8218 		}
8219 
8220 		if (rv == CKR_OK)
8221 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
8222 
8223 		// Store the attributes that are being supplied by the key generation to the object
8224 		if (rv == CKR_OK)
8225 		{
8226 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
8227 			if (osobject == NULL_PTR || !osobject->isValid()) {
8228 				rv = CKR_FUNCTION_FAILED;
8229 			} else if (osobject->startTransaction()) {
8230 				bool bOK = true;
8231 
8232 				// Common Key Attributes
8233 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8234 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_RSA_PKCS_KEY_PAIR_GEN;
8235 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8236 
8237 				// RSA Public Key Attributes
8238 				ByteString modulus;
8239 				ByteString publicExponent;
8240 				if (isPublicKeyPrivate)
8241 				{
8242 					token->encrypt(pub->getN(), modulus);
8243 					token->encrypt(pub->getE(), publicExponent);
8244 				}
8245 				else
8246 				{
8247 					modulus = pub->getN();
8248 					publicExponent = pub->getE();
8249 				}
8250 				bOK = bOK && osobject->setAttribute(CKA_MODULUS, modulus);
8251 				bOK = bOK && osobject->setAttribute(CKA_PUBLIC_EXPONENT, publicExponent);
8252 
8253 				if (bOK)
8254 					bOK = osobject->commitTransaction();
8255 				else
8256 					osobject->abortTransaction();
8257 
8258 				if (!bOK)
8259 					rv = CKR_FUNCTION_FAILED;
8260 			} else
8261 				rv = CKR_FUNCTION_FAILED;
8262 		}
8263 	}
8264 
8265 	// Create a private key using C_CreateObject
8266 	if (rv == CKR_OK)
8267 	{
8268 		const CK_ULONG maxAttribs = 32;
8269 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
8270 		CK_KEY_TYPE privateKeyType = CKK_RSA;
8271 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
8272 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
8273 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
8274 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
8275 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
8276 		};
8277 		CK_ULONG privateKeyAttribsCount = 4;
8278 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
8279 			rv = CKR_TEMPLATE_INCONSISTENT;
8280 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
8281 		{
8282 			switch (pPrivateKeyTemplate[i].type)
8283 			{
8284 				case CKA_CLASS:
8285 				case CKA_TOKEN:
8286 				case CKA_PRIVATE:
8287 				case CKA_KEY_TYPE:
8288 					continue;
8289 				default:
8290 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
8291 			}
8292 		}
8293 
8294 		if (rv == CKR_OK)
8295 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
8296 
8297 		// Store the attributes that are being supplied by the key generation to the object
8298 		if (rv == CKR_OK)
8299 		{
8300 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
8301 			if (osobject == NULL_PTR || !osobject->isValid()) {
8302 				rv = CKR_FUNCTION_FAILED;
8303 			} else if (osobject->startTransaction()) {
8304 				bool bOK = true;
8305 
8306 				// Common Key Attributes
8307 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8308 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_RSA_PKCS_KEY_PAIR_GEN;
8309 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8310 
8311 				// Common Private Key Attributes
8312 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
8313 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
8314 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
8315 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
8316 
8317 				// RSA Private Key Attributes
8318 				ByteString modulus;
8319 				ByteString publicExponent;
8320 				ByteString privateExponent;
8321 				ByteString prime1;
8322 				ByteString prime2;
8323 				ByteString exponent1;
8324 				ByteString exponent2;
8325 				ByteString coefficient;
8326 				if (isPrivateKeyPrivate)
8327 				{
8328 					token->encrypt(priv->getN(), modulus);
8329 					token->encrypt(priv->getE(), publicExponent);
8330 					token->encrypt(priv->getD(), privateExponent);
8331 					token->encrypt(priv->getP(), prime1);
8332 					token->encrypt(priv->getQ(), prime2);
8333 					token->encrypt(priv->getDP1(), exponent1);
8334 					token->encrypt(priv->getDQ1(), exponent2);
8335 					token->encrypt(priv->getPQ(), coefficient);
8336 				}
8337 				else
8338 				{
8339 					modulus = priv->getN();
8340 					publicExponent = priv->getE();
8341 					privateExponent = priv->getD();
8342 					prime1 = priv->getP();
8343 					prime2 = priv->getQ();
8344 					exponent1 =  priv->getDP1();
8345 					exponent2 = priv->getDQ1();
8346 					coefficient = priv->getPQ();
8347 				}
8348 				bOK = bOK && osobject->setAttribute(CKA_MODULUS, modulus);
8349 				bOK = bOK && osobject->setAttribute(CKA_PUBLIC_EXPONENT, publicExponent);
8350 				bOK = bOK && osobject->setAttribute(CKA_PRIVATE_EXPONENT, privateExponent);
8351 				bOK = bOK && osobject->setAttribute(CKA_PRIME_1, prime1);
8352 				bOK = bOK && osobject->setAttribute(CKA_PRIME_2, prime2);
8353 				bOK = bOK && osobject->setAttribute(CKA_EXPONENT_1,exponent1);
8354 				bOK = bOK && osobject->setAttribute(CKA_EXPONENT_2, exponent2);
8355 				bOK = bOK && osobject->setAttribute(CKA_COEFFICIENT, coefficient);
8356 
8357 				if (bOK)
8358 					bOK = osobject->commitTransaction();
8359 				else
8360 					osobject->abortTransaction();
8361 
8362 				if (!bOK)
8363 					rv = CKR_FUNCTION_FAILED;
8364 			} else
8365 				rv = CKR_FUNCTION_FAILED;
8366 		}
8367 	}
8368 
8369 	// Clean up
8370 	rsa->recycleKeyPair(kp);
8371 	CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
8372 
8373 	// Remove keys that may have been created already when the function fails.
8374 	if (rv != CKR_OK)
8375 	{
8376 		if (*phPrivateKey != CK_INVALID_HANDLE)
8377 		{
8378 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
8379 			handleManager->destroyObject(*phPrivateKey);
8380 			if (ospriv) ospriv->destroyObject();
8381 			*phPrivateKey = CK_INVALID_HANDLE;
8382 		}
8383 
8384 		if (*phPublicKey != CK_INVALID_HANDLE)
8385 		{
8386 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
8387 			handleManager->destroyObject(*phPublicKey);
8388 			if (ospub) ospub->destroyObject();
8389 			*phPublicKey = CK_INVALID_HANDLE;
8390 		}
8391 	}
8392 
8393 	return rv;
8394 }
8395 
8396 // Generate a DSA key pair
generateDSA(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)8397 CK_RV SoftHSM::generateDSA
8398 (CK_SESSION_HANDLE hSession,
8399 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
8400 	CK_ULONG ulPublicKeyAttributeCount,
8401 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
8402 	CK_ULONG ulPrivateKeyAttributeCount,
8403 	CK_OBJECT_HANDLE_PTR phPublicKey,
8404 	CK_OBJECT_HANDLE_PTR phPrivateKey,
8405 	CK_BBOOL isPublicKeyOnToken,
8406 	CK_BBOOL isPublicKeyPrivate,
8407 	CK_BBOOL isPrivateKeyOnToken,
8408 	CK_BBOOL isPrivateKeyPrivate)
8409 {
8410 	*phPublicKey = CK_INVALID_HANDLE;
8411 	*phPrivateKey = CK_INVALID_HANDLE;
8412 
8413 	// Get the session
8414 	Session* session = (Session*)handleManager->getSession(hSession);
8415 	if (session == NULL)
8416 		return CKR_SESSION_HANDLE_INVALID;
8417 
8418 	// Get the token
8419 	Token* token = session->getToken();
8420 	if (token == NULL)
8421 		return CKR_GENERAL_ERROR;
8422 
8423 	// Extract desired key information
8424 	ByteString prime;
8425 	ByteString subprime;
8426 	ByteString generator;
8427 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
8428 	{
8429 		switch (pPublicKeyTemplate[i].type)
8430 		{
8431 			case CKA_PRIME:
8432 				prime = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
8433 				break;
8434 			case CKA_SUBPRIME:
8435 				subprime = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
8436 				break;
8437 			case CKA_BASE:
8438 				generator = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
8439 				break;
8440 			default:
8441 				break;
8442 		}
8443 	}
8444 
8445 	// The parameters must be specified to be able to generate a key pair.
8446 	if (prime.size() == 0 || subprime.size() == 0 || generator.size() == 0) {
8447 		INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
8448 		return CKR_TEMPLATE_INCOMPLETE;
8449 	}
8450 
8451 	// Set the parameters
8452 	DSAParameters p;
8453 	p.setP(prime);
8454 	p.setQ(subprime);
8455 	p.setG(generator);
8456 
8457 	// Generate key pair
8458 	AsymmetricKeyPair* kp = NULL;
8459 	AsymmetricAlgorithm* dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
8460 	if (dsa == NULL) return CKR_GENERAL_ERROR;
8461 	if (!dsa->generateKeyPair(&kp, &p))
8462 	{
8463 		ERROR_MSG("Could not generate key pair");
8464 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
8465 		return CKR_GENERAL_ERROR;
8466 	}
8467 
8468 	DSAPublicKey* pub = (DSAPublicKey*) kp->getPublicKey();
8469 	DSAPrivateKey* priv = (DSAPrivateKey*) kp->getPrivateKey();
8470 
8471 	CK_RV rv = CKR_OK;
8472 
8473 	// Create a public key using C_CreateObject
8474 	if (rv == CKR_OK)
8475 	{
8476 		const CK_ULONG maxAttribs = 32;
8477 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
8478 		CK_KEY_TYPE publicKeyType = CKK_DSA;
8479 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
8480 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
8481 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
8482 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
8483 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
8484 		};
8485 		CK_ULONG publicKeyAttribsCount = 4;
8486 
8487 		// Add the additional
8488 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
8489 			rv = CKR_TEMPLATE_INCONSISTENT;
8490 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
8491 		{
8492 			switch (pPublicKeyTemplate[i].type)
8493 			{
8494 				case CKA_CLASS:
8495 				case CKA_TOKEN:
8496 				case CKA_PRIVATE:
8497 				case CKA_KEY_TYPE:
8498 					continue;
8499 				default:
8500 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
8501 			}
8502 		}
8503 
8504 		if (rv == CKR_OK)
8505 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
8506 
8507 		// Store the attributes that are being supplied by the key generation to the object
8508 		if (rv == CKR_OK)
8509 		{
8510 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
8511 			if (osobject == NULL_PTR || !osobject->isValid()) {
8512 				rv = CKR_FUNCTION_FAILED;
8513 			} else if (osobject->startTransaction()) {
8514 				bool bOK = true;
8515 
8516 				// Common Key Attributes
8517 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8518 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DSA_KEY_PAIR_GEN;
8519 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8520 
8521 				// DSA Public Key Attributes
8522 				ByteString value;
8523 				if (isPublicKeyPrivate)
8524 				{
8525 					token->encrypt(pub->getY(), value);
8526 				}
8527 				else
8528 				{
8529 					value = pub->getY();
8530 				}
8531 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
8532 
8533 				if (bOK)
8534 					bOK = osobject->commitTransaction();
8535 				else
8536 					osobject->abortTransaction();
8537 
8538 				if (!bOK)
8539 					rv = CKR_FUNCTION_FAILED;
8540 			} else
8541 				rv = CKR_FUNCTION_FAILED;
8542 		}
8543 	}
8544 
8545 	// Create a private key using C_CreateObject
8546 	if (rv == CKR_OK)
8547 	{
8548 		const CK_ULONG maxAttribs = 32;
8549 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
8550 		CK_KEY_TYPE privateKeyType = CKK_DSA;
8551 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
8552 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
8553 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
8554 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
8555 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
8556 		};
8557 		CK_ULONG privateKeyAttribsCount = 4;
8558 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
8559 			rv = CKR_TEMPLATE_INCONSISTENT;
8560 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
8561 		{
8562 			switch (pPrivateKeyTemplate[i].type)
8563 			{
8564 				case CKA_CLASS:
8565 				case CKA_TOKEN:
8566 				case CKA_PRIVATE:
8567 				case CKA_KEY_TYPE:
8568 					continue;
8569 				default:
8570 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
8571 			}
8572 		}
8573 
8574 		if (rv == CKR_OK)
8575 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
8576 
8577 		// Store the attributes that are being supplied by the key generation to the object
8578 		if (rv == CKR_OK)
8579 		{
8580 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
8581 			if (osobject == NULL_PTR || !osobject->isValid()) {
8582 				rv = CKR_FUNCTION_FAILED;
8583 			} else if (osobject->startTransaction()) {
8584 				bool bOK = true;
8585 
8586 				// Common Key Attributes
8587 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8588 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DSA_KEY_PAIR_GEN;
8589 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8590 
8591 				// Common Private Key Attributes
8592 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
8593 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
8594 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
8595 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
8596 
8597 				// DSA Private Key Attributes
8598 				ByteString bPrime;
8599 				ByteString bSubprime;
8600 				ByteString bGenerator;
8601 				ByteString bValue;
8602 				if (isPrivateKeyPrivate)
8603 				{
8604 					token->encrypt(priv->getP(), bPrime);
8605 					token->encrypt(priv->getQ(), bSubprime);
8606 					token->encrypt(priv->getG(), bGenerator);
8607 					token->encrypt(priv->getX(), bValue);
8608 				}
8609 				else
8610 				{
8611 					bPrime = priv->getP();
8612 					bSubprime = priv->getQ();
8613 					bGenerator = priv->getG();
8614 					bValue = priv->getX();
8615 				}
8616 				bOK = bOK && osobject->setAttribute(CKA_PRIME, bPrime);
8617 				bOK = bOK && osobject->setAttribute(CKA_SUBPRIME, bSubprime);
8618 				bOK = bOK && osobject->setAttribute(CKA_BASE, bGenerator);
8619 				bOK = bOK && osobject->setAttribute(CKA_VALUE, bValue);
8620 
8621 				if (bOK)
8622 					bOK = osobject->commitTransaction();
8623 				else
8624 					osobject->abortTransaction();
8625 
8626 				if (!bOK)
8627 					rv = CKR_FUNCTION_FAILED;
8628 			} else
8629 				rv = CKR_FUNCTION_FAILED;
8630 		}
8631 	}
8632 
8633 	// Clean up
8634 	dsa->recycleKeyPair(kp);
8635 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
8636 
8637 	// Remove keys that may have been created already when the function fails.
8638 	if (rv != CKR_OK)
8639 	{
8640 		if (*phPrivateKey != CK_INVALID_HANDLE)
8641 		{
8642 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
8643 			handleManager->destroyObject(*phPrivateKey);
8644 			if (ospriv) ospriv->destroyObject();
8645 			*phPrivateKey = CK_INVALID_HANDLE;
8646 		}
8647 
8648 		if (*phPublicKey != CK_INVALID_HANDLE)
8649 		{
8650 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
8651 			handleManager->destroyObject(*phPublicKey);
8652 			if (ospub) ospub->destroyObject();
8653 			*phPublicKey = CK_INVALID_HANDLE;
8654 		}
8655 	}
8656 
8657 	return rv;
8658 }
8659 
8660 // Generate a DSA domain parameter set
generateDSAParameters(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)8661 CK_RV SoftHSM::generateDSAParameters
8662 (CK_SESSION_HANDLE hSession,
8663 	CK_ATTRIBUTE_PTR pTemplate,
8664 	CK_ULONG ulCount,
8665 	CK_OBJECT_HANDLE_PTR phKey,
8666 	CK_BBOOL isOnToken,
8667 	CK_BBOOL isPrivate)
8668 {
8669 	*phKey = CK_INVALID_HANDLE;
8670 
8671 	// Get the session
8672 	Session* session = (Session*)handleManager->getSession(hSession);
8673 	if (session == NULL)
8674 		return CKR_SESSION_HANDLE_INVALID;
8675 
8676 	// Get the token
8677 	Token* token = session->getToken();
8678 	if (token == NULL)
8679 		return CKR_GENERAL_ERROR;
8680 
8681 	// Extract desired parameter information
8682 	size_t bitLen = 0;
8683 	size_t qLen = 0;
8684 	for (CK_ULONG i = 0; i < ulCount; i++)
8685 	{
8686 		switch (pTemplate[i].type)
8687 		{
8688 			case CKA_PRIME_BITS:
8689 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
8690 				{
8691 					INFO_MSG("CKA_PRIME_BITS does not have the size of CK_ULONG");
8692 					return CKR_ATTRIBUTE_VALUE_INVALID;
8693 				}
8694 				bitLen = *(CK_ULONG*)pTemplate[i].pValue;
8695 				break;
8696 			case CKA_SUB_PRIME_BITS:
8697 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
8698 				{
8699 					INFO_MSG("CKA_SUB_PRIME_BITS does not have the size of CK_ULONG");
8700 					return CKR_ATTRIBUTE_VALUE_INVALID;
8701 				}
8702 				qLen = *(CK_ULONG*)pTemplate[i].pValue;
8703 				break;
8704 			default:
8705 				break;
8706 		}
8707 	}
8708 
8709 	// CKA_PRIME_BITS must be specified
8710 	if (bitLen == 0)
8711 	{
8712 		INFO_MSG("Missing CKA_PRIME_BITS in pTemplate");
8713 		return CKR_TEMPLATE_INCOMPLETE;
8714 	}
8715 
8716 	// No real choice for CKA_SUB_PRIME_BITS
8717 	if ((qLen != 0) &&
8718 	    (((bitLen >= 2048) && (qLen != 256)) ||
8719 	     ((bitLen < 2048) && (qLen != 160))))
8720 		INFO_MSG("CKA_SUB_PRIME_BITS is ignored");
8721 
8722 
8723 	// Generate domain parameters
8724 	AsymmetricParameters* p = NULL;
8725 	AsymmetricAlgorithm* dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
8726 	if (dsa == NULL) return CKR_GENERAL_ERROR;
8727 	if (!dsa->generateParameters(&p, (void *)bitLen))
8728 	{
8729 		ERROR_MSG("Could not generate parameters");
8730 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
8731 		return CKR_GENERAL_ERROR;
8732 	}
8733 
8734 	DSAParameters* params = (DSAParameters*) p;
8735 
8736 	CK_RV rv = CKR_OK;
8737 
8738 	// Create the domain parameter object using C_CreateObject
8739 	const CK_ULONG maxAttribs = 32;
8740 	CK_OBJECT_CLASS objClass = CKO_DOMAIN_PARAMETERS;
8741 	CK_KEY_TYPE keyType = CKK_DSA;
8742 	CK_ATTRIBUTE paramsAttribs[maxAttribs] = {
8743 		{ CKA_CLASS, &objClass, sizeof(objClass) },
8744 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
8745 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
8746 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
8747 	};
8748 	CK_ULONG paramsAttribsCount = 4;
8749 
8750 	// Add the additional
8751 	if (ulCount > (maxAttribs - paramsAttribsCount))
8752 		rv = CKR_TEMPLATE_INCONSISTENT;
8753 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
8754 	{
8755 		switch (pTemplate[i].type)
8756 		{
8757 			case CKA_CLASS:
8758 			case CKA_TOKEN:
8759 			case CKA_PRIVATE:
8760 			case CKA_KEY_TYPE:
8761 				continue;
8762 		default:
8763 			paramsAttribs[paramsAttribsCount++] = pTemplate[i];
8764 		}
8765 	}
8766 
8767 	if (rv == CKR_OK)
8768 		rv = this->CreateObject(hSession, paramsAttribs, paramsAttribsCount, phKey,OBJECT_OP_GENERATE);
8769 
8770 	// Store the attributes that are being supplied
8771 	if (rv == CKR_OK)
8772 	{
8773 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
8774 		if (osobject == NULL_PTR || !osobject->isValid()) {
8775 			rv = CKR_FUNCTION_FAILED;
8776 		} else if (osobject->startTransaction()) {
8777 			bool bOK = true;
8778 
8779 			// Common Attributes
8780 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8781 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DSA_PARAMETER_GEN;
8782 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8783 
8784 			// DSA Domain Parameters Attributes
8785 			ByteString prime;
8786 			ByteString subprime;
8787 			ByteString generator;
8788 			if (isPrivate)
8789 			{
8790 				token->encrypt(params->getP(), prime);
8791 				token->encrypt(params->getQ(), subprime);
8792 				token->encrypt(params->getG(), generator);
8793 			}
8794 			else
8795 			{
8796 				prime = params->getP();
8797 				subprime = params->getQ();
8798 				generator = params->getG();
8799 			}
8800 			bOK = bOK && osobject->setAttribute(CKA_PRIME, prime);
8801 			bOK = bOK && osobject->setAttribute(CKA_SUBPRIME, subprime);
8802 			bOK = bOK && osobject->setAttribute(CKA_BASE, generator);
8803 
8804 			if (bOK)
8805 				bOK = osobject->commitTransaction();
8806 			else
8807 				osobject->abortTransaction();
8808 
8809 			if (!bOK)
8810 				rv = CKR_FUNCTION_FAILED;
8811 		} else
8812 			rv = CKR_FUNCTION_FAILED;
8813 	}
8814 
8815 	// Clean up
8816 	dsa->recycleParameters(p);
8817 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
8818 
8819 	// Remove parameters that may have been created already when the function fails.
8820 	if (rv != CKR_OK)
8821 	{
8822 		if (*phKey != CK_INVALID_HANDLE)
8823 		{
8824 			OSObject* osparams = (OSObject*)handleManager->getObject(*phKey);
8825 			handleManager->destroyObject(*phKey);
8826 			if (osparams) osparams->destroyObject();
8827 			*phKey = CK_INVALID_HANDLE;
8828 		}
8829 	}
8830 
8831 	return rv;
8832 }
8833 
8834 // Generate an EC key pair
generateEC(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)8835 CK_RV SoftHSM::generateEC
8836 (CK_SESSION_HANDLE hSession,
8837 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
8838 	CK_ULONG ulPublicKeyAttributeCount,
8839 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
8840 	CK_ULONG ulPrivateKeyAttributeCount,
8841 	CK_OBJECT_HANDLE_PTR phPublicKey,
8842 	CK_OBJECT_HANDLE_PTR phPrivateKey,
8843 	CK_BBOOL isPublicKeyOnToken,
8844 	CK_BBOOL isPublicKeyPrivate,
8845 	CK_BBOOL isPrivateKeyOnToken,
8846 	CK_BBOOL isPrivateKeyPrivate)
8847 {
8848 	*phPublicKey = CK_INVALID_HANDLE;
8849 	*phPrivateKey = CK_INVALID_HANDLE;
8850 
8851 	// Get the session
8852 	Session* session = (Session*)handleManager->getSession(hSession);
8853 	if (session == NULL)
8854 		return CKR_SESSION_HANDLE_INVALID;
8855 
8856 	// Get the token
8857 	Token* token = session->getToken();
8858 	if (token == NULL)
8859 		return CKR_GENERAL_ERROR;
8860 
8861 	// Extract desired key information
8862 	ByteString params;
8863 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
8864 	{
8865 		switch (pPublicKeyTemplate[i].type)
8866 		{
8867 			case CKA_EC_PARAMS:
8868 				params = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
8869 				break;
8870 			default:
8871 				break;
8872 		}
8873 	}
8874 
8875 	// The parameters must be specified to be able to generate a key pair.
8876 	if (params.size() == 0) {
8877 		INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
8878 		return CKR_TEMPLATE_INCOMPLETE;
8879 	}
8880 
8881 	// Set the parameters
8882 	ECParameters p;
8883 	p.setEC(params);
8884 
8885 	// Generate key pair
8886 	AsymmetricKeyPair* kp = NULL;
8887 	AsymmetricAlgorithm* ec = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
8888 	if (ec == NULL) return CKR_GENERAL_ERROR;
8889 	if (!ec->generateKeyPair(&kp, &p))
8890 	{
8891 		ERROR_MSG("Could not generate key pair");
8892 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ec);
8893 		return CKR_GENERAL_ERROR;
8894 	}
8895 
8896 	ECPublicKey* pub = (ECPublicKey*) kp->getPublicKey();
8897 	ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
8898 
8899 	CK_RV rv = CKR_OK;
8900 
8901 	// Create a public key using C_CreateObject
8902 	if (rv == CKR_OK)
8903 	{
8904 		const CK_ULONG maxAttribs = 32;
8905 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
8906 		CK_KEY_TYPE publicKeyType = CKK_EC;
8907 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
8908 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
8909 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
8910 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
8911 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
8912 		};
8913 		CK_ULONG publicKeyAttribsCount = 4;
8914 
8915 		// Add the additional
8916 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
8917 			rv = CKR_TEMPLATE_INCONSISTENT;
8918 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
8919 		{
8920 			switch (pPublicKeyTemplate[i].type)
8921 			{
8922 				case CKA_CLASS:
8923 				case CKA_TOKEN:
8924 				case CKA_PRIVATE:
8925 				case CKA_KEY_TYPE:
8926 					continue;
8927 				default:
8928 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
8929 			}
8930 		}
8931 
8932 		if (rv == CKR_OK)
8933 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
8934 
8935 		// Store the attributes that are being supplied by the key generation to the object
8936 		if (rv == CKR_OK)
8937 		{
8938 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
8939 			if (osobject == NULL_PTR || !osobject->isValid()) {
8940 				rv = CKR_FUNCTION_FAILED;
8941 			} else if (osobject->startTransaction()) {
8942 				bool bOK = true;
8943 
8944 				// Common Key Attributes
8945 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
8946 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_KEY_PAIR_GEN;
8947 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
8948 
8949 				// EC Public Key Attributes
8950 				ByteString point;
8951 				if (isPublicKeyPrivate)
8952 				{
8953 					token->encrypt(pub->getQ(), point);
8954 				}
8955 				else
8956 				{
8957 					point = pub->getQ();
8958 				}
8959 				bOK = bOK && osobject->setAttribute(CKA_EC_POINT, point);
8960 
8961 				if (bOK)
8962 					bOK = osobject->commitTransaction();
8963 				else
8964 					osobject->abortTransaction();
8965 
8966 				if (!bOK)
8967 					rv = CKR_FUNCTION_FAILED;
8968 			} else
8969 				rv = CKR_FUNCTION_FAILED;
8970 		}
8971 	}
8972 
8973 	// Create a private key using C_CreateObject
8974 	if (rv == CKR_OK)
8975 	{
8976 		const CK_ULONG maxAttribs = 32;
8977 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
8978 		CK_KEY_TYPE privateKeyType = CKK_EC;
8979 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
8980 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
8981 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
8982 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
8983 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
8984 		};
8985 		CK_ULONG privateKeyAttribsCount = 4;
8986 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
8987 			rv = CKR_TEMPLATE_INCONSISTENT;
8988 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
8989 		{
8990 			switch (pPrivateKeyTemplate[i].type)
8991 			{
8992 				case CKA_CLASS:
8993 				case CKA_TOKEN:
8994 				case CKA_PRIVATE:
8995 				case CKA_KEY_TYPE:
8996 					continue;
8997 				default:
8998 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
8999 			}
9000 		}
9001 
9002 		if (rv == CKR_OK)
9003 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
9004 
9005 		// Store the attributes that are being supplied by the key generation to the object
9006 		if (rv == CKR_OK)
9007 		{
9008 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
9009 			if (osobject == NULL_PTR || !osobject->isValid()) {
9010 				rv = CKR_FUNCTION_FAILED;
9011 			} else if (osobject->startTransaction()) {
9012 				bool bOK = true;
9013 
9014 				// Common Key Attributes
9015 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9016 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_KEY_PAIR_GEN;
9017 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9018 
9019 				// Common Private Key Attributes
9020 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
9021 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
9022 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
9023 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
9024 
9025 				// EC Private Key Attributes
9026 				ByteString group;
9027 				ByteString value;
9028 				if (isPrivateKeyPrivate)
9029 				{
9030 					token->encrypt(priv->getEC(), group);
9031 					token->encrypt(priv->getD(), value);
9032 				}
9033 				else
9034 				{
9035 					group = priv->getEC();
9036 					value = priv->getD();
9037 				}
9038 				bOK = bOK && osobject->setAttribute(CKA_EC_PARAMS, group);
9039 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
9040 
9041 				if (bOK)
9042 					bOK = osobject->commitTransaction();
9043 				else
9044 					osobject->abortTransaction();
9045 
9046 				if (!bOK)
9047 					rv = CKR_FUNCTION_FAILED;
9048 			} else
9049 				rv = CKR_FUNCTION_FAILED;
9050 		}
9051 	}
9052 
9053 	// Clean up
9054 	ec->recycleKeyPair(kp);
9055 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ec);
9056 
9057 	// Remove keys that may have been created already when the function fails.
9058 	if (rv != CKR_OK)
9059 	{
9060 		if (*phPrivateKey != CK_INVALID_HANDLE)
9061 		{
9062 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
9063 			handleManager->destroyObject(*phPrivateKey);
9064 			if (ospriv) ospriv->destroyObject();
9065 			*phPrivateKey = CK_INVALID_HANDLE;
9066 		}
9067 
9068 		if (*phPublicKey != CK_INVALID_HANDLE)
9069 		{
9070 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
9071 			handleManager->destroyObject(*phPublicKey);
9072 			if (ospub) ospub->destroyObject();
9073 			*phPublicKey = CK_INVALID_HANDLE;
9074 		}
9075 	}
9076 
9077 	return rv;
9078 }
9079 
9080 // Generate an EDDSA key pair
generateED(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)9081 CK_RV SoftHSM::generateED
9082 (CK_SESSION_HANDLE hSession,
9083 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
9084 	CK_ULONG ulPublicKeyAttributeCount,
9085 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
9086 	CK_ULONG ulPrivateKeyAttributeCount,
9087 	CK_OBJECT_HANDLE_PTR phPublicKey,
9088 	CK_OBJECT_HANDLE_PTR phPrivateKey,
9089 	CK_BBOOL isPublicKeyOnToken,
9090 	CK_BBOOL isPublicKeyPrivate,
9091 	CK_BBOOL isPrivateKeyOnToken,
9092 	CK_BBOOL isPrivateKeyPrivate)
9093 {
9094 	*phPublicKey = CK_INVALID_HANDLE;
9095 	*phPrivateKey = CK_INVALID_HANDLE;
9096 
9097 	// Get the session
9098 	Session* session = (Session*)handleManager->getSession(hSession);
9099 	if (session == NULL)
9100 		return CKR_SESSION_HANDLE_INVALID;
9101 
9102 	// Get the token
9103 	Token* token = session->getToken();
9104 	if (token == NULL)
9105 		return CKR_GENERAL_ERROR;
9106 
9107 	// Extract desired key information
9108 	ByteString params;
9109 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
9110 	{
9111 		switch (pPublicKeyTemplate[i].type)
9112 		{
9113 			case CKA_EC_PARAMS:
9114 				params = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9115 				break;
9116 			default:
9117 				break;
9118 		}
9119 	}
9120 
9121 	// The parameters must be specified to be able to generate a key pair.
9122 	if (params.size() == 0) {
9123 		INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
9124 		return CKR_TEMPLATE_INCOMPLETE;
9125 	}
9126 
9127 	// Set the parameters
9128 	ECParameters p;
9129 	p.setEC(params);
9130 
9131 	// Generate key pair
9132 	AsymmetricKeyPair* kp = NULL;
9133 	AsymmetricAlgorithm* ec = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
9134 	if (ec == NULL) return CKR_GENERAL_ERROR;
9135 	if (!ec->generateKeyPair(&kp, &p))
9136 	{
9137 		ERROR_MSG("Could not generate key pair");
9138 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ec);
9139 		return CKR_GENERAL_ERROR;
9140 	}
9141 
9142 	EDPublicKey* pub = (EDPublicKey*) kp->getPublicKey();
9143 	EDPrivateKey* priv = (EDPrivateKey*) kp->getPrivateKey();
9144 
9145 	CK_RV rv = CKR_OK;
9146 
9147 	// Create a public key using C_CreateObject
9148 	if (rv == CKR_OK)
9149 	{
9150 		const CK_ULONG maxAttribs = 32;
9151 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
9152 		CK_KEY_TYPE publicKeyType = CKK_EC_EDWARDS;
9153 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
9154 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
9155 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
9156 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
9157 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
9158 		};
9159 		CK_ULONG publicKeyAttribsCount = 4;
9160 
9161 		// Add the additional
9162 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
9163 			rv = CKR_TEMPLATE_INCONSISTENT;
9164 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
9165 		{
9166 			switch (pPublicKeyTemplate[i].type)
9167 			{
9168 				case CKA_CLASS:
9169 				case CKA_TOKEN:
9170 				case CKA_PRIVATE:
9171 				case CKA_KEY_TYPE:
9172 					continue;
9173 				default:
9174 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
9175 			}
9176 		}
9177 
9178 		if (rv == CKR_OK)
9179 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
9180 
9181 		// Store the attributes that are being supplied by the key generation to the object
9182 		if (rv == CKR_OK)
9183 		{
9184 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
9185 			if (osobject == NULL_PTR || !osobject->isValid()) {
9186 				rv = CKR_FUNCTION_FAILED;
9187 			} else if (osobject->startTransaction()) {
9188 				bool bOK = true;
9189 
9190 				// Common Key Attributes
9191 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9192 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_EDWARDS_KEY_PAIR_GEN;
9193 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9194 
9195 				// EDDSA Public Key Attributes
9196 				ByteString value;
9197 				if (isPublicKeyPrivate)
9198 				{
9199 					token->encrypt(pub->getA(), value);
9200 				}
9201 				else
9202 				{
9203 					value = pub->getA();
9204 				}
9205 				bOK = bOK && osobject->setAttribute(CKA_EC_POINT, value);
9206 
9207 				if (bOK)
9208 					bOK = osobject->commitTransaction();
9209 				else
9210 					osobject->abortTransaction();
9211 
9212 				if (!bOK)
9213 					rv = CKR_FUNCTION_FAILED;
9214 			} else
9215 				rv = CKR_FUNCTION_FAILED;
9216 		}
9217 	}
9218 
9219 	// Create a private key using C_CreateObject
9220 	if (rv == CKR_OK)
9221 	{
9222 		const CK_ULONG maxAttribs = 32;
9223 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
9224 		CK_KEY_TYPE privateKeyType = CKK_EC_EDWARDS;
9225 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
9226 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
9227 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
9228 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
9229 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
9230 		};
9231 		CK_ULONG privateKeyAttribsCount = 4;
9232 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
9233 			rv = CKR_TEMPLATE_INCONSISTENT;
9234 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
9235 		{
9236 			switch (pPrivateKeyTemplate[i].type)
9237 			{
9238 				case CKA_CLASS:
9239 				case CKA_TOKEN:
9240 				case CKA_PRIVATE:
9241 				case CKA_KEY_TYPE:
9242 					continue;
9243 				default:
9244 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
9245 			}
9246 		}
9247 
9248 		if (rv == CKR_OK)
9249 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
9250 
9251 		// Store the attributes that are being supplied by the key generation to the object
9252 		if (rv == CKR_OK)
9253 		{
9254 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
9255 			if (osobject == NULL_PTR || !osobject->isValid()) {
9256 				rv = CKR_FUNCTION_FAILED;
9257 			} else if (osobject->startTransaction()) {
9258 				bool bOK = true;
9259 
9260 				// Common Key Attributes
9261 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9262 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_EDWARDS_KEY_PAIR_GEN;
9263 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9264 
9265 				// Common Private Key Attributes
9266 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
9267 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
9268 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
9269 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
9270 
9271 				// EDDSA Private Key Attributes
9272 				ByteString group;
9273 				ByteString value;
9274 				if (isPrivateKeyPrivate)
9275 				{
9276 					token->encrypt(priv->getEC(), group);
9277 					token->encrypt(priv->getK(), value);
9278 				}
9279 				else
9280 				{
9281 					group = priv->getEC();
9282 					value = priv->getK();
9283 				}
9284 				bOK = bOK && osobject->setAttribute(CKA_EC_PARAMS, group);
9285 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
9286 
9287 				if (bOK)
9288 					bOK = osobject->commitTransaction();
9289 				else
9290 					osobject->abortTransaction();
9291 
9292 				if (!bOK)
9293 					rv = CKR_FUNCTION_FAILED;
9294 			} else
9295 				rv = CKR_FUNCTION_FAILED;
9296 		}
9297 	}
9298 
9299 	// Clean up
9300 	ec->recycleKeyPair(kp);
9301 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ec);
9302 
9303 	// Remove keys that may have been created already when the function fails.
9304 	if (rv != CKR_OK)
9305 	{
9306 		if (*phPrivateKey != CK_INVALID_HANDLE)
9307 		{
9308 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
9309 			handleManager->destroyObject(*phPrivateKey);
9310 			if (ospriv) ospriv->destroyObject();
9311 			*phPrivateKey = CK_INVALID_HANDLE;
9312 		}
9313 
9314 		if (*phPublicKey != CK_INVALID_HANDLE)
9315 		{
9316 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
9317 			handleManager->destroyObject(*phPublicKey);
9318 			if (ospub) ospub->destroyObject();
9319 			*phPublicKey = CK_INVALID_HANDLE;
9320 		}
9321 	}
9322 
9323 	return rv;
9324 }
9325 
9326 // Generate a DH key pair
generateDH(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)9327 CK_RV SoftHSM::generateDH
9328 (CK_SESSION_HANDLE hSession,
9329 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
9330 	CK_ULONG ulPublicKeyAttributeCount,
9331 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
9332 	CK_ULONG ulPrivateKeyAttributeCount,
9333 	CK_OBJECT_HANDLE_PTR phPublicKey,
9334 	CK_OBJECT_HANDLE_PTR phPrivateKey,
9335 	CK_BBOOL isPublicKeyOnToken,
9336 	CK_BBOOL isPublicKeyPrivate,
9337 	CK_BBOOL isPrivateKeyOnToken,
9338 	CK_BBOOL isPrivateKeyPrivate)
9339 {
9340 	*phPublicKey = CK_INVALID_HANDLE;
9341 	*phPrivateKey = CK_INVALID_HANDLE;
9342 
9343 	// Get the session
9344 	Session* session = (Session*)handleManager->getSession(hSession);
9345 	if (session == NULL)
9346 		return CKR_SESSION_HANDLE_INVALID;
9347 
9348 	// Get the token
9349 	Token* token = session->getToken();
9350 	if (token == NULL)
9351 		return CKR_GENERAL_ERROR;
9352 
9353 	// Extract desired key information
9354 	ByteString prime;
9355 	ByteString generator;
9356 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
9357 	{
9358 		switch (pPublicKeyTemplate[i].type)
9359 		{
9360 			case CKA_PRIME:
9361 				prime = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9362 				break;
9363 			case CKA_BASE:
9364 				generator = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9365 				break;
9366 			default:
9367 				break;
9368 		}
9369 	}
9370 
9371 	// The parameters must be specified to be able to generate a key pair.
9372 	if (prime.size() == 0 || generator.size() == 0) {
9373 		INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
9374 		return CKR_TEMPLATE_INCOMPLETE;
9375 	}
9376 
9377 	// Extract optional bit length
9378 	size_t bitLen = 0;
9379 	for (CK_ULONG i = 0; i < ulPrivateKeyAttributeCount; i++)
9380 	{
9381 		switch (pPrivateKeyTemplate[i].type)
9382 		{
9383 			case CKA_VALUE_BITS:
9384 				bitLen = *(CK_ULONG*)pPrivateKeyTemplate[i].pValue;
9385 				break;
9386 			default:
9387 				break;
9388 		}
9389 	}
9390 
9391 	// Set the parameters
9392 	DHParameters p;
9393 	p.setP(prime);
9394 	p.setG(generator);
9395 	p.setXBitLength(bitLen);
9396 
9397 	// Generate key pair
9398 	AsymmetricKeyPair* kp = NULL;
9399 	AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
9400 	if (dh == NULL) return CKR_GENERAL_ERROR;
9401 	if (!dh->generateKeyPair(&kp, &p))
9402 	{
9403 		ERROR_MSG("Could not generate key pair");
9404 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
9405 		return CKR_GENERAL_ERROR;
9406 	}
9407 
9408 	DHPublicKey* pub = (DHPublicKey*) kp->getPublicKey();
9409 	DHPrivateKey* priv = (DHPrivateKey*) kp->getPrivateKey();
9410 
9411 	CK_RV rv = CKR_OK;
9412 
9413 	// Create a public key using C_CreateObject
9414 	if (rv == CKR_OK)
9415 	{
9416 		const CK_ULONG maxAttribs = 32;
9417 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
9418 		CK_KEY_TYPE publicKeyType = CKK_DH;
9419 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
9420 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
9421 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
9422 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
9423 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
9424 		};
9425 		CK_ULONG publicKeyAttribsCount = 4;
9426 
9427 		// Add the additional
9428 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
9429 			rv = CKR_TEMPLATE_INCONSISTENT;
9430 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
9431 		{
9432 			switch (pPublicKeyTemplate[i].type)
9433 			{
9434 				case CKA_CLASS:
9435 				case CKA_TOKEN:
9436 				case CKA_PRIVATE:
9437 				case CKA_KEY_TYPE:
9438 					continue;
9439 				default:
9440 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
9441 			}
9442 		}
9443 
9444 		if (rv == CKR_OK)
9445 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
9446 
9447 		// Store the attributes that are being supplied by the key generation to the object
9448 		if (rv == CKR_OK)
9449 		{
9450 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
9451 			if (osobject == NULL_PTR || !osobject->isValid()) {
9452 				rv = CKR_FUNCTION_FAILED;
9453 			} else if (osobject->startTransaction()) {
9454 				bool bOK = true;
9455 
9456 				// Common Key Attributes
9457 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9458 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DH_PKCS_KEY_PAIR_GEN;
9459 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9460 
9461 				// DH Public Key Attributes
9462 				ByteString value;
9463 				if (isPublicKeyPrivate)
9464 				{
9465 					token->encrypt(pub->getY(), value);
9466 				}
9467 				else
9468 				{
9469 					value = pub->getY();
9470 				}
9471 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
9472 
9473 				if (bOK)
9474 					bOK = osobject->commitTransaction();
9475 				else
9476 					osobject->abortTransaction();
9477 
9478 				if (!bOK)
9479 					rv = CKR_FUNCTION_FAILED;
9480 			} else
9481 				rv = CKR_FUNCTION_FAILED;
9482 		}
9483 	}
9484 
9485 	// Create a private key using C_CreateObject
9486 	if (rv == CKR_OK)
9487 	{
9488 		const CK_ULONG maxAttribs = 32;
9489 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
9490 		CK_KEY_TYPE privateKeyType = CKK_DH;
9491 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
9492 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
9493 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
9494 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
9495 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
9496 		};
9497 		CK_ULONG privateKeyAttribsCount = 4;
9498 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
9499 			rv = CKR_TEMPLATE_INCONSISTENT;
9500 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
9501 		{
9502 			switch (pPrivateKeyTemplate[i].type)
9503 			{
9504 				case CKA_CLASS:
9505 				case CKA_TOKEN:
9506 				case CKA_PRIVATE:
9507 				case CKA_KEY_TYPE:
9508 					continue;
9509 				default:
9510 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
9511 			}
9512 		}
9513 
9514 		if (rv == CKR_OK)
9515 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
9516 
9517 		// Store the attributes that are being supplied by the key generation to the object
9518 		if (rv == CKR_OK)
9519 		{
9520 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
9521 			if (osobject == NULL_PTR || !osobject->isValid()) {
9522 				rv = CKR_FUNCTION_FAILED;
9523 			} else if (osobject->startTransaction()) {
9524 				bool bOK = true;
9525 
9526 				// Common Key Attributes
9527 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9528 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DH_PKCS_KEY_PAIR_GEN;
9529 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9530 
9531 				// Common Private Key Attributes
9532 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
9533 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
9534 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
9535 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
9536 
9537 				// DH Private Key Attributes
9538 				ByteString bPrime;
9539 				ByteString bGenerator;
9540 				ByteString bValue;
9541 				if (isPrivateKeyPrivate)
9542 				{
9543 					token->encrypt(priv->getP(), bPrime);
9544 					token->encrypt(priv->getG(), bGenerator);
9545 					token->encrypt(priv->getX(), bValue);
9546 				}
9547 				else
9548 				{
9549 					bPrime = priv->getP();
9550 					bGenerator = priv->getG();
9551 					bValue = priv->getX();
9552 				}
9553 				bOK = bOK && osobject->setAttribute(CKA_PRIME, bPrime);
9554 				bOK = bOK && osobject->setAttribute(CKA_BASE, bGenerator);
9555 				bOK = bOK && osobject->setAttribute(CKA_VALUE, bValue);
9556 
9557 				if (bitLen == 0)
9558 				{
9559 					bOK = bOK && osobject->setAttribute(CKA_VALUE_BITS, (unsigned long)priv->getX().bits());
9560 				}
9561 
9562 				if (bOK)
9563 					bOK = osobject->commitTransaction();
9564 				else
9565 					osobject->abortTransaction();
9566 
9567 				if (!bOK)
9568 					rv = CKR_FUNCTION_FAILED;
9569 			} else
9570 				rv = CKR_FUNCTION_FAILED;
9571 		}
9572 	}
9573 
9574 	// Clean up
9575 	dh->recycleKeyPair(kp);
9576 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
9577 
9578 	// Remove keys that may have been created already when the function fails.
9579 	if (rv != CKR_OK)
9580 	{
9581 		if (*phPrivateKey != CK_INVALID_HANDLE)
9582 		{
9583 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
9584 			handleManager->destroyObject(*phPrivateKey);
9585 			if (ospriv) ospriv->destroyObject();
9586 			*phPrivateKey = CK_INVALID_HANDLE;
9587 		}
9588 
9589 		if (*phPublicKey != CK_INVALID_HANDLE)
9590 		{
9591 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
9592 			handleManager->destroyObject(*phPublicKey);
9593 			if (ospub) ospub->destroyObject();
9594 			*phPublicKey = CK_INVALID_HANDLE;
9595 		}
9596 	}
9597 
9598 	return rv;
9599 }
9600 
9601 // Generate a DH domain parameter set
generateDHParameters(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_BBOOL isOnToken,CK_BBOOL isPrivate)9602 CK_RV SoftHSM::generateDHParameters
9603 (CK_SESSION_HANDLE hSession,
9604 	CK_ATTRIBUTE_PTR pTemplate,
9605 	CK_ULONG ulCount,
9606 	CK_OBJECT_HANDLE_PTR phKey,
9607 	CK_BBOOL isOnToken,
9608 	CK_BBOOL isPrivate)
9609 {
9610 	*phKey = CK_INVALID_HANDLE;
9611 
9612 	// Get the session
9613 	Session* session = (Session*)handleManager->getSession(hSession);
9614 	if (session == NULL)
9615 		return CKR_SESSION_HANDLE_INVALID;
9616 
9617 	// Get the token
9618 	Token* token = session->getToken();
9619 	if (token == NULL)
9620 		return CKR_GENERAL_ERROR;
9621 
9622 	// Extract desired parameter information
9623 	size_t bitLen = 0;
9624 	for (CK_ULONG i = 0; i < ulCount; i++)
9625 	{
9626 		switch (pTemplate[i].type)
9627 		{
9628 			case CKA_PRIME_BITS:
9629 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
9630 				{
9631 					INFO_MSG("CKA_PRIME_BITS does not have the size of CK_ULONG");
9632 					return CKR_ATTRIBUTE_VALUE_INVALID;
9633 				}
9634 				bitLen = *(CK_ULONG*)pTemplate[i].pValue;
9635 				break;
9636 			default:
9637 				break;
9638 		}
9639 	}
9640 
9641 	// CKA_PRIME_BITS must be specified
9642 	if (bitLen == 0)
9643 	{
9644 		INFO_MSG("Missing CKA_PRIME_BITS in pTemplate");
9645 		return CKR_TEMPLATE_INCOMPLETE;
9646 	}
9647 
9648 	// Generate domain parameters
9649 	AsymmetricParameters* p = NULL;
9650 	AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
9651 	if (dh == NULL) return CKR_GENERAL_ERROR;
9652 	if (!dh->generateParameters(&p, (void *)bitLen))
9653 	{
9654 		ERROR_MSG("Could not generate parameters");
9655 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
9656 		return CKR_GENERAL_ERROR;
9657 	}
9658 
9659 	DHParameters* params = (DHParameters*) p;
9660 
9661 	CK_RV rv = CKR_OK;
9662 
9663 	// Create the domain parameter object using C_CreateObject
9664 	const CK_ULONG maxAttribs = 32;
9665 	CK_OBJECT_CLASS objClass = CKO_DOMAIN_PARAMETERS;
9666 	CK_KEY_TYPE keyType = CKK_DH;
9667 	CK_ATTRIBUTE paramsAttribs[maxAttribs] = {
9668 		{ CKA_CLASS, &objClass, sizeof(objClass) },
9669 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
9670 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
9671 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
9672 	};
9673 	CK_ULONG paramsAttribsCount = 4;
9674 
9675 	// Add the additional
9676 	if (ulCount > (maxAttribs - paramsAttribsCount))
9677 		rv = CKR_TEMPLATE_INCONSISTENT;
9678 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
9679 	{
9680 		switch (pTemplate[i].type)
9681 		{
9682 			case CKA_CLASS:
9683 			case CKA_TOKEN:
9684 			case CKA_PRIVATE:
9685 			case CKA_KEY_TYPE:
9686 				continue;
9687 		default:
9688 			paramsAttribs[paramsAttribsCount++] = pTemplate[i];
9689 		}
9690 	}
9691 
9692 	if (rv == CKR_OK)
9693 		rv = this->CreateObject(hSession, paramsAttribs, paramsAttribsCount, phKey,OBJECT_OP_GENERATE);
9694 
9695 	// Store the attributes that are being supplied
9696 	if (rv == CKR_OK)
9697 	{
9698 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
9699 		if (osobject == NULL_PTR || !osobject->isValid()) {
9700 			rv = CKR_FUNCTION_FAILED;
9701 		} else if (osobject->startTransaction()) {
9702 			bool bOK = true;
9703 
9704 			// Common Attributes
9705 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9706 			CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_DH_PKCS_PARAMETER_GEN;
9707 			bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9708 
9709 			// DH Domain Parameters Attributes
9710 			ByteString prime;
9711 			ByteString generator;
9712 			if (isPrivate)
9713 			{
9714 				token->encrypt(params->getP(), prime);
9715 				token->encrypt(params->getG(), generator);
9716 			}
9717 			else
9718 			{
9719 				prime = params->getP();
9720 				generator = params->getG();
9721 			}
9722 			bOK = bOK && osobject->setAttribute(CKA_PRIME, prime);
9723 			bOK = bOK && osobject->setAttribute(CKA_BASE, generator);
9724 
9725 			if (bOK)
9726 				bOK = osobject->commitTransaction();
9727 			else
9728 				osobject->abortTransaction();
9729 
9730 			if (!bOK)
9731 				rv = CKR_FUNCTION_FAILED;
9732 		} else
9733 			rv = CKR_FUNCTION_FAILED;
9734 	}
9735 
9736 	// Clean up
9737 	dh->recycleParameters(p);
9738 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
9739 
9740 	// Remove parameters that may have been created already when the function fails.
9741 	if (rv != CKR_OK)
9742 	{
9743 		if (*phKey != CK_INVALID_HANDLE)
9744 		{
9745 			OSObject* osparams = (OSObject*)handleManager->getObject(*phKey);
9746 			handleManager->destroyObject(*phKey);
9747 			if (osparams) osparams->destroyObject();
9748 			*phKey = CK_INVALID_HANDLE;
9749 		}
9750 	}
9751 
9752 	return rv;
9753 }
9754 
9755 // Generate a GOST key pair
generateGOST(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pPublicKeyTemplate,CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey,CK_BBOOL isPublicKeyOnToken,CK_BBOOL isPublicKeyPrivate,CK_BBOOL isPrivateKeyOnToken,CK_BBOOL isPrivateKeyPrivate)9756 CK_RV SoftHSM::generateGOST
9757 (CK_SESSION_HANDLE hSession,
9758 	CK_ATTRIBUTE_PTR pPublicKeyTemplate,
9759 	CK_ULONG ulPublicKeyAttributeCount,
9760 	CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
9761 	CK_ULONG ulPrivateKeyAttributeCount,
9762 	CK_OBJECT_HANDLE_PTR phPublicKey,
9763 	CK_OBJECT_HANDLE_PTR phPrivateKey,
9764 	CK_BBOOL isPublicKeyOnToken,
9765 	CK_BBOOL isPublicKeyPrivate,
9766 	CK_BBOOL isPrivateKeyOnToken,
9767 	CK_BBOOL isPrivateKeyPrivate)
9768 {
9769 	*phPublicKey = CK_INVALID_HANDLE;
9770 	*phPrivateKey = CK_INVALID_HANDLE;
9771 
9772 	// Get the session
9773 	Session* session = (Session*)handleManager->getSession(hSession);
9774 	if (session == NULL)
9775 		return CKR_SESSION_HANDLE_INVALID;
9776 
9777 	// Get the token
9778 	Token* token = session->getToken();
9779 	if (token == NULL)
9780 		return CKR_GENERAL_ERROR;
9781 
9782 	// Extract desired key information
9783 	ByteString param_3410;
9784 	ByteString param_3411;
9785 	ByteString param_28147;
9786 	for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++)
9787 	{
9788 		switch (pPublicKeyTemplate[i].type)
9789 		{
9790 			case CKA_GOSTR3410_PARAMS:
9791 				param_3410 = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9792 				break;
9793 			case CKA_GOSTR3411_PARAMS:
9794 				param_3411 = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9795 				break;
9796 			case CKA_GOST28147_PARAMS:
9797 				param_28147 = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen);
9798 				break;
9799 			default:
9800 				break;
9801 		}
9802 	}
9803 
9804 	// The parameters must be specified to be able to generate a key pair.
9805 	if (param_3410.size() == 0 || param_3411.size() == 0) {
9806 		INFO_MSG("Missing parameter(s) in pPublicKeyTemplate");
9807 		return CKR_TEMPLATE_INCOMPLETE;
9808 	}
9809 
9810 	// Set the parameters
9811 	ECParameters p;
9812 	p.setEC(param_3410);
9813 
9814 	// Generate key pair
9815 	AsymmetricKeyPair* kp = NULL;
9816 	AsymmetricAlgorithm* gost = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
9817 	if (gost == NULL) return CKR_GENERAL_ERROR;
9818 	if (!gost->generateKeyPair(&kp, &p))
9819 	{
9820 		ERROR_MSG("Could not generate key pair");
9821 		CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
9822 		return CKR_GENERAL_ERROR;
9823 	}
9824 
9825 	GOSTPublicKey* pub = (GOSTPublicKey*) kp->getPublicKey();
9826 	GOSTPrivateKey* priv = (GOSTPrivateKey*) kp->getPrivateKey();
9827 
9828 	CK_RV rv = CKR_OK;
9829 
9830 	// Create a public key using C_CreateObject
9831 	if (rv == CKR_OK)
9832 	{
9833 		const CK_ULONG maxAttribs = 32;
9834 		CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY;
9835 		CK_KEY_TYPE publicKeyType = CKK_GOSTR3410;
9836 		CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = {
9837 			{ CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) },
9838 			{ CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) },
9839 			{ CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) },
9840 			{ CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) },
9841 		};
9842 		CK_ULONG publicKeyAttribsCount = 4;
9843 
9844 		// Add the additional
9845 		if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount))
9846 			rv = CKR_TEMPLATE_INCONSISTENT;
9847 		for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i)
9848 		{
9849 			switch (pPublicKeyTemplate[i].type)
9850 			{
9851 				case CKA_CLASS:
9852 				case CKA_TOKEN:
9853 				case CKA_PRIVATE:
9854 				case CKA_KEY_TYPE:
9855 					continue;
9856 				default:
9857 					publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i];
9858 			}
9859 		}
9860 
9861 		if (rv == CKR_OK)
9862 			rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE);
9863 
9864 		// Store the attributes that are being supplied by the key generation to the object
9865 		if (rv == CKR_OK)
9866 		{
9867 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey);
9868 			if (osobject == NULL_PTR || !osobject->isValid()) {
9869 				rv = CKR_FUNCTION_FAILED;
9870 			} else if (osobject->startTransaction()) {
9871 				bool bOK = true;
9872 
9873 				// Common Key Attributes
9874 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9875 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_KEY_PAIR_GEN;
9876 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9877 
9878 				// EC Public Key Attributes
9879 				ByteString point;
9880 				if (isPublicKeyPrivate)
9881 				{
9882 					token->encrypt(pub->getQ(), point);
9883 				}
9884 				else
9885 				{
9886 					point = pub->getQ();
9887 				}
9888 				bOK = bOK && osobject->setAttribute(CKA_VALUE, point);
9889 
9890 				if (bOK)
9891 					bOK = osobject->commitTransaction();
9892 				else
9893 					osobject->abortTransaction();
9894 
9895 				if (!bOK)
9896 					rv = CKR_FUNCTION_FAILED;
9897 			} else
9898 				rv = CKR_FUNCTION_FAILED;
9899 		}
9900 	}
9901 
9902 	// Create a private key using C_CreateObject
9903 	if (rv == CKR_OK)
9904 	{
9905 		const CK_ULONG maxAttribs = 32;
9906 		CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY;
9907 		CK_KEY_TYPE privateKeyType = CKK_GOSTR3410;
9908 		CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = {
9909 			{ CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) },
9910 			{ CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) },
9911 			{ CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) },
9912 			{ CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) },
9913 		};
9914 		CK_ULONG privateKeyAttribsCount = 4;
9915 		if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount))
9916 			rv = CKR_TEMPLATE_INCONSISTENT;
9917 		for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i)
9918 		{
9919 			switch (pPrivateKeyTemplate[i].type)
9920 			{
9921 				case CKA_CLASS:
9922 				case CKA_TOKEN:
9923 				case CKA_PRIVATE:
9924 				case CKA_KEY_TYPE:
9925 					continue;
9926 				default:
9927 					privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i];
9928 			}
9929 		}
9930 
9931 		if (rv == CKR_OK)
9932 			rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE);
9933 
9934 		// Store the attributes that are being supplied by the key generation to the object
9935 		if (rv == CKR_OK)
9936 		{
9937 			OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey);
9938 			if (osobject == NULL_PTR || !osobject->isValid()) {
9939 				rv = CKR_FUNCTION_FAILED;
9940 			} else if (osobject->startTransaction()) {
9941 				bool bOK = true;
9942 
9943 				// Common Key Attributes
9944 				bOK = bOK && osobject->setAttribute(CKA_LOCAL,true);
9945 				CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_KEY_PAIR_GEN;
9946 				bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism);
9947 
9948 				// Common Private Key Attributes
9949 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
9950 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
9951 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
9952 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable);
9953 
9954 				// GOST Private Key Attributes
9955 				ByteString value;
9956 				ByteString param_a;
9957 				ByteString param_b;
9958 				ByteString param_c;
9959 				if (isPrivateKeyPrivate)
9960 				{
9961 					token->encrypt(priv->getD(), value);
9962 					token->encrypt(priv->getEC(), param_a);
9963 					token->encrypt(param_3411, param_b);
9964 					token->encrypt(param_28147, param_c);
9965 				}
9966 				else
9967 				{
9968 					value = priv->getD();
9969 					param_a = priv->getEC();
9970 					param_b = param_3411;
9971 					param_c = param_28147;
9972 				}
9973 				bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
9974 				bOK = bOK && osobject->setAttribute(CKA_GOSTR3410_PARAMS, param_a);
9975 				bOK = bOK && osobject->setAttribute(CKA_GOSTR3411_PARAMS, param_b);
9976 				bOK = bOK && osobject->setAttribute(CKA_GOST28147_PARAMS, param_c);
9977 
9978 				if (bOK)
9979 					bOK = osobject->commitTransaction();
9980 				else
9981 					osobject->abortTransaction();
9982 
9983 				if (!bOK)
9984 					rv = CKR_FUNCTION_FAILED;
9985 			} else
9986 				  rv = CKR_FUNCTION_FAILED;
9987 		}
9988 	}
9989 
9990 	// Clean up
9991 	gost->recycleKeyPair(kp);
9992 	CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
9993 
9994 	// Remove keys that may have been created already when the function fails.
9995 	if (rv != CKR_OK)
9996 	{
9997 		if (*phPrivateKey != CK_INVALID_HANDLE)
9998 		{
9999 			OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey);
10000 			handleManager->destroyObject(*phPrivateKey);
10001 			if (ospriv) ospriv->destroyObject();
10002 			*phPrivateKey = CK_INVALID_HANDLE;
10003 		}
10004 
10005 		if (*phPublicKey != CK_INVALID_HANDLE)
10006 		{
10007 			OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
10008 			handleManager->destroyObject(*phPublicKey);
10009 			if (ospub) ospub->destroyObject();
10010 			*phPublicKey = CK_INVALID_HANDLE;
10011 		}
10012 	}
10013 
10014 	return rv;
10015 }
10016 
10017 // Derive a DH secret
deriveDH(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_KEY_TYPE keyType,CK_BBOOL isOnToken,CK_BBOOL isPrivate)10018 CK_RV SoftHSM::deriveDH
10019 (CK_SESSION_HANDLE hSession,
10020 	CK_MECHANISM_PTR pMechanism,
10021 	CK_OBJECT_HANDLE hBaseKey,
10022 	CK_ATTRIBUTE_PTR pTemplate,
10023 	CK_ULONG ulCount,
10024 	CK_OBJECT_HANDLE_PTR phKey,
10025 	CK_KEY_TYPE keyType,
10026 	CK_BBOOL isOnToken,
10027 	CK_BBOOL isPrivate)
10028 {
10029 	*phKey = CK_INVALID_HANDLE;
10030 
10031 	if (pMechanism->pParameter == NULL_PTR) return CKR_MECHANISM_PARAM_INVALID;
10032 	if (pMechanism->ulParameterLen == 0) return CKR_MECHANISM_PARAM_INVALID;
10033 
10034 	// Get the session
10035 	Session* session = (Session*)handleManager->getSession(hSession);
10036 	if (session == NULL)
10037 		return CKR_SESSION_HANDLE_INVALID;
10038 
10039 	// Get the token
10040 	Token* token = session->getToken();
10041 	if (token == NULL)
10042 		return CKR_GENERAL_ERROR;
10043 
10044 	// Extract desired parameter information
10045 	size_t byteLen = 0;
10046 	bool checkValue = true;
10047 	for (CK_ULONG i = 0; i < ulCount; i++)
10048 	{
10049 		switch (pTemplate[i].type)
10050 		{
10051 			case CKA_VALUE:
10052 				INFO_MSG("CKA_VALUE must not be included");
10053 				return CKR_ATTRIBUTE_READ_ONLY;
10054 			case CKA_VALUE_LEN:
10055 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
10056 				{
10057 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
10058 					return CKR_ATTRIBUTE_VALUE_INVALID;
10059 				}
10060 				byteLen = *(CK_ULONG*)pTemplate[i].pValue;
10061 				break;
10062 			case CKA_CHECK_VALUE:
10063 				if (pTemplate[i].ulValueLen > 0)
10064 				{
10065 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
10066 					return CKR_ATTRIBUTE_VALUE_INVALID;
10067 				}
10068 				checkValue = false;
10069 				break;
10070 			default:
10071 				break;
10072 		}
10073 	}
10074 
10075 	// Check the length
10076 	switch (keyType)
10077 	{
10078 		case CKK_GENERIC_SECRET:
10079 			if (byteLen == 0)
10080 			{
10081 				INFO_MSG("CKA_VALUE_LEN must be set");
10082 				return CKR_TEMPLATE_INCOMPLETE;
10083 			}
10084 			break;
10085 #ifndef WITH_FIPS
10086 		case CKK_DES:
10087 			if (byteLen != 0)
10088 			{
10089 				INFO_MSG("CKA_VALUE_LEN must not be set");
10090 				return CKR_ATTRIBUTE_READ_ONLY;
10091 			}
10092 			byteLen = 8;
10093 			break;
10094 #endif
10095 		case CKK_DES2:
10096 			if (byteLen != 0)
10097 			{
10098 				INFO_MSG("CKA_VALUE_LEN must not be set");
10099 				return CKR_ATTRIBUTE_READ_ONLY;
10100 			}
10101 			byteLen = 16;
10102 			break;
10103 		case CKK_DES3:
10104 			if (byteLen != 0)
10105 			{
10106 				INFO_MSG("CKA_VALUE_LEN must not be set");
10107 				return CKR_ATTRIBUTE_READ_ONLY;
10108 			}
10109 			byteLen = 24;
10110 			break;
10111 		case CKK_AES:
10112 			if (byteLen != 16 && byteLen != 24 && byteLen != 32)
10113 			{
10114 				INFO_MSG("CKA_VALUE_LEN must be 16, 24, or 32");
10115 				return CKR_ATTRIBUTE_VALUE_INVALID;
10116 			}
10117 			break;
10118 		default:
10119 			return CKR_ATTRIBUTE_VALUE_INVALID;
10120 	}
10121 
10122 	// Get the base key handle
10123 	OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10124 	if (baseKey == NULL || !baseKey->isValid())
10125 		return CKR_KEY_HANDLE_INVALID;
10126 
10127 	// Get the DH algorithm handler
10128 	AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
10129 	if (dh == NULL)
10130 		return CKR_MECHANISM_INVALID;
10131 
10132 	// Get the keys
10133 	PrivateKey* privateKey = dh->newPrivateKey();
10134 	if (privateKey == NULL)
10135 	{
10136 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
10137 		return CKR_HOST_MEMORY;
10138 	}
10139 	if (getDHPrivateKey((DHPrivateKey*)privateKey, token, baseKey) != CKR_OK)
10140 	{
10141 		dh->recyclePrivateKey(privateKey);
10142 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
10143 		return CKR_GENERAL_ERROR;
10144 	}
10145 
10146 	ByteString mechParameters;
10147 	mechParameters.resize(pMechanism->ulParameterLen);
10148 	memcpy(&mechParameters[0], pMechanism->pParameter, pMechanism->ulParameterLen);
10149 	PublicKey* publicKey = dh->newPublicKey();
10150 	if (publicKey == NULL)
10151 	{
10152 		dh->recyclePrivateKey(privateKey);
10153 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
10154 		return CKR_HOST_MEMORY;
10155 	}
10156 	if (getDHPublicKey((DHPublicKey*)publicKey, (DHPrivateKey*)privateKey, mechParameters) != CKR_OK)
10157 	{
10158 		dh->recyclePrivateKey(privateKey);
10159 		dh->recyclePublicKey(publicKey);
10160 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
10161 		return CKR_GENERAL_ERROR;
10162 	}
10163 
10164 	// Derive the secret
10165 	SymmetricKey* secret = NULL;
10166 	CK_RV rv = CKR_OK;
10167 	if (!dh->deriveKey(&secret, publicKey, privateKey))
10168 		rv = CKR_GENERAL_ERROR;
10169 	dh->recyclePrivateKey(privateKey);
10170 	dh->recyclePublicKey(publicKey);
10171 
10172 	// Create the secret object using C_CreateObject
10173 	const CK_ULONG maxAttribs = 32;
10174 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
10175 	CK_ATTRIBUTE secretAttribs[maxAttribs] = {
10176 		{ CKA_CLASS, &objClass, sizeof(objClass) },
10177 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
10178 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
10179 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
10180 	};
10181 	CK_ULONG secretAttribsCount = 4;
10182 
10183 	// Add the additional
10184 	if (ulCount > (maxAttribs - secretAttribsCount))
10185 		rv = CKR_TEMPLATE_INCONSISTENT;
10186 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
10187 	{
10188 		switch (pTemplate[i].type)
10189 		{
10190 			case CKA_CLASS:
10191 			case CKA_TOKEN:
10192 			case CKA_PRIVATE:
10193 			case CKA_KEY_TYPE:
10194 			case CKA_CHECK_VALUE:
10195 				continue;
10196 		default:
10197 			secretAttribs[secretAttribsCount++] = pTemplate[i];
10198 		}
10199 	}
10200 
10201 	if (rv == CKR_OK)
10202 		rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, phKey, OBJECT_OP_DERIVE);
10203 
10204 	// Store the attributes that are being supplied
10205 	if (rv == CKR_OK)
10206 	{
10207 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
10208 		if (osobject == NULL_PTR || !osobject->isValid()) {
10209 			rv = CKR_FUNCTION_FAILED;
10210 		} else if (osobject->startTransaction()) {
10211 			bool bOK = true;
10212 
10213 			// Common Attributes
10214 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,false);
10215 
10216 			// Common Secret Key Attributes
10217 			if (baseKey->getBooleanValue(CKA_ALWAYS_SENSITIVE, false))
10218 			{
10219 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
10220 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
10221 			}
10222 			else
10223 			{
10224 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,false);
10225 			}
10226 			if (baseKey->getBooleanValue(CKA_NEVER_EXTRACTABLE, true))
10227 			{
10228 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
10229 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,bNeverExtractable);
10230 			}
10231 			else
10232 			{
10233 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,false);
10234 			}
10235 
10236 			// Secret Attributes
10237 			ByteString secretValue = secret->getKeyBits();
10238 			ByteString value;
10239 			ByteString plainKCV;
10240 			ByteString kcv;
10241 
10242 			if (byteLen > secretValue.size())
10243 			{
10244 				INFO_MSG("The derived secret is too short");
10245 				bOK = false;
10246 			}
10247 			else
10248 			{
10249 				// Truncate value when requested, remove from the leading end
10250 				if (byteLen < secretValue.size())
10251 					secretValue.split(secretValue.size() - byteLen);
10252 
10253 				// Fix the odd parity for DES
10254 				if (keyType == CKK_DES ||
10255 				    keyType == CKK_DES2 ||
10256 				    keyType == CKK_DES3)
10257 				{
10258 					for (size_t i = 0; i < secretValue.size(); i++)
10259 					{
10260 						secretValue[i] = odd_parity[secretValue[i]];
10261 					}
10262 				}
10263 
10264 				// Get the KCV
10265 				switch (keyType)
10266 				{
10267 					case CKK_GENERIC_SECRET:
10268 						secret->setBitLen(byteLen * 8);
10269 						plainKCV = secret->getKeyCheckValue();
10270 						break;
10271 					case CKK_DES:
10272 					case CKK_DES2:
10273 					case CKK_DES3:
10274 						secret->setBitLen(byteLen * 7);
10275 						plainKCV = ((DESKey*)secret)->getKeyCheckValue();
10276 						break;
10277 					case CKK_AES:
10278 						secret->setBitLen(byteLen * 8);
10279 						plainKCV = ((AESKey*)secret)->getKeyCheckValue();
10280 						break;
10281 					default:
10282 						bOK = false;
10283 						break;
10284 				}
10285 
10286 				if (isPrivate)
10287 				{
10288 					token->encrypt(secretValue, value);
10289 					token->encrypt(plainKCV, kcv);
10290 				}
10291 				else
10292 				{
10293 					value = secretValue;
10294 					kcv = plainKCV;
10295 				}
10296 			}
10297 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
10298 			if (checkValue)
10299 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
10300 
10301 			if (bOK)
10302 				bOK = osobject->commitTransaction();
10303 			else
10304 				osobject->abortTransaction();
10305 
10306 			if (!bOK)
10307 				rv = CKR_FUNCTION_FAILED;
10308 		} else
10309 			rv = CKR_FUNCTION_FAILED;
10310 	}
10311 
10312 	// Clean up
10313 	dh->recycleSymmetricKey(secret);
10314 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
10315 
10316 	// Remove secret that may have been created already when the function fails.
10317 	if (rv != CKR_OK)
10318 	{
10319 		if (*phKey != CK_INVALID_HANDLE)
10320 		{
10321 			OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey);
10322 			handleManager->destroyObject(*phKey);
10323 			if (ossecret) ossecret->destroyObject();
10324 			*phKey = CK_INVALID_HANDLE;
10325 		}
10326 	}
10327 
10328 	return rv;
10329 }
10330 
10331 // Derive an ECDH secret
10332 #ifdef WITH_ECC
deriveECDH(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_KEY_TYPE keyType,CK_BBOOL isOnToken,CK_BBOOL isPrivate)10333 CK_RV SoftHSM::deriveECDH
10334 (CK_SESSION_HANDLE hSession,
10335 	CK_MECHANISM_PTR pMechanism,
10336 	CK_OBJECT_HANDLE hBaseKey,
10337 	CK_ATTRIBUTE_PTR pTemplate,
10338 	CK_ULONG ulCount,
10339 	CK_OBJECT_HANDLE_PTR phKey,
10340 	CK_KEY_TYPE keyType,
10341 	CK_BBOOL isOnToken,
10342 	CK_BBOOL isPrivate)
10343 {
10344 	*phKey = CK_INVALID_HANDLE;
10345 
10346 	if ((pMechanism->pParameter == NULL_PTR) ||
10347 	    (pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)))
10348 	{
10349 		DEBUG_MSG("pParameter must be of type CK_ECDH1_DERIVE_PARAMS");
10350 		return CKR_MECHANISM_PARAM_INVALID;
10351 	}
10352 	if (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->kdf != CKD_NULL)
10353 	{
10354 		DEBUG_MSG("kdf must be CKD_NULL");
10355 		return CKR_MECHANISM_PARAM_INVALID;
10356 	}
10357 	if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulSharedDataLen != 0) ||
10358 	    (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pSharedData != NULL_PTR))
10359 	{
10360 		DEBUG_MSG("there must be no shared data");
10361 		return CKR_MECHANISM_PARAM_INVALID;
10362 	}
10363 	if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen == 0) ||
10364 	    (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData == NULL_PTR))
10365 	{
10366 		DEBUG_MSG("there must be a public data");
10367 		return CKR_MECHANISM_PARAM_INVALID;
10368 	}
10369 
10370 	// Get the session
10371 	Session* session = (Session*)handleManager->getSession(hSession);
10372 	if (session == NULL)
10373 		return CKR_SESSION_HANDLE_INVALID;
10374 
10375 	// Get the token
10376 	Token* token = session->getToken();
10377 	if (token == NULL)
10378 		return CKR_GENERAL_ERROR;
10379 
10380 	// Extract desired parameter information
10381 	size_t byteLen = 0;
10382 	bool checkValue = true;
10383 	for (CK_ULONG i = 0; i < ulCount; i++)
10384 	{
10385 		switch (pTemplate[i].type)
10386 		{
10387 			case CKA_VALUE:
10388 				INFO_MSG("CKA_VALUE must not be included");
10389 				return CKR_ATTRIBUTE_READ_ONLY;
10390 			case CKA_VALUE_LEN:
10391 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
10392 				{
10393 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
10394 					return CKR_ATTRIBUTE_VALUE_INVALID;
10395 				}
10396 				byteLen = *(CK_ULONG*)pTemplate[i].pValue;
10397 				break;
10398 			case CKA_CHECK_VALUE:
10399 				if (pTemplate[i].ulValueLen > 0)
10400 				{
10401 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
10402 					return CKR_ATTRIBUTE_VALUE_INVALID;
10403 				}
10404 				checkValue = false;
10405 				break;
10406 			default:
10407 				break;
10408 		}
10409 	}
10410 
10411 	// Check the length
10412 	// byteLen == 0 impiles return max size the ECC can derive
10413 	switch (keyType)
10414 	{
10415 		case CKK_GENERIC_SECRET:
10416 			break;
10417 #ifndef WITH_FIPS
10418 		case CKK_DES:
10419 			if (byteLen != 0 && byteLen != 8)
10420 			{
10421 				INFO_MSG("CKA_VALUE_LEN must be 0 or 8");
10422 				return CKR_ATTRIBUTE_VALUE_INVALID;
10423 			}
10424 			byteLen = 8;
10425 			break;
10426 #endif
10427 		case CKK_DES2:
10428 			if (byteLen != 0 && byteLen != 16)
10429 			{
10430 				INFO_MSG("CKA_VALUE_LEN must be 0 or 16");
10431 				return CKR_ATTRIBUTE_VALUE_INVALID;
10432 			}
10433 			byteLen = 16;
10434 			break;
10435 		case CKK_DES3:
10436 			if (byteLen != 0 && byteLen != 24)
10437 			{
10438 				INFO_MSG("CKA_VALUE_LEN must be 0 or 24");
10439 				return CKR_ATTRIBUTE_VALUE_INVALID;
10440 			}
10441 			byteLen = 24;
10442 			break;
10443 		case CKK_AES:
10444 			if (byteLen != 0 && byteLen != 16 && byteLen != 24 && byteLen != 32)
10445 			{
10446 				INFO_MSG("CKA_VALUE_LEN must be 0, 16, 24, or 32");
10447 				return CKR_ATTRIBUTE_VALUE_INVALID;
10448 			}
10449 			break;
10450 		default:
10451 			return CKR_ATTRIBUTE_VALUE_INVALID;
10452 	}
10453 
10454 	// Get the base key handle
10455 	OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10456 	if (baseKey == NULL || !baseKey->isValid())
10457 		return CKR_KEY_HANDLE_INVALID;
10458 
10459 	// Get the ECDH algorithm handler
10460 	AsymmetricAlgorithm* ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
10461 	if (ecdh == NULL)
10462 		return CKR_MECHANISM_INVALID;
10463 
10464 	// Get the keys
10465 	PrivateKey* privateKey = ecdh->newPrivateKey();
10466 	if (privateKey == NULL)
10467 	{
10468 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
10469 		return CKR_HOST_MEMORY;
10470 	}
10471 	if (getECPrivateKey((ECPrivateKey*)privateKey, token, baseKey) != CKR_OK)
10472 	{
10473 		ecdh->recyclePrivateKey(privateKey);
10474 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
10475 		return CKR_GENERAL_ERROR;
10476 	}
10477 
10478 	ByteString publicData;
10479 	publicData.resize(CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen);
10480 	memcpy(&publicData[0],
10481 	       CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData,
10482 	       CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen);
10483 	PublicKey* publicKey = ecdh->newPublicKey();
10484 	if (publicKey == NULL)
10485 	{
10486 		ecdh->recyclePrivateKey(privateKey);
10487 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
10488 		return CKR_HOST_MEMORY;
10489 	}
10490 	if (getECDHPublicKey((ECPublicKey*)publicKey, (ECPrivateKey*)privateKey, publicData) != CKR_OK)
10491 	{
10492 		ecdh->recyclePrivateKey(privateKey);
10493 		ecdh->recyclePublicKey(publicKey);
10494 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
10495 		return CKR_GENERAL_ERROR;
10496 	}
10497 
10498 	// Derive the secret
10499 	SymmetricKey* secret = NULL;
10500 	CK_RV rv = CKR_OK;
10501 	if (!ecdh->deriveKey(&secret, publicKey, privateKey))
10502 		rv = CKR_GENERAL_ERROR;
10503 	ecdh->recyclePrivateKey(privateKey);
10504 	ecdh->recyclePublicKey(publicKey);
10505 
10506 	// Create the secret object using C_CreateObject
10507 	const CK_ULONG maxAttribs = 32;
10508 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
10509 	CK_ATTRIBUTE secretAttribs[maxAttribs] = {
10510 		{ CKA_CLASS, &objClass, sizeof(objClass) },
10511 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
10512 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
10513 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
10514 	};
10515 	CK_ULONG secretAttribsCount = 4;
10516 
10517 	// Add the additional
10518 	if (ulCount > (maxAttribs - secretAttribsCount))
10519 		rv = CKR_TEMPLATE_INCONSISTENT;
10520 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
10521 	{
10522 		switch (pTemplate[i].type)
10523 		{
10524 			case CKA_CLASS:
10525 			case CKA_TOKEN:
10526 			case CKA_PRIVATE:
10527 			case CKA_KEY_TYPE:
10528 			case CKA_CHECK_VALUE:
10529 				continue;
10530 		default:
10531 			secretAttribs[secretAttribsCount++] = pTemplate[i];
10532 		}
10533 	}
10534 
10535 	if (rv == CKR_OK)
10536 		rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, phKey, OBJECT_OP_DERIVE);
10537 
10538 	// Store the attributes that are being supplied
10539 	if (rv == CKR_OK)
10540 	{
10541 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
10542 		if (osobject == NULL_PTR || !osobject->isValid()) {
10543 			rv = CKR_FUNCTION_FAILED;
10544 		} else if (osobject->startTransaction()) {
10545 			bool bOK = true;
10546 
10547 			// Common Attributes
10548 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,false);
10549 
10550 			// Common Secret Key Attributes
10551 			if (baseKey->getBooleanValue(CKA_ALWAYS_SENSITIVE, false))
10552 			{
10553 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
10554 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
10555 			}
10556 			else
10557 			{
10558 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,false);
10559 			}
10560 			if (baseKey->getBooleanValue(CKA_NEVER_EXTRACTABLE, true))
10561 			{
10562 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
10563 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,bNeverExtractable);
10564 			}
10565 			else
10566 			{
10567 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,false);
10568 			}
10569 
10570 			// Secret Attributes
10571 			ByteString secretValue = secret->getKeyBits();
10572 			ByteString value;
10573 			ByteString plainKCV;
10574 			ByteString kcv;
10575 
10576 			// For generic and AES keys:
10577 			// default to return max size available.
10578 			if (byteLen == 0)
10579 			{
10580 				switch (keyType)
10581 				{
10582 					case CKK_GENERIC_SECRET:
10583 						byteLen = secretValue.size();
10584 						break;
10585 					case CKK_AES:
10586 						if (secretValue.size() >= 32)
10587 							byteLen = 32;
10588 						else if (secretValue.size() >= 24)
10589 							byteLen = 24;
10590 						else
10591 							byteLen = 16;
10592 				}
10593 			}
10594 
10595 			if (byteLen > secretValue.size())
10596 			{
10597 				INFO_MSG("The derived secret is too short");
10598 				bOK = false;
10599 			}
10600 			else
10601 			{
10602 				// Truncate value when requested, remove from the leading end
10603 				if (byteLen < secretValue.size())
10604 					secretValue.split(secretValue.size() - byteLen);
10605 
10606 				// Fix the odd parity for DES
10607 				if (keyType == CKK_DES ||
10608 				    keyType == CKK_DES2 ||
10609 				    keyType == CKK_DES3)
10610 				{
10611 					for (size_t i = 0; i < secretValue.size(); i++)
10612 					{
10613 						secretValue[i] = odd_parity[secretValue[i]];
10614 					}
10615 				}
10616 
10617 				// Get the KCV
10618 				switch (keyType)
10619 				{
10620 					case CKK_GENERIC_SECRET:
10621 						secret->setBitLen(byteLen * 8);
10622 						plainKCV = secret->getKeyCheckValue();
10623 						break;
10624 					case CKK_DES:
10625 					case CKK_DES2:
10626 					case CKK_DES3:
10627 						secret->setBitLen(byteLen * 7);
10628 						plainKCV = ((DESKey*)secret)->getKeyCheckValue();
10629 						break;
10630 					case CKK_AES:
10631 						secret->setBitLen(byteLen * 8);
10632 						plainKCV = ((AESKey*)secret)->getKeyCheckValue();
10633 						break;
10634 					default:
10635 						bOK = false;
10636 						break;
10637 				}
10638 
10639 				if (isPrivate)
10640 				{
10641 					token->encrypt(secretValue, value);
10642 					token->encrypt(plainKCV, kcv);
10643 				}
10644 				else
10645 				{
10646 					value = secretValue;
10647 					kcv = plainKCV;
10648 				}
10649 			}
10650 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
10651 			if (checkValue)
10652 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
10653 
10654 			if (bOK)
10655 				bOK = osobject->commitTransaction();
10656 			else
10657 				osobject->abortTransaction();
10658 
10659 			if (!bOK)
10660 				rv = CKR_FUNCTION_FAILED;
10661 		} else
10662 			rv = CKR_FUNCTION_FAILED;
10663 	}
10664 
10665 	// Clean up
10666 	ecdh->recycleSymmetricKey(secret);
10667 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
10668 
10669 	// Remove secret that may have been created already when the function fails.
10670 	if (rv != CKR_OK)
10671 	{
10672 		if (*phKey != CK_INVALID_HANDLE)
10673 		{
10674 			OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey);
10675 			handleManager->destroyObject(*phKey);
10676 			if (ossecret) ossecret->destroyObject();
10677 			*phKey = CK_INVALID_HANDLE;
10678 		}
10679 	}
10680 
10681 	return rv;
10682 }
10683 #endif
10684 
10685 // Derive an ECDH secret using Montgomery curves
10686 #ifdef WITH_EDDSA
deriveEDDSA(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_KEY_TYPE keyType,CK_BBOOL isOnToken,CK_BBOOL isPrivate)10687 CK_RV SoftHSM::deriveEDDSA
10688 (CK_SESSION_HANDLE hSession,
10689 	CK_MECHANISM_PTR pMechanism,
10690 	CK_OBJECT_HANDLE hBaseKey,
10691 	CK_ATTRIBUTE_PTR pTemplate,
10692 	CK_ULONG ulCount,
10693 	CK_OBJECT_HANDLE_PTR phKey,
10694 	CK_KEY_TYPE keyType,
10695 	CK_BBOOL isOnToken,
10696 	CK_BBOOL isPrivate)
10697 {
10698 	*phKey = CK_INVALID_HANDLE;
10699 
10700 	if ((pMechanism->pParameter == NULL_PTR) ||
10701 	    (pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)))
10702 	{
10703 		DEBUG_MSG("pParameter must be of type CK_ECDH1_DERIVE_PARAMS");
10704 		return CKR_MECHANISM_PARAM_INVALID;
10705 	}
10706 	if (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->kdf != CKD_NULL)
10707 	{
10708 		DEBUG_MSG("kdf must be CKD_NULL");
10709 		return CKR_MECHANISM_PARAM_INVALID;
10710 	}
10711 	if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulSharedDataLen != 0) ||
10712 	    (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pSharedData != NULL_PTR))
10713 	{
10714 		DEBUG_MSG("there must be no shared data");
10715 		return CKR_MECHANISM_PARAM_INVALID;
10716 	}
10717 	if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen == 0) ||
10718 	    (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData == NULL_PTR))
10719 	{
10720 		DEBUG_MSG("there must be a public data");
10721 		return CKR_MECHANISM_PARAM_INVALID;
10722 	}
10723 
10724 	// Get the session
10725 	Session* session = (Session*)handleManager->getSession(hSession);
10726 	if (session == NULL)
10727 		return CKR_SESSION_HANDLE_INVALID;
10728 
10729 	// Get the token
10730 	Token* token = session->getToken();
10731 	if (token == NULL)
10732 		return CKR_GENERAL_ERROR;
10733 
10734 	// Extract desired parameter information
10735 	size_t byteLen = 0;
10736 	bool checkValue = true;
10737 	for (CK_ULONG i = 0; i < ulCount; i++)
10738 	{
10739 		switch (pTemplate[i].type)
10740 		{
10741 			case CKA_VALUE:
10742 				INFO_MSG("CKA_VALUE must not be included");
10743 				return CKR_ATTRIBUTE_READ_ONLY;
10744 			case CKA_VALUE_LEN:
10745 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
10746 				{
10747 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
10748 					return CKR_ATTRIBUTE_VALUE_INVALID;
10749 				}
10750 				byteLen = *(CK_ULONG*)pTemplate[i].pValue;
10751 				break;
10752 			case CKA_CHECK_VALUE:
10753 				if (pTemplate[i].ulValueLen > 0)
10754 				{
10755 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
10756 					return CKR_ATTRIBUTE_VALUE_INVALID;
10757 				}
10758 				checkValue = false;
10759 				break;
10760 			default:
10761 				break;
10762 		}
10763 	}
10764 
10765 	// Check the length
10766 	// byteLen == 0 impiles return max size the ECC can derive
10767 	switch (keyType)
10768 	{
10769 		case CKK_GENERIC_SECRET:
10770 			break;
10771 #ifndef WITH_FIPS
10772 		case CKK_DES:
10773 			if (byteLen != 0 && byteLen != 8)
10774 			{
10775 				INFO_MSG("CKA_VALUE_LEN must be 0 or 8");
10776 				return CKR_ATTRIBUTE_VALUE_INVALID;
10777 			}
10778 			byteLen = 8;
10779 			break;
10780 #endif
10781 		case CKK_DES2:
10782 			if (byteLen != 0 && byteLen != 16)
10783 			{
10784 				INFO_MSG("CKA_VALUE_LEN must be 0 or 16");
10785 				return CKR_ATTRIBUTE_VALUE_INVALID;
10786 			}
10787 			byteLen = 16;
10788 			break;
10789 		case CKK_DES3:
10790 			if (byteLen != 0 && byteLen != 24)
10791 			{
10792 				INFO_MSG("CKA_VALUE_LEN must be 0 or 24");
10793 				return CKR_ATTRIBUTE_VALUE_INVALID;
10794 			}
10795 			byteLen = 24;
10796 			break;
10797 		case CKK_AES:
10798 			if (byteLen != 0 && byteLen != 16 && byteLen != 24 && byteLen != 32)
10799 			{
10800 				INFO_MSG("CKA_VALUE_LEN must be 0, 16, 24, or 32");
10801 				return CKR_ATTRIBUTE_VALUE_INVALID;
10802 			}
10803 			break;
10804 		default:
10805 			return CKR_ATTRIBUTE_VALUE_INVALID;
10806 	}
10807 
10808 	// Get the base key handle
10809 	OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
10810 	if (baseKey == NULL || !baseKey->isValid())
10811 		return CKR_KEY_HANDLE_INVALID;
10812 
10813 	// Get the EDDSA algorithm handler
10814 	AsymmetricAlgorithm* eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
10815 	if (eddsa == NULL)
10816 		return CKR_MECHANISM_INVALID;
10817 
10818 	// Get the keys
10819 	PrivateKey* privateKey = eddsa->newPrivateKey();
10820 	if (privateKey == NULL)
10821 	{
10822 		CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
10823 		return CKR_HOST_MEMORY;
10824 	}
10825 	if (getEDPrivateKey((EDPrivateKey*)privateKey, token, baseKey) != CKR_OK)
10826 	{
10827 		eddsa->recyclePrivateKey(privateKey);
10828 		CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
10829 		return CKR_GENERAL_ERROR;
10830 	}
10831 
10832 	ByteString publicData;
10833 	publicData.resize(CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen);
10834 	memcpy(&publicData[0],
10835 	       CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData,
10836 	       CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen);
10837 	PublicKey* publicKey = eddsa->newPublicKey();
10838 	if (publicKey == NULL)
10839 	{
10840 		eddsa->recyclePrivateKey(privateKey);
10841 		CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
10842 		return CKR_HOST_MEMORY;
10843 	}
10844 	if (getEDDHPublicKey((EDPublicKey*)publicKey, (EDPrivateKey*)privateKey, publicData) != CKR_OK)
10845 	{
10846 		eddsa->recyclePrivateKey(privateKey);
10847 		eddsa->recyclePublicKey(publicKey);
10848 		CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
10849 		return CKR_GENERAL_ERROR;
10850 	}
10851 
10852 	// Derive the secret
10853 	SymmetricKey* secret = NULL;
10854 	CK_RV rv = CKR_OK;
10855 	if (!eddsa->deriveKey(&secret, publicKey, privateKey))
10856 		rv = CKR_GENERAL_ERROR;
10857 	eddsa->recyclePrivateKey(privateKey);
10858 	eddsa->recyclePublicKey(publicKey);
10859 
10860 	// Create the secret object using C_CreateObject
10861 	const CK_ULONG maxAttribs = 32;
10862 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
10863 	CK_ATTRIBUTE secretAttribs[maxAttribs] = {
10864 		{ CKA_CLASS, &objClass, sizeof(objClass) },
10865 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
10866 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
10867 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
10868 	};
10869 	CK_ULONG secretAttribsCount = 4;
10870 
10871 	// Add the additional
10872 	if (ulCount > (maxAttribs - secretAttribsCount))
10873 		rv = CKR_TEMPLATE_INCONSISTENT;
10874 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
10875 	{
10876 		switch (pTemplate[i].type)
10877 		{
10878 			case CKA_CLASS:
10879 			case CKA_TOKEN:
10880 			case CKA_PRIVATE:
10881 			case CKA_KEY_TYPE:
10882 			case CKA_CHECK_VALUE:
10883 				continue;
10884 		default:
10885 			secretAttribs[secretAttribsCount++] = pTemplate[i];
10886 		}
10887 	}
10888 
10889 	if (rv == CKR_OK)
10890 		rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, phKey, OBJECT_OP_DERIVE);
10891 
10892 	// Store the attributes that are being supplied
10893 	if (rv == CKR_OK)
10894 	{
10895 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
10896 		if (osobject == NULL_PTR || !osobject->isValid()) {
10897 			rv = CKR_FUNCTION_FAILED;
10898 		} else if (osobject->startTransaction()) {
10899 			bool bOK = true;
10900 
10901 			// Common Attributes
10902 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,false);
10903 
10904 			// Common Secret Key Attributes
10905 			if (baseKey->getBooleanValue(CKA_ALWAYS_SENSITIVE, false))
10906 			{
10907 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
10908 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
10909 			}
10910 			else
10911 			{
10912 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,false);
10913 			}
10914 			if (baseKey->getBooleanValue(CKA_NEVER_EXTRACTABLE, true))
10915 			{
10916 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
10917 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,bNeverExtractable);
10918 			}
10919 			else
10920 			{
10921 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,false);
10922 			}
10923 
10924 			// Secret Attributes
10925 			ByteString secretValue = secret->getKeyBits();
10926 			ByteString value;
10927 			ByteString plainKCV;
10928 			ByteString kcv;
10929 
10930 			// For generic and AES keys:
10931 			// default to return max size available.
10932 			if (byteLen == 0)
10933 			{
10934 				switch (keyType)
10935 				{
10936 					case CKK_GENERIC_SECRET:
10937 						byteLen = secretValue.size();
10938 						break;
10939 					case CKK_AES:
10940 						if (secretValue.size() >= 32)
10941 							byteLen = 32;
10942 						else if (secretValue.size() >= 24)
10943 							byteLen = 24;
10944 						else
10945 							byteLen = 16;
10946 				}
10947 			}
10948 
10949 			if (byteLen > secretValue.size())
10950 			{
10951 				INFO_MSG("The derived secret is too short");
10952 				bOK = false;
10953 			}
10954 			else
10955 			{
10956 				// Truncate value when requested, remove from the leading end
10957 				if (byteLen < secretValue.size())
10958 					secretValue.split(secretValue.size() - byteLen);
10959 
10960 				// Fix the odd parity for DES
10961 				if (keyType == CKK_DES ||
10962 				    keyType == CKK_DES2 ||
10963 				    keyType == CKK_DES3)
10964 				{
10965 					for (size_t i = 0; i < secretValue.size(); i++)
10966 					{
10967 						secretValue[i] = odd_parity[secretValue[i]];
10968 					}
10969 				}
10970 
10971 				// Get the KCV
10972 				switch (keyType)
10973 				{
10974 					case CKK_GENERIC_SECRET:
10975 						secret->setBitLen(byteLen * 8);
10976 						plainKCV = secret->getKeyCheckValue();
10977 						break;
10978 					case CKK_DES:
10979 					case CKK_DES2:
10980 					case CKK_DES3:
10981 						secret->setBitLen(byteLen * 7);
10982 						plainKCV = ((DESKey*)secret)->getKeyCheckValue();
10983 						break;
10984 					case CKK_AES:
10985 						secret->setBitLen(byteLen * 8);
10986 						plainKCV = ((AESKey*)secret)->getKeyCheckValue();
10987 						break;
10988 					default:
10989 						bOK = false;
10990 						break;
10991 				}
10992 
10993 				if (isPrivate)
10994 				{
10995 					token->encrypt(secretValue, value);
10996 					token->encrypt(plainKCV, kcv);
10997 				}
10998 				else
10999 				{
11000 					value = secretValue;
11001 					kcv = plainKCV;
11002 				}
11003 			}
11004 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
11005 			if (checkValue)
11006 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
11007 
11008 			if (bOK)
11009 				bOK = osobject->commitTransaction();
11010 			else
11011 				osobject->abortTransaction();
11012 
11013 			if (!bOK)
11014 				rv = CKR_FUNCTION_FAILED;
11015 		} else
11016 			rv = CKR_FUNCTION_FAILED;
11017 	}
11018 
11019 	// Clean up
11020 	eddsa->recycleSymmetricKey(secret);
11021 	CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
11022 
11023 	// Remove secret that may have been created already when the function fails.
11024 	if (rv != CKR_OK)
11025 	{
11026 		if (*phKey != CK_INVALID_HANDLE)
11027 		{
11028 			OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey);
11029 			handleManager->destroyObject(*phKey);
11030 			if (ossecret) ossecret->destroyObject();
11031 			*phKey = CK_INVALID_HANDLE;
11032 		}
11033 	}
11034 
11035 	return rv;
11036 }
11037 #endif
11038 
11039 // Derive an symmetric secret
deriveSymmetric(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hBaseKey,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phKey,CK_KEY_TYPE keyType,CK_BBOOL isOnToken,CK_BBOOL isPrivate)11040 CK_RV SoftHSM::deriveSymmetric
11041 (CK_SESSION_HANDLE hSession,
11042 	CK_MECHANISM_PTR pMechanism,
11043 	CK_OBJECT_HANDLE hBaseKey,
11044 	CK_ATTRIBUTE_PTR pTemplate,
11045 	CK_ULONG ulCount,
11046 	CK_OBJECT_HANDLE_PTR phKey,
11047 	CK_KEY_TYPE keyType,
11048 	CK_BBOOL isOnToken,
11049 	CK_BBOOL isPrivate)
11050 {
11051 	*phKey = CK_INVALID_HANDLE;
11052 
11053 	if (pMechanism->pParameter == NULL_PTR)
11054 	{
11055 		DEBUG_MSG("pParameter must be supplied");
11056 		return CKR_MECHANISM_PARAM_INVALID;
11057 	}
11058 
11059 	ByteString data;
11060 
11061 	if ((pMechanism->mechanism == CKM_DES_ECB_ENCRYPT_DATA ||
11062 	    pMechanism->mechanism == CKM_DES3_ECB_ENCRYPT_DATA) &&
11063 	    pMechanism->ulParameterLen == sizeof(CK_KEY_DERIVATION_STRING_DATA))
11064 	{
11065 		CK_BYTE_PTR pData = CK_KEY_DERIVATION_STRING_DATA_PTR(pMechanism->pParameter)->pData;
11066 		CK_ULONG ulLen = CK_KEY_DERIVATION_STRING_DATA_PTR(pMechanism->pParameter)->ulLen;
11067 		if (ulLen == 0 || pData == NULL_PTR)
11068 		{
11069 			DEBUG_MSG("There must be data in the parameter");
11070 			return CKR_MECHANISM_PARAM_INVALID;
11071 		}
11072 		if (ulLen % 8 != 0)
11073 		{
11074 			DEBUG_MSG("The data must be a multiple of 8 bytes long");
11075 			return CKR_MECHANISM_PARAM_INVALID;
11076 		}
11077 		data.resize(ulLen);
11078 		memcpy(&data[0],
11079 		       pData,
11080 		       ulLen);
11081 	}
11082 	else if ((pMechanism->mechanism == CKM_DES_CBC_ENCRYPT_DATA ||
11083 		 pMechanism->mechanism == CKM_DES3_CBC_ENCRYPT_DATA) &&
11084 		 pMechanism->ulParameterLen == sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS))
11085 	{
11086 		CK_BYTE_PTR pData = CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->pData;
11087 		CK_ULONG length = CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->length;
11088 		if (length == 0 || pData == NULL_PTR)
11089 		{
11090 			DEBUG_MSG("There must be data in the parameter");
11091 			return CKR_MECHANISM_PARAM_INVALID;
11092 		}
11093 		if (length % 8 != 0)
11094 		{
11095 			DEBUG_MSG("The data must be a multiple of 8 bytes long");
11096 			return CKR_MECHANISM_PARAM_INVALID;
11097 		}
11098 		data.resize(length);
11099 		memcpy(&data[0],
11100 		       pData,
11101 		       length);
11102 	}
11103 	else if (pMechanism->mechanism == CKM_AES_ECB_ENCRYPT_DATA &&
11104 		 pMechanism->ulParameterLen == sizeof(CK_KEY_DERIVATION_STRING_DATA))
11105 	{
11106 		CK_BYTE_PTR pData = CK_KEY_DERIVATION_STRING_DATA_PTR(pMechanism->pParameter)->pData;
11107 		CK_ULONG ulLen = CK_KEY_DERIVATION_STRING_DATA_PTR(pMechanism->pParameter)->ulLen;
11108 		if (ulLen == 0 || pData == NULL_PTR)
11109 		{
11110 			DEBUG_MSG("There must be data in the parameter");
11111 			return CKR_MECHANISM_PARAM_INVALID;
11112 		}
11113 		if (ulLen % 16 != 0)
11114 		{
11115 			DEBUG_MSG("The data must be a multiple of 16 bytes long");
11116 			return CKR_MECHANISM_PARAM_INVALID;
11117 		}
11118 		data.resize(ulLen);
11119 		memcpy(&data[0],
11120 		       pData,
11121 		       ulLen);
11122 	}
11123 	else if ((pMechanism->mechanism == CKM_AES_CBC_ENCRYPT_DATA) &&
11124 		 pMechanism->ulParameterLen == sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))
11125 	{
11126 		CK_BYTE_PTR pData = CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->pData;
11127 		CK_ULONG length = CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->length;
11128 		if (length == 0 || pData == NULL_PTR)
11129 		{
11130 			DEBUG_MSG("There must be data in the parameter");
11131 			return CKR_MECHANISM_PARAM_INVALID;
11132 		}
11133 		if (length % 16 != 0)
11134 		{
11135 			DEBUG_MSG("The data must be a multiple of 16 bytes long");
11136 			return CKR_MECHANISM_PARAM_INVALID;
11137 		}
11138 		data.resize(length);
11139 		memcpy(&data[0],
11140 		       pData,
11141 		       length);
11142 	}
11143 	else
11144 	{
11145 		DEBUG_MSG("pParameter is invalid");
11146 		return CKR_MECHANISM_PARAM_INVALID;
11147 	}
11148 
11149 	// Get the session
11150 	Session* session = (Session*)handleManager->getSession(hSession);
11151 	if (session == NULL)
11152 		return CKR_SESSION_HANDLE_INVALID;
11153 
11154 	// Get the token
11155 	Token* token = session->getToken();
11156 	if (token == NULL)
11157 		return CKR_GENERAL_ERROR;
11158 
11159 	// Extract desired parameter information
11160 	size_t byteLen = 0;
11161 	bool checkValue = true;
11162 	for (CK_ULONG i = 0; i < ulCount; i++)
11163 	{
11164 		switch (pTemplate[i].type)
11165 		{
11166 			case CKA_VALUE:
11167 				INFO_MSG("CKA_VALUE must not be included");
11168 				return CKR_ATTRIBUTE_READ_ONLY;
11169 			case CKA_VALUE_LEN:
11170 				if (pTemplate[i].ulValueLen != sizeof(CK_ULONG))
11171 				{
11172 					INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG");
11173 					return CKR_ATTRIBUTE_VALUE_INVALID;
11174 				}
11175 				byteLen = *(CK_ULONG*)pTemplate[i].pValue;
11176 				break;
11177 			case CKA_CHECK_VALUE:
11178 				if (pTemplate[i].ulValueLen > 0)
11179 				{
11180 					INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry");
11181 					return CKR_ATTRIBUTE_VALUE_INVALID;
11182 				}
11183 				checkValue = false;
11184 				break;
11185 			default:
11186 				break;
11187 		}
11188 	}
11189 
11190 	// Check the length
11191 	switch (keyType)
11192 	{
11193 		case CKK_GENERIC_SECRET:
11194 			if (byteLen == 0)
11195 			{
11196 				INFO_MSG("CKA_VALUE_LEN must be set");
11197 				return CKR_TEMPLATE_INCOMPLETE;
11198 			}
11199 			break;
11200 #ifndef WITH_FIPS
11201 		case CKK_DES:
11202 			if (byteLen != 0)
11203 			{
11204 				INFO_MSG("CKA_VALUE_LEN must not be set");
11205 				return CKR_ATTRIBUTE_READ_ONLY;
11206 			}
11207 			byteLen = 8;
11208 			break;
11209 #endif
11210 		case CKK_DES2:
11211 			if (byteLen != 0)
11212 			{
11213 				INFO_MSG("CKA_VALUE_LEN must not be set");
11214 				return CKR_ATTRIBUTE_READ_ONLY;
11215 			}
11216 			byteLen = 16;
11217 			break;
11218 		case CKK_DES3:
11219 			if (byteLen != 0)
11220 			{
11221 				INFO_MSG("CKA_VALUE_LEN must not be set");
11222 				return CKR_ATTRIBUTE_READ_ONLY;
11223 			}
11224 			byteLen = 24;
11225 			break;
11226 		case CKK_AES:
11227 			if (byteLen != 16 && byteLen != 24 && byteLen != 32)
11228 			{
11229 				INFO_MSG("CKA_VALUE_LEN must be 16, 24, or 32");
11230 				return CKR_ATTRIBUTE_VALUE_INVALID;
11231 			}
11232 			break;
11233 		default:
11234 			return CKR_ATTRIBUTE_VALUE_INVALID;
11235 	}
11236 
11237 	// Get the symmetric algorithm matching the mechanism
11238 	SymAlgo::Type algo = SymAlgo::Unknown;
11239 	SymMode::Type mode = SymMode::Unknown;
11240 	bool padding = false;
11241 	ByteString iv;
11242 	size_t bb = 8;
11243 	switch(pMechanism->mechanism) {
11244 #ifndef WITH_FIPS
11245 		case CKM_DES_ECB_ENCRYPT_DATA:
11246 			algo = SymAlgo::DES;
11247 			mode = SymMode::ECB;
11248 			bb = 7;
11249 			break;
11250 		case CKM_DES_CBC_ENCRYPT_DATA:
11251 			algo = SymAlgo::DES;
11252 			mode = SymMode::CBC;
11253 			bb = 7;
11254 			iv.resize(8);
11255 			memcpy(&iv[0],
11256 			       &(CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->iv[0]),
11257 			       8);
11258 			break;
11259 #endif
11260 		case CKM_DES3_ECB_ENCRYPT_DATA:
11261 			algo = SymAlgo::DES3;
11262 			mode = SymMode::ECB;
11263 			bb = 7;
11264 			break;
11265 		case CKM_DES3_CBC_ENCRYPT_DATA:
11266 			algo = SymAlgo::DES3;
11267 			mode = SymMode::CBC;
11268 			bb = 7;
11269 			iv.resize(8);
11270 			memcpy(&iv[0],
11271 			       &(CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->iv[0]),
11272 			       8);
11273 			break;
11274 		case CKM_AES_ECB_ENCRYPT_DATA:
11275 			algo = SymAlgo::AES;
11276 			mode = SymMode::ECB;
11277 			break;
11278 		case CKM_AES_CBC_ENCRYPT_DATA:
11279 			algo = SymAlgo::AES;
11280 			mode = SymMode::CBC;
11281 			iv.resize(16);
11282 			memcpy(&iv[0],
11283 			       &(CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR(pMechanism->pParameter)->iv[0]),
11284 			       16);
11285 			break;
11286 		default:
11287 			return CKR_MECHANISM_INVALID;
11288 	}
11289 
11290 	// Check the key handle
11291 	OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey);
11292 	if (baseKey == NULL_PTR || !baseKey->isValid()) return CKR_OBJECT_HANDLE_INVALID;
11293 
11294 	SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
11295 	if (cipher == NULL) return CKR_MECHANISM_INVALID;
11296 
11297 	SymmetricKey* secretkey = new SymmetricKey();
11298 
11299 	if (getSymmetricKey(secretkey, token, baseKey) != CKR_OK)
11300 	{
11301 		cipher->recycleKey(secretkey);
11302 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
11303 		return CKR_GENERAL_ERROR;
11304 	}
11305 
11306 	// adjust key bit length
11307 	secretkey->setBitLen(secretkey->getKeyBits().size() * bb);
11308 
11309 	// Initialize encryption
11310 	if (!cipher->encryptInit(secretkey, mode, iv, padding))
11311 	{
11312 		cipher->recycleKey(secretkey);
11313 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
11314 		return CKR_MECHANISM_INVALID;
11315 	}
11316 
11317 	// Get the data
11318 	ByteString secretValue;
11319 
11320 	// Encrypt the data
11321 	if (!cipher->encryptUpdate(data, secretValue))
11322 	{
11323 		cipher->recycleKey(secretkey);
11324 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
11325 		return CKR_GENERAL_ERROR;
11326 	}
11327 
11328 	// Finalize encryption
11329 	ByteString encryptedFinal;
11330 	if (!cipher->encryptFinal(encryptedFinal))
11331 	{
11332 		cipher->recycleKey(secretkey);
11333 		CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
11334 		return CKR_GENERAL_ERROR;
11335 	}
11336 	cipher->recycleKey(secretkey);
11337 	CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
11338 	secretValue += encryptedFinal;
11339 
11340 	// Create the secret object using C_CreateObject
11341 	const CK_ULONG maxAttribs = 32;
11342 	CK_OBJECT_CLASS objClass = CKO_SECRET_KEY;
11343 	CK_ATTRIBUTE secretAttribs[maxAttribs] = {
11344 		{ CKA_CLASS, &objClass, sizeof(objClass) },
11345 		{ CKA_TOKEN, &isOnToken, sizeof(isOnToken) },
11346 		{ CKA_PRIVATE, &isPrivate, sizeof(isPrivate) },
11347 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
11348 	};
11349 	CK_ULONG secretAttribsCount = 4;
11350 
11351 	// Add the additional
11352 	CK_RV rv = CKR_OK;
11353 	if (ulCount > (maxAttribs - secretAttribsCount))
11354 		rv = CKR_TEMPLATE_INCONSISTENT;
11355 	for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i)
11356 	{
11357 		switch (pTemplate[i].type)
11358 		{
11359 			case CKA_CLASS:
11360 			case CKA_TOKEN:
11361 			case CKA_PRIVATE:
11362 			case CKA_KEY_TYPE:
11363 			case CKA_CHECK_VALUE:
11364 				continue;
11365 			default:
11366 				secretAttribs[secretAttribsCount++] = pTemplate[i];
11367 		}
11368 	}
11369 
11370 	if (rv == CKR_OK)
11371 		rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, phKey, OBJECT_OP_DERIVE);
11372 
11373 	// Store the attributes that are being supplied
11374 	if (rv == CKR_OK)
11375 	{
11376 		OSObject* osobject = (OSObject*)handleManager->getObject(*phKey);
11377 		if (osobject == NULL_PTR || !osobject->isValid()) {
11378 			rv = CKR_FUNCTION_FAILED;
11379 		} else if (osobject->startTransaction()) {
11380 			bool bOK = true;
11381 
11382 			// Common Attributes
11383 			bOK = bOK && osobject->setAttribute(CKA_LOCAL,false);
11384 
11385 			// Common Secret Key Attributes
11386 			if (baseKey->getBooleanValue(CKA_ALWAYS_SENSITIVE, false))
11387 			{
11388 				bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false);
11389 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive);
11390 			}
11391 			else
11392 			{
11393 				bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,false);
11394 			}
11395 			if (baseKey->getBooleanValue(CKA_NEVER_EXTRACTABLE, true))
11396 			{
11397 				bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false;
11398 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,bNeverExtractable);
11399 			}
11400 			else
11401 			{
11402 				bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,false);
11403 			}
11404 
11405 			ByteString value;
11406 			ByteString plainKCV;
11407 			ByteString kcv;
11408 
11409 			if (byteLen > secretValue.size())
11410 			{
11411 				INFO_MSG("The derived secret is too short");
11412 				bOK = false;
11413 			}
11414 			else
11415 			{
11416 				// Truncate value when requested, remove from the trailing end
11417 				if (byteLen < secretValue.size())
11418 					secretValue.resize(byteLen);
11419 
11420 				// Fix the odd parity for DES
11421 				if (keyType == CKK_DES ||
11422 				    keyType == CKK_DES2 ||
11423 				    keyType == CKK_DES3)
11424 				{
11425 					for (size_t i = 0; i < secretValue.size(); i++)
11426 					{
11427 						secretValue[i] = odd_parity[secretValue[i]];
11428 					}
11429 				}
11430 
11431 				// Get the KCV
11432 				SymmetricKey* secret = new SymmetricKey();
11433 				secret->setKeyBits(secretValue);
11434 				switch (keyType)
11435 				{
11436 					case CKK_GENERIC_SECRET:
11437 						secret->setBitLen(byteLen * 8);
11438 						plainKCV = secret->getKeyCheckValue();
11439 						break;
11440 					case CKK_DES:
11441 					case CKK_DES2:
11442 					case CKK_DES3:
11443 						secret->setBitLen(byteLen * 7);
11444 						plainKCV = ((DESKey*)secret)->getKeyCheckValue();
11445 						break;
11446 					case CKK_AES:
11447 						secret->setBitLen(byteLen * 8);
11448 						plainKCV = ((AESKey*)secret)->getKeyCheckValue();
11449 						break;
11450 					default:
11451 						bOK = false;
11452 						break;
11453 				}
11454 				delete secret;
11455 
11456 				if (isPrivate)
11457 				{
11458 					token->encrypt(secretValue, value);
11459 					token->encrypt(plainKCV, kcv);
11460 				}
11461 				else
11462 				{
11463 					value = secretValue;
11464 					kcv = plainKCV;
11465 				}
11466 			}
11467 			bOK = bOK && osobject->setAttribute(CKA_VALUE, value);
11468 			if (checkValue)
11469 				bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv);
11470 
11471 			if (bOK)
11472 				bOK = osobject->commitTransaction();
11473 			else
11474 				osobject->abortTransaction();
11475 
11476 			if (!bOK)
11477 				rv = CKR_FUNCTION_FAILED;
11478 		} else
11479 			rv = CKR_FUNCTION_FAILED;
11480 	}
11481 
11482 	// Remove secret that may have been created already when the function fails.
11483 	if (rv != CKR_OK)
11484 	{
11485 		if (*phKey != CK_INVALID_HANDLE)
11486 		{
11487 			OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey);
11488 			handleManager->destroyObject(*phKey);
11489 			if (ossecret) ossecret->destroyObject();
11490 			*phKey = CK_INVALID_HANDLE;
11491 		}
11492 	}
11493 
11494 	return rv;
11495 }
11496 
CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject,int op)11497 CK_RV SoftHSM::CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject, int op)
11498 {
11499 	if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED;
11500 
11501 	if (pTemplate == NULL_PTR) return CKR_ARGUMENTS_BAD;
11502 	if (phObject == NULL_PTR) return CKR_ARGUMENTS_BAD;
11503 
11504 	// Get the session
11505 	Session* session = (Session*)handleManager->getSession(hSession);
11506 	if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
11507 
11508 	// Get the slot
11509 	Slot* slot = session->getSlot();
11510 	if (slot == NULL_PTR) return CKR_GENERAL_ERROR;
11511 
11512 	// Get the token
11513 	Token* token = session->getToken();
11514 	if (token == NULL_PTR) return CKR_GENERAL_ERROR;
11515 
11516 	// Extract information from the template that is needed to create the object.
11517 	CK_OBJECT_CLASS objClass = CKO_DATA;
11518 	CK_KEY_TYPE keyType = CKK_RSA;
11519 	CK_CERTIFICATE_TYPE certType = CKC_X_509;
11520 	CK_BBOOL isOnToken = CK_FALSE;
11521 	CK_BBOOL isPrivate = CK_TRUE;
11522 	bool isImplicit = false;
11523 	CK_RV rv = extractObjectInformation(pTemplate,ulCount,objClass,keyType,certType, isOnToken, isPrivate, isImplicit);
11524 	if (rv != CKR_OK)
11525 	{
11526 		ERROR_MSG("Mandatory attribute not present in template");
11527 		return rv;
11528 	}
11529 
11530 	// Check user credentials
11531 	rv = haveWrite(session->getState(), isOnToken, isPrivate);
11532 	if (rv != CKR_OK)
11533 	{
11534 		if (rv == CKR_USER_NOT_LOGGED_IN)
11535 			INFO_MSG("User is not authorized");
11536 		if (rv == CKR_SESSION_READ_ONLY)
11537 			INFO_MSG("Session is read-only");
11538 
11539 		return rv;
11540 	}
11541 
11542 	// Change order of attributes
11543 	const CK_ULONG maxAttribs = 32;
11544 	CK_ATTRIBUTE attribs[maxAttribs];
11545 	CK_ATTRIBUTE saveAttribs[maxAttribs];
11546 	CK_ULONG attribsCount = 0;
11547 	CK_ULONG saveAttribsCount = 0;
11548 	if (ulCount > maxAttribs)
11549 	{
11550 		return CKR_TEMPLATE_INCONSISTENT;
11551 	}
11552 	for (CK_ULONG i=0; i < ulCount; i++)
11553 	{
11554 		switch (pTemplate[i].type)
11555 		{
11556 			case CKA_CHECK_VALUE:
11557 				saveAttribs[saveAttribsCount++] = pTemplate[i];
11558 				break;
11559 			default:
11560 				attribs[attribsCount++] = pTemplate[i];
11561 		}
11562 	}
11563 	for (CK_ULONG i=0; i < saveAttribsCount; i++)
11564 	{
11565 		attribs[attribsCount++] = saveAttribs[i];
11566 	}
11567 
11568 	P11Object* p11object = NULL;
11569 	rv = newP11Object(objClass,keyType,certType,&p11object);
11570 	if (rv != CKR_OK)
11571 		return rv;
11572 
11573 	// Create the object in session or on the token
11574 	OSObject *object = NULL_PTR;
11575 	if (isOnToken)
11576 	{
11577 		object = (OSObject*) token->createObject();
11578 	}
11579 	else
11580 	{
11581 		object = sessionObjectStore->createObject(slot->getSlotID(), hSession, isPrivate != CK_FALSE);
11582 	}
11583 
11584 	if (object == NULL || !p11object->init(object))
11585 	{
11586 		delete p11object;
11587 		return CKR_GENERAL_ERROR;
11588 	}
11589 
11590 	rv = p11object->saveTemplate(token, isPrivate != CK_FALSE, attribs,attribsCount,op);
11591 	delete p11object;
11592 	if (rv != CKR_OK)
11593 		return rv;
11594 
11595 	if (op == OBJECT_OP_CREATE)
11596 	{
11597 		if (objClass == CKO_PUBLIC_KEY &&
11598 		    (!object->startTransaction() ||
11599 		    !object->setAttribute(CKA_LOCAL, false) ||
11600 		    !object->commitTransaction()))
11601 		{
11602 			return CKR_GENERAL_ERROR;
11603 		}
11604 
11605 		if ((objClass == CKO_SECRET_KEY || objClass == CKO_PRIVATE_KEY) &&
11606 		    (!object->startTransaction() ||
11607 		    !object->setAttribute(CKA_LOCAL, false) ||
11608 		    !object->setAttribute(CKA_ALWAYS_SENSITIVE, false) ||
11609 		    !object->setAttribute(CKA_NEVER_EXTRACTABLE, false) ||
11610 		    !object->commitTransaction()))
11611 		{
11612 			return CKR_GENERAL_ERROR;
11613 		}
11614 	}
11615 
11616 	if (isOnToken)
11617 	{
11618 		*phObject = handleManager->addTokenObject(slot->getSlotID(), isPrivate != CK_FALSE, object);
11619 	} else {
11620 		*phObject = handleManager->addSessionObject(slot->getSlotID(), hSession, isPrivate != CK_FALSE, object);
11621 	}
11622 
11623 	return CKR_OK;
11624 }
11625 
getRSAPrivateKey(RSAPrivateKey * privateKey,Token * token,OSObject * key)11626 CK_RV SoftHSM::getRSAPrivateKey(RSAPrivateKey* privateKey, Token* token, OSObject* key)
11627 {
11628 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11629 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11630 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11631 
11632 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11633 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11634 
11635 	// RSA Private Key Attributes
11636 	ByteString modulus;
11637 	ByteString publicExponent;
11638 	ByteString privateExponent;
11639 	ByteString prime1;
11640 	ByteString prime2;
11641 	ByteString exponent1;
11642 	ByteString exponent2;
11643 	ByteString coefficient;
11644 	if (isKeyPrivate)
11645 	{
11646 		bool bOK = true;
11647 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_MODULUS), modulus);
11648 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PUBLIC_EXPONENT), publicExponent);
11649 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIVATE_EXPONENT), privateExponent);
11650 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIME_1), prime1);
11651 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIME_2), prime2);
11652 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EXPONENT_1), exponent1);
11653 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EXPONENT_2), exponent2);
11654 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_COEFFICIENT), coefficient);
11655 		if (!bOK)
11656 			return CKR_GENERAL_ERROR;
11657 	}
11658 	else
11659 	{
11660 		modulus = key->getByteStringValue(CKA_MODULUS);
11661 		publicExponent = key->getByteStringValue(CKA_PUBLIC_EXPONENT);
11662 		privateExponent = key->getByteStringValue(CKA_PRIVATE_EXPONENT);
11663 		prime1 = key->getByteStringValue(CKA_PRIME_1);
11664 		prime2 = key->getByteStringValue(CKA_PRIME_2);
11665 		exponent1 =  key->getByteStringValue(CKA_EXPONENT_1);
11666 		exponent2 = key->getByteStringValue(CKA_EXPONENT_2);
11667 		coefficient = key->getByteStringValue(CKA_COEFFICIENT);
11668 	}
11669 
11670 	privateKey->setN(modulus);
11671 	privateKey->setE(publicExponent);
11672 	privateKey->setD(privateExponent);
11673 	privateKey->setP(prime1);
11674 	privateKey->setQ(prime2);
11675 	privateKey->setDP1(exponent1);
11676 	privateKey->setDQ1(exponent2);
11677 	privateKey->setPQ(coefficient);
11678 
11679 	return CKR_OK;
11680 }
11681 
getRSAPublicKey(RSAPublicKey * publicKey,Token * token,OSObject * key)11682 CK_RV SoftHSM::getRSAPublicKey(RSAPublicKey* publicKey, Token* token, OSObject* key)
11683 {
11684 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11685 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11686 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11687 
11688 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11689 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11690 
11691 	// RSA Public Key Attributes
11692 	ByteString modulus;
11693 	ByteString publicExponent;
11694 	if (isKeyPrivate)
11695 	{
11696 		bool bOK = true;
11697 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_MODULUS), modulus);
11698 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PUBLIC_EXPONENT), publicExponent);
11699 		if (!bOK)
11700 			return CKR_GENERAL_ERROR;
11701 	}
11702 	else
11703 	{
11704 		modulus = key->getByteStringValue(CKA_MODULUS);
11705 		publicExponent = key->getByteStringValue(CKA_PUBLIC_EXPONENT);
11706 	}
11707 
11708 	publicKey->setN(modulus);
11709 	publicKey->setE(publicExponent);
11710 
11711 	return CKR_OK;
11712 }
11713 
getDSAPrivateKey(DSAPrivateKey * privateKey,Token * token,OSObject * key)11714 CK_RV SoftHSM::getDSAPrivateKey(DSAPrivateKey* privateKey, Token* token, OSObject* key)
11715 {
11716 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11717 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11718 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11719 
11720 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11721 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11722 
11723 	// DSA Private Key Attributes
11724 	ByteString prime;
11725 	ByteString subprime;
11726 	ByteString generator;
11727 	ByteString value;
11728 	if (isKeyPrivate)
11729 	{
11730 		bool bOK = true;
11731 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIME), prime);
11732 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_SUBPRIME), subprime);
11733 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_BASE), generator);
11734 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
11735 		if (!bOK)
11736 			return CKR_GENERAL_ERROR;
11737 	}
11738 	else
11739 	{
11740 		prime = key->getByteStringValue(CKA_PRIME);
11741 		subprime = key->getByteStringValue(CKA_SUBPRIME);
11742 		generator = key->getByteStringValue(CKA_BASE);
11743 		value = key->getByteStringValue(CKA_VALUE);
11744 	}
11745 
11746 	privateKey->setP(prime);
11747 	privateKey->setQ(subprime);
11748 	privateKey->setG(generator);
11749 	privateKey->setX(value);
11750 
11751 	return CKR_OK;
11752 }
11753 
getDSAPublicKey(DSAPublicKey * publicKey,Token * token,OSObject * key)11754 CK_RV SoftHSM::getDSAPublicKey(DSAPublicKey* publicKey, Token* token, OSObject* key)
11755 {
11756 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11757 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11758 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11759 
11760 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11761 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11762 
11763 	// DSA Public Key Attributes
11764 	ByteString prime;
11765 	ByteString subprime;
11766 	ByteString generator;
11767 	ByteString value;
11768 	if (isKeyPrivate)
11769 	{
11770 		bool bOK = true;
11771 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIME), prime);
11772 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_SUBPRIME), subprime);
11773 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_BASE), generator);
11774 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
11775 		if (!bOK)
11776 			return CKR_GENERAL_ERROR;
11777 	}
11778 	else
11779 	{
11780 		prime = key->getByteStringValue(CKA_PRIME);
11781 		subprime = key->getByteStringValue(CKA_SUBPRIME);
11782 		generator = key->getByteStringValue(CKA_BASE);
11783 		value = key->getByteStringValue(CKA_VALUE);
11784 	}
11785 
11786 	publicKey->setP(prime);
11787 	publicKey->setQ(subprime);
11788 	publicKey->setG(generator);
11789 	publicKey->setY(value);
11790 
11791 	return CKR_OK;
11792 }
11793 
getECPrivateKey(ECPrivateKey * privateKey,Token * token,OSObject * key)11794 CK_RV SoftHSM::getECPrivateKey(ECPrivateKey* privateKey, Token* token, OSObject* key)
11795 {
11796 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11797 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11798 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11799 
11800 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11801 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11802 
11803 	// EC Private Key Attributes
11804 	ByteString group;
11805 	ByteString value;
11806 	if (isKeyPrivate)
11807 	{
11808 		bool bOK = true;
11809 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group);
11810 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
11811 		if (!bOK)
11812 			return CKR_GENERAL_ERROR;
11813 	}
11814 	else
11815 	{
11816 		group = key->getByteStringValue(CKA_EC_PARAMS);
11817 		value = key->getByteStringValue(CKA_VALUE);
11818 	}
11819 
11820 	privateKey->setEC(group);
11821 	privateKey->setD(value);
11822 
11823 	return CKR_OK;
11824 }
11825 
getECPublicKey(ECPublicKey * publicKey,Token * token,OSObject * key)11826 CK_RV SoftHSM::getECPublicKey(ECPublicKey* publicKey, Token* token, OSObject* key)
11827 {
11828 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11829 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11830 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11831 
11832 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11833 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11834 
11835 	// EC Public Key Attributes
11836 	ByteString group;
11837 	ByteString point;
11838 	if (isKeyPrivate)
11839 	{
11840 		bool bOK = true;
11841 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group);
11842 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_POINT), point);
11843 		if (!bOK)
11844 			return CKR_GENERAL_ERROR;
11845 	}
11846 	else
11847 	{
11848 		group = key->getByteStringValue(CKA_EC_PARAMS);
11849 		point = key->getByteStringValue(CKA_EC_POINT);
11850 	}
11851 
11852 	publicKey->setEC(group);
11853 	publicKey->setQ(point);
11854 
11855 	return CKR_OK;
11856 }
11857 
getEDPrivateKey(EDPrivateKey * privateKey,Token * token,OSObject * key)11858 CK_RV SoftHSM::getEDPrivateKey(EDPrivateKey* privateKey, Token* token, OSObject* key)
11859 {
11860 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11861 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11862 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11863 
11864 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11865 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11866 
11867 	// EDDSA Private Key Attributes
11868 	ByteString group;
11869 	ByteString value;
11870 	if (isKeyPrivate)
11871 	{
11872 		bool bOK = true;
11873 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group);
11874 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
11875 		if (!bOK)
11876 			return CKR_GENERAL_ERROR;
11877 	}
11878 	else
11879 	{
11880 		group = key->getByteStringValue(CKA_EC_PARAMS);
11881 		value = key->getByteStringValue(CKA_VALUE);
11882 	}
11883 
11884 	privateKey->setEC(group);
11885 	privateKey->setK(value);
11886 
11887 	return CKR_OK;
11888 }
11889 
getEDPublicKey(EDPublicKey * publicKey,Token * token,OSObject * key)11890 CK_RV SoftHSM::getEDPublicKey(EDPublicKey* publicKey, Token* token, OSObject* key)
11891 {
11892 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11893 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11894 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11895 
11896 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11897 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11898 
11899 	// EC Public Key Attributes
11900 	ByteString group;
11901 	ByteString value;
11902 	if (isKeyPrivate)
11903 	{
11904 		bool bOK = true;
11905 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group);
11906 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_POINT), value);
11907 		if (!bOK)
11908 			return CKR_GENERAL_ERROR;
11909 	}
11910 	else
11911 	{
11912 		group = key->getByteStringValue(CKA_EC_PARAMS);
11913 		value = key->getByteStringValue(CKA_EC_POINT);
11914 	}
11915 
11916 	publicKey->setEC(group);
11917 	publicKey->setA(value);
11918 
11919 	return CKR_OK;
11920 }
11921 
getDHPrivateKey(DHPrivateKey * privateKey,Token * token,OSObject * key)11922 CK_RV SoftHSM::getDHPrivateKey(DHPrivateKey* privateKey, Token* token, OSObject* key)
11923 {
11924 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11925 	if (token == NULL) return CKR_ARGUMENTS_BAD;
11926 	if (key == NULL) return CKR_ARGUMENTS_BAD;
11927 
11928 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
11929 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
11930 
11931 	// DH Private Key Attributes
11932 	ByteString prime;
11933 	ByteString generator;
11934 	ByteString value;
11935 	if (isKeyPrivate)
11936 	{
11937 		bool bOK = true;
11938 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_PRIME), prime);
11939 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_BASE), generator);
11940 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
11941 		if (!bOK)
11942 			return CKR_GENERAL_ERROR;
11943 	}
11944 	else
11945 	{
11946 		prime = key->getByteStringValue(CKA_PRIME);
11947 		generator = key->getByteStringValue(CKA_BASE);
11948 		value = key->getByteStringValue(CKA_VALUE);
11949 	}
11950 
11951 	privateKey->setP(prime);
11952 	privateKey->setG(generator);
11953 	privateKey->setX(value);
11954 
11955 	return CKR_OK;
11956 }
11957 
getDHPublicKey(DHPublicKey * publicKey,DHPrivateKey * privateKey,ByteString & pubParams)11958 CK_RV SoftHSM::getDHPublicKey(DHPublicKey* publicKey, DHPrivateKey* privateKey, ByteString& pubParams)
11959 {
11960 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11961 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11962 
11963 	// Copy Domain Parameters from Private Key
11964 	publicKey->setP(privateKey->getP());
11965 	publicKey->setG(privateKey->getG());
11966 
11967 	// Set value
11968 	publicKey->setY(pubParams);
11969 
11970 	return CKR_OK;
11971 }
11972 
getECDHPublicKey(ECPublicKey * publicKey,ECPrivateKey * privateKey,ByteString & pubData)11973 CK_RV SoftHSM::getECDHPublicKey(ECPublicKey* publicKey, ECPrivateKey* privateKey, ByteString& pubData)
11974 {
11975 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11976 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11977 
11978 	// Copy Domain Parameters from Private Key
11979 	publicKey->setEC(privateKey->getEC());
11980 
11981 	// Set value
11982 	ByteString data = getECDHPubData(pubData);
11983 	publicKey->setQ(data);
11984 
11985 	return CKR_OK;
11986 }
11987 
getEDDHPublicKey(EDPublicKey * publicKey,EDPrivateKey * privateKey,ByteString & pubData)11988 CK_RV SoftHSM::getEDDHPublicKey(EDPublicKey* publicKey, EDPrivateKey* privateKey, ByteString& pubData)
11989 {
11990 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
11991 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
11992 
11993 	// Copy Domain Parameters from Private Key
11994 	publicKey->setEC(privateKey->getEC());
11995 
11996 	// Set value
11997 	ByteString data = getECDHPubData(pubData);
11998 	publicKey->setA(data);
11999 
12000 	return CKR_OK;
12001 }
12002 
12003 // ECDH pubData can be in RAW or DER format.
12004 // Need to convert RAW as SoftHSM uses DER.
getECDHPubData(ByteString & pubData)12005 ByteString SoftHSM::getECDHPubData(ByteString& pubData)
12006 {
12007 	size_t len = pubData.size();
12008 	size_t controlOctets = 2;
12009 	if (len == 32 || len == 56 || len == 65 || len == 97 || len == 133)
12010 	{
12011 		// Raw: Length matches the public key size of:
12012 		// EDDSA: X25519, X448
12013 		// ECDSA: P-256, P-384, or P-521
12014 		controlOctets = 0;
12015 	}
12016 	else if (len < controlOctets || pubData[0] != 0x04)
12017 	{
12018 		// Raw: Too short or does not start with 0x04
12019 		controlOctets = 0;
12020 	}
12021 	else if (pubData[1] < 0x80)
12022 	{
12023 		// Raw: Length octet does not match remaining data length
12024 		if (pubData[1] != (len - controlOctets)) controlOctets = 0;
12025 	}
12026 	else
12027 	{
12028 		size_t lengthOctets = pubData[1] & 0x7F;
12029 		controlOctets += lengthOctets;
12030 
12031 		if (controlOctets >= len)
12032 		{
12033 			// Raw: Too short
12034 			controlOctets = 0;
12035 		}
12036 		else
12037 		{
12038 			ByteString length(&pubData[2], lengthOctets);
12039 
12040 			if (length.long_val() != (len - controlOctets))
12041 			{
12042 				// Raw: Length octets does not match remaining data length
12043 				controlOctets = 0;
12044 			}
12045 		}
12046 	}
12047 
12048 	// DER format
12049 	if (controlOctets != 0) return pubData;
12050 
12051 	return DERUTIL::raw2Octet(pubData);
12052 }
12053 
getGOSTPrivateKey(GOSTPrivateKey * privateKey,Token * token,OSObject * key)12054 CK_RV SoftHSM::getGOSTPrivateKey(GOSTPrivateKey* privateKey, Token* token, OSObject* key)
12055 {
12056 	if (privateKey == NULL) return CKR_ARGUMENTS_BAD;
12057 	if (token == NULL) return CKR_ARGUMENTS_BAD;
12058 	if (key == NULL) return CKR_ARGUMENTS_BAD;
12059 
12060 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
12061 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
12062 
12063 	// GOST Private Key Attributes
12064 	ByteString value;
12065 	ByteString param;
12066 	if (isKeyPrivate)
12067 	{
12068 		bool bOK = true;
12069 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value);
12070 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_GOSTR3410_PARAMS), param);
12071 		if (!bOK)
12072 			return CKR_GENERAL_ERROR;
12073 	}
12074 	else
12075 	{
12076 		value = key->getByteStringValue(CKA_VALUE);
12077 		param = key->getByteStringValue(CKA_GOSTR3410_PARAMS);
12078 	}
12079 
12080 	privateKey->setD(value);
12081 	privateKey->setEC(param);
12082 
12083 	return CKR_OK;
12084 }
12085 
getGOSTPublicKey(GOSTPublicKey * publicKey,Token * token,OSObject * key)12086 CK_RV SoftHSM::getGOSTPublicKey(GOSTPublicKey* publicKey, Token* token, OSObject* key)
12087 {
12088 	if (publicKey == NULL) return CKR_ARGUMENTS_BAD;
12089 	if (token == NULL) return CKR_ARGUMENTS_BAD;
12090 	if (key == NULL) return CKR_ARGUMENTS_BAD;
12091 
12092 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
12093 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
12094 
12095 	// GOST Public Key Attributes
12096 	ByteString point;
12097 	ByteString param;
12098 	if (isKeyPrivate)
12099 	{
12100 		bool bOK = true;
12101 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), point);
12102 		bOK = bOK && token->decrypt(key->getByteStringValue(CKA_GOSTR3410_PARAMS), param);
12103 		if (!bOK)
12104 			return CKR_GENERAL_ERROR;
12105 	}
12106 	else
12107 	{
12108 		point = key->getByteStringValue(CKA_VALUE);
12109 		param = key->getByteStringValue(CKA_GOSTR3410_PARAMS);
12110 	}
12111 
12112 	publicKey->setQ(point);
12113 	publicKey->setEC(param);
12114 
12115 	return CKR_OK;
12116 }
12117 
getSymmetricKey(SymmetricKey * skey,Token * token,OSObject * key)12118 CK_RV SoftHSM::getSymmetricKey(SymmetricKey* skey, Token* token, OSObject* key)
12119 {
12120 	if (skey == NULL) return CKR_ARGUMENTS_BAD;
12121 	if (token == NULL) return CKR_ARGUMENTS_BAD;
12122 	if (key == NULL) return CKR_ARGUMENTS_BAD;
12123 
12124 	// Get the CKA_PRIVATE attribute, when the attribute is not present use default false
12125 	bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false);
12126 
12127 	ByteString keybits;
12128 	if (isKeyPrivate)
12129 	{
12130 		if (!token->decrypt(key->getByteStringValue(CKA_VALUE), keybits))
12131 			return CKR_GENERAL_ERROR;
12132 	}
12133 	else
12134 	{
12135 		keybits = key->getByteStringValue(CKA_VALUE);
12136 	}
12137 
12138 	skey->setKeyBits(keybits);
12139 
12140 	return CKR_OK;
12141 }
12142 
setRSAPrivateKey(OSObject * key,const ByteString & ber,Token * token,bool isPrivate) const12143 bool SoftHSM::setRSAPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate) const
12144 {
12145 	AsymmetricAlgorithm* rsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
12146 	if (rsa == NULL)
12147 		return false;
12148 	PrivateKey* priv = rsa->newPrivateKey();
12149 	if (priv == NULL)
12150 	{
12151 		CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
12152 		return false;
12153 	}
12154 	if (!priv->PKCS8Decode(ber))
12155 	{
12156 		rsa->recyclePrivateKey(priv);
12157 		CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
12158 		return false;
12159 	}
12160 	// RSA Private Key Attributes
12161 	ByteString modulus;
12162 	ByteString publicExponent;
12163 	ByteString privateExponent;
12164 	ByteString prime1;
12165 	ByteString prime2;
12166 	ByteString exponent1;
12167 	ByteString exponent2;
12168 	ByteString coefficient;
12169 	if (isPrivate)
12170 	{
12171 		token->encrypt(((RSAPrivateKey*)priv)->getN(), modulus);
12172 		token->encrypt(((RSAPrivateKey*)priv)->getE(), publicExponent);
12173 		token->encrypt(((RSAPrivateKey*)priv)->getD(), privateExponent);
12174 		token->encrypt(((RSAPrivateKey*)priv)->getP(), prime1);
12175 		token->encrypt(((RSAPrivateKey*)priv)->getQ(), prime2);
12176 		token->encrypt(((RSAPrivateKey*)priv)->getDP1(), exponent1);
12177 		token->encrypt(((RSAPrivateKey*)priv)->getDQ1(), exponent2);
12178 		token->encrypt(((RSAPrivateKey*)priv)->getPQ(), coefficient);
12179 	}
12180 	else
12181 	{
12182 		modulus = ((RSAPrivateKey*)priv)->getN();
12183 		publicExponent = ((RSAPrivateKey*)priv)->getE();
12184 		privateExponent = ((RSAPrivateKey*)priv)->getD();
12185 		prime1 = ((RSAPrivateKey*)priv)->getP();
12186 		prime2 = ((RSAPrivateKey*)priv)->getQ();
12187 		exponent1 =  ((RSAPrivateKey*)priv)->getDP1();
12188 		exponent2 = ((RSAPrivateKey*)priv)->getDQ1();
12189 		coefficient = ((RSAPrivateKey*)priv)->getPQ();
12190 	}
12191 	bool bOK = true;
12192 	bOK = bOK && key->setAttribute(CKA_MODULUS, modulus);
12193 	bOK = bOK && key->setAttribute(CKA_PUBLIC_EXPONENT, publicExponent);
12194 	bOK = bOK && key->setAttribute(CKA_PRIVATE_EXPONENT, privateExponent);
12195 	bOK = bOK && key->setAttribute(CKA_PRIME_1, prime1);
12196 	bOK = bOK && key->setAttribute(CKA_PRIME_2, prime2);
12197 	bOK = bOK && key->setAttribute(CKA_EXPONENT_1,exponent1);
12198 	bOK = bOK && key->setAttribute(CKA_EXPONENT_2, exponent2);
12199 	bOK = bOK && key->setAttribute(CKA_COEFFICIENT, coefficient);
12200 
12201 	rsa->recyclePrivateKey(priv);
12202 	CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
12203 
12204 	return bOK;
12205 }
12206 
setDSAPrivateKey(OSObject * key,const ByteString & ber,Token * token,bool isPrivate) const12207 bool SoftHSM::setDSAPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate) const
12208 {
12209 	AsymmetricAlgorithm* dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
12210 	if (dsa == NULL)
12211 		return false;
12212 	PrivateKey* priv = dsa->newPrivateKey();
12213 	if (priv == NULL)
12214 	{
12215 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
12216 		return false;
12217 	}
12218 	if (!priv->PKCS8Decode(ber))
12219 	{
12220 		dsa->recyclePrivateKey(priv);
12221 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
12222 		return false;
12223 	}
12224 	// DSA Private Key Attributes
12225 	ByteString prime;
12226 	ByteString subprime;
12227 	ByteString generator;
12228 	ByteString value;
12229 	if (isPrivate)
12230 	{
12231 		token->encrypt(((DSAPrivateKey*)priv)->getP(), prime);
12232 		token->encrypt(((DSAPrivateKey*)priv)->getQ(), subprime);
12233 		token->encrypt(((DSAPrivateKey*)priv)->getG(), generator);
12234 		token->encrypt(((DSAPrivateKey*)priv)->getX(), value);
12235 	}
12236 	else
12237 	{
12238 		prime = ((DSAPrivateKey*)priv)->getP();
12239 		subprime = ((DSAPrivateKey*)priv)->getQ();
12240 		generator = ((DSAPrivateKey*)priv)->getG();
12241 		value = ((DSAPrivateKey*)priv)->getX();
12242 	}
12243 	bool bOK = true;
12244 	bOK = bOK && key->setAttribute(CKA_PRIME, prime);
12245 	bOK = bOK && key->setAttribute(CKA_SUBPRIME, subprime);
12246 	bOK = bOK && key->setAttribute(CKA_BASE, generator);
12247 	bOK = bOK && key->setAttribute(CKA_VALUE, value);
12248 
12249 	dsa->recyclePrivateKey(priv);
12250 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
12251 
12252 	return bOK;
12253 }
12254 
setDHPrivateKey(OSObject * key,const ByteString & ber,Token * token,bool isPrivate) const12255 bool SoftHSM::setDHPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate) const
12256 {
12257 	AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
12258 	if (dh == NULL)
12259 		return false;
12260 	PrivateKey* priv = dh->newPrivateKey();
12261 	if (priv == NULL)
12262 	{
12263 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
12264 		return false;
12265 	}
12266 	if (!priv->PKCS8Decode(ber))
12267 	{
12268 		dh->recyclePrivateKey(priv);
12269 		CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
12270 		return false;
12271 	}
12272 	// DH Private Key Attributes
12273 	ByteString prime;
12274 	ByteString generator;
12275 	ByteString value;
12276 	if (isPrivate)
12277 	{
12278 		token->encrypt(((DHPrivateKey*)priv)->getP(), prime);
12279 		token->encrypt(((DHPrivateKey*)priv)->getG(), generator);
12280 		token->encrypt(((DHPrivateKey*)priv)->getX(), value);
12281 	}
12282 	else
12283 	{
12284 		prime = ((DHPrivateKey*)priv)->getP();
12285 		generator = ((DHPrivateKey*)priv)->getG();
12286 		value = ((DHPrivateKey*)priv)->getX();
12287 	}
12288 	bool bOK = true;
12289 	bOK = bOK && key->setAttribute(CKA_PRIME, prime);
12290 	bOK = bOK && key->setAttribute(CKA_BASE, generator);
12291 	bOK = bOK && key->setAttribute(CKA_VALUE, value);
12292 
12293 	dh->recyclePrivateKey(priv);
12294 	CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
12295 
12296 	return bOK;
12297 }
12298 
setECPrivateKey(OSObject * key,const ByteString & ber,Token * token,bool isPrivate) const12299 bool SoftHSM::setECPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate) const
12300 {
12301 	AsymmetricAlgorithm* ecc = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
12302 	if (ecc == NULL)
12303 		return false;
12304 	PrivateKey* priv = ecc->newPrivateKey();
12305 	if (priv == NULL)
12306 	{
12307 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecc);
12308 		return false;
12309 	}
12310 	if (!priv->PKCS8Decode(ber))
12311 	{
12312 		ecc->recyclePrivateKey(priv);
12313 		CryptoFactory::i()->recycleAsymmetricAlgorithm(ecc);
12314 		return false;
12315 	}
12316 	// EC Private Key Attributes
12317 	ByteString group;
12318 	ByteString value;
12319 	if (isPrivate)
12320 	{
12321 		token->encrypt(((ECPrivateKey*)priv)->getEC(), group);
12322 		token->encrypt(((ECPrivateKey*)priv)->getD(), value);
12323 	}
12324 	else
12325 	{
12326 		group = ((ECPrivateKey*)priv)->getEC();
12327 		value = ((ECPrivateKey*)priv)->getD();
12328 	}
12329 	bool bOK = true;
12330 	bOK = bOK && key->setAttribute(CKA_EC_PARAMS, group);
12331 	bOK = bOK && key->setAttribute(CKA_VALUE, value);
12332 
12333 	ecc->recyclePrivateKey(priv);
12334 	CryptoFactory::i()->recycleAsymmetricAlgorithm(ecc);
12335 
12336 	return bOK;
12337 }
12338 
setGOSTPrivateKey(OSObject * key,const ByteString & ber,Token * token,bool isPrivate) const12339 bool SoftHSM::setGOSTPrivateKey(OSObject* key, const ByteString &ber, Token* token, bool isPrivate) const
12340 {
12341 	AsymmetricAlgorithm* gost = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
12342 	if (gost == NULL)
12343 		return false;
12344 	PrivateKey* priv = gost->newPrivateKey();
12345 	if (priv == NULL)
12346 	{
12347 		CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
12348 		return false;
12349 	}
12350 	if (!priv->PKCS8Decode(ber))
12351 	{
12352 		gost->recyclePrivateKey(priv);
12353 		CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
12354 		return false;
12355 	}
12356 	// GOST Private Key Attributes
12357 	ByteString value;
12358 	ByteString param_a;
12359 	if (isPrivate)
12360 	{
12361 		token->encrypt(((GOSTPrivateKey*)priv)->getD(), value);
12362 		token->encrypt(((GOSTPrivateKey*)priv)->getEC(), param_a);
12363 	}
12364 	else
12365 	{
12366 		value = ((GOSTPrivateKey*)priv)->getD();
12367 		param_a = ((GOSTPrivateKey*)priv)->getEC();
12368 	}
12369 	bool bOK = true;
12370 	bOK = bOK && key->setAttribute(CKA_VALUE, value);
12371 	bOK = bOK && key->setAttribute(CKA_GOSTR3410_PARAMS, param_a);
12372 
12373 	gost->recyclePrivateKey(priv);
12374 	CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
12375 
12376 	return bOK;
12377 }
12378 
MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism)12379 CK_RV SoftHSM::MechParamCheckRSAPKCSOAEP(CK_MECHANISM_PTR pMechanism)
12380 {
12381 	// This is a programming error
12382 	if (pMechanism->mechanism != CKM_RSA_PKCS_OAEP) {
12383 		ERROR_MSG("MechParamCheckRSAPKCSOAEP called on wrong mechanism");
12384 		return CKR_GENERAL_ERROR;
12385 	}
12386 
12387 	if (pMechanism->pParameter == NULL_PTR ||
12388 	    pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS))
12389 	{
12390 		ERROR_MSG("pParameter must be of type CK_RSA_PKCS_OAEP_PARAMS");
12391 		return CKR_ARGUMENTS_BAD;
12392 	}
12393 
12394 	CK_RSA_PKCS_OAEP_PARAMS_PTR params = (CK_RSA_PKCS_OAEP_PARAMS_PTR)pMechanism->pParameter;
12395 	if (params->hashAlg != CKM_SHA_1)
12396 	{
12397 		ERROR_MSG("hashAlg must be CKM_SHA_1");
12398 		return CKR_ARGUMENTS_BAD;
12399 	}
12400 	if (params->mgf != CKG_MGF1_SHA1)
12401 	{
12402 		ERROR_MSG("mgf must be CKG_MGF1_SHA1");
12403 		return CKR_ARGUMENTS_BAD;
12404 	}
12405 	if (params->source != CKZ_DATA_SPECIFIED)
12406 	{
12407 		ERROR_MSG("source must be CKZ_DATA_SPECIFIED");
12408 		return CKR_ARGUMENTS_BAD;
12409 	}
12410 	if (params->pSourceData != NULL)
12411 	{
12412 		ERROR_MSG("pSourceData must be NULL");
12413 		return CKR_ARGUMENTS_BAD;
12414 	}
12415 	if (params->ulSourceDataLen != 0)
12416 	{
12417 		ERROR_MSG("ulSourceDataLen must be 0");
12418 		return CKR_ARGUMENTS_BAD;
12419 	}
12420 	return CKR_OK;
12421 }
12422 
isMechanismPermitted(OSObject * key,CK_MECHANISM_PTR pMechanism)12423 bool SoftHSM::isMechanismPermitted(OSObject* key, CK_MECHANISM_PTR pMechanism)
12424 {
12425 	std::list<CK_MECHANISM_TYPE> mechs = supportedMechanisms;
12426 	/* First check if the algorithm is enabled in the global configuration */
12427 	auto it = std::find(mechs.begin(), mechs.end(), pMechanism->mechanism);
12428 	if (it == mechs.end())
12429 		return false;
12430 
12431 	OSAttribute attribute = key->getAttribute(CKA_ALLOWED_MECHANISMS);
12432 	std::set<CK_MECHANISM_TYPE> allowed = attribute.getMechanismTypeSetValue();
12433 
12434 	if (allowed.empty()) {
12435 		return true;
12436 	}
12437 
12438 	return allowed.find(pMechanism->mechanism) != allowed.end();
12439 }
12440 
detectFork(void)12441 bool SoftHSM::detectFork(void) {
12442 #ifdef _WIN32
12443 	return forkID != _getpid();
12444 #else
12445 	return forkID != getpid();
12446 #endif
12447 }
12448