Initial sshsm project structure
[aaf/sshsm.git] / SoftHSMv2 / src / lib / test / DeriveTests.cpp
1 /*
2  * Copyright (c) 2014 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  DeriveTests.cpp
29
30  Contains test cases for:
31          C_DeriveKey
32
33  *****************************************************************************/
34
35 #include <config.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include "DeriveTests.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
49 CPPUNIT_TEST_SUITE_REGISTRATION(DeriveTests);
50
51 CK_RV DeriveTests::generateDhKeyPair(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk)
52 {
53         CK_MECHANISM mechanism = { CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
54         CK_BBOOL bTrue = CK_TRUE;
55         CK_BYTE bn1024[] = {
56                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57                 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34,
58                 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,
59                 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
60                 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22,
61                 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
62                 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
63                 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37,
64                 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,
65                 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
66                 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b,
67                 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
68                 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
69                 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6,
70                 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81,
71                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
72         };
73         CK_BYTE bn2[] = { 2 };
74         CK_ATTRIBUTE pukAttribs[] = {
75                 { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) },
76                 { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) },
77                 { CKA_PRIME, &bn1024, sizeof(bn1024) },
78                 { CKA_BASE, &bn2, sizeof(bn2) }
79         };
80         CK_ATTRIBUTE prkAttribs[] = {
81                 { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) },
82                 { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) },
83                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
84                 { CKA_DERIVE, &bTrue, sizeof(bTrue) }
85         };
86
87         hPuk = CK_INVALID_HANDLE;
88         hPrk = CK_INVALID_HANDLE;
89         return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
90                         pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE),
91                         prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE),
92                         &hPuk, &hPrk) );
93 }
94
95 #ifdef WITH_ECC
96 CK_RV DeriveTests::generateEcKeyPair(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk)
97 {
98         CK_MECHANISM mechanism = { CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0 };
99         CK_KEY_TYPE keyType = CKK_EC;
100         CK_BYTE oidP256[] = { 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 };
101         CK_BYTE oidP384[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22 };
102         CK_BYTE oidP521[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23 };
103         CK_BBOOL bTrue = CK_TRUE;
104         CK_ATTRIBUTE pukAttribs[] = {
105                 { CKA_EC_PARAMS, NULL, 0 },
106                 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
107                 { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) },
108                 { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) }
109         };
110         CK_ATTRIBUTE prkAttribs[] = {
111                 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
112                 { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) },
113                 { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) },
114                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
115                 { CKA_DERIVE, &bTrue, sizeof(bTrue) }
116         };
117
118         /* Select the curve */
119         if (strcmp(curve, "P-256") == 0)
120         {
121                 pukAttribs[0].pValue = oidP256;
122                 pukAttribs[0].ulValueLen = sizeof(oidP256);
123         }
124         else if (strcmp(curve, "P-384") == 0)
125         {
126                 pukAttribs[0].pValue = oidP384;
127                 pukAttribs[0].ulValueLen = sizeof(oidP384);
128         }
129         else if (strcmp(curve, "P-521") == 0)
130         {
131                 pukAttribs[0].pValue = oidP521;
132                 pukAttribs[0].ulValueLen = sizeof(oidP521);
133         }
134         else
135         {
136                 return CKR_GENERAL_ERROR;
137         }
138
139         hPuk = CK_INVALID_HANDLE;
140         hPrk = CK_INVALID_HANDLE;
141         return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism,
142                         pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE),
143                         prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE),
144                         &hPuk, &hPrk) );
145 }
146 #endif
147
148 CK_RV DeriveTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
149 {
150         CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
151         CK_ULONG bytes = 16;
152         // CK_BBOOL bFalse = CK_FALSE;
153         CK_BBOOL bTrue = CK_TRUE;
154         CK_ATTRIBUTE keyAttribs[] = {
155                 { CKA_TOKEN, &bToken, sizeof(bToken) },
156                 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
157                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
158                 { CKA_DERIVE, &bTrue, sizeof(bTrue) },
159                 { CKA_VALUE_LEN, &bytes, sizeof(bytes) }
160         };
161
162         hKey = CK_INVALID_HANDLE;
163         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
164                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
165                              &hKey) );
166 }
167
168 #ifndef WITH_FIPS
169 CK_RV DeriveTests::generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
170 {
171         CK_MECHANISM mechanism = { CKM_DES_KEY_GEN, NULL_PTR, 0 };
172         // CK_BBOOL bFalse = CK_FALSE;
173         CK_BBOOL bTrue = CK_TRUE;
174         CK_ATTRIBUTE keyAttribs[] = {
175                 { CKA_TOKEN, &bToken, sizeof(bToken) },
176                 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
177                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
178                 { CKA_DERIVE, &bTrue, sizeof(bTrue) }
179         };
180
181         hKey = CK_INVALID_HANDLE;
182         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
183                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
184                              &hKey) );
185 }
186 #endif
187
188 CK_RV DeriveTests::generateDes2Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
189 {
190         CK_MECHANISM mechanism = { CKM_DES2_KEY_GEN, NULL_PTR, 0 };
191         // CK_BBOOL bFalse = CK_FALSE;
192         CK_BBOOL bTrue = CK_TRUE;
193         CK_ATTRIBUTE keyAttribs[] = {
194                 { CKA_TOKEN, &bToken, sizeof(bToken) },
195                 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
196                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
197                 { CKA_DERIVE, &bTrue, sizeof(bTrue) }
198         };
199
200         hKey = CK_INVALID_HANDLE;
201         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
202                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
203                              &hKey) );
204 }
205
206 CK_RV DeriveTests::generateDes3Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
207 {
208         CK_MECHANISM mechanism = { CKM_DES3_KEY_GEN, NULL_PTR, 0 };
209         // CK_BBOOL bFalse = CK_FALSE;
210         CK_BBOOL bTrue = CK_TRUE;
211         CK_ATTRIBUTE keyAttribs[] = {
212                 { CKA_TOKEN, &bToken, sizeof(bToken) },
213                 { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) },
214                 { CKA_SENSITIVE, &bTrue, sizeof(bTrue) },
215                 { CKA_DERIVE, &bTrue, sizeof(bTrue) }
216         };
217
218         hKey = CK_INVALID_HANDLE;
219         return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
220                              keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
221                              &hKey) );
222 }
223
224 void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey)
225 {
226         CK_ATTRIBUTE valAttrib = { CKA_VALUE, NULL_PTR, 0 };
227         CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
228         CPPUNIT_ASSERT(rv == CKR_OK);
229         valAttrib.pValue = (CK_BYTE_PTR)malloc(valAttrib.ulValueLen);
230         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
231         CPPUNIT_ASSERT(rv == CKR_OK);
232         CK_MECHANISM mechanism = { CKM_DH_PKCS_DERIVE, NULL_PTR, 0 };
233         mechanism.pParameter = valAttrib.pValue;
234         mechanism.ulParameterLen = valAttrib.ulValueLen;
235         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
236         CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
237         CK_BBOOL bFalse = CK_FALSE;
238         CK_BBOOL bTrue = CK_TRUE;
239         CK_ULONG secLen = 32;
240         CK_ATTRIBUTE keyAttribs[] = {
241                 { CKA_CLASS, &keyClass, sizeof(keyClass) },
242                 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
243                 { CKA_PRIVATE, &bFalse, sizeof(bFalse) },
244                 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
245                 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) },
246                 { CKA_VALUE_LEN, &secLen, sizeof(secLen) }
247         };
248
249         hKey = CK_INVALID_HANDLE;
250         rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hPrivateKey,
251                          keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
252                          &hKey) );
253         free(valAttrib.pValue);
254         CPPUNIT_ASSERT(rv == CKR_OK);
255 }
256
257 #ifdef WITH_ECC
258 void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw)
259 {
260         CK_ATTRIBUTE valAttrib = { CKA_EC_POINT, NULL_PTR, 0 };
261         CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
262         CPPUNIT_ASSERT(rv == CKR_OK);
263         valAttrib.pValue = (CK_BYTE_PTR)malloc(valAttrib.ulValueLen);
264         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hPublicKey, &valAttrib, 1) );
265         CPPUNIT_ASSERT(rv == CKR_OK);
266
267         CK_ECDH1_DERIVE_PARAMS parms = { CKD_NULL, 0, NULL_PTR, 0, NULL_PTR };
268         // Use RAW or DER format
269         if (useRaw)
270         {
271                 size_t offset = 0;
272                 unsigned char* buf = (unsigned char*)valAttrib.pValue;
273                 if (valAttrib.ulValueLen > 2 && buf[0] == 0x04)
274                 {
275                         if (buf[1] < 0x80)
276                         {
277                                 offset = 2;
278                         }
279                         else
280                         {
281                                 if (valAttrib.ulValueLen > ((buf[1] & 0x7F) + (unsigned int)2))
282                                 {
283                                         offset = 2 + (buf[1] & 0x7F);
284                                 }
285                         }
286                 }
287                 parms.pPublicData = buf + offset;
288                 parms.ulPublicDataLen = valAttrib.ulValueLen - offset;
289         }
290         else
291         {
292                 parms.pPublicData = (unsigned char*)valAttrib.pValue;
293                 parms.ulPublicDataLen = valAttrib.ulValueLen;
294         }
295
296         CK_MECHANISM mechanism = { CKM_ECDH1_DERIVE, NULL, 0 };
297         mechanism.pParameter = &parms;
298         mechanism.ulParameterLen = sizeof(parms);
299         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
300         CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
301         CK_BBOOL bFalse = CK_FALSE;
302         CK_BBOOL bTrue = CK_TRUE;
303         CK_ULONG secLen = 32;
304         CK_ATTRIBUTE keyAttribs[] = {
305                 { CKA_CLASS, &keyClass, sizeof(keyClass) },
306                 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
307                 { CKA_PRIVATE, &bFalse, sizeof(bFalse) },
308                 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
309                 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) },
310                 { CKA_VALUE_LEN, &secLen, sizeof(secLen) }
311         };
312
313         hKey = CK_INVALID_HANDLE;
314         rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hPrivateKey,
315                          keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
316                          &hKey) );
317         free(valAttrib.pValue);
318         CPPUNIT_ASSERT(rv == CKR_OK);
319 }
320 #endif
321
322 bool DeriveTests::compareSecret(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey1, CK_OBJECT_HANDLE hKey2)
323 {
324         CK_ATTRIBUTE keyAttribs[] = {
325                 { CKA_VALUE, NULL_PTR, 0 },
326                 { CKA_CHECK_VALUE, NULL_PTR, 0 }
327         };
328         CK_BYTE val1[128];
329         CK_BYTE check1[3];
330         keyAttribs[0].pValue = val1;
331         keyAttribs[0].ulValueLen = sizeof(val1);
332         keyAttribs[1].pValue = check1;
333         keyAttribs[1].ulValueLen = sizeof(check1);
334         CK_RV rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey1, keyAttribs, 2) );
335         CPPUNIT_ASSERT(rv == CKR_OK);
336         CPPUNIT_ASSERT(keyAttribs[0].ulValueLen == 32);
337         CPPUNIT_ASSERT(keyAttribs[1].ulValueLen == 3);
338         CK_BYTE val2[128];
339         CK_BYTE check2[3];
340         keyAttribs[0].pValue = val2;
341         keyAttribs[0].ulValueLen = sizeof(val2);
342         keyAttribs[1].pValue = check2;
343         keyAttribs[1].ulValueLen = sizeof(check2);
344         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hKey2, keyAttribs, 2) );
345         CPPUNIT_ASSERT(rv == CKR_OK);
346         CPPUNIT_ASSERT(keyAttribs[0].ulValueLen == 32);
347         CPPUNIT_ASSERT(keyAttribs[1].ulValueLen == 3);
348         return memcmp(val1, val2, 32) == 0 &&
349                memcmp(check1, check2, 3) == 0;
350 }
351
352 void DeriveTests::testDhDerive()
353 {
354         CK_RV rv;
355         CK_SESSION_HANDLE hSessionRO;
356         CK_SESSION_HANDLE hSessionRW;
357
358         // Just make sure that we finalize any previous tests
359         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
360
361         // Open read-only session on when the token is not initialized should fail
362         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
363         CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
364
365         // Initialize the library and start the test.
366         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
367         CPPUNIT_ASSERT(rv == CKR_OK);
368
369         // Open read-only session
370         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
371         CPPUNIT_ASSERT(rv == CKR_OK);
372
373         // Open read-write session
374         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
375         CPPUNIT_ASSERT(rv == CKR_OK);
376
377         // Login USER into the sessions so we can create a private objects
378         rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
379         CPPUNIT_ASSERT(rv == CKR_OK);
380
381         // Public Session keys
382         CK_OBJECT_HANDLE hPuk1 = CK_INVALID_HANDLE;
383         CK_OBJECT_HANDLE hPrk1 = CK_INVALID_HANDLE;
384         CK_OBJECT_HANDLE hPuk2 = CK_INVALID_HANDLE;
385         CK_OBJECT_HANDLE hPrk2 = CK_INVALID_HANDLE;
386
387         rv = generateDhKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk1,hPrk1);
388         CPPUNIT_ASSERT(rv == CKR_OK);
389         rv = generateDhKeyPair(hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
390         CPPUNIT_ASSERT(rv == CKR_OK);
391         CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
392         dhDerive(hSessionRW,hPuk1,hPrk2,hKey1);
393         CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
394         dhDerive(hSessionRW,hPuk2,hPrk1,hKey2);
395         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
396
397         // Private Session Keys
398         rv = generateDhKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
399         CPPUNIT_ASSERT(rv == CKR_OK);
400         rv = generateDhKeyPair(hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
401         CPPUNIT_ASSERT(rv == CKR_OK);
402         dhDerive(hSessionRW,hPuk1,hPrk2,hKey1);
403         dhDerive(hSessionRW,hPuk2,hPrk1,hKey2);
404         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
405
406         // Public Token Keys
407         rv = generateDhKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
408         CPPUNIT_ASSERT(rv == CKR_OK);
409         rv = generateDhKeyPair(hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
410         CPPUNIT_ASSERT(rv == CKR_OK);
411         dhDerive(hSessionRW,hPuk1,hPrk2,hKey1);
412         dhDerive(hSessionRW,hPuk2,hPrk1,hKey2);
413         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
414
415         // Private Token Keys
416         rv = generateDhKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
417         CPPUNIT_ASSERT(rv == CKR_OK);
418         rv = generateDhKeyPair(hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
419         CPPUNIT_ASSERT(rv == CKR_OK);
420         dhDerive(hSessionRW,hPuk1,hPrk2,hKey1);
421         dhDerive(hSessionRW,hPuk2,hPrk1,hKey2);
422         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
423 }
424
425 #ifdef WITH_ECC
426 void DeriveTests::testEcdhDerive()
427 {
428         CK_RV rv;
429         CK_SESSION_HANDLE hSessionRO;
430         CK_SESSION_HANDLE hSessionRW;
431
432         // Just make sure that we finalize any previous tests
433         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
434
435         // Open read-only session on when the token is not initialized should fail
436         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
437         CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
438
439         // Initialize the library and start the test.
440         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
441         CPPUNIT_ASSERT(rv == CKR_OK);
442
443         // Open read-only session
444         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
445         CPPUNIT_ASSERT(rv == CKR_OK);
446
447         // Open read-write session
448         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
449         CPPUNIT_ASSERT(rv == CKR_OK);
450
451         // Login USER into the sessions so we can create a private objects
452         rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
453         CPPUNIT_ASSERT(rv == CKR_OK);
454
455         // Public Session keys
456         CK_OBJECT_HANDLE hPuk1 = CK_INVALID_HANDLE;
457         CK_OBJECT_HANDLE hPrk1 = CK_INVALID_HANDLE;
458         CK_OBJECT_HANDLE hPuk2 = CK_INVALID_HANDLE;
459         CK_OBJECT_HANDLE hPrk2 = CK_INVALID_HANDLE;
460
461         rv = generateEcKeyPair("P-256",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk1,hPrk1);
462         CPPUNIT_ASSERT(rv == CKR_OK);
463         rv = generateEcKeyPair("P-256",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2);
464         CPPUNIT_ASSERT(rv == CKR_OK);
465         CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE;
466         ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
467         CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE;
468         ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
469         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
470
471         // Private Session Keys
472         rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1);
473         CPPUNIT_ASSERT(rv == CKR_OK);
474         rv = generateEcKeyPair("P-384",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2);
475         CPPUNIT_ASSERT(rv == CKR_OK);
476         ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
477         ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
478         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
479
480         // Public Token Keys
481         rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1);
482         CPPUNIT_ASSERT(rv == CKR_OK);
483         rv = generateEcKeyPair("P-521",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2);
484         CPPUNIT_ASSERT(rv == CKR_OK);
485         ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
486         ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
487         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
488
489         // Private Token Keys
490         rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1);
491         CPPUNIT_ASSERT(rv == CKR_OK);
492         rv = generateEcKeyPair("P-256",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2);
493         CPPUNIT_ASSERT(rv == CKR_OK);
494         ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true);
495         ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false);
496         CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2));
497 }
498 #endif
499
500 void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE &hDerive, CK_MECHANISM_TYPE mechType, CK_KEY_TYPE keyType)
501 {
502         CK_RV rv;
503         CK_MECHANISM mechanism = { mechType, NULL_PTR, 0 };
504         CK_MECHANISM mechEncrypt = { CKM_VENDOR_DEFINED, NULL_PTR, 0 };
505         CK_KEY_DERIVATION_STRING_DATA param1;
506         CK_DES_CBC_ENCRYPT_DATA_PARAMS param2;
507         CK_AES_CBC_ENCRYPT_DATA_PARAMS param3;
508
509         CK_BYTE data[] = {
510                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
511                 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
512                 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24,
513                 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32
514         };
515         CK_ULONG secLen = 0;
516
517         switch (mechType)
518         {
519                 case CKM_DES_ECB_ENCRYPT_DATA:
520                 case CKM_DES3_ECB_ENCRYPT_DATA:
521                 case CKM_AES_ECB_ENCRYPT_DATA:
522                         param1.pData = &data[0];
523                         param1.ulLen = sizeof(data);
524                         mechanism.pParameter = &param1;
525                         mechanism.ulParameterLen = sizeof(param1);
526                         break;
527                 case CKM_DES_CBC_ENCRYPT_DATA:
528                 case CKM_DES3_CBC_ENCRYPT_DATA:
529                         memcpy(param2.iv, "12345678", 8);
530                         param2.pData = &data[0];
531                         param2.length = sizeof(data);
532                         mechanism.pParameter = &param2;
533                         mechanism.ulParameterLen = sizeof(param2);
534                         break;
535                 case CKM_AES_CBC_ENCRYPT_DATA:
536                         memcpy(param3.iv, "1234567890ABCDEF", 16);
537                         param3.pData = &data[0];
538                         param3.length = sizeof(data);
539                         mechanism.pParameter = &param3;
540                         mechanism.ulParameterLen = sizeof(param3);
541                         break;
542                 default:
543                         CPPUNIT_FAIL("Invalid mechanism");
544         }
545
546         switch (keyType)
547         {
548                 case CKK_GENERIC_SECRET:
549                         secLen = 32;
550                         break;
551                 case CKK_DES:
552                         mechEncrypt.mechanism = CKM_DES_ECB;
553                         break;
554                 case CKK_DES2:
555                 case CKK_DES3:
556                         mechEncrypt.mechanism = CKM_DES3_ECB;
557                         break;
558                 case CKK_AES:
559                         mechEncrypt.mechanism = CKM_AES_ECB;
560                         secLen = 32;
561                         break;
562                 default:
563                         CPPUNIT_FAIL("Invalid key type");
564         }
565
566         CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
567         CK_BBOOL bFalse = CK_FALSE;
568         CK_BBOOL bTrue = CK_TRUE;
569         CK_ATTRIBUTE keyAttribs[] = {
570                 { CKA_CLASS, &keyClass, sizeof(keyClass) },
571                 { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
572                 { CKA_PRIVATE, &bFalse, sizeof(bFalse) },
573                 { CKA_ENCRYPT, &bTrue, sizeof(bTrue) },
574                 { CKA_DECRYPT, &bTrue, sizeof(bTrue) },
575                 { CKA_SENSITIVE, &bFalse, sizeof(bFalse) },
576                 { CKA_EXTRACTABLE, &bTrue, sizeof(bTrue) },
577                 { CKA_VALUE_LEN, &secLen, sizeof(secLen) }
578         };
579
580         hDerive = CK_INVALID_HANDLE;
581         if (secLen > 0)
582         {
583                 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hKey,
584                                  keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
585                                  &hDerive) );
586         }
587         else
588         {
589                 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hKey,
590                                  keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE) - 1,
591                                  &hDerive) );
592         }
593         CPPUNIT_ASSERT(rv == CKR_OK);
594
595         // Check that KCV has been set
596         CK_ATTRIBUTE checkAttribs[] = {
597                 { CKA_CHECK_VALUE, NULL_PTR, 0 }
598         };
599         CK_BYTE check[3];
600         checkAttribs[0].pValue = check;
601         checkAttribs[0].ulValueLen = sizeof(check);
602         rv = CRYPTOKI_F_PTR( C_GetAttributeValue(hSession, hDerive, checkAttribs, 1) );
603         CPPUNIT_ASSERT(rv == CKR_OK);
604         CPPUNIT_ASSERT(checkAttribs[0].ulValueLen == 3);
605
606         if (keyType == CKK_GENERIC_SECRET) return;
607
608         CK_BYTE cipherText[300];
609         CK_ULONG ulCipherTextLen;
610         CK_BYTE recoveredText[300];
611         CK_ULONG ulRecoveredTextLen;
612
613         rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechEncrypt,hDerive) );
614         CPPUNIT_ASSERT(rv==CKR_OK);
615
616         ulCipherTextLen = sizeof(cipherText);
617         rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,data,sizeof(data),cipherText,&ulCipherTextLen) );
618         CPPUNIT_ASSERT(rv==CKR_OK);
619
620         rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechEncrypt,hDerive) );
621         CPPUNIT_ASSERT(rv==CKR_OK);
622
623         ulRecoveredTextLen = sizeof(recoveredText);
624         rv = CRYPTOKI_F_PTR( C_Decrypt(hSession,cipherText,ulCipherTextLen,recoveredText,&ulRecoveredTextLen) );
625         CPPUNIT_ASSERT(rv==CKR_OK);
626         CPPUNIT_ASSERT(ulRecoveredTextLen==sizeof(data));
627
628         CPPUNIT_ASSERT(memcmp(data, recoveredText, sizeof(data)) == 0);
629 }
630
631 void DeriveTests::testSymDerive()
632 {
633         CK_RV rv;
634         CK_SESSION_HANDLE hSessionRO;
635         CK_SESSION_HANDLE hSessionRW;
636
637         // Just make sure that we finalize any previous tests
638         CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
639
640         // Open read-only session on when the token is not initialized should fail
641         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
642         CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED);
643
644         // Initialize the library and start the test.
645         rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
646         CPPUNIT_ASSERT(rv == CKR_OK);
647
648         // Open read-only session
649         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) );
650         CPPUNIT_ASSERT(rv == CKR_OK);
651
652         // Open read-write session
653         rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) );
654         CPPUNIT_ASSERT(rv == CKR_OK);
655
656         // Login USER into the sessions so we can create private objects
657         rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) );
658         CPPUNIT_ASSERT(rv == CKR_OK);
659
660         // Generate base key
661 #ifndef WITH_FIPS
662         CK_OBJECT_HANDLE hKeyDes = CK_INVALID_HANDLE;
663 #endif
664         CK_OBJECT_HANDLE hKeyDes2 = CK_INVALID_HANDLE;
665         CK_OBJECT_HANDLE hKeyDes3 = CK_INVALID_HANDLE;
666         CK_OBJECT_HANDLE hKeyAes = CK_INVALID_HANDLE;
667 #ifndef WITH_FIPS
668         rv = generateDesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKeyDes);
669         CPPUNIT_ASSERT(rv == CKR_OK);
670 #endif
671         rv = generateDes2Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKeyDes2);
672         CPPUNIT_ASSERT(rv == CKR_OK);
673         rv = generateDes3Key(hSessionRW,IN_SESSION,IS_PUBLIC,hKeyDes3);
674         CPPUNIT_ASSERT(rv == CKR_OK);
675         rv = generateAesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKeyAes);
676         CPPUNIT_ASSERT(rv == CKR_OK);
677
678         // Derive keys
679         CK_OBJECT_HANDLE hDerive = CK_INVALID_HANDLE;
680 #ifndef WITH_FIPS
681         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET);
682         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES);
683         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES2);
684         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_DES3);
685         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_ECB_ENCRYPT_DATA,CKK_AES);
686 #endif
687         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET);
688 #ifndef WITH_FIPS
689         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES);
690 #endif
691         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES2);
692         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES3);
693         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_AES);
694         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET);
695 #ifndef WITH_FIPS
696         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES);
697 #endif
698         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES2);
699         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES3);
700         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_AES);
701         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET);
702 #ifndef WITH_FIPS
703         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES);
704 #endif
705         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES2);
706         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES3);
707         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_AES);
708 #ifndef WITH_FIPS
709         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET);
710         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES);
711         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES2);
712         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_DES3);
713         symDerive(hSessionRW,hKeyDes,hDerive,CKM_DES_CBC_ENCRYPT_DATA,CKK_AES);
714 #endif
715         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET);
716 #ifndef WITH_FIPS
717         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES);
718 #endif
719         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES2);
720         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES3);
721         symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_AES);
722         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET);
723 #ifndef WITH_FIPS
724         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES);
725 #endif
726         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES2);
727         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES3);
728         symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_AES);
729         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET);
730 #ifndef WITH_FIPS
731         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES);
732 #endif
733         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES2);
734         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES3);
735         symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_AES);
736 }
737