1 /*
2 * COPYRIGHT (c) International Business Machines Corp. 2006-2017
3 *
4 * This program is provided under the terms of the Common Public License,
5 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7 * found in the file LICENSE file or at
8 * https://opensource.org/licenses/cpl1.0.php
9 */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <dlfcn.h>
15
16 #include "pkcs11types.h"
17 #include "regress.h"
18
19 CK_ULONG t_total = 0; // total test assertions
20 CK_ULONG t_ran = 0; // number of assertions ran
21 CK_ULONG t_passed = 0; // number of assertions passed
22 CK_ULONG t_failed = 0; // number of assertions failed
23 CK_ULONG t_skipped = 0; // number of assertions skipped
24 CK_ULONG t_errors = 0; // number of errors
25
26 #define MAX_MODEL 4
27
28 #define DES_KEY_SIZE 8
29 #define DES3_KEY_SIZE 24
30
31 static void *pkcs11lib = NULL;
32
unload_pkcslib(void)33 static void unload_pkcslib(void)
34 {
35 if (pkcs11lib != NULL) {
36 dlclose(pkcs11lib);
37 }
38 }
39
mech_supported(CK_SLOT_ID slot_id,CK_ULONG mechanism)40 int mech_supported(CK_SLOT_ID slot_id, CK_ULONG mechanism)
41 {
42 CK_MECHANISM_INFO mech_info;
43 int rc;
44 rc = funcs->C_GetMechanismInfo(slot_id, mechanism, &mech_info);
45
46 return (rc == CKR_OK);
47 }
48
mech_supported_flags(CK_SLOT_ID slot_id,CK_ULONG mechanism,CK_FLAGS flags)49 int mech_supported_flags(CK_SLOT_ID slot_id, CK_ULONG mechanism, CK_FLAGS flags)
50 {
51 CK_MECHANISM_INFO mech_info;
52 int rc;
53
54 rc = funcs->C_GetMechanismInfo(slot_id, mechanism, &mech_info);
55 if (rc != CKR_OK)
56 return FALSE;
57
58 if (mech_info.flags & flags)
59 return TRUE;
60
61 return FALSE;
62 }
63
64 /*
65 * Check if the specified key size is in the supported range of the mechanism.
66 *
67 * ATTENTION: It is mechanism dependent if the key size is in bits or bytes.
68 * The caller of this function must take care that the keylen parameter is
69 * specified in the appropriate unit.
70 */
check_supp_keysize(CK_SLOT_ID slot_id,CK_ULONG mechanism,CK_ULONG keylen)71 int check_supp_keysize(CK_SLOT_ID slot_id, CK_ULONG mechanism, CK_ULONG keylen)
72 {
73 CK_MECHANISM_INFO mech_info;
74 int rc;
75 rc = funcs->C_GetMechanismInfo(slot_id, mechanism, &mech_info);
76 if (rc != CKR_OK)
77 return FALSE;
78
79 return ((mech_info.ulMinKeySize <= keylen)
80 && (keylen <= mech_info.ulMaxKeySize));
81 }
82
83 /** Returns true if and only if slot supports
84 key wrapping with specified mechanism **/
wrap_supported(CK_SLOT_ID slot_id,CK_MECHANISM mech)85 int wrap_supported(CK_SLOT_ID slot_id, CK_MECHANISM mech)
86 {
87 CK_MECHANISM_INFO mech_info;
88 CK_RV rc;
89 // get mech info
90 rc = funcs->C_GetMechanismInfo(slot_id, mech.mechanism, &mech_info);
91 if (rc != CKR_OK) {
92 testcase_error("C_GetMechanismInfo(), rc=%s.", p11_get_ckr(rc));
93 return -1;
94 }
95 rc = mech_info.flags & CKF_WRAP;
96
97 return rc;
98 }
99
100 /** Returns true if and only if slot supports
101 key unwrapping with specified mechanism **/
unwrap_supported(CK_SLOT_ID slot_id,CK_MECHANISM mech)102 int unwrap_supported(CK_SLOT_ID slot_id, CK_MECHANISM mech)
103 {
104 CK_MECHANISM_INFO mech_info;
105 CK_RV rc;
106 // get mech info
107 rc = funcs->C_GetMechanismInfo(slot_id, mech.mechanism, &mech_info);
108 if (rc != CKR_OK) {
109 testcase_error("C_GetMechanismInfo(), rc=%s.", p11_get_ckr(rc));
110 return -1;
111 }
112 rc = mech_info.flags & CKF_UNWRAP;
113
114 return rc;
115 }
116
117 /** Create an AES key handle with given value **/
create_AESKey(CK_SESSION_HANDLE session,unsigned char key[],unsigned char key_len,CK_OBJECT_HANDLE * h_key)118 int create_AESKey(CK_SESSION_HANDLE session,
119 unsigned char key[], unsigned char key_len,
120 CK_OBJECT_HANDLE * h_key)
121 {
122 CK_RV rc;
123 CK_BBOOL true = TRUE;
124 CK_BBOOL false = FALSE;
125 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
126 CK_KEY_TYPE keyType = CKK_AES;
127 CK_ATTRIBUTE keyTemplate[] = {
128 {CKA_CLASS, &keyClass, sizeof(keyClass)},
129 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
130 {CKA_ENCRYPT, &true, sizeof(true)},
131 {CKA_TOKEN, &false, sizeof(false)},
132 {CKA_VALUE, key, key_len}
133 };
134
135 rc = funcs->C_CreateObject(session, keyTemplate, 5, h_key);
136
137 return rc;
138 }
139
140 /** Generate an AES key handle **/
generate_AESKey(CK_SESSION_HANDLE session,CK_ULONG key_len,CK_MECHANISM * mechkey,CK_OBJECT_HANDLE * h_key)141 int generate_AESKey(CK_SESSION_HANDLE session,
142 CK_ULONG key_len,
143 CK_MECHANISM * mechkey, CK_OBJECT_HANDLE * h_key)
144 {
145 CK_ATTRIBUTE key_gen_tmpl[] = {
146 {CKA_VALUE_LEN, &key_len, sizeof(CK_ULONG)}
147 };
148
149 CK_RV rc = funcs->C_GenerateKey(session,
150 mechkey,
151 key_gen_tmpl,
152 1,
153 h_key);
154
155 return rc;
156 }
157
158 /** Create a DES key handle with given value **/
create_DESKey(CK_SESSION_HANDLE session,unsigned char key[],unsigned char klen,CK_OBJECT_HANDLE * h_key)159 int create_DESKey(CK_SESSION_HANDLE session,
160 unsigned char key[], unsigned char klen,
161 CK_OBJECT_HANDLE * h_key)
162 {
163 CK_RV rc;
164 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
165 CK_KEY_TYPE keyType = CKK_DES;
166 CK_BYTE value[DES_KEY_SIZE];
167 CK_BBOOL true = TRUE;
168 CK_BBOOL false = FALSE;
169
170 CK_ATTRIBUTE keyTemplate[] = {
171 {CKA_CLASS, &keyClass, sizeof(keyClass)},
172 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
173 {CKA_ENCRYPT, &true, sizeof(true)},
174 {CKA_TOKEN, &false, sizeof(false)},
175 {CKA_VALUE, value, klen}
176 };
177
178 memset(value, 0, sizeof(value));
179 memcpy(value, key, klen);
180 rc = funcs->C_CreateObject(session, keyTemplate, 5, h_key);
181 if (rc != CKR_OK) {
182 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
183 }
184
185 return rc;
186 }
187
188 /** Create DES3 key handle with given value **/
create_DES3Key(CK_SESSION_HANDLE session,unsigned char key[],unsigned char klen,CK_OBJECT_HANDLE * h_key)189 int create_DES3Key(CK_SESSION_HANDLE session,
190 unsigned char key[], unsigned char klen,
191 CK_OBJECT_HANDLE * h_key)
192 {
193 CK_RV rc;
194 CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
195 CK_KEY_TYPE keyType = CKK_DES3;
196 CK_BYTE value[DES3_KEY_SIZE];
197 CK_BBOOL true = TRUE;
198 CK_BBOOL false = FALSE;
199 CK_ATTRIBUTE keyTemplate[] = {
200 {CKA_CLASS, &keyClass, sizeof(keyClass)},
201 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
202 {CKA_ENCRYPT, &true, sizeof(true)},
203 {CKA_TOKEN, &false, sizeof(false)},
204 {CKA_VALUE, value, klen}
205 };
206
207 memset(value, 0, sizeof(value));
208 memcpy(value, key, klen);
209 rc = funcs->C_CreateObject(session, keyTemplate, 5, h_key);
210 if (rc != CKR_OK) {
211 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
212 }
213
214 return rc;
215 }
216
217 /** Create Generic Secret key handle with given value **/
create_GenericSecretKey(CK_SESSION_HANDLE session,CK_BYTE key[],CK_ULONG key_len,CK_OBJECT_HANDLE * h_key)218 int create_GenericSecretKey(CK_SESSION_HANDLE session,
219 CK_BYTE key[],
220 CK_ULONG key_len, CK_OBJECT_HANDLE * h_key)
221 {
222 CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
223 CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
224 CK_BBOOL false = FALSE;
225 CK_RV rc;
226 CK_ATTRIBUTE key_attribs[] = {
227 {CKA_CLASS, &key_class, sizeof(key_class)},
228 {CKA_KEY_TYPE, &key_type, sizeof(key_type)},
229 {CKA_TOKEN, &false, sizeof(false)},
230 {CKA_VALUE, key, key_len}
231 };
232
233 rc = funcs->C_CreateObject(session, key_attribs, 4, h_key);
234 if (rc != CKR_OK) {
235 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
236 }
237
238 return rc;
239 }
240
241 /** Create an RSA private key using ctr
242 (chinese remainder theorem) values **/
create_RSAPrivateKey(CK_SESSION_HANDLE session,CK_BYTE modulus[],CK_BYTE publicExponent[],CK_BYTE privateExponent[],CK_BYTE prime1[],CK_BYTE prime2[],CK_BYTE exponent1[],CK_BYTE exponent2[],CK_BYTE coefficient[],CK_ULONG modulus_len,CK_ULONG publicExponent_len,CK_ULONG privateExponent_len,CK_ULONG prime1_len,CK_ULONG prime2_len,CK_ULONG exponent1_len,CK_ULONG exponent2_len,CK_ULONG coefficient_len,CK_OBJECT_HANDLE * priv_key)243 CK_RV create_RSAPrivateKey(CK_SESSION_HANDLE session,
244 CK_BYTE modulus[],
245 CK_BYTE publicExponent[],
246 CK_BYTE privateExponent[],
247 CK_BYTE prime1[],
248 CK_BYTE prime2[],
249 CK_BYTE exponent1[],
250 CK_BYTE exponent2[],
251 CK_BYTE coefficient[],
252 CK_ULONG modulus_len,
253 CK_ULONG publicExponent_len,
254 CK_ULONG privateExponent_len,
255 CK_ULONG prime1_len,
256 CK_ULONG prime2_len,
257 CK_ULONG exponent1_len,
258 CK_ULONG exponent2_len,
259 CK_ULONG coefficient_len,
260 CK_OBJECT_HANDLE * priv_key)
261 {
262
263 CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
264 CK_KEY_TYPE keyType = CKK_RSA;
265 CK_UTF8CHAR label[] = "An RSA private key object";
266 CK_BYTE subject[] = {0};
267 CK_BYTE id[] = { 123 };
268 CK_RV rc;
269
270 CK_BBOOL true = TRUE;
271 CK_ATTRIBUTE template[] = {
272 {CKA_CLASS, &class, sizeof(class)},
273 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
274 {CKA_TOKEN, &true, sizeof(true)},
275 {CKA_LABEL, label, sizeof(label) - 1},
276 {CKA_SUBJECT, subject, 0},
277 {CKA_ID, id, sizeof(id)},
278 {CKA_SENSITIVE, &true, sizeof(true)},
279 {CKA_DECRYPT, &true, sizeof(true)},
280 {CKA_SIGN, &true, sizeof(true)},
281 {CKA_MODULUS, modulus, modulus_len},
282 {CKA_PUBLIC_EXPONENT, publicExponent, publicExponent_len},
283 {CKA_PRIVATE_EXPONENT, privateExponent, privateExponent_len},
284 {CKA_PRIME_1, prime1, prime1_len},
285 {CKA_PRIME_2, prime2, prime2_len},
286 {CKA_EXPONENT_1, exponent1, exponent1_len},
287 {CKA_EXPONENT_2, exponent2, exponent2_len},
288 {CKA_COEFFICIENT, coefficient, coefficient_len}
289 };
290
291 // create key
292 rc = funcs->C_CreateObject(session, template, 17, priv_key);
293 if (rc != CKR_OK) {
294 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
295 }
296
297 return rc;
298 }
299
300 /** Create an RSA public key **/
create_RSAPublicKey(CK_SESSION_HANDLE session,CK_BYTE modulus[],CK_BYTE publicExponent[],CK_ULONG modulus_len,CK_ULONG publicExponent_len,CK_OBJECT_HANDLE * publ_key)301 CK_RV create_RSAPublicKey(CK_SESSION_HANDLE session,
302 CK_BYTE modulus[],
303 CK_BYTE publicExponent[],
304 CK_ULONG modulus_len,
305 CK_ULONG publicExponent_len,
306 CK_OBJECT_HANDLE * publ_key)
307 {
308
309 CK_RV rc;
310 CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
311 CK_KEY_TYPE keyType = CKK_RSA;
312 CK_UTF8CHAR label[] = "An RSA public key object";
313 CK_BBOOL true = TRUE;
314 CK_ATTRIBUTE template[] = {
315 {CKA_CLASS, &class, sizeof(class)},
316 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
317 {CKA_TOKEN, &true, sizeof(true)},
318 {CKA_LABEL, label, sizeof(label) - 1},
319 {CKA_WRAP, &true, sizeof(true)},
320 {CKA_ENCRYPT, &true, sizeof(true)},
321 {CKA_MODULUS, modulus, modulus_len},
322 {CKA_PUBLIC_EXPONENT, publicExponent, publicExponent_len}
323 };
324
325 // create key
326 rc = funcs->C_CreateObject(session, template, 8, publ_key);
327 if (rc != CKR_OK) {
328 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
329 }
330
331 return rc;
332 }
333
334 /** Generate an RSA (PKCS) key pair **/
generate_RSA_PKCS_KeyPair(CK_SESSION_HANDLE session,CK_ULONG modulusBits,CK_BYTE publicExponent[],CK_ULONG publicExponent_len,CK_OBJECT_HANDLE * publ_key,CK_OBJECT_HANDLE * priv_key)335 CK_RV generate_RSA_PKCS_KeyPair(CK_SESSION_HANDLE session,
336 CK_ULONG modulusBits,
337 CK_BYTE publicExponent[],
338 CK_ULONG publicExponent_len,
339 CK_OBJECT_HANDLE * publ_key,
340 CK_OBJECT_HANDLE * priv_key)
341 {
342 CK_RV rc;
343 CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 };
344 CK_BYTE subject[] = {0};
345 CK_BYTE id[] = { 123 };
346 CK_BBOOL true = TRUE;
347 CK_ATTRIBUTE publicKeyTemplate[] = {
348 {CKA_ENCRYPT, &true, sizeof(true)},
349 {CKA_VERIFY, &true, sizeof(true)},
350 {CKA_WRAP, &true, sizeof(true)},
351 {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
352 {CKA_PUBLIC_EXPONENT, publicExponent, publicExponent_len}
353 };
354 CK_ATTRIBUTE privateKeyTemplate[] = {
355 {CKA_TOKEN, &true, sizeof(true)},
356 {CKA_PRIVATE, &true, sizeof(true)},
357 {CKA_SUBJECT, subject, 0},
358 {CKA_ID, id, sizeof(id)},
359 {CKA_SENSITIVE, &true, sizeof(true)},
360 {CKA_DECRYPT, &true, sizeof(true)},
361 {CKA_SIGN, &true, sizeof(true)},
362 {CKA_UNWRAP, &true, sizeof(true)},
363 };
364
365 // generate keys
366 rc = funcs->C_GenerateKeyPair(session,
367 &mech,
368 publicKeyTemplate,
369 5, privateKeyTemplate, 8, publ_key, priv_key);
370
371 return rc;
372 // no error checking due to
373 // ICA Token + public exponent values + CKR_TEMPLATE_INCONSISTENT
374 // work around
375 // see rsa_func.c
376 }
377
378 /** Create an EC private key using private value 'd'
379 and ec parameter values (alg id of curve) **/
create_ECPrivateKey(CK_SESSION_HANDLE session,CK_BYTE params[],CK_ULONG params_len,CK_BYTE privatekey[],CK_ULONG privatekey_len,CK_BYTE pubkey[],CK_ULONG pubkey_len,CK_OBJECT_HANDLE * priv_key)380 CK_RV create_ECPrivateKey(CK_SESSION_HANDLE session,
381 CK_BYTE params[],
382 CK_ULONG params_len,
383 CK_BYTE privatekey[],
384 CK_ULONG privatekey_len,
385 CK_BYTE pubkey[],
386 CK_ULONG pubkey_len, CK_OBJECT_HANDLE * priv_key)
387 {
388
389 CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
390 CK_KEY_TYPE keyType = CKK_EC;
391 CK_UTF8CHAR label[] = "An EC private key object";
392 CK_BYTE subject[] = {0};
393 CK_BYTE id[] = { 123 };
394 CK_RV rc;
395
396 CK_BBOOL true = TRUE;
397 CK_ATTRIBUTE template[] = {
398 {CKA_CLASS, &class, sizeof(class)},
399 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
400 {CKA_TOKEN, &true, sizeof(true)},
401 {CKA_PRIVATE, &true, sizeof(true)},
402 {CKA_LABEL, label, sizeof(label)},
403 {CKA_SUBJECT, subject, 0},
404 {CKA_ID, id, sizeof(id)},
405 {CKA_SENSITIVE, &true, sizeof(true)},
406 {CKA_DECRYPT, &true, sizeof(true)},
407 {CKA_SIGN, &true, sizeof(true)},
408 {CKA_EC_PARAMS, params, params_len},
409 {CKA_EC_POINT, pubkey, pubkey_len},
410 {CKA_VALUE, privatekey, privatekey_len}
411 };
412
413 // create key
414 rc = funcs->C_CreateObject(session, template,
415 sizeof(template) / sizeof(CK_ATTRIBUTE),
416 priv_key);
417 if (rc != CKR_OK) {
418 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
419 }
420
421 return rc;
422 }
423
424 /** Create an EC public key using ec params and point 'Q' **/
create_ECPublicKey(CK_SESSION_HANDLE session,CK_BYTE params[],CK_ULONG params_len,CK_BYTE pointq[],CK_ULONG pointq_len,CK_OBJECT_HANDLE * publ_key)425 CK_RV create_ECPublicKey(CK_SESSION_HANDLE session,
426 CK_BYTE params[],
427 CK_ULONG params_len,
428 CK_BYTE pointq[],
429 CK_ULONG pointq_len, CK_OBJECT_HANDLE * publ_key)
430 {
431 CK_RV rc;
432 CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
433 CK_KEY_TYPE keyType = CKK_EC;
434 CK_UTF8CHAR label[] = "An EC public key object";
435 CK_BBOOL true = TRUE;
436 CK_ATTRIBUTE template[] = {
437 {CKA_CLASS, &class, sizeof(class)},
438 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
439 {CKA_TOKEN, &true, sizeof(true)},
440 {CKA_LABEL, label, sizeof(label)},
441 {CKA_ENCRYPT, &true, sizeof(true)},
442 {CKA_VERIFY, &true, sizeof(true)},
443 {CKA_EC_PARAMS, params, params_len},
444 {CKA_EC_POINT, pointq, pointq_len}
445 };
446
447 // create key
448 rc = funcs->C_CreateObject(session, template,
449 sizeof(template) / sizeof(CK_ATTRIBUTE),
450 publ_key);
451 if (rc != CKR_OK) {
452 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
453 }
454
455 return rc;
456 }
457
458 /** Create an DSA public key using the prime 'p', subprime 'q', base 'g' and private value 'y' **/
create_DSAPrivateKey(CK_SESSION_HANDLE session,CK_BYTE prime[],CK_ULONG prime_len,CK_BYTE subprime[],CK_ULONG subprime_len,CK_BYTE base[],CK_ULONG base_len,CK_BYTE privatekey[],CK_ULONG privatekey_len,CK_OBJECT_HANDLE * priv_key)459 CK_RV create_DSAPrivateKey(CK_SESSION_HANDLE session,
460 CK_BYTE prime[],
461 CK_ULONG prime_len,
462 CK_BYTE subprime[],
463 CK_ULONG subprime_len,
464 CK_BYTE base[],
465 CK_ULONG base_len,
466 CK_BYTE privatekey[],
467 CK_ULONG privatekey_len, CK_OBJECT_HANDLE * priv_key)
468 {
469
470 CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
471 CK_KEY_TYPE keyType = CKK_DSA;
472 CK_UTF8CHAR label[] = "An DSA private key object";
473 CK_BYTE subject[] = {0};
474 CK_BYTE id[] = { 123 };
475 CK_RV rc;
476
477 CK_BBOOL true = TRUE;
478 CK_ATTRIBUTE template[] = {
479 {CKA_CLASS, &class, sizeof(class)},
480 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
481 {CKA_TOKEN, &true, sizeof(true)},
482 {CKA_LABEL, label, sizeof(label)},
483 {CKA_SUBJECT, subject, 0},
484 {CKA_ID, id, sizeof(id)},
485 {CKA_SENSITIVE, &true, sizeof(true)},
486 {CKA_DECRYPT, &true, sizeof(true)},
487 {CKA_SIGN, &true, sizeof(true)},
488 {CKA_PRIME, prime, prime_len},
489 {CKA_SUBPRIME, subprime, subprime_len},
490 {CKA_BASE, base, base_len},
491 {CKA_VALUE, privatekey, privatekey_len}
492 };
493
494 // create key
495 rc = funcs->C_CreateObject(session, template,
496 sizeof(template) / sizeof(CK_ATTRIBUTE),
497 priv_key);
498 if (rc != CKR_OK) {
499 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
500 }
501
502 return rc;
503 }
504
505 /** Create an DSA public key using the prime 'p', subprime 'q', base 'g' and public value 'x' **/
create_DSAPublicKey(CK_SESSION_HANDLE session,CK_BYTE prime[],CK_ULONG prime_len,CK_BYTE subprime[],CK_ULONG subprime_len,CK_BYTE base[],CK_ULONG base_len,CK_BYTE publickey[],CK_ULONG publickey_len,CK_OBJECT_HANDLE * publ_key)506 CK_RV create_DSAPublicKey(CK_SESSION_HANDLE session,
507 CK_BYTE prime[],
508 CK_ULONG prime_len,
509 CK_BYTE subprime[],
510 CK_ULONG subprime_len,
511 CK_BYTE base[],
512 CK_ULONG base_len,
513 CK_BYTE publickey[],
514 CK_ULONG publickey_len, CK_OBJECT_HANDLE * publ_key)
515 {
516 CK_RV rc;
517 CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
518 CK_KEY_TYPE keyType = CKK_DSA;
519 CK_UTF8CHAR label[] = "An DSA public key object";
520 CK_BBOOL true = TRUE;
521 CK_ATTRIBUTE template[] = {
522 {CKA_CLASS, &class, sizeof(class)},
523 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
524 {CKA_TOKEN, &true, sizeof(true)},
525 {CKA_LABEL, label, sizeof(label)},
526 {CKA_ENCRYPT, &true, sizeof(true)},
527 {CKA_VERIFY, &true, sizeof(true)},
528 {CKA_PRIME, prime, prime_len},
529 {CKA_SUBPRIME, subprime, subprime_len},
530 {CKA_BASE, base, base_len},
531 {CKA_VALUE, publickey, publickey_len}
532 };
533
534 // create key
535 rc = funcs->C_CreateObject(session, template,
536 sizeof(template) / sizeof(CK_ATTRIBUTE),
537 publ_key);
538 if (rc != CKR_OK) {
539 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
540 }
541
542 return rc;
543 }
544
545 /** Create an DH public key using the prime 'p', base 'g' and private value 'y' **/
create_DHPrivateKey(CK_SESSION_HANDLE session,CK_BYTE prime[],CK_ULONG prime_len,CK_BYTE base[],CK_ULONG base_len,CK_BYTE privatekey[],CK_ULONG privatekey_len,CK_OBJECT_HANDLE * priv_key)546 CK_RV create_DHPrivateKey(CK_SESSION_HANDLE session,
547 CK_BYTE prime[],
548 CK_ULONG prime_len,
549 CK_BYTE base[],
550 CK_ULONG base_len,
551 CK_BYTE privatekey[],
552 CK_ULONG privatekey_len, CK_OBJECT_HANDLE * priv_key)
553 {
554
555 CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
556 CK_KEY_TYPE keyType = CKK_DH;
557 CK_UTF8CHAR label[] = "An DH private key object";
558 CK_BYTE subject[] = {0};
559 CK_BYTE id[] = { 123 };
560 CK_RV rc;
561
562 CK_BBOOL true = TRUE;
563 CK_ATTRIBUTE template[] = {
564 {CKA_CLASS, &class, sizeof(class)},
565 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
566 {CKA_TOKEN, &true, sizeof(true)},
567 {CKA_LABEL, label, sizeof(label)},
568 {CKA_SUBJECT, subject, 0},
569 {CKA_ID, id, sizeof(id)},
570 {CKA_SENSITIVE, &true, sizeof(true)},
571 {CKA_DECRYPT, &true, sizeof(true)},
572 {CKA_SIGN, &true, sizeof(true)},
573 {CKA_DERIVE, &true, sizeof(true)},
574 {CKA_PRIME, prime, prime_len},
575 {CKA_BASE, base, base_len},
576 {CKA_VALUE, privatekey, privatekey_len}
577 };
578
579 // create key
580 rc = funcs->C_CreateObject(session, template,
581 sizeof(template) / sizeof(CK_ATTRIBUTE),
582 priv_key);
583 if (rc != CKR_OK) {
584 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
585 }
586
587 return rc;
588 }
589
590 /* Create an DH public key using the prime 'p', base 'g' and public value 'x' */
create_DHPublicKey(CK_SESSION_HANDLE session,CK_BYTE prime[],CK_ULONG prime_len,CK_BYTE base[],CK_ULONG base_len,CK_BYTE publickey[],CK_ULONG publickey_len,CK_OBJECT_HANDLE * publ_key)591 CK_RV create_DHPublicKey(CK_SESSION_HANDLE session,
592 CK_BYTE prime[],
593 CK_ULONG prime_len,
594 CK_BYTE base[],
595 CK_ULONG base_len,
596 CK_BYTE publickey[],
597 CK_ULONG publickey_len, CK_OBJECT_HANDLE * publ_key)
598 {
599 CK_RV rc;
600 CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
601 CK_KEY_TYPE keyType = CKK_DH;
602 CK_UTF8CHAR label[] = "An DH public key object";
603 CK_BBOOL true = TRUE;
604 CK_ATTRIBUTE template[] = {
605 {CKA_CLASS, &class, sizeof(class)},
606 {CKA_KEY_TYPE, &keyType, sizeof(keyType)},
607 {CKA_TOKEN, &true, sizeof(true)},
608 {CKA_LABEL, label, sizeof(label)},
609 {CKA_ENCRYPT, &true, sizeof(true)},
610 {CKA_VERIFY, &true, sizeof(true)},
611 {CKA_PRIME, prime, prime_len},
612 {CKA_BASE, base, base_len},
613 {CKA_VALUE, publickey, publickey_len}
614 };
615
616 // create key
617 rc = funcs->C_CreateObject(session, template,
618 sizeof(template) / sizeof(CK_ATTRIBUTE),
619 publ_key);
620 if (rc != CKR_OK) {
621 testcase_error("C_CreateObject rc=%s", p11_get_ckr(rc));
622 }
623
624 return rc;
625 }
626
627 /* Generate a secret key */
generate_SecretKey(CK_SESSION_HANDLE session,CK_ULONG keylen,CK_MECHANISM * mech,CK_OBJECT_HANDLE * secret_key)628 CK_RV generate_SecretKey(CK_SESSION_HANDLE session,
629 CK_ULONG keylen,
630 CK_MECHANISM * mech, CK_OBJECT_HANDLE * secret_key)
631 {
632 CK_RV rc;
633 CK_OBJECT_CLASS class = CKO_SECRET_KEY;
634 CK_ATTRIBUTE secret_tmpl[] = {
635 {CKA_CLASS, &class, sizeof(class)},
636 {CKA_VALUE_LEN, &keylen, sizeof(keylen)}
637 };
638
639 rc = funcs->C_GenerateKey(session, mech, secret_tmpl, 2, secret_key);
640 if (rc != CKR_OK) {
641 testcase_fail("C_GenerateKey, rc=%s", p11_get_ckr(rc));
642 }
643
644 return rc;
645 }
646
keysize_supported(CK_SLOT_ID slot_id,CK_ULONG mechanism,CK_ULONG size)647 int keysize_supported(CK_SLOT_ID slot_id, CK_ULONG mechanism, CK_ULONG size)
648 {
649 CK_MECHANISM_INFO mech_info;
650 CK_RV rc;
651
652 rc = funcs->C_GetMechanismInfo(slot_id, mechanism, &mech_info);
653 if (size < mech_info.ulMinKeySize || size > mech_info.ulMaxKeySize)
654 return 0;
655
656 return (rc == CKR_OK);
657 }
658
659 /** Returns true if pubexp is valid for EP11 Tokens **/
is_valid_ep11_pubexp(CK_BYTE pubexp[],CK_ULONG pubexp_len)660 int is_valid_ep11_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len)
661 {
662 CK_ULONG i;
663
664 /* everything > 0x10 valid */
665 if (pubexp[0] > 0x10) {
666 return 1;
667 } else {
668 for (i = 1; i < pubexp_len + 1; i++) {
669 if (pubexp[i] != 0)
670 return 1;
671 }
672 }
673
674 return 0;
675 }
676
677 /** Returns true if slot_id is an ICA Token **/
is_ep11_token(CK_SLOT_ID slot_id)678 int is_ep11_token(CK_SLOT_ID slot_id)
679 {
680 CK_RV rc;
681 CK_TOKEN_INFO tokinfo;
682
683 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
684 if (rc != CKR_OK)
685 return FALSE;
686
687 return strstr((const char *) tokinfo.model, "EP11") != NULL;
688 }
689
690 /** Returns true if pubexp is valid for CCA Tokens **/
is_valid_cca_pubexp(CK_BYTE pubexp[],CK_ULONG pubexp_len)691 int is_valid_cca_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len)
692 {
693 CK_BYTE exp3[] = { 0x03 }; // 3
694 CK_BYTE exp65537[] = { 0x01, 0x00, 0x01 }; // 65537
695
696 return (pubexp_len == 1 && (!memcmp(pubexp, exp3, 1)))
697 || (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3)));
698 }
699
700 /** Returns true if slot_id is an ICSF token
701 ** ICSF token info is not necessarily hard-coded like the other tokens
702 ** so there is no single identifying attribute. So, instead just
703 ** use logical deduction....
704 **/
is_icsf_token(CK_SLOT_ID slot_id)705 int is_icsf_token(CK_SLOT_ID slot_id)
706 {
707 CK_RV rc;
708 CK_TOKEN_INFO tokinfo;
709
710 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
711 if (rc != CKR_OK)
712 return FALSE;
713
714 if ((strstr((const char *) tokinfo.model, "ICA") == NULL) &&
715 (strstr((const char *) tokinfo.model, "EP11") == NULL) &&
716 (strstr((const char *) tokinfo.model, "CCA") == NULL) &&
717 (strstr((const char *) tokinfo.model, "SoftTok") == NULL))
718 return TRUE;
719
720 return FALSE;
721 }
722
723 /** Returns true if pubexp is valid for ICSF token **/
is_valid_icsf_pubexp(CK_BYTE pubexp[],CK_ULONG pubexp_len)724 int is_valid_icsf_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len)
725 {
726 CK_BYTE exp65537[] = { 0x01, 0x00, 0x01 }; // 65537
727
728 return (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3)));
729 }
730
731 /** Returns true if slot_id is an ICA Token **/
is_ica_token(CK_SLOT_ID slot_id)732 int is_ica_token(CK_SLOT_ID slot_id)
733 {
734 CK_RV rc;
735 CK_TOKEN_INFO tokinfo;
736
737 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
738 if (rc != CKR_OK)
739 return FALSE;
740
741 return strstr((const char *) tokinfo.model, "ICA") != NULL;
742 }
743
744 /** Returns true if slot_id is a CCA Token **/
is_cca_token(CK_SLOT_ID slot_id)745 int is_cca_token(CK_SLOT_ID slot_id)
746 {
747 CK_RV rc;
748 CK_TOKEN_INFO tokinfo;
749
750 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
751 if (rc != CKR_OK)
752 return FALSE;
753
754 return strstr((const char *) tokinfo.model, "CCA") != NULL;
755 }
756
757 /** Returns true if slot_id is a SoftTok Token **/
is_soft_token(CK_SLOT_ID slot_id)758 int is_soft_token(CK_SLOT_ID slot_id)
759 {
760 CK_RV rc;
761 CK_TOKEN_INFO tokinfo;
762
763 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
764 if (rc != CKR_OK)
765 return FALSE;
766
767 return strstr((const char *) tokinfo.model, "SoftTok") != NULL;
768 }
769
770 /** Returns true if slot_id is a TPM Token **/
is_tpm_token(CK_SLOT_ID slot_id)771 int is_tpm_token(CK_SLOT_ID slot_id)
772 {
773 CK_RV rc;
774 CK_TOKEN_INFO tokinfo;
775
776 rc = funcs->C_GetTokenInfo(slot_id, &tokinfo);
777 if (rc != CKR_OK)
778 return FALSE;
779
780 return strstr((const char *) tokinfo.model, "TPM") != NULL;
781 }
782
783 /** Returns true if pubexp is valid for CCA Tokens **/
is_valid_tpm_pubexp(CK_BYTE pubexp[],CK_ULONG pubexp_len)784 int is_valid_tpm_pubexp(CK_BYTE pubexp[], CK_ULONG pubexp_len)
785 {
786 CK_BYTE exp65537[] = { 0x01, 0x00, 0x01 }; // 65537
787
788 return (pubexp_len == 3 && (!memcmp(pubexp, exp65537, 3)));
789 }
790
is_valid_tpm_modbits(CK_ULONG modbits)791 int is_valid_tpm_modbits(CK_ULONG modbits)
792 {
793 switch (modbits) {
794 case 512:
795 case 1024:
796 case 2048:
797 return 1;
798 default:
799 return 0;
800 }
801 }
802
get_so_pin(CK_BYTE * dest)803 int get_so_pin(CK_BYTE * dest)
804 {
805 char *val;
806
807 val = getenv(PKCS11_SO_PIN_ENV_VAR);
808 if (val == NULL) {
809 fprintf(stderr, "The environment variable %s must be set "
810 "before this testcase is run.\n", PKCS11_SO_PIN_ENV_VAR);
811 return -1;
812 }
813
814 if ((strlen(val) + 1) > PKCS11_MAX_PIN_LEN) {
815 fprintf(stderr, "The environment variable %s must hold a "
816 "value less than %d chars in length.\n",
817 PKCS11_SO_PIN_ENV_VAR, (int) PKCS11_MAX_PIN_LEN);
818 return -1;
819 }
820
821 memcpy(dest, val, strlen(val) + 1);
822
823 return 0;
824 }
825
get_user_pin(CK_BYTE * dest)826 int get_user_pin(CK_BYTE * dest)
827 {
828 char *val;
829
830 val = getenv(PKCS11_USER_PIN_ENV_VAR);
831 if (val == NULL) {
832 fprintf(stderr, "The environment variable %s must be set "
833 "before this testcase is run.\n", PKCS11_USER_PIN_ENV_VAR);
834 return -1;
835 }
836
837 if ((strlen(val) + 1) > PKCS11_MAX_PIN_LEN) {
838 fprintf(stderr, "The environment variable %s must hold a "
839 "value less than %d chars in length.\n",
840 PKCS11_SO_PIN_ENV_VAR, (int) PKCS11_MAX_PIN_LEN);
841 return -1;
842 }
843
844 memcpy(dest, val, strlen(val) + 1);
845
846 return 0;
847 }
848
849
850
process_time(SYSTEMTIME t1,SYSTEMTIME t2)851 void process_time(SYSTEMTIME t1, SYSTEMTIME t2)
852 {
853 long ms = t2.millitm - t1.millitm;
854 long s = t2.time - t1.time;
855
856 while (ms < 0) {
857 ms += 1000;
858 s--;
859 }
860
861 ms += (s * 1000);
862
863 printf("Time: %u msec\n", (unsigned int) ms);
864 }
865
866
867
868 //
869 //
print_hex(CK_BYTE * buf,CK_ULONG len)870 void print_hex(CK_BYTE * buf, CK_ULONG len)
871 {
872 CK_ULONG i, j;
873
874 i = 0;
875
876 while (i < len) {
877 for (j = 0; (j < 16) && (i < len); j++, i++)
878 fprintf(stderr, "%02x ", buf[i]);
879 fprintf(stderr, "\n");
880 }
881 fprintf(stderr, "\n");
882 }
883
usage(char * fct)884 void usage(char *fct)
885 {
886 printf("usage: %s [-securekey] [-noskip] [-noinit] [-h] -slot <num>\n\n",
887 fct);
888
889 return;
890 }
891
892
do_ParseArgs(int argc,char ** argv)893 int do_ParseArgs(int argc, char **argv)
894 {
895 int i;
896 char *endp;
897
898 skip_token_obj = TRUE;
899 no_stop = FALSE;
900 no_init = FALSE;
901 securekey = FALSE;
902 SLOT_ID = 1000;
903
904
905 for (i = 1; i < argc; i++) {
906 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
907 usage(argv[0]);
908 return 0;
909 } else if (strcmp(argv[i], "-noskip") == 0) {
910 skip_token_obj = FALSE;
911 } else if (strcmp(argv[i], "-slot") == 0) {
912 if (argc <= i + 1) {
913 printf("No slot number specified\n");
914 usage(argv[0]);
915 return -1;
916 }
917 SLOT_ID = strtol(argv[i + 1], &endp, 10);
918 if (*endp != '\0') {
919 printf("Invalid slot number specified: %s\n", argv[i + 1]);
920 usage(argv[0]);
921 return -1;
922 }
923 i++;
924 } else if (strcmp(argv[i], "-securekey") == 0) {
925 securekey = TRUE;
926 } else if (strcmp(argv[i], "-noinit") == 0) {
927 no_init = TRUE;
928 } else if (strcmp(argv[i], "-nostop") == 0) {
929 no_stop = TRUE;
930 } else {
931 printf("Invalid argument passed as option: %s\n", argv[i]);
932 usage(argv[0]);
933 return -1;
934 }
935 }
936
937 // error if slot has not been identified.
938 if (SLOT_ID == 1000) {
939 printf("Please specify the slot to be tested.\n");
940 usage(argv[0]);
941 return -1;
942 }
943
944 return 1;
945 }
946
947 //
948 //
do_GetFunctionList(void)949 int do_GetFunctionList(void)
950 {
951 CK_RV rc;
952 CK_RV(*pfoo) ();
953 char *e;
954 char *f = "libopencryptoki.so";
955
956 e = getenv("PKCSLIB");
957 if (e == NULL) {
958 e = f;
959 // return FALSE;
960 }
961 pkcs11lib = dlopen(e, RTLD_NOW);
962 if (pkcs11lib == NULL) {
963 return FALSE;
964 }
965
966 *(void **)(&pfoo) = dlsym(pkcs11lib, "C_GetFunctionList");
967 if (pfoo == NULL) {
968 dlclose(pkcs11lib);
969 return FALSE;
970 }
971 rc = pfoo(&funcs);
972
973 if (rc != CKR_OK) {
974 testcase_error("C_GetFunctionList rc=%s", p11_get_ckr(rc));
975 dlclose(pkcs11lib);
976 return FALSE;
977 }
978
979 atexit(unload_pkcslib);
980 return TRUE;
981 }
982