blob: 588d0b9c099df39f1b18078f39f0400a77e2898d [file] [log] [blame]
NingSun0c89b3c2018-02-08 08:34:03 -08001/*
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
41const CK_BBOOL ON_TOKEN = CK_TRUE;
42const CK_BBOOL IN_SESSION = CK_FALSE;
43
44// CKA_PRIVATE
45const CK_BBOOL IS_PRIVATE = CK_TRUE;
46const CK_BBOOL IS_PUBLIC = CK_FALSE;
47
48
49CPPUNIT_TEST_SUITE_REGISTRATION(DeriveTests);
50
51CK_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
96CK_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
148CK_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
169CK_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
188CK_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
206CK_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
224void 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
258void 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
322bool 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
352void 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
426void 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
500void 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
631void 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