2 * Copyright (c) 2012 SURFnet
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
27 /*****************************************************************************
28 SymmetricAlgorithmTests.cpp
30 Contains test cases for symmetrical algorithms (i.e., AES and DES)
31 *****************************************************************************/
38 #include "SymmetricAlgorithmTests.h"
41 const CK_BBOOL ON_TOKEN = CK_TRUE;
42 const CK_BBOOL IN_SESSION = CK_FALSE;
45 const CK_BBOOL IS_PRIVATE = CK_TRUE;
46 const CK_BBOOL IS_PUBLIC = CK_FALSE;
48 #define NR_OF_BLOCKS_IN_TEST 0x10001
50 CPPUNIT_TEST_SUITE_REGISTRATION(SymmetricAlgorithmTests);
52 CK_RV SymmetricAlgorithmTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
54 CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
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) },
68 hKey = CK_INVALID_HANDLE;
69 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
70 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
75 CK_RV SymmetricAlgorithmTests::generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
77 CK_MECHANISM mechanism = { CKM_DES_KEY_GEN, NULL_PTR, 0 };
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) },
87 hKey = CK_INVALID_HANDLE;
88 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
89 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
93 CK_RV SymmetricAlgorithmTests::generateDes2Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
95 CK_MECHANISM mechanism = { CKM_DES2_KEY_GEN, NULL_PTR, 0 };
96 // CK_BBOOL bFalse = CK_FALSE;
97 CK_BBOOL bTrue = CK_TRUE;
98 CK_ATTRIBUTE keyAttribs[] = {
99 { CKA_TOKEN, &bToken, sizeof(bToken) },
100 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
101 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
102 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
105 hKey = CK_INVALID_HANDLE;
106 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
107 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
112 CK_RV SymmetricAlgorithmTests::generateDes3Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
114 CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
115 // CK_BBOOL bFalse = CK_FALSE;
116 CK_BBOOL bTrue = CK_TRUE;
117 CK_ATTRIBUTE keyAttribs[] = {
118 { CKA_TOKEN, &bToken, sizeof(bToken) },
119 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
120 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
121 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
124 hKey = CK_INVALID_HANDLE;
125 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
126 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
130 void SymmetricAlgorithmTests::encryptDecrypt(
131 const CK_MECHANISM_TYPE mechanismType,
132 const size_t blockSize,
133 const CK_SESSION_HANDLE hSession,
134 const CK_OBJECT_HANDLE hKey,
135 const size_t messageSize,
138 class PartSize {// class to get random size for part
139 private: // we want to know for sure that no part length is causing any problem.
141 const unsigned* pRandom;// point to memory with random data. We are using the data to be encrypted.
142 const unsigned* pBack;// point to memory where random data ends.
143 int current;// the current size.
146 const int _blockSize,
147 const std::vector<CK_BYTE>* pvData) :
148 blockSize(_blockSize),
149 pRandom((const unsigned*)&pvData->front()),
150 pBack((const unsigned*)&pvData->back()),
151 current(blockSize*4){};
152 int getCurrent() {// current part size
155 int getNext() {// get next part size.
156 // Check if we do not have more random data
157 if ((pRandom+sizeof(unsigned)-1) > pBack) {
158 current = blockSize*4;
161 const unsigned random(*(pRandom++));
162 // Bit shift to handle 32- and 64-bit systems.
163 // Just want a simple random part length,
164 // not a perfect random number (bit shifting will
165 // give some loss of precision).
166 current = ((unsigned long)random >> 20)*blockSize*0x100/(UINT_MAX >> 20) + 1;
167 //std::cout << "New random " << std::hex << random << " current " << std::hex << std::setfill('0') << std::setw(4) << current << " block size " << std::hex << blockSize << std::endl;
172 const std::vector<CK_BYTE> vData(messageSize);
173 std::vector<CK_BYTE> vEncryptedData;
174 std::vector<CK_BYTE> vEncryptedDataParted;
175 PartSize partSize(blockSize, &vData);
177 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_GenerateRandom(hSession, (CK_BYTE_PTR)&vData.front(), messageSize) ) );
179 const CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
180 CK_MECHANISM_PTR pMechanism((CK_MECHANISM_PTR)&mechanism);
181 CK_AES_CTR_PARAMS ctrParams =
185 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
190 0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE,
191 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88
194 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
195 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
196 0xAB, 0xAD, 0xDA, 0xD2
198 CK_GCM_PARAMS gcmParams =
208 switch (mechanismType)
211 case CKM_DES_CBC_PAD:
213 case CKM_DES3_CBC_PAD:
215 case CKM_AES_CBC_PAD:
216 pMechanism->pParameter = (CK_VOID_PTR)&vData.front();
217 pMechanism->ulParameterLen = blockSize;
220 pMechanism->pParameter = &ctrParams;
221 pMechanism->ulParameterLen = sizeof(ctrParams);
224 pMechanism->pParameter = &gcmParams;
225 pMechanism->ulParameterLen = sizeof(gcmParams);
231 // Single-part encryption
232 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
234 CK_ULONG ulEncryptedDataLen;
235 const CK_RV rv( CRYPTOKI_F_PTR( C_Encrypt(hSession,(CK_BYTE_PTR)&vData.front(),messageSize,NULL_PTR,&ulEncryptedDataLen) ) );
237 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
238 vEncryptedData.resize(ulEncryptedDataLen);
239 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Encrypt(hSession,(CK_BYTE_PTR)&vData.front(),messageSize,&vEncryptedData.front(),&ulEncryptedDataLen) ) );
240 vEncryptedData.resize(ulEncryptedDataLen);
242 CPPUNIT_ASSERT_EQUAL_MESSAGE("C_Encrypt should fail with C_CKR_DATA_LEN_RANGE", (CK_RV)CKR_DATA_LEN_RANGE, rv);
243 vEncryptedData = vData;
247 // Multi-part encryption
248 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
250 for ( std::vector<CK_BYTE>::const_iterator i(vData.begin()); i<vData.end(); i+=partSize.getCurrent() ) {
251 const CK_ULONG lPartLen( i+partSize.getNext()<vData.end() ? partSize.getCurrent() : vData.end()-i );
252 CK_ULONG ulEncryptedPartLen;
253 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,(CK_BYTE_PTR)&(*i),lPartLen,NULL_PTR,&ulEncryptedPartLen) ) );
254 const size_t oldSize( vEncryptedDataParted.size() );
255 vEncryptedDataParted.resize(oldSize+ulEncryptedPartLen);
257 const CK_BYTE_PTR pEncryptedPart( ulEncryptedPartLen>0 ? &vEncryptedDataParted.at(oldSize) : &dummy );
258 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,(CK_BYTE_PTR)&(*i),lPartLen,pEncryptedPart,&ulEncryptedPartLen) ) );
259 vEncryptedDataParted.resize(oldSize+ulEncryptedPartLen);
262 CK_ULONG ulLastEncryptedPartLen;
263 const CK_RV rv( CRYPTOKI_F_PTR( C_EncryptFinal(hSession,NULL_PTR,&ulLastEncryptedPartLen) ) );
265 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
266 const size_t oldSize( vEncryptedDataParted.size() );
268 vEncryptedDataParted.resize(oldSize+ulLastEncryptedPartLen);
269 const CK_BYTE_PTR pLastEncryptedPart( ulLastEncryptedPartLen>0 ? &vEncryptedDataParted.at(oldSize) : &dummy );
270 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptFinal(hSession,pLastEncryptedPart,&ulLastEncryptedPartLen) ) );
271 vEncryptedDataParted.resize(oldSize+ulLastEncryptedPartLen);
273 CPPUNIT_ASSERT_EQUAL_MESSAGE("C_EncryptFinal should fail with C_CKR_DATA_LEN_RANGE", (CK_RV)CKR_DATA_LEN_RANGE, rv);
274 vEncryptedDataParted = vData;
278 // Single-part decryption
279 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
283 const CK_RV rv( CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataLen) ) );
285 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
286 std::vector<CK_BYTE> vDecryptedData(ulDataLen);
287 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedData.front(),&ulDataLen) ) );
288 vDecryptedData.resize(ulDataLen);
289 CPPUNIT_ASSERT_MESSAGE("C_Encrypt C_Decrypt does not give the original", vData==vDecryptedData);
291 CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_Decrypt should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
295 // Multi-part decryption
296 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
298 std::vector<CK_BYTE> vDecryptedData;
300 for ( std::vector<CK_BYTE>::iterator i(vEncryptedDataParted.begin()); i<vEncryptedDataParted.end(); i+=partSize.getCurrent()) {
301 const CK_ULONG ulPartLen( i+partSize.getNext()<vEncryptedDataParted.end() ? partSize.getCurrent() : vEncryptedDataParted.end()-i );
302 CK_ULONG ulDecryptedPartLen;
303 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&(*i),ulPartLen,NULL_PTR,&ulDecryptedPartLen) ) );
304 const size_t oldSize( vDecryptedData.size() );
305 vDecryptedData.resize(oldSize+ulDecryptedPartLen);
306 const CK_BYTE_PTR pDecryptedPart( ulDecryptedPartLen>0 ? &vDecryptedData.at(oldSize) : &dummy );
307 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&(*i),ulPartLen,pDecryptedPart,&ulDecryptedPartLen) ) );
308 vDecryptedData.resize(oldSize+ulDecryptedPartLen);
311 CK_ULONG ulLastPartLen;
312 const CK_RV rv( CRYPTOKI_F_PTR( C_DecryptFinal(hSession,NULL_PTR,&ulLastPartLen) ) );
314 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
315 const size_t oldSize( vDecryptedData.size() );
316 vDecryptedData.resize(oldSize+ulLastPartLen);
317 const CK_BYTE_PTR pLastPart( ulLastPartLen>0 ? &vDecryptedData.at(oldSize) : &dummy );
318 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptFinal(hSession,pLastPart,&ulLastPartLen) ) );
319 vDecryptedData.resize(oldSize+ulLastPartLen);
320 CPPUNIT_ASSERT_MESSAGE("C_EncryptUpdate/C_EncryptFinal C_DecryptUpdate/C_DecryptFinal does not give the original", vData==vDecryptedData);
322 CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_EncryptFinal should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
328 CK_RV SymmetricAlgorithmTests::generateRsaPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
330 CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
331 CK_ULONG bits = 1536;
332 CK_BYTE pubExp[] = {0x01, 0x00, 0x01};
333 CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
334 CK_BYTE id[] = { 123 } ; // dummy
335 CK_BBOOL bFalse = CK_FALSE;
336 CK_BBOOL bTrue = CK_TRUE;
337 CK_ATTRIBUTE pubAttribs[] = {
338 { CKA_TOKEN, &bToken, sizeof(bToken) },
339 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
340 { CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
341 { CKA_VERIFY, &bTrue, sizeof(bTrue) },
342 { CKA_WRAP, &bFalse, sizeof(bFalse) },
343 { CKA_MODULUS_BITS, &bits, sizeof(bits) },
344 { CKA_PUBLIC_EXPONENT, &pubExp[0], sizeof(pubExp) }
346 CK_ATTRIBUTE privAttribs[] = {
347 { CKA_TOKEN, &bToken, sizeof(bToken) },
348 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
349 { CKA_SUBJECT, &subject[0], sizeof(subject) },
350 { CKA_ID, &id[0], sizeof(id) },
351 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
352 { CKA_DECRYPT, &bFalse, sizeof(bFalse) },
353 { CKA_SIGN, &bTrue, sizeof(bTrue) },
354 { CKA_UNWRAP, &bFalse, sizeof(bFalse) },
355 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
356 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
359 CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
360 hKey = CK_INVALID_HANDLE;
362 rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
363 pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
364 privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
366 if (hPub != CK_INVALID_HANDLE)
368 CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
374 CK_RV SymmetricAlgorithmTests::generateGostPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
376 CK_MECHANISM mechanism = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL_PTR, 0 };
377 CK_BYTE param_a[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
378 CK_BYTE param_b[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 };
379 CK_BYTE subject[] = { 0x12, 0x34 }; // dummy
380 CK_BYTE id[] = { 123 } ; // dummy
381 CK_BBOOL bFalse = CK_FALSE;
382 CK_BBOOL bTrue = CK_TRUE;
383 CK_ATTRIBUTE pubAttribs[] = {
384 { CKA_TOKEN, &bToken, sizeof(bToken) },
385 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
386 { CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
387 { CKA_VERIFY, &bTrue, sizeof(bTrue) },
388 { CKA_WRAP, &bFalse, sizeof(bFalse) },
389 { CKA_GOSTR3410_PARAMS, ¶m_a[0], sizeof(param_a) },
390 { CKA_GOSTR3411_PARAMS, ¶m_b[0], sizeof(param_b) }
392 CK_ATTRIBUTE privAttribs[] = {
393 { CKA_TOKEN, &bToken, sizeof(bToken) },
394 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
395 { CKA_SUBJECT, &subject[0], sizeof(subject) },
396 { CKA_ID, &id[0], sizeof(id) },
397 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
398 { CKA_DECRYPT, &bFalse, sizeof(bFalse) },
399 { CKA_SIGN, &bTrue, sizeof(bTrue) },
400 { CKA_UNWRAP, &bFalse, sizeof(bFalse) },
401 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
402 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
405 CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
406 hKey = CK_INVALID_HANDLE;
408 rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
409 pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
410 privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
412 if (hPub != CK_INVALID_HANDLE)
414 CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
420 void SymmetricAlgorithmTests::aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
422 CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
423 CK_BBOOL bFalse = CK_FALSE;
424 CK_BBOOL bTrue = CK_TRUE;
425 CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
426 CK_KEY_TYPE genKeyType = CKK_GENERIC_SECRET;
429 mechanismType == CKM_AES_KEY_WRAP_PAD ? 125UL : 128UL;
430 CK_ATTRIBUTE attribs[] = {
431 { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) },
432 { CKA_CLASS, &secretClass, sizeof(secretClass) },
433 { CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
434 { CKA_TOKEN, &bFalse, sizeof(bFalse) },
435 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
436 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, // Wrapping is allowed even on sensitive objects
437 { CKA_VALUE, keyPtr, keyLen }
439 CK_OBJECT_HANDLE hSecret;
442 rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, keyPtr, keyLen) );
443 CPPUNIT_ASSERT(rv == CKR_OK);
445 hSecret = CK_INVALID_HANDLE;
446 rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
447 CPPUNIT_ASSERT(rv == CKR_OK);
448 CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
450 CK_BYTE_PTR wrappedPtr = NULL_PTR;
451 CK_ULONG wrappedLen = 0UL;
453 CK_ULONG rndKeyLen = keyLen;
454 if (mechanismType == CKM_AES_KEY_WRAP_PAD)
455 rndKeyLen = (keyLen + 7) & ~7;
456 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
457 CPPUNIT_ASSERT(rv == CKR_KEY_UNEXTRACTABLE);
458 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
459 CPPUNIT_ASSERT(rv == CKR_OK);
461 attribs[0].pValue = &bTrue;
463 hSecret = CK_INVALID_HANDLE;
464 rv = CRYPTOKI_F_PTR( C_CreateObject(hSession, attribs, sizeof(attribs)/sizeof(CK_ATTRIBUTE), &hSecret) );
465 CPPUNIT_ASSERT(rv == CKR_OK);
466 CPPUNIT_ASSERT(hSecret != CK_INVALID_HANDLE);
468 // Estimate wrapped length
469 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
470 CPPUNIT_ASSERT(rv == CKR_OK);
471 CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);
473 wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
474 CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
475 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &wrappedLen) );
476 CPPUNIT_ASSERT(rv == CKR_OK);
477 CPPUNIT_ASSERT(wrappedLen == rndKeyLen + 8);
479 // This should always fail because wrapped data have to be longer than 0 bytes
481 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero) );
482 CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);
484 CK_ATTRIBUTE nattribs[] = {
485 { CKA_CLASS, &secretClass, sizeof(secretClass) },
486 { CKA_KEY_TYPE, &genKeyType, sizeof(genKeyType) },
487 { CKA_TOKEN, &bFalse, sizeof(bFalse) },
488 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
489 { CKA_ENCRYPT, &bFalse, sizeof(bFalse) },
490 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
491 { CKA_SIGN, &bFalse,sizeof(bFalse) },
492 { CKA_VERIFY, &bTrue, sizeof(bTrue) }
494 CK_OBJECT_HANDLE hNew;
496 hNew = CK_INVALID_HANDLE;
497 rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nattribs, sizeof(nattribs)/sizeof(CK_ATTRIBUTE), &hNew) );
498 CPPUNIT_ASSERT(rv == CKR_OK);
499 CPPUNIT_ASSERT(hNew != CK_INVALID_HANDLE);
502 wrappedPtr = NULL_PTR;
503 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
504 CPPUNIT_ASSERT(rv == CKR_OK);
507 void SymmetricAlgorithmTests::aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
509 CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
510 CK_BBOOL bFalse = CK_FALSE;
511 CK_BBOOL bTrue = CK_TRUE;
512 CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
513 CK_RV rv = generateRsaPrivateKey(hSession, CK_TRUE, CK_TRUE, hPrk);
514 CPPUNIT_ASSERT(rv == CKR_OK);
515 CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
517 CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY;
518 CK_KEY_TYPE keyType = CKK_RSA;
519 CK_BYTE_PTR prkAttrPtr = NULL_PTR;
520 CK_ULONG prkAttrLen = 0UL;
521 CK_ATTRIBUTE prkAttribs[] = {
522 { CKA_CLASS, &privateClass, sizeof(privateClass) },
523 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
524 { CKA_PRIME_2, NULL_PTR, 0UL }
527 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
528 CPPUNIT_ASSERT(rv == CKR_OK);
530 CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
531 CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
532 CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
533 CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_RSA);
535 prkAttrLen = prkAttribs[2].ulValueLen;
536 prkAttrPtr = (CK_BYTE_PTR) malloc(2 * prkAttrLen);
537 CPPUNIT_ASSERT(prkAttrPtr != NULL_PTR);
538 prkAttribs[2].pValue = prkAttrPtr;
539 prkAttribs[2].ulValueLen = prkAttrLen;
541 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
542 CPPUNIT_ASSERT(rv == CKR_OK);
543 CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
545 CK_BYTE_PTR wrappedPtr = NULL_PTR;
546 CK_ULONG wrappedLen = 0UL;
547 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
548 CPPUNIT_ASSERT(rv == CKR_OK);
549 wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
550 CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
551 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
552 CPPUNIT_ASSERT(rv == CKR_OK);
554 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
555 CPPUNIT_ASSERT(rv == CKR_OK);
557 CK_ATTRIBUTE nPrkAttribs[] = {
558 { CKA_CLASS, &privateClass, sizeof(privateClass) },
559 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
560 { CKA_TOKEN, &bFalse, sizeof(bFalse) },
561 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
562 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
563 { CKA_SIGN, &bFalse,sizeof(bFalse) },
564 { CKA_UNWRAP, &bTrue, sizeof(bTrue) },
565 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
566 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
569 hPrk = CK_INVALID_HANDLE;
570 rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nPrkAttribs, sizeof(nPrkAttribs)/sizeof(CK_ATTRIBUTE), &hPrk) );
571 CPPUNIT_ASSERT(rv == CKR_OK);
572 CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
574 prkAttribs[2].pValue = prkAttrPtr + prkAttrLen;
575 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
576 CPPUNIT_ASSERT(rv == CKR_OK);
578 CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
579 CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
580 CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
581 CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_RSA);
582 CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
583 CPPUNIT_ASSERT(memcmp(prkAttrPtr, prkAttrPtr + prkAttrLen, prkAttrLen) == 0);
587 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
588 CPPUNIT_ASSERT(rv == CKR_OK);
592 void SymmetricAlgorithmTests::aesWrapUnwrapGost(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
594 CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
595 CK_BBOOL bFalse = CK_FALSE;
596 CK_BBOOL bTrue = CK_TRUE;
597 CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE;
598 CK_RV rv = generateGostPrivateKey(hSession, CK_TRUE, CK_TRUE, hPrk);
599 CPPUNIT_ASSERT(rv == CKR_OK);
600 CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
602 CK_OBJECT_CLASS privateClass = CKO_PRIVATE_KEY;
603 CK_KEY_TYPE keyType = CKK_GOSTR3410;
604 CK_BYTE_PTR prkAttrPtr = NULL_PTR;
605 CK_ULONG prkAttrLen = 0UL;
606 CK_ATTRIBUTE prkAttribs[] = {
607 { CKA_CLASS, &privateClass, sizeof(privateClass) },
608 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
609 { CKA_VALUE, NULL_PTR, 0UL }
612 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
613 CPPUNIT_ASSERT(rv == CKR_OK);
615 CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
616 CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
617 CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
618 CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_GOSTR3410);
620 prkAttrLen = prkAttribs[2].ulValueLen;
621 prkAttrPtr = (CK_BYTE_PTR) malloc(2 * prkAttrLen);
622 CPPUNIT_ASSERT(prkAttrPtr != NULL_PTR);
623 prkAttribs[2].pValue = prkAttrPtr;
624 prkAttribs[2].ulValueLen = prkAttrLen;
626 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
627 CPPUNIT_ASSERT(rv == CKR_OK);
628 CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
630 CK_BYTE_PTR wrappedPtr = NULL_PTR;
631 CK_ULONG wrappedLen = 0UL;
632 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
633 CPPUNIT_ASSERT(rv == CKR_OK);
634 wrappedPtr = (CK_BYTE_PTR) malloc(wrappedLen);
635 CPPUNIT_ASSERT(wrappedPtr != NULL_PTR);
636 rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hPrk, wrappedPtr, &wrappedLen) );
637 CPPUNIT_ASSERT(rv == CKR_OK);
639 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
640 CPPUNIT_ASSERT(rv == CKR_OK);
642 CK_ATTRIBUTE nPrkAttribs[] = {
643 { CKA_CLASS, &privateClass, sizeof(privateClass) },
644 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
645 { CKA_TOKEN, &bFalse, sizeof(bFalse) },
646 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
647 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
648 { CKA_SIGN, &bFalse,sizeof(bFalse) },
649 { CKA_UNWRAP, &bTrue, sizeof(bTrue) },
650 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
651 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) }
654 hPrk = CK_INVALID_HANDLE;
655 rv = CRYPTOKI_F_PTR( C_UnwrapKey(hSession, &mechanism, hKey, wrappedPtr, wrappedLen, nPrkAttribs, sizeof(nPrkAttribs)/sizeof(CK_ATTRIBUTE), &hPrk) );
656 CPPUNIT_ASSERT(rv == CKR_OK);
657 CPPUNIT_ASSERT(hPrk != CK_INVALID_HANDLE);
659 prkAttribs[2].pValue = prkAttrPtr + prkAttrLen;
660 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
661 CPPUNIT_ASSERT(rv == CKR_OK);
663 CPPUNIT_ASSERT(prkAttribs[0].ulValueLen == sizeof(CK_OBJECT_CLASS));
664 CPPUNIT_ASSERT(*(CK_OBJECT_CLASS*)prkAttribs[0].pValue == CKO_PRIVATE_KEY);
665 CPPUNIT_ASSERT(prkAttribs[1].ulValueLen == sizeof(CK_KEY_TYPE));
666 CPPUNIT_ASSERT(*(CK_KEY_TYPE*)prkAttribs[1].pValue == CKK_GOSTR3410);
667 CPPUNIT_ASSERT(prkAttribs[2].ulValueLen == prkAttrLen);
668 CPPUNIT_ASSERT(memcmp(prkAttrPtr, prkAttrPtr + prkAttrLen, prkAttrLen) == 0);
672 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
673 CPPUNIT_ASSERT(rv == CKR_OK);
677 void SymmetricAlgorithmTests::testAesEncryptDecrypt()
680 // CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
681 // CK_ULONG sopinLength = sizeof(sopin) - 1;
682 CK_SESSION_HANDLE hSessionRO;
683 CK_SESSION_HANDLE hSessionRW;
685 // Just make sure that we finalize any previous tests
686 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
688 // Open read-only session on when the token is not initialized should fail
689 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
690 CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
692 // Initialize the library and start the test.
693 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
694 CPPUNIT_ASSERT(rv == CKR_OK);
696 // Open read-only session
697 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
698 CPPUNIT_ASSERT(rv == CKR_OK);
700 // Open read-write session
701 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
702 CPPUNIT_ASSERT(rv == CKR_OK);
704 // Login USER into the sessions so we can create a private objects
705 rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
706 CPPUNIT_ASSERT(rv==CKR_OK);
708 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
710 // Generate all combinations of session/token keys.
711 rv = generateAesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
712 CPPUNIT_ASSERT(rv == CKR_OK);
714 // AES allways have the block size of 128 bits (0x80 bits 0x10 bytes).
715 // with padding all message sizes could be encrypted-decrypted.
716 // without padding the message size must be a multiple of the block size.
717 const int blockSize(0x10);
718 encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
719 encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
720 encryptDecrypt(CKM_AES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
721 encryptDecrypt(CKM_AES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
722 encryptDecrypt(CKM_AES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
723 encryptDecrypt(CKM_AES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
724 encryptDecrypt(CKM_AES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
725 encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
726 encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
727 encryptDecrypt(CKM_AES_CTR,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
729 encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
730 encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
731 encryptDecrypt(CKM_AES_GCM,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
735 void SymmetricAlgorithmTests::testAesWrapUnwrap()
738 // CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
739 // CK_ULONG sopinLength = sizeof(sopin) - 1;
740 CK_SESSION_HANDLE hSession;
742 // Just make sure that we finalize any previous tests
743 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
745 // Initialize the library and start the test.
746 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
747 CPPUNIT_ASSERT(rv == CKR_OK);
750 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
751 CPPUNIT_ASSERT(rv == CKR_OK);
753 // Login USER into the session so we can create a private object
754 rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
755 CPPUNIT_ASSERT(rv==CKR_OK);
757 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
759 // Generate a wrapping session public key
760 rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
761 CPPUNIT_ASSERT(rv == CKR_OK);
763 aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP, hSession, hKey);
764 aesWrapUnwrapRsa(CKM_AES_KEY_WRAP, hSession, hKey);
766 aesWrapUnwrapGost(CKM_AES_KEY_WRAP, hSession, hKey);
769 #ifdef HAVE_AES_KEY_WRAP_PAD
770 aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
771 aesWrapUnwrapRsa(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
773 aesWrapUnwrapGost(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
778 void SymmetricAlgorithmTests::testDesEncryptDecrypt()
781 // CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
782 // CK_ULONG sopinLength = sizeof(sopin) - 1;
783 CK_SESSION_HANDLE hSessionRO;
784 CK_SESSION_HANDLE hSessionRW;
786 // Just make sure that we finalize any previous tests
787 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
789 // Open read-only session on when the token is not initialized should fail
790 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
791 CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
793 // Initialize the library and start the test.
794 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
795 CPPUNIT_ASSERT(rv == CKR_OK);
797 // Open read-only session
798 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
799 CPPUNIT_ASSERT(rv == CKR_OK);
801 // Open read-write session
802 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
803 CPPUNIT_ASSERT(rv == CKR_OK);
805 // Login USER into the sessions so we can create a private objects
806 rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
807 CPPUNIT_ASSERT(rv==CKR_OK);
809 // 3DES and DES always have the block size of 64 bits (0x40 bits 0x8 bytes).
810 // with padding all message sizes could be encrypted-decrypted.
811 // without padding the message size must be a multiple of the block size.
812 const int blockSize(0x8);
815 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
817 // Generate all combinations of session/token keys.
818 rv = generateDesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
819 CPPUNIT_ASSERT(rv == CKR_OK);
821 encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
822 encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
823 encryptDecrypt(CKM_DES_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
824 encryptDecrypt(CKM_DES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
825 encryptDecrypt(CKM_DES_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
826 encryptDecrypt(CKM_DES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
827 encryptDecrypt(CKM_DES_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
829 CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
831 // Generate all combinations of session/token keys.
832 rv = generateDes2Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey2);
833 CPPUNIT_ASSERT(rv == CKR_OK);
835 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
836 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
837 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
838 encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
839 encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
840 encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
841 encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
844 CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
846 // Generate all combinations of session/token keys.
847 rv = generateDes3Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey3);
848 CPPUNIT_ASSERT(rv == CKR_OK);
850 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST-1);
851 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1);
852 encryptDecrypt(CKM_DES3_CBC_PAD,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
853 encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
854 encryptDecrypt(CKM_DES3_CBC,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
855 encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST);
856 encryptDecrypt(CKM_DES3_ECB,blockSize,hSessionRO,hKey,blockSize*NR_OF_BLOCKS_IN_TEST+1, false);
859 void SymmetricAlgorithmTests::testNullTemplate()
862 CK_SESSION_HANDLE hSession;
863 CK_MECHANISM mechanism1 = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
864 CK_MECHANISM mechanism2 = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
865 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
867 // Just make sure that we finalize any previous tests
868 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
870 // Initialize the library and start the test.
871 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
872 CPPUNIT_ASSERT(rv == CKR_OK);
874 // Open read-write session
875 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
876 CPPUNIT_ASSERT(rv == CKR_OK);
878 // Login USER into the sessions so we can create a private objects
879 rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
880 CPPUNIT_ASSERT(rv==CKR_OK);
882 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism1, NULL_PTR, 0, &hKey) );
883 CPPUNIT_ASSERT(rv == CKR_OK);
885 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
886 CPPUNIT_ASSERT(rv == CKR_OK);
888 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism2, NULL_PTR, 0, &hKey) );
889 CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCOMPLETE);
892 void SymmetricAlgorithmTests::testNonModifiableDesKeyGeneration()
895 CK_SESSION_HANDLE hSession;
896 CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
897 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
898 CK_BBOOL bFalse = CK_FALSE;
899 CK_BBOOL bTrue = CK_TRUE;
900 CK_BBOOL bToken = IN_SESSION;
902 CK_ATTRIBUTE keyAttribs[] =
904 { CKA_TOKEN, &bToken, sizeof(bToken) },
905 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
906 { CKA_MODIFIABLE, &bTrue, sizeof(bTrue) },
907 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
908 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
909 { CKA_WRAP, &bTrue, sizeof(bTrue) }
912 // Just make sure that we finalize any previous tests
913 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
915 // Initialize the library and start the test.
916 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
917 CPPUNIT_ASSERT(rv == CKR_OK);
919 // Open read-write session
920 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
921 CPPUNIT_ASSERT(rv == CKR_OK);
923 // Login USER into the sessions so we can create a private objects
924 rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
925 CPPUNIT_ASSERT(rv==CKR_OK);
927 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
928 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
930 CPPUNIT_ASSERT(rv == CKR_OK);
932 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
933 CPPUNIT_ASSERT(rv == CKR_OK);
935 // The C_GenerateKey call failed if CKA_MODIFIABLE was bFalse
936 // This was a bug in the SoftHSM implementation
937 keyAttribs[2].pValue = &bFalse;
938 keyAttribs[2].ulValueLen = sizeof(bFalse);
940 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
941 keyAttribs, sizeof(keyAttribs) / sizeof(CK_ATTRIBUTE),
943 // The call would fail with CKR_ATTRIBUTE_READ_ONLY
944 CPPUNIT_ASSERT(rv == CKR_OK);
946 // Now create a template where the CKA_MODIFIABLE attribute is last in the list
947 CK_ATTRIBUTE keyAttribs1[] =
949 { CKA_TOKEN, &bToken, sizeof(bToken) },
950 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
951 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
952 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
953 { CKA_WRAP, &bTrue, sizeof(bTrue) },
954 { CKA_MODIFIABLE, &bTrue, sizeof(bTrue) }
957 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
958 keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
960 CPPUNIT_ASSERT(rv == CKR_OK);
962 // Now when CKA_MODIFIABLE is bFalse the key generation succeeds
963 keyAttribs1[2].pValue = &bFalse;
964 keyAttribs1[2].ulValueLen = sizeof(bFalse);
966 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
967 keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
969 CPPUNIT_ASSERT(rv == CKR_OK);
972 void SymmetricAlgorithmTests::testCheckValue()
975 CK_SESSION_HANDLE hSession;
976 CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
977 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
979 // Just make sure that we finalize any previous tests
980 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
982 // Initialize the library and start the test.
983 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
984 CPPUNIT_ASSERT(rv == CKR_OK);
986 // Open read-write session
987 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
988 CPPUNIT_ASSERT(rv == CKR_OK);
990 // Login USER into the sessions so we can create a private objects
991 rv = CRYPTOKI_F_PTR( C_Login(hSession, CKU_USER, m_userPin1, m_userPin1Length) );
992 CPPUNIT_ASSERT(rv==CKR_OK);
995 CK_BYTE pCheckValue[] = { 0x2b, 0x84, 0xf6 };
996 CK_BBOOL bFalse = CK_FALSE;
997 CK_BBOOL bTrue = CK_TRUE;
998 CK_ATTRIBUTE keyAttribs[] = {
999 { CKA_TOKEN, &bFalse, sizeof(bFalse) },
1000 { CKA_PRIVATE, &bTrue, sizeof(bTrue) },
1001 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
1002 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
1003 { CKA_WRAP, &bTrue, sizeof(bTrue) },
1004 { CKA_UNWRAP, &bTrue, sizeof(bTrue) },
1005 { CKA_VALUE_LEN, &bytes, sizeof(bytes) },
1006 { CKA_CHECK_VALUE, &pCheckValue, sizeof(pCheckValue) }
1009 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1012 CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_VALUE_INVALID);
1014 keyAttribs[7].ulValueLen = 0;
1015 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1018 CPPUNIT_ASSERT(rv == CKR_OK);
1020 CK_ATTRIBUTE checkAttrib[] = {
1021 { CKA_CHECK_VALUE, &pCheckValue, sizeof(pCheckValue) }
1024 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey, checkAttrib, 1) );
1025 CPPUNIT_ASSERT(rv == CKR_OK);
1026 CPPUNIT_ASSERT(checkAttrib[0].ulValueLen == 0);
1028 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1029 CPPUNIT_ASSERT(rv == CKR_OK);
1031 rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1034 CPPUNIT_ASSERT(rv == CKR_OK);
1036 checkAttrib[0].ulValueLen = sizeof(pCheckValue);
1037 rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey, checkAttrib, 1) );
1038 CPPUNIT_ASSERT(rv == CKR_OK);
1039 CPPUNIT_ASSERT(checkAttrib[0].ulValueLen == 3);
1041 rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1042 CPPUNIT_ASSERT(rv == CKR_OK);
1045 void SymmetricAlgorithmTests::testAesCtrOverflow()
1048 CK_SESSION_HANDLE hSession;
1050 // Just make sure that we finalize any previous tests
1051 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1053 // Initialize the library and start the test.
1054 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1055 CPPUNIT_ASSERT(rv == CKR_OK);
1057 // Open read-write session
1058 rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) );
1059 CPPUNIT_ASSERT(rv == CKR_OK);
1061 // Login USER into the session so we can create a private objects
1062 rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) );
1063 CPPUNIT_ASSERT(rv==CKR_OK);
1065 CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1067 // Generate a session keys.
1068 rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
1069 CPPUNIT_ASSERT(rv == CKR_OK);
1071 CK_MECHANISM mechanism = { CKM_AES_CTR, NULL_PTR, 0 };
1072 CK_AES_CTR_PARAMS ctrParams =
1076 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1080 mechanism.pParameter = &ctrParams;
1081 mechanism.ulParameterLen = sizeof(ctrParams);
1083 CK_BYTE plainText[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1084 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1085 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1087 std::vector<CK_BYTE> vEncryptedData;
1088 std::vector<CK_BYTE> vEncryptedDataParted;
1089 std::vector<CK_BYTE> vDecryptedData;
1090 std::vector<CK_BYTE> vDecryptedDataParted;
1091 CK_ULONG ulEncryptedDataLen;
1092 CK_ULONG ulEncryptedPartLen;
1094 CK_ULONG ulDataPartLen;
1096 // Single-part encryption
1097 rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1098 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1099 rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText),NULL_PTR,&ulEncryptedDataLen) );
1100 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_DATA_LEN_RANGE, rv );
1101 rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1102 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1103 rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedDataLen) );
1104 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1105 vEncryptedData.resize(ulEncryptedDataLen);
1106 rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,plainText,sizeof(plainText)-1,&vEncryptedData.front(),&ulEncryptedDataLen) );
1107 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1108 vEncryptedData.resize(ulEncryptedDataLen);
1110 // Multi-part encryption
1111 rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechanism,hKey) );
1112 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1113 rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,NULL_PTR,&ulEncryptedPartLen) );
1114 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1115 vEncryptedDataParted.resize(ulEncryptedPartLen);
1116 rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,sizeof(plainText)-1,&vEncryptedDataParted.front(),&ulEncryptedPartLen) );
1117 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1118 vEncryptedDataParted.resize(ulEncryptedPartLen);
1119 rv = CRYPTOKI_F_PTR( C_EncryptUpdate(hSession,plainText,1,NULL_PTR,&ulEncryptedPartLen) );
1120 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_DATA_LEN_RANGE, rv );
1122 // Single-part decryption
1123 rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1124 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1125 rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size()+1,NULL_PTR,&ulDataLen) );
1126 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
1127 rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1128 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1129 rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataLen) );
1130 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1131 vDecryptedData.resize(ulDataLen);
1132 rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedData.front(),&ulDataLen) );
1133 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1134 vDecryptedData.resize(ulDataLen);
1136 // Multi-part decryption
1137 rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechanism,hKey) );
1138 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1139 rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataPartLen) );
1140 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1141 vDecryptedDataParted.resize(ulDataPartLen);
1142 rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),vEncryptedData.size(),&vDecryptedDataParted.front(),&ulDataPartLen) );
1143 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
1144 vDecryptedDataParted.resize(ulDataPartLen);
1145 rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),1,NULL_PTR,&ulDataPartLen) );
1146 CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );