Remove win32 support in SoftHSMv2
[aaf/sshsm.git] / SoftHSMv2 / src / lib / test / SymmetricAlgorithmTests.cpp
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
52 CK_RV SymmetricAlgorithmTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
53 {
54         CK_MECHANISM mechanism = { CKM_AES_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
74 #ifndef WITH_FIPS
75 CK_RV SymmetricAlgorithmTests::generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
76 {
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) },
85         };
86
87         hKey = CK_INVALID_HANDLE;
88         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
89                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
90                              &hKey) );
91 }
92
93 CK_RV SymmetricAlgorithmTests::generateDes2Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
94 {
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) },
103         };
104
105         hKey = CK_INVALID_HANDLE;
106         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
107                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
108                              &hKey) );
109 }
110 #endif
111
112 CK_RV SymmetricAlgorithmTests::generateDes3Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
113 {
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) },
122         };
123
124         hKey = CK_INVALID_HANDLE;
125         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
126                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
127                              &hKey) );
128 }
129
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,
136                 const bool isSizeOK)
137 {
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.
140                 const int blockSize;
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.
144         public:
145                 PartSize(
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
153                         return current;
154                 }
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;
159                                 return current;
160                         }
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;
168                         return current;
169                 }
170         };
171
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);
176
177         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_GenerateRandom(hSession, (CK_BYTE_PTR)&vData.front(), messageSize) ) );
178
179         const CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
180         CK_MECHANISM_PTR pMechanism((CK_MECHANISM_PTR)&mechanism);
181         CK_AES_CTR_PARAMS ctrParams =
182         {
183                 32,
184                 {
185                         0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
186                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
187                 }
188         };
189         CK_BYTE gcmIV[] = {
190                 0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE,
191                 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88
192         };
193         CK_BYTE gcmAAD[] = {
194                 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
195                 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF,
196                 0xAB, 0xAD, 0xDA, 0xD2
197         };
198         CK_GCM_PARAMS gcmParams =
199         {
200                 &gcmIV[0],
201                 sizeof(gcmIV),
202                 sizeof(gcmIV)*8,
203                 &gcmAAD[0],
204                 sizeof(gcmAAD),
205                 16*8
206         };
207
208         switch (mechanismType)
209         {
210                 case CKM_DES_CBC:
211                 case CKM_DES_CBC_PAD:
212                 case CKM_DES3_CBC:
213                 case CKM_DES3_CBC_PAD:
214                 case CKM_AES_CBC:
215                 case CKM_AES_CBC_PAD:
216                         pMechanism->pParameter = (CK_VOID_PTR)&vData.front();
217                         pMechanism->ulParameterLen = blockSize;
218                         break;
219                 case CKM_AES_CTR:
220                         pMechanism->pParameter = &ctrParams;
221                         pMechanism->ulParameterLen = sizeof(ctrParams);
222                         break;
223                 case CKM_AES_GCM:
224                         pMechanism->pParameter = &gcmParams;
225                         pMechanism->ulParameterLen = sizeof(gcmParams);
226                         break;
227                 default:
228                         break;
229         }
230
231         // Single-part encryption
232         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
233         {
234                 CK_ULONG ulEncryptedDataLen;
235                 const CK_RV rv( CRYPTOKI_F_PTR( C_Encrypt(hSession,(CK_BYTE_PTR)&vData.front(),messageSize,NULL_PTR,&ulEncryptedDataLen) ) );
236                 if ( isSizeOK ) {
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);
241                 } else {
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;
244                 }
245         }
246
247         // Multi-part encryption
248         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_EncryptInit(hSession,pMechanism,hKey) ) );
249
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);
256                 CK_BYTE dummy;
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);
260         }
261         {
262                 CK_ULONG ulLastEncryptedPartLen;
263                 const CK_RV rv( CRYPTOKI_F_PTR( C_EncryptFinal(hSession,NULL_PTR,&ulLastEncryptedPartLen) ) );
264                 if ( isSizeOK ) {
265                         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, rv );
266                         const size_t oldSize( vEncryptedDataParted.size() );
267                         CK_BYTE dummy;
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);
272                 } else {
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;
275                 }
276         }
277
278         // Single-part decryption
279         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
280
281         {
282                 CK_ULONG ulDataLen;
283                 const CK_RV rv( CRYPTOKI_F_PTR( C_Decrypt(hSession,&vEncryptedData.front(),vEncryptedData.size(),NULL_PTR,&ulDataLen) ) );
284                 if ( isSizeOK ) {
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);
290                 } else {
291                         CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_Decrypt should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
292                 }
293         }
294
295         // Multi-part decryption
296         CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_DecryptInit(hSession,pMechanism,hKey) ) );
297         {
298                 std::vector<CK_BYTE> vDecryptedData;
299                 CK_BYTE dummy;
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);
309                 }
310                 {
311                         CK_ULONG ulLastPartLen;
312                         const CK_RV rv( CRYPTOKI_F_PTR( C_DecryptFinal(hSession,NULL_PTR,&ulLastPartLen) ) );
313                         if ( isSizeOK ) {
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);
321                         } else {
322                                 CPPUNIT_ASSERT_EQUAL_MESSAGE( "C_EncryptFinal should fail with CKR_ENCRYPTED_DATA_LEN_RANGE", (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv );
323                         }
324                 }
325         }
326 }
327
328 CK_RV SymmetricAlgorithmTests::generateRsaPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
329 {
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) }
345         };
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) }
357         };
358
359         CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
360         hKey = CK_INVALID_HANDLE;
361         CK_RV rv;
362         rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
363                                pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
364                                privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
365                                &hPub, &hKey) );
366         if (hPub != CK_INVALID_HANDLE)
367         {
368                 CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
369         }
370         return rv;
371 }
372
373 #ifdef WITH_GOST
374 CK_RV SymmetricAlgorithmTests::generateGostPrivateKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
375 {
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, &param_a[0], sizeof(param_a) },
390                 { CKA_GOSTR3411_PARAMS, &param_b[0], sizeof(param_b) }
391         };
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) }
403         };
404
405         CK_OBJECT_HANDLE hPub = CK_INVALID_HANDLE;
406         hKey = CK_INVALID_HANDLE;
407         CK_RV rv;
408         rv = CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
409                                pubAttribs, sizeof(pubAttribs)/sizeof(CK_ATTRIBUTE),
410                                privAttribs, sizeof(privAttribs)/sizeof(CK_ATTRIBUTE),
411                                &hPub, &hKey) );
412         if (hPub != CK_INVALID_HANDLE)
413         {
414                 CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPub) );
415         }
416         return rv;
417 }
418 #endif
419
420 void SymmetricAlgorithmTests::aesWrapUnwrapGeneric(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
421 {
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;
427         CK_BYTE keyPtr[128];
428         CK_ULONG keyLen =
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 }
438         };
439         CK_OBJECT_HANDLE hSecret;
440         CK_RV rv;
441
442         rv = CRYPTOKI_F_PTR( C_GenerateRandom(hSession, keyPtr, keyLen) );
443         CPPUNIT_ASSERT(rv == CKR_OK);
444
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);
449
450         CK_BYTE_PTR wrappedPtr = NULL_PTR;
451         CK_ULONG wrappedLen = 0UL;
452         CK_ULONG zero = 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);
460
461         attribs[0].pValue = &bTrue;
462
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);
467
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);
472
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);
478
479         // This should always fail because wrapped data have to be longer than 0 bytes
480         zero = 0;
481         rv = CRYPTOKI_F_PTR( C_WrapKey(hSession, &mechanism, hKey, hSecret, wrappedPtr, &zero) );
482         CPPUNIT_ASSERT(rv == CKR_BUFFER_TOO_SMALL);
483
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) }
493         };
494         CK_OBJECT_HANDLE hNew;
495
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);
500
501         free(wrappedPtr);
502         wrappedPtr = NULL_PTR;
503         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hSecret) );
504         CPPUNIT_ASSERT(rv == CKR_OK);
505 }
506
507 void SymmetricAlgorithmTests::aesWrapUnwrapRsa(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
508 {
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);
516
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 }
525         };
526
527         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
528         CPPUNIT_ASSERT(rv == CKR_OK);
529
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);
534
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;
540
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);
544
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);
553
554         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
555         CPPUNIT_ASSERT(rv == CKR_OK);
556
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) }
567         };
568
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);
573
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);
577
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);
584
585         free(wrappedPtr);
586         free(prkAttrPtr);
587         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
588         CPPUNIT_ASSERT(rv == CKR_OK);
589 }
590
591 #ifdef WITH_GOST
592 void SymmetricAlgorithmTests::aesWrapUnwrapGost(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
593 {
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);
601
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 }
610         };
611
612         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPrk, prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE)) );
613         CPPUNIT_ASSERT(rv == CKR_OK);
614
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);
619
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;
625
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);
629
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);
638
639         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
640         CPPUNIT_ASSERT(rv == CKR_OK);
641
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) }
652         };
653
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);
658
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);
662
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);
669
670         free(wrappedPtr);
671         free(prkAttrPtr);
672         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hPrk) );
673         CPPUNIT_ASSERT(rv == CKR_OK);
674 }
675 #endif
676
677 void SymmetricAlgorithmTests::testAesEncryptDecrypt()
678 {
679         CK_RV rv;
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;
684
685         // Just make sure that we finalize any previous tests
686         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
687
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);
691
692         // Initialize the library and start the test.
693         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
694         CPPUNIT_ASSERT(rv == CKR_OK);
695
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);
699
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);
703
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);
707
708         CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
709
710         // Generate all combinations of session/token keys.
711         rv = generateAesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
712         CPPUNIT_ASSERT(rv == CKR_OK);
713
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);
728 #ifdef WITH_AES_GCM
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);
732 #endif
733 }
734
735 void SymmetricAlgorithmTests::testAesWrapUnwrap()
736 {
737         CK_RV rv;
738         // CK_UTF8CHAR sopin[] = SLOT_0_SO1_PIN;
739         // CK_ULONG sopinLength = sizeof(sopin) - 1;
740         CK_SESSION_HANDLE hSession;
741
742         // Just make sure that we finalize any previous tests
743         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
744
745         // Initialize the library and start the test.
746         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
747         CPPUNIT_ASSERT(rv == CKR_OK);
748
749         // Open session
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);
752
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);
756
757         CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
758
759         // Generate a wrapping session public key
760         rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
761         CPPUNIT_ASSERT(rv == CKR_OK);
762
763         aesWrapUnwrapGeneric(CKM_AES_KEY_WRAP, hSession, hKey);
764         aesWrapUnwrapRsa(CKM_AES_KEY_WRAP, hSession, hKey);
765 #ifdef WITH_GOST
766         aesWrapUnwrapGost(CKM_AES_KEY_WRAP, hSession, hKey);
767 #endif
768
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);
772 #ifdef WITH_GOST
773         aesWrapUnwrapGost(CKM_AES_KEY_WRAP_PAD, hSession, hKey);
774 #endif
775 #endif
776 }
777
778 void SymmetricAlgorithmTests::testDesEncryptDecrypt()
779 {
780         CK_RV rv;
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;
785
786         // Just make sure that we finalize any previous tests
787         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
788
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);
792
793         // Initialize the library and start the test.
794         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
795         CPPUNIT_ASSERT(rv == CKR_OK);
796
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);
800
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);
804
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);
808
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);
813
814 #ifndef WITH_FIPS
815         CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
816
817         // Generate all combinations of session/token keys.
818         rv = generateDesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKey);
819         CPPUNIT_ASSERT(rv == CKR_OK);
820
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);
828
829         CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
830
831         // Generate all combinations of session/token keys.
832         rv = generateDes2Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey2);
833         CPPUNIT_ASSERT(rv == CKR_OK);
834
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);
842 #endif
843
844         CK_OBJECT_HANDLE hKey3 = CK_INVALID_HANDLE;
845
846         // Generate all combinations of session/token keys.
847         rv = generateDes3Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKey3);
848         CPPUNIT_ASSERT(rv == CKR_OK);
849
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);
857 }
858
859 void SymmetricAlgorithmTests::testNullTemplate()
860 {
861         CK_RV rv;
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;
866
867         // Just make sure that we finalize any previous tests
868         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
869
870         // Initialize the library and start the test.
871         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
872         CPPUNIT_ASSERT(rv == CKR_OK);
873
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);
877
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);
881
882         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism1, NULL_PTR, 0, &hKey) );
883         CPPUNIT_ASSERT(rv == CKR_OK);
884
885         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
886         CPPUNIT_ASSERT(rv == CKR_OK);
887
888         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism2, NULL_PTR, 0, &hKey) );
889         CPPUNIT_ASSERT(rv == CKR_TEMPLATE_INCOMPLETE);
890 }
891
892 void SymmetricAlgorithmTests::testNonModifiableDesKeyGeneration()
893 {
894         CK_RV rv;
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;
901
902         CK_ATTRIBUTE keyAttribs[] =
903                 {
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) }
910         };
911
912         // Just make sure that we finalize any previous tests
913         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
914
915         // Initialize the library and start the test.
916         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
917         CPPUNIT_ASSERT(rv == CKR_OK);
918
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);
922
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);
926
927         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
928                 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
929                 &hKey) );
930         CPPUNIT_ASSERT(rv == CKR_OK);
931
932         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
933         CPPUNIT_ASSERT(rv == CKR_OK);
934
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);
939
940         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
941                 keyAttribs, sizeof(keyAttribs) / sizeof(CK_ATTRIBUTE),
942                 &hKey) );
943         // The call would fail with CKR_ATTRIBUTE_READ_ONLY
944         CPPUNIT_ASSERT(rv == CKR_OK);
945
946         // Now create a template where the CKA_MODIFIABLE attribute is last in the list
947         CK_ATTRIBUTE keyAttribs1[] =
948         {
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) }
955         };
956
957         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
958                 keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
959                 &hKey) );
960         CPPUNIT_ASSERT(rv == CKR_OK);
961
962         // Now when CKA_MODIFIABLE is bFalse the key generation succeeds
963         keyAttribs1[2].pValue = &bFalse;
964         keyAttribs1[2].ulValueLen = sizeof(bFalse);
965
966         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
967                 keyAttribs1, sizeof(keyAttribs1) / sizeof(CK_ATTRIBUTE),
968                 &hKey) );
969         CPPUNIT_ASSERT(rv == CKR_OK);
970 }
971
972 void SymmetricAlgorithmTests::testCheckValue()
973 {
974         CK_RV rv;
975         CK_SESSION_HANDLE hSession;
976         CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
977         CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
978
979         // Just make sure that we finalize any previous tests
980         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
981
982         // Initialize the library and start the test.
983         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
984         CPPUNIT_ASSERT(rv == CKR_OK);
985
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);
989
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);
993
994         CK_ULONG bytes = 16;
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) }
1007         };
1008
1009         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1010                            keyAttribs, 8,
1011                            &hKey) );
1012         CPPUNIT_ASSERT(rv == CKR_ATTRIBUTE_VALUE_INVALID);
1013
1014         keyAttribs[7].ulValueLen = 0;
1015         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1016                            keyAttribs, 8,
1017                            &hKey) );
1018         CPPUNIT_ASSERT(rv == CKR_OK);
1019
1020         CK_ATTRIBUTE checkAttrib[] = {
1021                 { CKA_CHECK_VALUE, &pCheckValue, sizeof(pCheckValue) }
1022         };
1023
1024         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey, checkAttrib, 1) );
1025         CPPUNIT_ASSERT(rv == CKR_OK);
1026         CPPUNIT_ASSERT(checkAttrib[0].ulValueLen == 0);
1027
1028         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1029         CPPUNIT_ASSERT(rv == CKR_OK);
1030
1031         rv = CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
1032                            keyAttribs, 7,
1033                            &hKey) );
1034         CPPUNIT_ASSERT(rv == CKR_OK);
1035
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);
1040
1041         rv = CRYPTOKI_F_PTR( C_DestroyObject(hSession, hKey) );
1042         CPPUNIT_ASSERT(rv == CKR_OK);
1043 }
1044
1045 void SymmetricAlgorithmTests::testAesCtrOverflow()
1046 {
1047         CK_RV rv;
1048         CK_SESSION_HANDLE hSession;
1049
1050         // Just make sure that we finalize any previous tests
1051         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
1052
1053         // Initialize the library and start the test.
1054         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
1055         CPPUNIT_ASSERT(rv == CKR_OK);
1056
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);
1060
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);
1064
1065         CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
1066
1067         // Generate a session keys.
1068         rv = generateAesKey(hSession,IN_SESSION,IS_PUBLIC,hKey);
1069         CPPUNIT_ASSERT(rv == CKR_OK);
1070
1071         CK_MECHANISM mechanism = { CKM_AES_CTR, NULL_PTR, 0 };
1072         CK_AES_CTR_PARAMS ctrParams =
1073         {
1074                 2,
1075                 {
1076                         0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1077                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1078                 }
1079         };
1080         mechanism.pParameter = &ctrParams;
1081         mechanism.ulParameterLen = sizeof(ctrParams);
1082
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,
1086                                 0x00 };
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;
1093         CK_ULONG ulDataLen;
1094         CK_ULONG ulDataPartLen;
1095
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);
1109
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 );
1121
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);
1135
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 );
1147 }