2 * Copyright (c) 2014 SURFnet
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /*****************************************************************************
30 Contains test cases for:
33 *****************************************************************************/
38 #include "DeriveTests.h"
41 const CK_BBOOL ON_TOKEN = CK_TRUE;
42 const CK_BBOOL IN_SESSION = CK_FALSE;
45 const CK_BBOOL IS_PRIVATE = CK_TRUE;
46 const CK_BBOOL IS_PUBLIC = CK_FALSE;
49 CPPUNIT_TEST_SUITE_REGISTRATION(DeriveTests);
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)
53 CK_MECHANISM mechanism = { CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
54 CK_BBOOL bTrue = CK_TRUE;
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
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) }
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) }
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),
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)
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) }
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) }
118 /* Select the curve */
119 if (strcmp(curve, "P-256") == 0)
121 pukAttribs[0].pValue = oidP256;
122 pukAttribs[0].ulValueLen = sizeof(oidP256);
124 else if (strcmp(curve, "P-384") == 0)
126 pukAttribs[0].pValue = oidP384;
127 pukAttribs[0].ulValueLen = sizeof(oidP384);
129 else if (strcmp(curve, "P-521") == 0)
131 pukAttribs[0].pValue = oidP521;
132 pukAttribs[0].ulValueLen = sizeof(oidP521);
136 return CKR_GENERAL_ERROR;
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),
148 CK_RV DeriveTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
150 CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 };
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) }
162 hKey = CK_INVALID_HANDLE;
163 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
164 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
169 CK_RV DeriveTests::generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
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) }
181 hKey = CK_INVALID_HANDLE;
182 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
183 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
188 CK_RV DeriveTests::generateDes2Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
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) }
200 hKey = CK_INVALID_HANDLE;
201 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
202 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
206 CK_RV DeriveTests::generateDes3Key(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey)
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) }
218 hKey = CK_INVALID_HANDLE;
219 return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism,
220 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
224 void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey)
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) }
249 hKey = CK_INVALID_HANDLE;
250 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hPrivateKey,
251 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
253 free(valAttrib.pValue);
254 CPPUNIT_ASSERT(rv == CKR_OK);
258 void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw)
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);
267 CK_ECDH1_DERIVE_PARAMS parms = { CKD_NULL, 0, NULL_PTR, 0, NULL_PTR };
268 // Use RAW or DER format
272 unsigned char* buf = (unsigned char*)valAttrib.pValue;
273 if (valAttrib.ulValueLen > 2 && buf[0] == 0x04)
281 if (valAttrib.ulValueLen > ((buf[1] & 0x7F) + (unsigned int)2))
283 offset = 2 + (buf[1] & 0x7F);
287 parms.pPublicData = buf + offset;
288 parms.ulPublicDataLen = valAttrib.ulValueLen - offset;
292 parms.pPublicData = (unsigned char*)valAttrib.pValue;
293 parms.ulPublicDataLen = valAttrib.ulValueLen;
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) }
313 hKey = CK_INVALID_HANDLE;
314 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hPrivateKey,
315 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
317 free(valAttrib.pValue);
318 CPPUNIT_ASSERT(rv == CKR_OK);
322 bool DeriveTests::compareSecret(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey1, CK_OBJECT_HANDLE hKey2)
324 CK_ATTRIBUTE keyAttribs[] = {
325 { CKA_VALUE, NULL_PTR, 0 },
326 { CKA_CHECK_VALUE, NULL_PTR, 0 }
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);
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;
352 void DeriveTests::testDhDerive()
355 CK_SESSION_HANDLE hSessionRO;
356 CK_SESSION_HANDLE hSessionRW;
358 // Just make sure that we finalize any previous tests
359 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
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);
365 // Initialize the library and start the test.
366 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
367 CPPUNIT_ASSERT(rv == CKR_OK);
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);
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);
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);
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;
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));
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));
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));
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));
426 void DeriveTests::testEcdhDerive()
429 CK_SESSION_HANDLE hSessionRO;
430 CK_SESSION_HANDLE hSessionRW;
432 // Just make sure that we finalize any previous tests
433 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
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);
439 // Initialize the library and start the test.
440 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
441 CPPUNIT_ASSERT(rv == CKR_OK);
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);
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);
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);
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;
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));
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));
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));
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));
500 void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE &hDerive, CK_MECHANISM_TYPE mechType, CK_KEY_TYPE keyType)
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;
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
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 = ¶m1;
525 mechanism.ulParameterLen = sizeof(param1);
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 = ¶m2;
533 mechanism.ulParameterLen = sizeof(param2);
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 = ¶m3;
540 mechanism.ulParameterLen = sizeof(param3);
543 CPPUNIT_FAIL("Invalid mechanism");
548 case CKK_GENERIC_SECRET:
552 mechEncrypt.mechanism = CKM_DES_ECB;
556 mechEncrypt.mechanism = CKM_DES3_ECB;
559 mechEncrypt.mechanism = CKM_AES_ECB;
563 CPPUNIT_FAIL("Invalid key type");
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) }
580 hDerive = CK_INVALID_HANDLE;
583 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hKey,
584 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE),
589 rv = CRYPTOKI_F_PTR( C_DeriveKey(hSession, &mechanism, hKey,
590 keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE) - 1,
593 CPPUNIT_ASSERT(rv == CKR_OK);
595 // Check that KCV has been set
596 CK_ATTRIBUTE checkAttribs[] = {
597 { CKA_CHECK_VALUE, NULL_PTR, 0 }
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);
606 if (keyType == CKK_GENERIC_SECRET) return;
608 CK_BYTE cipherText[300];
609 CK_ULONG ulCipherTextLen;
610 CK_BYTE recoveredText[300];
611 CK_ULONG ulRecoveredTextLen;
613 rv = CRYPTOKI_F_PTR( C_EncryptInit(hSession,&mechEncrypt,hDerive) );
614 CPPUNIT_ASSERT(rv==CKR_OK);
616 ulCipherTextLen = sizeof(cipherText);
617 rv = CRYPTOKI_F_PTR( C_Encrypt(hSession,data,sizeof(data),cipherText,&ulCipherTextLen) );
618 CPPUNIT_ASSERT(rv==CKR_OK);
620 rv = CRYPTOKI_F_PTR( C_DecryptInit(hSession,&mechEncrypt,hDerive) );
621 CPPUNIT_ASSERT(rv==CKR_OK);
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));
628 CPPUNIT_ASSERT(memcmp(data, recoveredText, sizeof(data)) == 0);
631 void DeriveTests::testSymDerive()
634 CK_SESSION_HANDLE hSessionRO;
635 CK_SESSION_HANDLE hSessionRW;
637 // Just make sure that we finalize any previous tests
638 CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) );
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);
644 // Initialize the library and start the test.
645 rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) );
646 CPPUNIT_ASSERT(rv == CKR_OK);
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);
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);
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);
662 CK_OBJECT_HANDLE hKeyDes = CK_INVALID_HANDLE;
664 CK_OBJECT_HANDLE hKeyDes2 = CK_INVALID_HANDLE;
665 CK_OBJECT_HANDLE hKeyDes3 = CK_INVALID_HANDLE;
666 CK_OBJECT_HANDLE hKeyAes = CK_INVALID_HANDLE;
668 rv = generateDesKey(hSessionRW,IN_SESSION,IS_PUBLIC,hKeyDes);
669 CPPUNIT_ASSERT(rv == CKR_OK);
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);
679 CK_OBJECT_HANDLE hDerive = CK_INVALID_HANDLE;
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);
687 symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_GENERIC_SECRET);
689 symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES);
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);
696 symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_ECB_ENCRYPT_DATA,CKK_DES);
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);
703 symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_ECB_ENCRYPT_DATA,CKK_DES);
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);
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);
715 symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_GENERIC_SECRET);
717 symDerive(hSessionRW,hKeyDes2,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES);
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);
724 symDerive(hSessionRW,hKeyDes3,hDerive,CKM_DES3_CBC_ENCRYPT_DATA,CKK_DES);
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);
731 symDerive(hSessionRW,hKeyAes,hDerive,CKM_AES_CBC_ENCRYPT_DATA,CKK_DES);
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);