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