1 /*
2  * Copyright (c) 2012 SURFnet
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*****************************************************************************
28  SymmetricAlgorithmTests.cpp
29 
30  Contains test cases for symmetrical algorithms (i.e., AES and DES)
31  *****************************************************************************/
32 
33 #include <config.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <climits>
37 //#include <iomanip>
38 #include "SymmetricAlgorithmTests.h"
39 
40 // CKA_TOKEN
41 const CK_BBOOL ON_TOKEN = CK_TRUE;
42 const CK_BBOOL IN_SESSION = CK_FALSE;
43 
44 // CKA_PRIVATE
45 const CK_BBOOL IS_PRIVATE = CK_TRUE;
46 const CK_BBOOL IS_PUBLIC = CK_FALSE;
47 
48 #define NR_OF_BLOCKS_IN_TEST 0x10001
49 
50 CPPUNIT_TEST_SUITE_REGISTRATION(SymmetricAlgorithmTests);
51 
generateGenericKey(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)52 CK_RV SymmetricAlgorithmTests::generateGenericKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
53 {
54 	CK_MECHANISM mechanism = { CKM_GENERIC_SECRET_KEY_GEN, NULL_PTR, 0 };
55 	CK_ULONG bytes = 16;
56 	// CK_BBOOL bFalse = CK_FALSE;
57 	CK_BBOOL bTrue = CK_TRUE;
58 	CK_ATTRIBUTE keyAttribs[] = {
59 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
60 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
61 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
62 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
63 		{ CKA_WRAP, &bTrue, sizeof(bTrue) },
64 		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
65 		{ CKA_VALUE_LEN, &bytes, sizeof(bytes) },
66 	};
67 
68 	hKey = CK_INVALID_HANDLE;
69 	return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
70 			     keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
71 			     &hKey) );
72 }
73 
generateAesKey(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)74 CK_RV SymmetricAlgorithmTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
75 {
76 	CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
77 	CK_ULONG bytes = 16;
78 	// CK_BBOOL bFalse = CK_FALSE;
79 	CK_BBOOL bTrue = CK_TRUE;
80 	CK_ATTRIBUTE keyAttribs[] = {
81 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
82 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
83 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
84 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
85 		{ CKA_WRAP, &bTrue, sizeof(bTrue) },
86 		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
87 		{ CKA_VALUE_LEN, &bytes, sizeof(bytes) },
88 	};
89 
90 	hKey = CK_INVALID_HANDLE;
91 	return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
92 			     keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
93 			     &hKey) );
94 }
95 
96 #ifndef WITH_FIPS
generateDesKey(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)97 CK_RV SymmetricAlgorithmTests::generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
98 {
99 	CK_MECHANISM mechanism = { CKM_DES_KEY_GEN, NULL_PTR, 0 };
100 	// CK_BBOOL bFalse = CK_FALSE;
101 	CK_BBOOL bTrue = CK_TRUE;
102 	CK_ATTRIBUTE keyAttribs[] = {
103 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
104 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
105 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
106 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
107 	};
108 
109 	hKey = CK_INVALID_HANDLE;
110 	return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
111 			     keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
112 			     &hKey) );
113 }
114 
generateDes2Key(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)115 CK_RV SymmetricAlgorithmTests::generateDes2Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
116 {
117 	CK_MECHANISM mechanism = { CKM_DES2_KEY_GEN, NULL_PTR, 0 };
118 	// CK_BBOOL bFalse = CK_FALSE;
119 	CK_BBOOL bTrue = CK_TRUE;
120 	CK_ATTRIBUTE keyAttribs[] = {
121 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
122 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
123 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
124 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
125 	};
126 
127 	hKey = CK_INVALID_HANDLE;
128 	return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
129 			     keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
130 			     &hKey) );
131 }
132 #endif
133 
generateDes3Key(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)134 CK_RV SymmetricAlgorithmTests::generateDes3Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
135 {
136 	CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
137 	// CK_BBOOL bFalse = CK_FALSE;
138 	CK_BBOOL bTrue = CK_TRUE;
139 	CK_ATTRIBUTE keyAttribs[] = {
140 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
141 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
142 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
143 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
144 	};
145 
146 	hKey = CK_INVALID_HANDLE;
147 	return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
148 			     keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
149 			     &hKey) );
150 }
151 
encryptDecrypt(const CK_MECHANISM_TYPE mechanismType,const size_t blockSize,const CK_SESSION_HANDLE hSession,const CK_OBJECT_HANDLE hKey,const size_t messageSize,const bool isSizeOK)152 void SymmetricAlgorithmTests::encryptDecrypt(
153 		const CK_MECHANISM_TYPE mechanismType,
154 		const size_t blockSize,
155 		const CK_SESSION_HANDLE hSession,
156 		const CK_OBJECT_HANDLE hKey,
157 		const size_t messageSize,
158 		const bool isSizeOK)
159 {
160 	class PartSize {// class to get random size for part
161 	private:        // we want to know for sure that no part length is causing any problem.
162 		const int blockSize;
163 		const unsigned* pRandom;// point to memory with random data. We are using the data to be encrypted.
164 		const unsigned* pBack;// point to memory where random data ends.
165 		int current;// the current size.
166 	public:
167 		PartSize(
168 				const int _blockSize,
169 				const std::vector<CK_BYTE>* pvData) :
170 					blockSize(_blockSize),
171 					pRandom((const unsigned*)&pvData->front()),
172 					pBack((const unsigned*)&pvData->back()),
173 					current(blockSize*4){};
174 		int getCurrent() {// current part size
175 			return current;
176 		}
177 		int getNext() {// get next part size.
178 			// Check if we do not have more random data
179 			if ((pRandom+sizeof(unsigned)-1) > pBack) {
180 				current = blockSize*4;
181 				return current;
182 			}
183 			const unsigned random(*(pRandom++));
184 			// Bit shift to handle 32- and 64-bit systems.
185 			// Just want a simple random part length,
186 			// not a perfect random number (bit shifting will
187 			// give some loss of precision).
188 			current = ((unsigned long)random >> 20)*blockSize*0x100/(UINT_MAX >> 20) + 1;
189 			//std::cout << "New random " << std::hex << random << " current " << std::hex << std::setfill('0') << std::setw(4) << current << " block size " << std::hex << blockSize << std::endl;
190 			return current;
191 		}
192 	};
193 
194 	const std::vector<CK_BYTE> vData(messageSize);
195 	std::vector<CK_BYTE> vEncryptedData;
196 	std::vector<CK_BYTE> vEncryptedDataParted;
197 	PartSize partSize(blockSize, &vData);
198 
199 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_GenerateRandom(hSession, (CK_BYTE_PTR)&vData.front(), messageSize) ) );
200 
201 	const CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
202 	CK_MECHANISM_PTR pMechanism((CK_MECHANISM_PTR)&mechanism);
203 	CK_AES_CTR_PARAMS ctrParams =
204 	{
205 		32,
206 		{
207 			0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
208 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
209 		}
210 	};
211 	CK_BYTE gcmIV[] = {
212 		0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE,
213 		0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88
214 	};
215 	CK_BYTE gcmAAD[] = {
216 		0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
217 		0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
218 		0xAB, 0xAD, 0xDA, 0xD2
219 	};
220 	CK_GCM_PARAMS gcmParams =
221 	{
222 		&gcmIV[0],
223 		sizeof(gcmIV),
224 		sizeof(gcmIV)*8,
225 		&gcmAAD[0],
226 		sizeof(gcmAAD),
227 		16*8
228 	};
229 
230 	switch (mechanismType)
231 	{
232 		case CKM_DES_CBC:
233 		case CKM_DES_CBC_PAD:
234 		case CKM_DES3_CBC:
235 		case CKM_DES3_CBC_PAD:
236 		case CKM_AES_CBC:
237 		case CKM_AES_CBC_PAD:
238 			pMechanism->pParameter = (CK_VOID_PTR)&vData.front();
239 			pMechanism->ulParameterLen = blockSize;
240 			break;
241 		case CKM_AES_CTR:
242 			pMechanism->pParameter = &ctrParams;
243 			pMechanism->ulParameterLen = sizeof(ctrParams);
244 			break;
245 		case CKM_AES_GCM:
246 			pMechanism->pParameter = &gcmParams;
247 			pMechanism->ulParameterLen = sizeof(gcmParams);
248 			break;
249 		default:
250 			break;
251 	}
252 
253 	// Single-part encryption
254 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
255 	{
256 		CK_ULONG ulEncryptedDataLen;
257 		const CK_RV rv( CRYPTOKI_F_PTR( C_Encrypt(hSession,(CK_BYTE_PTR)&vData.front(),messageSize,NULL_PTR,&ulEncryptedDataLen) ) );
258 		if ( isSizeOK ) {
259 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
260 			vEncryptedData.resize(ulEncryptedDataLen);
261 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Encrypt(hSession,(CK_BYTE_PTR)&vData.front(),messageSize,&vEncryptedData.front(),&ulEncryptedDataLen) ) );
262 			vEncryptedData.resize(ulEncryptedDataLen);
263 		} else {
264 			CPPUNIT_ASSERT_EQUAL_MESSAGE("C_Encrypt should fail with C_CKR_DATA_LEN_RANGE", (CK_RV)CKR_DATA_LEN_RANGE, rv);
265 			vEncryptedData = vData;
266 		}
267 	}
268 
269 	// Multi-part encryption
270 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
271 
272 	for ( std::vector<CK_BYTE>::const_iterator i(vData.begin()); i<vData.end(); i+=partSize.getCurrent() ) {
273 		const CK_ULONG lPartLen( i+partSize.getNext()<vData.end() ? partSize.getCurrent() : vData.end()-i );
274 		CK_ULONG ulEncryptedPartLen;
275 		CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,(CK_BYTE_PTR)&(*i),lPartLen,NULL_PTR,&ulEncryptedPartLen) ) );
276 		const size_t oldSize( vEncryptedDataParted.size() );
277 		vEncryptedDataParted.resize(oldSize+ulEncryptedPartLen);
278 		CK_BYTE dummy;
279 		const CK_BYTE_PTR pEncryptedPart( ulEncryptedPartLen>0 ? &vEncryptedDataParted.at(oldSize) : &dummy );
280 		CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,(CK_BYTE_PTR)&(*i),lPartLen,pEncryptedPart,&ulEncryptedPartLen) ) );
281 		vEncryptedDataParted.resize(oldSize+ulEncryptedPartLen);
282 	}
283 	{
284 		CK_ULONG ulLastEncryptedPartLen;
285 		const CK_RV rv( CRYPTOKI_F_PTR( C_EncryptFinal(hSession,NULL_PTR,&ulLastEncryptedPartLen) ) );
286 		if ( isSizeOK ) {
287 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
288 			const size_t oldSize( vEncryptedDataParted.size() );
289 			CK_BYTE dummy;
290 			vEncryptedDataParted.resize(oldSize+ulLastEncryptedPartLen);
291 			const CK_BYTE_PTR pLastEncryptedPart( ulLastEncryptedPartLen>0 ? &vEncryptedDataParted.at(oldSize) : &dummy );
292 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptFinal(hSession,pLastEncryptedPart,&ulLastEncryptedPartLen) ) );
293 			vEncryptedDataParted.resize(oldSize+ulLastEncryptedPartLen);
294 		} else {
295 			CPPUNIT_ASSERT_EQUAL_MESSAGE("C_EncryptFinal should fail with C_CKR_DATA_LEN_RANGE", (CK_RV)CKR_DATA_LEN_RANGE, rv);
296 			vEncryptedDataParted = vData;
297 		}
298 	}
299 
300 	// Single-part decryption
301 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
302 
303 	{
304 		CK_ULONG ulDataLen;
305 		const CK_RV rv( CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataLen) ) );
306 		if ( isSizeOK ) {
307 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
308 			std::vector<CK_BYTE> vDecryptedData(ulDataLen);
309 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedData.front(),&ulDataLen) ) );
310 			vDecryptedData.resize(ulDataLen);
311 			CPPUNIT_ASSERT_MESSAGE("C_Encrypt C_Decrypt does not give the original", vData==vDecryptedData);
312 		} else {
313 			CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_Decrypt should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
314 		}
315 	}
316 
317 	// Multi-part decryption
318 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
319 	{
320 		std::vector<CK_BYTE> vDecryptedData;
321 		CK_BYTE dummy;
322 		for ( std::vector<CK_BYTE>::iterator i(vEncryptedDataParted.begin()); i<vEncryptedDataParted.end(); i+=partSize.getCurrent()) {
323 			const CK_ULONG ulPartLen( i+partSize.getNext()<vEncryptedDataParted.end() ? partSize.getCurrent() : vEncryptedDataParted.end()-i );
324 			CK_ULONG ulDecryptedPartLen;
325 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&(*i),ulPartLen,NULL_PTR,&ulDecryptedPartLen) ) );
326 			const size_t oldSize( vDecryptedData.size() );
327 			vDecryptedData.resize(oldSize+ulDecryptedPartLen);
328 			const CK_BYTE_PTR pDecryptedPart( ulDecryptedPartLen>0 ? &vDecryptedData.at(oldSize) : &dummy );
329 			CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&(*i),ulPartLen,pDecryptedPart,&ulDecryptedPartLen) ) );
330 			vDecryptedData.resize(oldSize+ulDecryptedPartLen);
331 		}
332 		{
333 			CK_ULONG ulLastPartLen;
334 			const CK_RV rv( CRYPTOKI_F_PTR( C_DecryptFinal(hSession,NULL_PTR,&ulLastPartLen) ) );
335 			if ( isSizeOK ) {
336 				CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
337 				const size_t oldSize( vDecryptedData.size() );
338 				vDecryptedData.resize(oldSize+ulLastPartLen);
339 				const CK_BYTE_PTR pLastPart( ulLastPartLen>0 ? &vDecryptedData.at(oldSize) : &dummy );
340 				CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptFinal(hSession,pLastPart,&ulLastPartLen) ) );
341 				vDecryptedData.resize(oldSize+ulLastPartLen);
342 				CPPUNIT_ASSERT_MESSAGE("C_EncryptUpdate/C_EncryptFinal C_DecryptUpdate/C_DecryptFinal does not give the original", vData==vDecryptedData);
343 			} else {
344 				CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_EncryptFinal should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
345 			}
346 		}
347 	}
348 }
349 
generateRsaPrivateKey(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)350 CK_RV SymmetricAlgorithmTests::generateRsaPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
351 {
352 	CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
353 	CK_ULONG bits = 1536;
354 	CK_BYTE pubExp[] = {0x01, 0x00, 0x01};
355 	CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
356 	CK_BYTE id[] = { 123 } ; // dummy
357 	CK_BBOOL bFalse = CK_FALSE;
358 	CK_BBOOL bTrue = CK_TRUE;
359 	CK_ATTRIBUTE pubAttribs[] = {
360 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
361 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
362 		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
363 		{ CKA_VERIFY, &bTrue, sizeof(bTrue) },
364 		{ CKA_WRAP, &bFalse, sizeof(bFalse) },
365 		{ CKA_MODULUS_BITS, &bits, sizeof(bits) },
366 		{ CKA_PUBLIC_EXPONENT, &pubExp[0], sizeof(pubExp) }
367 	};
368 	CK_ATTRIBUTE privAttribs[] = {
369 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
370 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
371 		{ CKA_SUBJECT, &subject[0], sizeof(subject) },
372 		{ CKA_ID, &id[0], sizeof(id) },
373 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
374 		{ CKA_DECRYPT, &bFalse, sizeof(bFalse) },
375 		{ CKA_SIGN, &bTrue, sizeof(bTrue) },
376 		{ CKA_UNWRAP, &bFalse, sizeof(bFalse) },
377 		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
378 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
379 	};
380 
381 	CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
382 	hKey = CK_INVALID_HANDLE;
383 	CK_RV rv;
384 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
385 			       pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
386 			       privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
387 			       &hPub, &hKey) );
388 	if (hPub != CK_INVALID_HANDLE)
389 	{
390 		CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
391 	}
392 	return rv;
393 }
394 
395 #ifdef WITH_GOST
generateGostPrivateKey(CK_SESSION_HANDLE hSession,CK_BBOOL bToken,CK_BBOOL bPrivate,CK_OBJECT_HANDLE & hKey)396 CK_RV SymmetricAlgorithmTests::generateGostPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
397 {
398 	CK_MECHANISM mechanism = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL_PTR, 0 };
399 	CK_BYTE param_a[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
400 	CK_BYTE param_b[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 };
401 	CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
402 	CK_BYTE id[] = { 123 } ; // dummy
403 	CK_BBOOL bFalse = CK_FALSE;
404 	CK_BBOOL bTrue = CK_TRUE;
405 	CK_ATTRIBUTE pubAttribs[] = {
406 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
407 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
408 		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
409 		{ CKA_VERIFY, &bTrue, sizeof(bTrue) },
410 		{ CKA_WRAP, &bFalse, sizeof(bFalse) },
411 		{ CKA_GOSTR3410_PARAMS, &param_a[0], sizeof(param_a) },
412 		{ CKA_GOSTR3411_PARAMS, &param_b[0], sizeof(param_b) }
413 	};
414 	CK_ATTRIBUTE privAttribs[] = {
415 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
416 		{ CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
417 		{ CKA_SUBJECT, &subject[0], sizeof(subject) },
418 		{ CKA_ID, &id[0], sizeof(id) },
419 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
420 		{ CKA_DECRYPT, &bFalse, sizeof(bFalse) },
421 		{ CKA_SIGN, &bTrue, sizeof(bTrue) },
422 		{ CKA_UNWRAP, &bFalse, sizeof(bFalse) },
423 		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
424 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
425 	};
426 
427 	CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
428 	hKey = CK_INVALID_HANDLE;
429 	CK_RV rv;
430 	rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
431 			       pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
432 			       privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
433 			       &hPub, &hKey) );
434 	if (hPub != CK_INVALID_HANDLE)
435 	{
436 		CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
437 	}
438 	return rv;
439 }
440 #endif
441 
aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismType,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)442 void SymmetricAlgorithmTests::aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
443 {
444 	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
445 	CK_BBOOL bFalse = CK_FALSE;
446 	CK_BBOOL bTrue = CK_TRUE;
447 	CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
448 	CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
449 	CK_BYTE keyPtr[128];
450 	CK_ULONG keyLen =
451 		mechanismType == CKM_AES_KEY_WRAP_PAD ? 125UL : 128UL;
452 	CK_ATTRIBUTE attribs[] = {
453 		{ CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
454 		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
455 		{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
456 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
457 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
458 		{ CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, // Wrapping is allowed even on sensitive objects
459 		{ CKA_VALUE, keyPtr, keyLen }
460 	};
461 	CK_OBJECT_HANDLE hSecret;
462 	CK_RV rv;
463 
464 	rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, keyPtr, keyLen) );
465 	CPPUNIT_ASSERT(rv == CKR_OK);
466 
467 	hSecret = CK_INVALID_HANDLE;
468 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
469 	CPPUNIT_ASSERT(rv == CKR_OK);
470 	CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
471 
472 	CK_BYTE_PTR wrappedPtr = NULL_PTR;
473 	CK_ULONG wrappedLen = 0UL;
474 	CK_ULONG zero = 0UL;
475 	CK_ULONG rndKeyLen = keyLen;
476 	if (mechanismType == CKM_AES_KEY_WRAP_PAD)
477 		rndKeyLen =  (keyLen + 7) & ~7;
478 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
479 	CPPUNIT_ASSERT(rv == CKR_KEY_UNEXTRACTABLE);
480 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
481 	CPPUNIT_ASSERT(rv == CKR_OK);
482 
483 	attribs[0].pValue = &bTrue;
484 
485 	hSecret = CK_INVALID_HANDLE;
486 	rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
487 	CPPUNIT_ASSERT(rv == CKR_OK);
488 	CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
489 
490 	// Estimate wrapped length
491 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
492 	CPPUNIT_ASSERT(rv == CKR_OK);
493 	CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);
494 
495 	wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
496 	CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
497 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
498 	CPPUNIT_ASSERT(rv == CKR_OK);
499 	CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);
500 
501 	// This should always fail because wrapped data have to be longer than 0 bytes
502 	zero = 0;
503 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero) );
504 	CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);
505 
506 	CK_ATTRIBUTE nattribs[] = {
507 		{ CKA_CLASS, &secretClass, sizeof(secretClass) },
508 		{ CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
509 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
510 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
511 		{ CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
512 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
513 		{ CKA_SIGN, &bFalse,sizeof(bFalse) },
514 		{ CKA_VERIFY, &bTrue, sizeof(bTrue) }
515 	};
516 	CK_OBJECT_HANDLE hNew;
517 
518 	hNew = CK_INVALID_HANDLE;
519 	rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nattribs, sizeof(nattribs)/sizeof(CK_ATTRIBUTE), &hNew) );
520 	CPPUNIT_ASSERT(rv == CKR_OK);
521 	CPPUNIT_ASSERT(hNew != CK_INVALID_HANDLE);
522 
523 	free(wrappedPtr);
524 	wrappedPtr = NULL_PTR;
525 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
526 	CPPUNIT_ASSERT(rv == CKR_OK);
527 }
528 
aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)529 void SymmetricAlgorithmTests::aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
530 {
531 	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
532 	CK_BBOOL bFalse = CK_FALSE;
533 	CK_BBOOL bTrue = CK_TRUE;
534 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
535 	CK_RV rv = generateRsaPrivateKey(hSession, CK_TRUE, CK_TRUE, hPrk);
536 	CPPUNIT_ASSERT(rv == CKR_OK);
537 	CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
538 
539 	CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY;
540 	CK_KEY_TYPE keyType = CKK_RSA;
541 	CK_BYTE_PTR prkAttrPtr = NULL_PTR;
542 	CK_ULONG prkAttrLen = 0UL;
543 	CK_ATTRIBUTE prkAttribs[] = {
544 		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
545 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
546 		{ CKA_PRIME_2, NULL_PTR, 0UL }
547 	};
548 
549 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
550 	CPPUNIT_ASSERT(rv == CKR_OK);
551 
552 	CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
553 	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
554 	CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
555 	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_RSA);
556 
557 	prkAttrLen = prkAttribs[2].ulValueLen;
558 	prkAttrPtr = (CK_BYTE_PTR) malloc(2 * prkAttrLen);
559 	CPPUNIT_ASSERT(prkAttrPtr != NULL_PTR);
560 	prkAttribs[2].pValue = prkAttrPtr;
561 	prkAttribs[2].ulValueLen = prkAttrLen;
562 
563 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
564 	CPPUNIT_ASSERT(rv == CKR_OK);
565 	CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
566 
567 	CK_BYTE_PTR wrappedPtr = NULL_PTR;
568 	CK_ULONG wrappedLen = 0UL;
569 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
570 	CPPUNIT_ASSERT(rv == CKR_OK);
571 	wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
572 	CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
573 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
574 	CPPUNIT_ASSERT(rv == CKR_OK);
575 
576 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
577 	CPPUNIT_ASSERT(rv == CKR_OK);
578 
579 	CK_ATTRIBUTE nPrkAttribs[] = {
580 		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
581 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
582 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
583 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
584 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
585 		{ CKA_SIGN, &bFalse,sizeof(bFalse) },
586 		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
587 		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
588 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
589 	};
590 
591 	hPrk = CK_INVALID_HANDLE;
592 	rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nPrkAttribs, sizeof(nPrkAttribs)/sizeof(CK_ATTRIBUTE), &hPrk) );
593 	CPPUNIT_ASSERT(rv == CKR_OK);
594 	CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
595 
596 	prkAttribs[2].pValue = prkAttrPtr + prkAttrLen;
597 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
598 	CPPUNIT_ASSERT(rv == CKR_OK);
599 
600 	CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
601 	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
602 	CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
603 	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_RSA);
604 	CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
605 	CPPUNIT_ASSERT(memcmp(prkAttrPtr, prkAttrPtr + prkAttrLen, prkAttrLen) == 0);
606 
607 	free(wrappedPtr);
608 	free(prkAttrPtr);
609 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
610 	CPPUNIT_ASSERT(rv == CKR_OK);
611 }
612 
613 #ifdef WITH_GOST
aesWrapUnwrapGost(CK_MECHANISM_TYPE mechanismType,CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hKey)614 void SymmetricAlgorithmTests::aesWrapUnwrapGost(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
615 {
616 	CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
617 	CK_BBOOL bFalse = CK_FALSE;
618 	CK_BBOOL bTrue = CK_TRUE;
619 	CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
620 	CK_RV rv = generateGostPrivateKey(hSession, CK_TRUE, CK_TRUE, hPrk);
621 	CPPUNIT_ASSERT(rv == CKR_OK);
622 	CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
623 
624 	CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY;
625 	CK_KEY_TYPE keyType = CKK_GOSTR3410;
626 	CK_BYTE_PTR prkAttrPtr = NULL_PTR;
627 	CK_ULONG prkAttrLen = 0UL;
628 	CK_ATTRIBUTE prkAttribs[] = {
629 		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
630 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
631 		{ CKA_VALUE, NULL_PTR, 0UL }
632 	};
633 
634 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
635 	CPPUNIT_ASSERT(rv == CKR_OK);
636 
637 	CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
638 	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
639 	CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
640 	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_GOSTR3410);
641 
642 	prkAttrLen = prkAttribs[2].ulValueLen;
643 	prkAttrPtr = (CK_BYTE_PTR) malloc(2 * prkAttrLen);
644 	CPPUNIT_ASSERT(prkAttrPtr != NULL_PTR);
645 	prkAttribs[2].pValue = prkAttrPtr;
646 	prkAttribs[2].ulValueLen = prkAttrLen;
647 
648 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
649 	CPPUNIT_ASSERT(rv == CKR_OK);
650 	CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
651 
652 	CK_BYTE_PTR wrappedPtr = NULL_PTR;
653 	CK_ULONG wrappedLen = 0UL;
654 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
655 	CPPUNIT_ASSERT(rv == CKR_OK);
656 	wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
657 	CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
658 	rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
659 	CPPUNIT_ASSERT(rv == CKR_OK);
660 
661 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
662 	CPPUNIT_ASSERT(rv == CKR_OK);
663 
664 	CK_ATTRIBUTE nPrkAttribs[] = {
665 		{ CKA_CLASS, &privateClass, sizeof(privateClass) },
666 		{ CKA_KEY_TYPE, &keyType, sizeof(keyType) },
667 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
668 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
669 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
670 		{ CKA_SIGN, &bFalse,sizeof(bFalse) },
671 		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
672 		{ CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
673 		{ CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
674 	};
675 
676 	hPrk = CK_INVALID_HANDLE;
677 	rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nPrkAttribs, sizeof(nPrkAttribs)/sizeof(CK_ATTRIBUTE), &hPrk) );
678 	CPPUNIT_ASSERT(rv == CKR_OK);
679 	CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
680 
681 	prkAttribs[2].pValue = prkAttrPtr + prkAttrLen;
682 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
683 	CPPUNIT_ASSERT(rv == CKR_OK);
684 
685 	CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
686 	CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
687 	CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
688 	CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_GOSTR3410);
689 	CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
690 	CPPUNIT_ASSERT(memcmp(prkAttrPtr, prkAttrPtr + prkAttrLen, prkAttrLen) == 0);
691 
692 	free(wrappedPtr);
693 	free(prkAttrPtr);
694 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
695 	CPPUNIT_ASSERT(rv == CKR_OK);
696 }
697 #endif
698 
testAesEncryptDecrypt()699 void SymmetricAlgorithmTests::testAesEncryptDecrypt()
700 {
701 	CK_RV rv;
702 	// CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
703 	// CK_ULONG sopinLength = sizeof(sopin) - 1;
704 	CK_SESSION_HANDLE hSessionRO;
705 	CK_SESSION_HANDLE hSessionRW;
706 
707 	// Just make sure that we finalize any previous tests
708 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
709 
710 	// Open read-only session on when the token is not initialized should fail
711 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
712 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
713 
714 	// Initialize the library and start the test.
715 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
716 	CPPUNIT_ASSERT(rv == CKR_OK);
717 
718 	// Open read-only session
719 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
720 	CPPUNIT_ASSERT(rv == CKR_OK);
721 
722 	// Open read-write session
723 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
724 	CPPUNIT_ASSERT(rv == CKR_OK);
725 
726 	// Login USER into the sessions so we can create a private objects
727 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
728 	CPPUNIT_ASSERT(rv==CKR_OK);
729 
730 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
731 
732 	// Generate all combinations of session/token keys.
733 	rv = generateAesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
734 	CPPUNIT_ASSERT(rv == CKR_OK);
735 
736 	// AES allways have the block size of 128 bits (0x80 bits 0x10 bytes).
737 	// with padding all message sizes could be encrypted-decrypted.
738 	// without padding the message size must be a multiple of the block size.
739 	const int blockSize(0x10);
740 	encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
741 	encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
742 	encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
743 	encryptDecrypt(CKM_AES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
744 	encryptDecrypt(CKM_AES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
745 	encryptDecrypt(CKM_AES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
746 	encryptDecrypt(CKM_AES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
747 	encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
748 	encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
749 	encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
750 	encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
751 	encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
752 	encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
753 }
754 
testAesWrapUnwrap()755 void SymmetricAlgorithmTests::testAesWrapUnwrap()
756 {
757 	CK_RV rv;
758 	// CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
759 	// CK_ULONG sopinLength = sizeof(sopin) - 1;
760 	CK_SESSION_HANDLE hSession;
761 
762 	// Just make sure that we finalize any previous tests
763 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
764 
765 	// Initialize the library and start the test.
766 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
767 	CPPUNIT_ASSERT(rv == CKR_OK);
768 
769 	// Open session
770 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
771 	CPPUNIT_ASSERT(rv == CKR_OK);
772 
773 	// Login USER into the session so we can create a private object
774 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
775 	CPPUNIT_ASSERT(rv==CKR_OK);
776 
777 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
778 
779 	// Generate a wrapping session public key
780 	rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
781 	CPPUNIT_ASSERT(rv == CKR_OK);
782 
783 	aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP, hSession, hKey);
784 	aesWrapUnwrapRsa(CKM_AES_KEY_WRAP, hSession, hKey);
785 #ifdef WITH_GOST
786 	aesWrapUnwrapGost(CKM_AES_KEY_WRAP, hSession, hKey);
787 #endif
788 
789 #ifdef HAVE_AES_KEY_WRAP_PAD
790 	aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
791 	aesWrapUnwrapRsa(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
792 #ifdef WITH_GOST
793 	aesWrapUnwrapGost(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
794 #endif
795 #endif
796 }
797 
testDesEncryptDecrypt()798 void SymmetricAlgorithmTests::testDesEncryptDecrypt()
799 {
800 	CK_RV rv;
801 	// CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
802 	// CK_ULONG sopinLength = sizeof(sopin) - 1;
803 	CK_SESSION_HANDLE hSessionRO;
804 	CK_SESSION_HANDLE hSessionRW;
805 
806 	// Just make sure that we finalize any previous tests
807 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
808 
809 	// Open read-only session on when the token is not initialized should fail
810 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
811 	CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
812 
813 	// Initialize the library and start the test.
814 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
815 	CPPUNIT_ASSERT(rv == CKR_OK);
816 
817 	// Open read-only session
818 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
819 	CPPUNIT_ASSERT(rv == CKR_OK);
820 
821 	// Open read-write session
822 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
823 	CPPUNIT_ASSERT(rv == CKR_OK);
824 
825 	// Login USER into the sessions so we can create a private objects
826 	rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
827 	CPPUNIT_ASSERT(rv==CKR_OK);
828 
829 	// 3DES and DES always have the block size of 64 bits (0x40 bits 0x8 bytes).
830 	// with padding all message sizes could be encrypted-decrypted.
831 	// without padding the message size must be a multiple of the block size.
832 	const int blockSize(0x8);
833 
834 #ifndef WITH_FIPS
835 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
836 
837 	// Generate all combinations of session/token keys.
838 	rv = generateDesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
839 	CPPUNIT_ASSERT(rv == CKR_OK);
840 
841 	encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
842 	encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
843 	encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
844 	encryptDecrypt(CKM_DES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
845 	encryptDecrypt(CKM_DES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
846 	encryptDecrypt(CKM_DES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
847 	encryptDecrypt(CKM_DES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
848 
849 	CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
850 
851 	// Generate all combinations of session/token keys.
852 	rv = generateDes2Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey2);
853 	CPPUNIT_ASSERT(rv == CKR_OK);
854 
855 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST-1);
856 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST+1);
857 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST);
858 	encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST);
859 	encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
860 	encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST);
861 	encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey2,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
862 #endif
863 
864 	CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
865 
866 	// Generate all combinations of session/token keys.
867 	rv = generateDes3Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey3);
868 	CPPUNIT_ASSERT(rv == CKR_OK);
869 
870 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST-1);
871 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST+1);
872 	encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST);
873 	encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST);
874 	encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
875 	encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST);
876 	encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey3,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
877 }
878 
testNullTemplate()879 void SymmetricAlgorithmTests::testNullTemplate()
880 {
881 	CK_RV rv;
882 	CK_SESSION_HANDLE hSession;
883 	CK_MECHANISM mechanism1 = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
884 	CK_MECHANISM mechanism2 = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
885 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
886 
887 	// Just make sure that we finalize any previous tests
888 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
889 
890 	// Initialize the library and start the test.
891 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
892 	CPPUNIT_ASSERT(rv == CKR_OK);
893 
894 	// Open read-write session
895 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
896 	CPPUNIT_ASSERT(rv == CKR_OK);
897 
898 	// Login USER into the sessions so we can create a private objects
899 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
900 	CPPUNIT_ASSERT(rv==CKR_OK);
901 
902 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism1, NULL_PTR, 0, &hKey) );
903 	CPPUNIT_ASSERT(rv == CKR_OK);
904 
905 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism1, NULL_PTR, 1, &hKey) );
906 	CPPUNIT_ASSERT(rv == CKR_ARGUMENTS_BAD);
907 
908 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
909 	CPPUNIT_ASSERT(rv == CKR_OK);
910 
911 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism2, NULL_PTR, 0, &hKey) );
912 	CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCOMPLETE);
913 }
914 
testNonModifiableDesKeyGeneration()915 void SymmetricAlgorithmTests::testNonModifiableDesKeyGeneration()
916 {
917 	CK_RV rv;
918 	CK_SESSION_HANDLE hSession;
919 	CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
920 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
921 	CK_BBOOL bFalse = CK_FALSE;
922 	CK_BBOOL bTrue = CK_TRUE;
923 	CK_BBOOL bToken = IN_SESSION;
924 
925 	CK_ATTRIBUTE keyAttribs[] =
926 		{
927 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
928 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
929 		{ CKA_MODIFIABLE, &bTrue, sizeof(bTrue) },
930 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
931 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
932 		{ CKA_WRAP, &bTrue, sizeof(bTrue) }
933 	};
934 
935 	// Just make sure that we finalize any previous tests
936 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
937 
938 	// Initialize the library and start the test.
939 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
940 	CPPUNIT_ASSERT(rv == CKR_OK);
941 
942 	// Open read-write session
943 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
944 	CPPUNIT_ASSERT(rv == CKR_OK);
945 
946 	// Login USER into the sessions so we can create a private objects
947 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
948 	CPPUNIT_ASSERT(rv==CKR_OK);
949 
950 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
951 		keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
952 		&hKey) );
953 	CPPUNIT_ASSERT(rv == CKR_OK);
954 
955 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
956 	CPPUNIT_ASSERT(rv == CKR_OK);
957 
958 	// The C_GenerateKey call failed if CKA_MODIFIABLE was bFalse
959 	// This was a bug in the SoftHSM implementation
960 	keyAttribs[2].pValue = &bFalse;
961 	keyAttribs[2].ulValueLen = sizeof(bFalse);
962 
963 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
964 		keyAttribs, sizeof(keyAttribs) / sizeof(CK_ATTRIBUTE),
965 		&hKey) );
966 	// The call would fail with CKR_ATTRIBUTE_READ_ONLY
967 	CPPUNIT_ASSERT(rv == CKR_OK);
968 
969 	// Now create a template where the CKA_MODIFIABLE attribute is last in the list
970 	CK_ATTRIBUTE keyAttribs1[] =
971 	{
972 		{ CKA_TOKEN, &bToken, sizeof(bToken) },
973 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
974 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
975 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
976 		{ CKA_WRAP, &bTrue, sizeof(bTrue) },
977 		{ CKA_MODIFIABLE, &bTrue, sizeof(bTrue) }
978 	};
979 
980 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
981 		keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
982 		&hKey) );
983 	CPPUNIT_ASSERT(rv == CKR_OK);
984 
985 	// Now when CKA_MODIFIABLE is bFalse the key generation succeeds
986 	keyAttribs1[2].pValue = &bFalse;
987 	keyAttribs1[2].ulValueLen = sizeof(bFalse);
988 
989 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
990 		keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
991 		&hKey) );
992 	CPPUNIT_ASSERT(rv == CKR_OK);
993 }
994 
testCheckValue()995 void SymmetricAlgorithmTests::testCheckValue()
996 {
997 	CK_RV rv;
998 	CK_SESSION_HANDLE hSession;
999 	CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
1000 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1001 
1002 	// Just make sure that we finalize any previous tests
1003 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1004 
1005 	// Initialize the library and start the test.
1006 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1007 	CPPUNIT_ASSERT(rv == CKR_OK);
1008 
1009 	// Open read-write session
1010 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1011 	CPPUNIT_ASSERT(rv == CKR_OK);
1012 
1013 	// Login USER into the sessions so we can create a private objects
1014 	rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
1015 	CPPUNIT_ASSERT(rv==CKR_OK);
1016 
1017 	CK_ULONG bytes = 16;
1018 	CK_BYTE pCheckValue[] = { 0x2b, 0x84, 0xf6 };
1019 	CK_BBOOL bFalse = CK_FALSE;
1020 	CK_BBOOL bTrue = CK_TRUE;
1021 	CK_ATTRIBUTE keyAttribs[] = {
1022 		{ CKA_TOKEN, &bFalse, sizeof(bFalse) },
1023 		{ CKA_PRIVATE, &bTrue, sizeof(bTrue) },
1024 		{ CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
1025 		{ CKA_DECRYPT, &bTrue, sizeof(bTrue) },
1026 		{ CKA_WRAP, &bTrue, sizeof(bTrue) },
1027 		{ CKA_UNWRAP, &bTrue, sizeof(bTrue) },
1028 		{ CKA_VALUE_LEN, &bytes, sizeof(bytes) },
1029 		{ CKA_CHECK_VALUE, &pCheckValue, sizeof(pCheckValue) }
1030 	};
1031 
1032 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1033 			   keyAttribs, 8,
1034 			   &hKey) );
1035 	CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_VALUE_INVALID);
1036 
1037 	keyAttribs[7].ulValueLen = 0;
1038 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1039 			   keyAttribs, 8,
1040 			   &hKey) );
1041 	CPPUNIT_ASSERT(rv == CKR_OK);
1042 
1043 	CK_ATTRIBUTE checkAttrib[] = {
1044 		{ CKA_CHECK_VALUE, &pCheckValue, sizeof(pCheckValue) }
1045 	};
1046 
1047 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey, checkAttrib, 1) );
1048 	CPPUNIT_ASSERT(rv == CKR_OK);
1049 	CPPUNIT_ASSERT(checkAttrib[0].ulValueLen == 0);
1050 
1051 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1052 	CPPUNIT_ASSERT(rv == CKR_OK);
1053 
1054 	rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1055 			   keyAttribs, 7,
1056 			   &hKey) );
1057 	CPPUNIT_ASSERT(rv == CKR_OK);
1058 
1059 	checkAttrib[0].ulValueLen = sizeof(pCheckValue);
1060 	rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey, checkAttrib, 1) );
1061 	CPPUNIT_ASSERT(rv == CKR_OK);
1062 	CPPUNIT_ASSERT(checkAttrib[0].ulValueLen == 3);
1063 
1064 	rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1065 	CPPUNIT_ASSERT(rv == CKR_OK);
1066 }
1067 
testAesCtrOverflow()1068 void SymmetricAlgorithmTests::testAesCtrOverflow()
1069 {
1070 	CK_RV rv;
1071 	CK_SESSION_HANDLE hSession;
1072 
1073 	// Just make sure that we finalize any previous tests
1074 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1075 
1076 	// Initialize the library and start the test.
1077 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1078 	CPPUNIT_ASSERT(rv == CKR_OK);
1079 
1080 	// Open read-write session
1081 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1082 	CPPUNIT_ASSERT(rv == CKR_OK);
1083 
1084 	// Login USER into the session so we can create a private objects
1085 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
1086 	CPPUNIT_ASSERT(rv==CKR_OK);
1087 
1088 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1089 
1090 	// Generate a session keys.
1091 	rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
1092 	CPPUNIT_ASSERT(rv == CKR_OK);
1093 
1094 	CK_MECHANISM mechanism = { CKM_AES_CTR, NULL_PTR, 0 };
1095 	CK_AES_CTR_PARAMS ctrParams =
1096 	{
1097 		2,
1098 		{
1099 			0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1100 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1101 		}
1102 	};
1103 	mechanism.pParameter = &ctrParams;
1104 	mechanism.ulParameterLen = sizeof(ctrParams);
1105 
1106 	CK_BYTE plainText[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1107 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1108 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1109 				0x00 };
1110 	std::vector<CK_BYTE> vEncryptedData;
1111 	std::vector<CK_BYTE> vEncryptedDataParted;
1112 	std::vector<CK_BYTE> vDecryptedData;
1113 	std::vector<CK_BYTE> vDecryptedDataParted;
1114 	CK_ULONG ulEncryptedDataLen;
1115 	CK_ULONG ulEncryptedPartLen;
1116 	CK_ULONG ulDataLen;
1117 	CK_ULONG ulDataPartLen;
1118 
1119 	// Single-part encryption
1120 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1121 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1122 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText),NULL_PTR,&ulEncryptedDataLen) );
1123 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_DATA_LEN_RANGE, rv );
1124 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1125 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1126 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedDataLen) );
1127 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1128 	vEncryptedData.resize(ulEncryptedDataLen);
1129 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,&vEncryptedData.front(),&ulEncryptedDataLen) );
1130 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1131 	vEncryptedData.resize(ulEncryptedDataLen);
1132 
1133 	// Multi-part encryption
1134 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1135 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1136 	rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedPartLen) );
1137 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1138 	vEncryptedDataParted.resize(ulEncryptedPartLen);
1139 	rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,&vEncryptedDataParted.front(),&ulEncryptedPartLen) );
1140 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1141 	vEncryptedDataParted.resize(ulEncryptedPartLen);
1142 	rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,1,NULL_PTR,&ulEncryptedPartLen) );
1143 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_DATA_LEN_RANGE, rv );
1144 
1145 	// Single-part decryption
1146 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1147 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1148 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size()+1,NULL_PTR,&ulDataLen) );
1149 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
1150 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1151 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1152 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataLen) );
1153 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1154 	vDecryptedData.resize(ulDataLen);
1155 	rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedData.front(),&ulDataLen) );
1156 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1157 	vDecryptedData.resize(ulDataLen);
1158 
1159 	// Multi-part decryption
1160 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1161 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1162 	rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataPartLen) );
1163 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1164 	vDecryptedDataParted.resize(ulDataPartLen);
1165 	rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedDataParted.front(),&ulDataPartLen) );
1166 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1167 	vDecryptedDataParted.resize(ulDataPartLen);
1168 	rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),1,NULL_PTR,&ulDataPartLen) );
1169 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
1170 }
1171 
testGenericKey()1172 void SymmetricAlgorithmTests::testGenericKey()
1173 {
1174 	CK_RV rv;
1175 	CK_SESSION_HANDLE hSession;
1176 
1177 	// Just make sure that we finalize any previous tests
1178 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1179 
1180 	// Initialize the library and start the test.
1181 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1182 	CPPUNIT_ASSERT(rv == CKR_OK);
1183 
1184 	// Open read-write session
1185 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1186 	CPPUNIT_ASSERT(rv == CKR_OK);
1187 
1188 	// Login USER into the session so we can create a private objects
1189 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
1190 	CPPUNIT_ASSERT(rv==CKR_OK);
1191 
1192 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1193 
1194 	// Generate a session key.
1195 	rv = generateGenericKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
1196 	CPPUNIT_ASSERT(rv == CKR_OK);
1197 }
1198 
testEncDecFinalNULLValidation()1199 void SymmetricAlgorithmTests::testEncDecFinalNULLValidation()
1200 {
1201 	CK_RV rv;
1202 	CK_SESSION_HANDLE hSession;
1203 
1204 	// Just make sure that we finalize any previous tests
1205 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1206 
1207 	// Initialize the library and start the test.
1208 	rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1209 	CPPUNIT_ASSERT(rv == CKR_OK);
1210 
1211 	// Open read-write session
1212 	rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1213 	CPPUNIT_ASSERT(rv == CKR_OK);
1214 
1215 	// Login USER into the sessions so we can create a private objects
1216 	rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
1217 	CPPUNIT_ASSERT(rv==CKR_OK);
1218 
1219 	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1220 
1221 	// Generate all combinations of session/token keys.
1222 	rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
1223 
1224 	CPPUNIT_ASSERT(rv == CKR_OK);
1225 
1226 	CK_MECHANISM mechanism = { CKM_AES_CTR, NULL_PTR, 0 };
1227 	CK_AES_CTR_PARAMS ctrParams =
1228 	{
1229 		2,
1230 		{
1231 			0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1232 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1233 		}
1234 	};
1235 	mechanism.pParameter = &ctrParams;
1236 	mechanism.ulParameterLen = sizeof(ctrParams);
1237 	CK_BYTE plainText[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1238 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1239 				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1240 				0x00 };
1241 	std::vector<CK_BYTE> vEncryptedData;
1242 	std::vector<CK_BYTE> vEncryptedDataParted;
1243 	std::vector<CK_BYTE> vDecryptedData;
1244 	std::vector<CK_BYTE> vDecryptedDataParted;
1245 	CK_ULONG ulEncryptedDataLen;
1246 	CK_ULONG ulEncryptedPartLen;
1247 	CK_ULONG ulDecryptedPartLen;
1248 	CK_ULONG ulDataPartLen;
1249 
1250 	// Single-part encryption
1251 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1252 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1253 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedDataLen) );
1254 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1255 	vEncryptedData.resize(ulEncryptedDataLen);
1256 	rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,&vEncryptedData.front(),&ulEncryptedDataLen) );
1257 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1258 	vEncryptedData.resize(ulEncryptedDataLen);
1259 
1260 	// Multi-part encryption
1261 	rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1262 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1263 	rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedPartLen) );
1264 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1265 	vEncryptedDataParted.resize(ulEncryptedPartLen);
1266 	rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,&vEncryptedDataParted.front(),&ulEncryptedPartLen) );
1267 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1268 
1269 	// Test input validation
1270 	rv = CRYPTOKI_F_PTR( C_EncryptFinal(hSession, NULL_PTR, NULL_PTR) );
1271 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ARGUMENTS_BAD, rv );
1272 	ulEncryptedPartLen = 0;
1273 	rv = CRYPTOKI_F_PTR( C_EncryptFinal(hSession, NULL_PTR, &ulEncryptedPartLen) );
1274 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OPERATION_NOT_INITIALIZED, rv );
1275 
1276 	// Multi-part decryption
1277 	rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1278 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1279 	rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataPartLen) );
1280 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1281 	vDecryptedDataParted.resize(ulDataPartLen);
1282 	rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedDataParted.front(),&ulDataPartLen) );
1283 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1284 
1285 	// Test input validation
1286 	rv = CRYPTOKI_F_PTR( C_DecryptFinal(hSession, NULL_PTR, NULL_PTR) );
1287 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ARGUMENTS_BAD, rv );
1288 	ulDecryptedPartLen = 0;
1289 	rv = CRYPTOKI_F_PTR( C_DecryptFinal(hSession, NULL_PTR, &ulDecryptedPartLen) );
1290 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OPERATION_NOT_INITIALIZED, rv );
1291 
1292 	CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1293 }
1294