1 /*
2  * Copyright (c) 2019-2020 Yubico AB
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 are
7  * met:
8  *
9  *   * Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *
12  *   * Redistributions in binary form must reproduce the above
13  *     copyright notice, this list of conditions and the following
14  *     disclaimer in the documentation and/or other materials provided
15  *     with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 #include "../../common/openssl-compat.h"
32 
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <openssl/rsa.h>
37 #include <openssl/ec.h>
38 #include <openssl/bn.h>
39 #include <openssl/x509.h>
40 #include <openssl/rand.h>
41 #include <openssl/err.h>
42 #include "pkcs11y.h"
43 #include "ykcs11_tests_util.h"
44 
45 static CK_BYTE SHA1_DIGEST[] = {0x30, 0x21, 0x30, 0x09, 0x06,
46                                 0x05, 0x2B, 0x0E, 0x03, 0x02,
47                                 0x1A, 0x05, 0x00, 0x04, 0x14};
48 
49 static CK_BYTE SHA256_DIGEST[] = {0x30, 0x31, 0x30, 0x0D, 0x06,
50                                   0x09, 0x60, 0x86, 0x48, 0x01,
51                                   0x65, 0x03, 0x04, 0x02, 0x01,
52                                   0x05, 0x00, 0x04, 0x20};
53 
54 static CK_BYTE SHA384_DIGEST[] = {0x30, 0x41, 0x30, 0x0D, 0x06,
55                                   0x09, 0x60, 0x86, 0x48, 0x01,
56                                   0x65, 0x03, 0x04, 0x02, 0x02,
57                                   0x05, 0x00, 0x04, 0x30};
58 
59 static CK_BYTE SHA512_DIGEST[] = {0x30, 0x51, 0x30, 0x0D, 0x06,
60                                   0x09, 0x60, 0x86, 0x48, 0x01,
61                                   0x65, 0x03, 0x04, 0x02, 0x03,
62                                   0x05, 0x00, 0x04, 0x40};
63 
64 #define asrt(c, e, m) _asrt(__FILE__, __LINE__, c, e, m);
65 
_asrt(const char * file,int line,CK_ULONG check,CK_ULONG expected,const char * msg)66 static void _asrt(const char *file, int line, CK_ULONG check, CK_ULONG expected, const char *msg) {
67 
68   if (check == expected)
69     return;
70 
71   fprintf(stderr, "%s.%d: <%s> check failed with value %lu (0x%lx), expected %lu (0x%lx)\n",
72           file, line, msg, check, check, expected, expected);
73 
74   exit(EXIT_FAILURE);
75 
76 }
77 
dump_hex(const unsigned char * buf,unsigned int len,FILE * output,int space)78 void dump_hex(const unsigned char *buf, unsigned int len, FILE *output, int space) {
79   unsigned int i;
80   for (i = 0; i < len; i++) {
81     fprintf(output, "%02x%s", buf[i], space == 1 ? " " : "");
82   }
83   fprintf(output, "\n");
84 }
85 
get_public_key_handle(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE privkey)86 static CK_OBJECT_HANDLE get_public_key_handle(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
87                         CK_OBJECT_HANDLE privkey) {
88   CK_OBJECT_HANDLE found_obj[10] = {0};
89   CK_ULONG n_found_obj = 0;
90   CK_ULONG class_pub = CKO_PUBLIC_KEY;
91   CK_BYTE ckaid = 0;
92 
93   CK_ATTRIBUTE idTemplate[] = {
94     {CKA_ID, &ckaid, sizeof(ckaid)}
95   };
96   CK_ATTRIBUTE idClassTemplate[] = {
97     {CKA_ID, &ckaid, sizeof(ckaid)},
98     {CKA_CLASS, &class_pub, sizeof(class_pub)}
99   };
100 
101   asrt(funcs->C_GetAttributeValue(session, privkey, idTemplate, 1), CKR_OK, "GET CKA_ID");
102   asrt(funcs->C_FindObjectsInit(session, idClassTemplate, 2), CKR_OK, "FIND INIT");
103   asrt(funcs->C_FindObjects(session, found_obj, 10, &n_found_obj), CKR_OK, "FIND");
104   asrt(n_found_obj, 1, "N FOUND OBJS");
105   asrt(funcs->C_FindObjectsFinal(session), CKR_OK, "FIND FINAL");
106   return found_obj[0];
107 }
108 
destroy_test_objects(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_cert,CK_ULONG n)109 void destroy_test_objects(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_cert, CK_ULONG n) {
110   CK_ULONG i;
111   asrt(funcs->C_Login(session, CKU_SO, (CK_CHAR_PTR)"010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
112   for(i=0; i<n; i++) {
113     asrt(funcs->C_DestroyObject(session, obj_cert[i]), CKR_OK, "Destroy Object");
114   }
115   asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
116 }
117 
get_hash(CK_MECHANISM_TYPE mech,CK_BYTE * data,CK_ULONG data_len,CK_BYTE * hdata,CK_ULONG * hdata_len)118 static CK_RV get_hash(CK_MECHANISM_TYPE mech,
119                     CK_BYTE* data, CK_ULONG data_len,
120                     CK_BYTE* hdata, CK_ULONG* hdata_len) {
121   if(data == NULL || hdata == NULL || hdata_len == NULL) {
122     return CKR_FUNCTION_FAILED;
123   }
124 
125   CK_BYTE hashed_data[512] = {0};
126   switch(mech) {
127     case CKM_SHA_1:
128     case CKM_RSA_PKCS_PSS:
129     case CKM_SHA1_RSA_PKCS_PSS:
130       SHA1(data, data_len, hashed_data);
131       memcpy(hdata, hashed_data, 20);
132       *hdata_len = 20;
133       break;
134     case CKM_SHA256:
135     case CKM_SHA256_RSA_PKCS_PSS:
136       SHA256(data, data_len, hashed_data);
137       memcpy(hdata, hashed_data, 32);
138       *hdata_len = 32;
139       break;
140     case CKM_SHA384:
141     case CKM_SHA384_RSA_PKCS_PSS:
142       SHA384(data, data_len, hashed_data);
143       memcpy(hdata, hashed_data, 48);
144       *hdata_len = 48;
145       break;
146     case CKM_SHA512:
147     case CKM_SHA512_RSA_PKCS_PSS:
148       SHA512(data, data_len, hashed_data);
149       memcpy(hdata, hashed_data, 64);
150       *hdata_len = 64;
151       break;
152     default:
153       break;
154   }
155   return CKR_OK;
156 }
157 
get_digest(CK_MECHANISM_TYPE mech,CK_BYTE * data,CK_ULONG data_len,CK_BYTE * hdata,CK_ULONG * hdata_len)158 static CK_RV get_digest(CK_MECHANISM_TYPE mech,
159                        CK_BYTE* data, CK_ULONG data_len,
160                        CK_BYTE* hdata, CK_ULONG* hdata_len) {
161   if(data == NULL || hdata == NULL || hdata_len == NULL) {
162     return CKR_FUNCTION_FAILED;
163   }
164 
165   CK_BYTE hashed_data[512] = {0};
166   switch(mech) {
167     case CKM_ECDSA:
168     case CKM_RSA_PKCS:
169       memcpy(hdata, data, data_len);
170       *hdata_len = data_len;
171       break;
172     case CKM_ECDSA_SHA1:
173     case CKM_SHA1_RSA_PKCS:
174     case CKM_SHA1_RSA_PKCS_PSS:
175       SHA1(data, data_len, hashed_data);
176       memcpy(hdata, SHA1_DIGEST, sizeof(SHA1_DIGEST));
177       memcpy(hdata + sizeof(SHA1_DIGEST), hashed_data, 20);
178       *hdata_len = sizeof(SHA1_DIGEST) + 20;
179       break;
180     case CKM_ECDSA_SHA256:
181     case CKM_SHA256_RSA_PKCS:
182     case CKM_SHA256_RSA_PKCS_PSS:
183       SHA256(data, data_len, hashed_data);
184       memcpy(hdata, SHA256_DIGEST, sizeof(SHA256_DIGEST));
185       memcpy(hdata + sizeof(SHA256_DIGEST), hashed_data, 32);
186       *hdata_len = sizeof(SHA256_DIGEST) + 32;
187       break;
188     case CKM_ECDSA_SHA384:
189     case CKM_SHA384_RSA_PKCS:
190     case CKM_SHA384_RSA_PKCS_PSS:
191       SHA384(data, data_len, hashed_data);
192       memcpy(hdata, SHA384_DIGEST, sizeof(SHA384_DIGEST));
193       memcpy(hdata + sizeof(SHA384_DIGEST), hashed_data, 48);
194       *hdata_len = sizeof(SHA384_DIGEST) + 48;
195       break;
196     case CKM_ECDSA_SHA512:
197     case CKM_SHA512_RSA_PKCS:
198     case CKM_SHA512_RSA_PKCS_PSS:
199       SHA512(data, data_len, hashed_data);
200       memcpy(hdata, SHA512_DIGEST, sizeof(SHA512_DIGEST));
201       memcpy(hdata + sizeof(SHA512_DIGEST), hashed_data, 64);
202       *hdata_len = sizeof(SHA512_DIGEST) + 64;
203       break;
204     default:
205       break;
206   }
207   return CKR_OK;
208 }
209 
get_md_type(CK_MECHANISM_TYPE mech)210 static const EVP_MD* get_md_type(CK_MECHANISM_TYPE mech) {
211   switch(mech) {
212     case CKM_SHA_1:
213     case CKM_SHA1_RSA_PKCS:
214     case CKM_SHA1_RSA_PKCS_PSS:
215     case CKM_ECDSA_SHA1:
216     case CKG_MGF1_SHA1:
217       return EVP_sha1();
218     case CKM_ECDSA_SHA224:
219     case CKG_MGF1_SHA224:
220       return EVP_sha224();
221     case CKM_SHA256:
222     case CKM_SHA256_RSA_PKCS:
223     case CKM_SHA256_RSA_PKCS_PSS:
224     case CKM_ECDSA_SHA256:
225     case CKG_MGF1_SHA256:
226       return EVP_sha256();
227     case CKM_SHA384:
228     case CKM_SHA384_RSA_PKCS:
229     case CKM_SHA384_RSA_PKCS_PSS:
230     case CKM_ECDSA_SHA384:
231     case CKG_MGF1_SHA384:
232       return EVP_sha384();
233     case CKM_SHA512:
234     case CKM_SHA512_RSA_PKCS:
235     case CKM_SHA512_RSA_PKCS_PSS:
236     case CKM_ECDSA_SHA512:
237     case CKG_MGF1_SHA512:
238       return EVP_sha512();
239     default:
240       return NULL;
241   }
242 }
243 
get_md_of(CK_MECHANISM_TYPE mech)244 static CK_MECHANISM_TYPE get_md_of(CK_MECHANISM_TYPE mech) {
245   switch(mech) {
246     case CKM_SHA_1:
247     case CKM_SHA1_RSA_PKCS:
248     case CKM_SHA1_RSA_PKCS_PSS:
249     case CKM_ECDSA_SHA1:
250     case CKG_MGF1_SHA1:
251       return CKM_SHA_1;
252     case CKM_SHA256:
253     case CKM_SHA256_RSA_PKCS:
254     case CKM_SHA256_RSA_PKCS_PSS:
255     case CKM_ECDSA_SHA256:
256     case CKG_MGF1_SHA256:
257       return CKM_SHA256;
258     case CKM_SHA384:
259     case CKM_SHA384_RSA_PKCS:
260     case CKM_SHA384_RSA_PKCS_PSS:
261     case CKM_ECDSA_SHA384:
262     case CKG_MGF1_SHA384:
263       return CKM_SHA384;
264     case CKM_SHA512:
265     case CKM_SHA512_RSA_PKCS:
266     case CKM_SHA512_RSA_PKCS_PSS:
267     case CKM_ECDSA_SHA512:
268     case CKG_MGF1_SHA512:
269       return CKM_SHA512;
270     default:
271       return CKM_SHA256;
272   }
273 }
274 
test_digest_func(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_MECHANISM_TYPE mech_type)275 void test_digest_func(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech_type) {
276   CK_BYTE     i;
277   CK_BYTE     data[32] = {0};
278   CK_ULONG    data_len = sizeof(data);
279   CK_BYTE     digest[128] = {0};
280   CK_ULONG    digest_len;
281   CK_BYTE     digest_update[128] = {0};
282   CK_ULONG    digest_update_len;
283   CK_BYTE     hdata[128] = {0};
284   CK_ULONG    hdata_len;
285 
286   CK_MECHANISM mech = {mech_type, NULL, 0};
287 
288   for(i=0; i<10; i++) {
289     if(RAND_bytes(data, data_len) <= 0)
290         exit(EXIT_FAILURE);
291 
292     asrt(get_hash(mech_type, data, data_len, hdata, &hdata_len), CKR_OK, "GET HASH");
293 
294     asrt(funcs->C_DigestInit(session, &mech), CKR_OK, "DIGEST INIT");
295     digest_len = sizeof(digest);
296     asrt(funcs->C_Digest(session, data, data_len, digest, &digest_len), CKR_OK, "DIGEST");
297     asrt(digest_len, hdata_len, "DIGEST LEN");
298     asrt(memcmp(hdata, digest, digest_len), 0, "DIGEST VALUE");
299 
300     digest_update_len = sizeof(digest_update);
301     asrt(funcs->C_DigestInit(session, &mech), CKR_OK, "DIGEST INIT");
302     asrt(funcs->C_DigestUpdate(session, data, 10), CKR_OK, "DIGEST UPDATE");
303     asrt(funcs->C_DigestUpdate(session, data+10, 22), CKR_OK, "DIGEST UPDATE");
304     asrt(funcs->C_DigestFinal(session, digest_update, &digest_update_len), CKR_OK, "DIGEST FINAL");
305     asrt(digest_update_len, hdata_len, "DIGEST LEN");
306     asrt(memcmp(hdata, digest_update, digest_update_len), 0, "DIGEST VALUE");
307   }
308 }
309 
import_ec_key(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_BYTE n_keys,int curve,CK_ULONG key_len,CK_BYTE * ec_params,CK_ULONG ec_params_len,CK_OBJECT_HANDLE_PTR obj_cert,CK_OBJECT_HANDLE_PTR obj_pvtkey)310 EC_KEY* import_ec_key(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_BYTE n_keys, int curve, CK_ULONG key_len,
311                       CK_BYTE* ec_params, CK_ULONG ec_params_len, CK_OBJECT_HANDLE_PTR obj_cert, CK_OBJECT_HANDLE_PTR obj_pvtkey) {
312   EVP_PKEY       *evp;
313   EC_KEY         *eck;
314   const BIGNUM   *bn;
315   X509           *cert;
316   CK_BYTE        i;
317   CK_CHAR        *pvt;
318   pvt = malloc(key_len);
319 
320   CK_ULONG    class_k = CKO_PRIVATE_KEY;
321   CK_ULONG    class_c = CKO_CERTIFICATE;
322   CK_ULONG    kt = CKK_ECDSA;
323   CK_BYTE     id = 0;
324   CK_BYTE     value_c[3100] = {0};
325   CK_ULONG    cert_len;
326 
327   unsigned char  *p;
328 
329   CK_ATTRIBUTE privateKeyTemplate[] = {
330     {CKA_CLASS, &class_k, sizeof(class_k)},
331     {CKA_KEY_TYPE, &kt, sizeof(kt)},
332     {CKA_ID, &id, sizeof(id)},
333     {CKA_EC_PARAMS, ec_params, ec_params_len},
334     {CKA_VALUE, pvt, key_len}
335   };
336 
337   CK_ATTRIBUTE publicKeyTemplate[] = {
338     {CKA_CLASS, &class_c, sizeof(class_c)},
339     {CKA_ID, &id, sizeof(id)},
340     {CKA_VALUE, value_c, sizeof(value_c)}
341   };
342 
343   evp = EVP_PKEY_new();
344 
345   if (evp == NULL)
346     exit(EXIT_FAILURE);
347 
348   eck = EC_KEY_new_by_curve_name(curve);
349 
350   if (eck == NULL)
351     exit(EXIT_FAILURE);
352 
353   asrt(EC_KEY_generate_key(eck), 1, "GENERATE ECK");
354 
355   bn = EC_KEY_get0_private_key(eck);
356 
357   asrt(BN_bn2bin(bn, pvt), key_len, "EXTRACT PVT");
358 
359   if (EVP_PKEY_set1_EC_KEY(evp, eck) == 0)
360     exit(EXIT_FAILURE);
361 
362   cert = X509_new();
363 
364   if (cert == NULL)
365     exit(EXIT_FAILURE);
366 
367   X509_set_version(cert, 2); // Version 3
368   X509_NAME_add_entry_by_txt(X509_get_issuer_name(cert), "CN", MBSTRING_ASC, (unsigned char*)"Test Issuer", -1, -1, 0);
369   X509_NAME_add_entry_by_txt(X509_get_subject_name(cert), "CN", MBSTRING_ASC, (unsigned char*)"Test Subject", -1, -1, 0);
370   ASN1_INTEGER_set(X509_get_serialNumber(cert), 0);
371   X509_gmtime_adj(X509_get_notBefore(cert), 0);
372   X509_gmtime_adj(X509_get_notAfter(cert), 0);
373 
374   if (X509_set_pubkey(cert, evp) == 0)
375     exit(EXIT_FAILURE);
376 
377   if (X509_sign(cert, evp, EVP_sha1()) == 0)
378     exit(EXIT_FAILURE);
379 
380   p = value_c;
381   if ((cert_len = (CK_ULONG) i2d_X509(cert, &p)) == 0 || cert_len > sizeof(value_c))
382     exit(EXIT_FAILURE);
383 
384   publicKeyTemplate[2].ulValueLen = cert_len;
385 
386   asrt(funcs->C_Login(session, CKU_SO, (CK_CHAR_PTR)"010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
387 
388   for (i = 0; i < n_keys; i++) {
389     id = i+1;
390     asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj_cert + i), CKR_OK, "IMPORT CERT");
391     asrt(obj_cert[i], 37+i, "CERTIFICATE HANDLE");
392     asrt(funcs->C_CreateObject(session, privateKeyTemplate, 5, obj_pvtkey + i), CKR_OK, "IMPORT KEY");
393     asrt(obj_pvtkey[i], 86+i, "PRIVATE KEY HANDLE");
394   }
395 
396   asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
397   free(pvt);
398   X509_free(cert);
399   EVP_PKEY_free(evp);
400   return eck;
401 }
402 
import_rsa_key(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,int keylen,EVP_PKEY ** evp,RSA ** rsak,CK_BYTE n_keys,CK_OBJECT_HANDLE_PTR obj_cert,CK_OBJECT_HANDLE_PTR obj_pvtkey)403 void import_rsa_key(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, int keylen, EVP_PKEY** evp, RSA** rsak,
404                     CK_BYTE n_keys, CK_OBJECT_HANDLE_PTR obj_cert, CK_OBJECT_HANDLE_PTR obj_pvtkey) {
405   X509        *cert;
406   CK_BYTE     i;
407   CK_BYTE     e[] = {0x01, 0x00, 0x01};
408   CK_BYTE     *p, *q, *dp, *dq, *qinv;
409   p = malloc(keylen / 16);
410   q = malloc(keylen / 16);
411   dp = malloc(keylen / 16);
412   dq = malloc(keylen / 16);
413   qinv = malloc(keylen / 16);
414 
415   BIGNUM      *e_bn;
416   CK_ULONG    class_k = CKO_PRIVATE_KEY;
417   CK_ULONG    class_c = CKO_CERTIFICATE;
418   CK_ULONG    kt = CKK_RSA;
419   CK_BYTE     id = 0;
420   CK_BYTE     value_c[3100] = {0};
421   CK_ULONG    cert_len;
422   const BIGNUM *bp, *bq, *biqmp, *bdmp1, *bdmq1;
423 
424   unsigned char  *px;
425   int p_len, q_len, dp_len, dq_len, qinv_len;
426   int len = keylen/16;
427 
428   CK_ATTRIBUTE privateKeyTemplate[] = {
429     {CKA_CLASS, &class_k, sizeof(class_k)},
430     {CKA_KEY_TYPE, &kt, sizeof(kt)},
431     {CKA_ID, &id, sizeof(id)},
432     {CKA_PUBLIC_EXPONENT, e, sizeof(e)},
433     {CKA_PRIME_1, p, (keylen / 16)},
434     {CKA_PRIME_2, q, (keylen / 16)},
435     {CKA_EXPONENT_1, dp, (keylen / 16)},
436     {CKA_EXPONENT_2, dq, (keylen / 16)},
437     {CKA_COEFFICIENT, qinv, (keylen / 16)}
438   };
439 
440   CK_ATTRIBUTE publicKeyTemplate[] = {
441     {CKA_CLASS, &class_c, sizeof(class_c)},
442     {CKA_ID, &id, sizeof(id)},
443     {CKA_VALUE, value_c, sizeof(value_c)}
444   };
445 
446   int len_correct = 0;
447 
448   e_bn = BN_bin2bn(e, 3, NULL);
449   if (e_bn == NULL)
450     exit(EXIT_FAILURE);
451 
452   do {
453     asrt(RSA_generate_key_ex(*rsak, keylen, e_bn, NULL), 1, "GENERATE RSAK");
454 
455     RSA_get0_factors(*rsak, &bp, &bq);
456     RSA_get0_crt_params(*rsak, &bdmp1, &bdmq1, &biqmp);
457     p_len = BN_bn2bin(bp, p);
458     q_len = BN_bn2bin(bq, q);
459     dp_len = BN_bn2bin(bdmp1, dp);
460     dq_len = BN_bn2bin(bdmq1, dq);
461     qinv_len = BN_bn2bin(biqmp, qinv);
462     len_correct = p_len == len && q_len == len && dp_len == len && dq_len == len && qinv_len == len;
463   } while(!len_correct);
464 
465 
466   if (EVP_PKEY_set1_RSA(*evp, *rsak) == 0)
467     exit(EXIT_FAILURE);
468 
469   cert = X509_new();
470 
471   if (cert == NULL)
472     exit(EXIT_FAILURE);
473 
474   X509_set_version(cert, 2); // Version 3
475   X509_NAME_add_entry_by_txt(X509_get_issuer_name(cert), "CN", MBSTRING_ASC, (unsigned char*)"Test Issuer", -1, -1, 0);
476   X509_NAME_add_entry_by_txt(X509_get_subject_name(cert), "CN", MBSTRING_ASC, (unsigned char*)"Test Subject", -1, -1, 0);
477   ASN1_INTEGER_set(X509_get_serialNumber(cert), 0);
478   X509_gmtime_adj(X509_get_notBefore(cert), 0);
479   X509_gmtime_adj(X509_get_notAfter(cert), 0);
480 
481   if (X509_set_pubkey(cert, *evp) == 0)
482     exit(EXIT_FAILURE);
483 
484   if (X509_sign(cert, *evp, EVP_sha1()) == 0)
485     exit(EXIT_FAILURE);
486 
487   px = value_c;
488   if ((cert_len = (CK_ULONG) i2d_X509(cert, &px)) == 0 || cert_len > sizeof(value_c))
489     exit(EXIT_FAILURE);
490 
491   publicKeyTemplate[2].ulValueLen = cert_len;
492 
493   asrt(funcs->C_Login(session, CKU_SO, (CK_CHAR_PTR)"010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
494 
495   for (i = 0; i < n_keys; i++) {
496     id = i+1;
497     asrt(funcs->C_CreateObject(session, publicKeyTemplate, 3, obj_cert + i), CKR_OK, "IMPORT CERT");
498     asrt(obj_cert[i], 37+i, "CERTIFICATE HANDLE");
499     asrt(funcs->C_CreateObject(session, privateKeyTemplate, 9, obj_pvtkey + i), CKR_OK, "IMPORT KEY");
500     asrt(obj_pvtkey[i], 86+i, "PRIVATE KEY HANDLE");
501   }
502 
503   asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
504 
505   X509_free(cert);
506   BN_free(e_bn);
507   free(p);
508   free(q);
509   free(dp);
510   free(dq);
511   free(qinv);
512 }
513 
generate_ec_keys(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_BYTE n_keys,CK_BYTE * ec_params,CK_ULONG ec_params_len,CK_OBJECT_HANDLE_PTR obj_pubkey,CK_OBJECT_HANDLE_PTR obj_pvtkey)514 void generate_ec_keys(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_BYTE n_keys,
515                       CK_BYTE* ec_params, CK_ULONG ec_params_len,
516                       CK_OBJECT_HANDLE_PTR obj_pubkey, CK_OBJECT_HANDLE_PTR obj_pvtkey) {
517   CK_BYTE     i;
518   CK_ULONG    class_k = CKO_PRIVATE_KEY;
519   CK_ULONG    class_c = CKO_PUBLIC_KEY;
520   CK_ULONG    kt = CKK_ECDSA;
521   CK_BYTE     id = 0;
522 
523   CK_ATTRIBUTE privateKeyTemplate[] = {
524     {CKA_CLASS, &class_k, sizeof(class_k)},
525     {CKA_KEY_TYPE, &kt, sizeof(kt)},
526     {CKA_ID, &id, sizeof(id)}
527   };
528 
529   CK_ATTRIBUTE publicKeyTemplate[] = {
530     {CKA_CLASS, &class_c, sizeof(class_c)},
531     {CKA_ID, &id, sizeof(id)},
532     {CKA_EC_PARAMS, ec_params, ec_params_len}
533   };
534 
535   CK_MECHANISM mech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
536 
537   asrt(funcs->C_Login(session, CKU_SO, (CK_CHAR_PTR)"010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
538 
539   for (i = 0; i < n_keys; i++) {
540     id = i+1;
541     asrt(funcs->C_GenerateKeyPair(session, &mech, publicKeyTemplate, 3, privateKeyTemplate, 3, obj_pubkey+i, obj_pvtkey+i), CKR_OK, "GEN EC KEYPAIR");
542     asrt(obj_pubkey[i], 111+i, "PUBLIC KEY HANDLE");
543     asrt(obj_pvtkey[i], 86+i, "PRIVATE KEY HANDLE");
544   }
545   asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
546 }
547 
generate_rsa_keys(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_ULONG key_size,CK_BYTE n_keys,CK_OBJECT_HANDLE_PTR obj_pubkey,CK_OBJECT_HANDLE_PTR obj_pvtkey)548 void generate_rsa_keys(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_ULONG key_size, CK_BYTE n_keys,
549                       CK_OBJECT_HANDLE_PTR obj_pubkey, CK_OBJECT_HANDLE_PTR obj_pvtkey) {
550   CK_BYTE     i;
551   CK_BYTE     e[] = {0x01, 0x00, 0x01};
552   CK_ULONG    class_k = CKO_PRIVATE_KEY;
553   CK_ULONG    class_c = CKO_PUBLIC_KEY;
554   CK_ULONG    kt = CKK_RSA;
555   CK_BYTE     id = 0;
556 
557   CK_ATTRIBUTE privateKeyTemplate[] = {
558     {CKA_CLASS, &class_k, sizeof(class_k)},
559     {CKA_KEY_TYPE, &kt, sizeof(kt)},
560     {CKA_ID, &id, sizeof(id)}
561   };
562 
563   CK_ATTRIBUTE publicKeyTemplate[] = {
564     {CKA_CLASS, &class_c, sizeof(class_c)},
565     {CKA_ID, &id, sizeof(id)},
566     {CKA_MODULUS_BITS, &key_size, sizeof(key_size)},
567     {CKA_PUBLIC_EXPONENT, e, sizeof(e)}
568   };
569 
570   CK_MECHANISM mech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
571 
572   asrt(funcs->C_Login(session, CKU_SO, (CK_CHAR_PTR)"010203040506070801020304050607080102030405060708", 48), CKR_OK, "Login SO");
573   for (i = 0; i < n_keys; i++) {
574     id = i+1;
575     asrt(funcs->C_GenerateKeyPair(session, &mech, publicKeyTemplate, 4, privateKeyTemplate, 3, obj_pubkey+i, obj_pvtkey+i), CKR_OK, "GEN RSA KEYPAIR");
576     asrt(obj_pubkey[i], 111+i, "PUBLIC KEY HANDLE");
577     asrt(obj_pvtkey[i], 86+i, "PRIVATE KEY HANDLE");
578   }
579   asrt(funcs->C_Logout(session), CKR_OK, "Logout SO");
580 }
581 
construct_der_encoded_sig(CK_BYTE sig[],CK_BYTE_PTR der_encoded,CK_ULONG key_len)582 static void construct_der_encoded_sig(CK_BYTE sig[], CK_BYTE_PTR der_encoded, CK_ULONG key_len) {
583   CK_BYTE_PTR der_ptr;
584   CK_BYTE_PTR r_ptr;
585   CK_BYTE_PTR s_ptr;
586   CK_ULONG r_len;
587   CK_ULONG s_len;
588 
589   r_len = key_len;
590   s_len = key_len;
591 
592   der_ptr = der_encoded;
593   *der_ptr++ = 0x30;
594   *der_ptr++ = 0xff; // placeholder, fix below
595 
596   r_ptr = sig;
597 
598   *der_ptr++ = 0x02;
599   *der_ptr++ = r_len;
600   if (*r_ptr >= 0x80) {
601     *(der_ptr - 1) = *(der_ptr - 1) + 1;
602     *der_ptr++ = 0x00;
603   } else if (*r_ptr == 0x00 && *(r_ptr + 1) < 0x80) {
604     r_len--;
605     *(der_ptr - 1) = *(der_ptr - 1) - 1;
606     r_ptr++;
607   }
608   memcpy(der_ptr, r_ptr, r_len);
609   der_ptr += r_len;
610 
611   s_ptr = sig + key_len;
612 
613   *der_ptr++ = 0x02;
614   *der_ptr++ = s_len;
615   if (*s_ptr >= 0x80) {
616     *(der_ptr - 1) = *(der_ptr - 1) + 1;
617     *der_ptr++ = 0x00;
618   } else if (*s_ptr == 0x00 && *(s_ptr + 1) < 0x80) {
619     s_len--;
620     *(der_ptr - 1) = *(der_ptr - 1) - 1;
621     s_ptr++;
622   }
623   memcpy(der_ptr, s_ptr, s_len);
624   der_ptr += s_len;
625 
626   der_encoded[1] = der_ptr - der_encoded - 2;
627 }
628 
test_ec_sign_simple(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,EC_KEY * eck,CK_ULONG key_len)629 void test_ec_sign_simple(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
630                          CK_BYTE n_keys, EC_KEY *eck, CK_ULONG key_len) {
631 
632   CK_BYTE     i;
633   CK_BYTE     data[32] = {0};
634   CK_ULONG    data_len;
635   CK_BYTE     sig[256] = {0};
636   CK_ULONG    sig_len;
637 
638   CK_BYTE     der_encoded[116] = {0};
639 
640   CK_MECHANISM mech = {CKM_ECDSA, NULL, 0};
641 
642   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
643 
644   data_len = sizeof(data);
645   for (i = 0; i < n_keys; i++) {
646     if(RAND_bytes(data, data_len) <= 0)
647       exit(EXIT_FAILURE);
648 
649     asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SignInit");
650     asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
651     sig_len = sizeof(sig);
652     asrt(funcs->C_Sign(session, data, sizeof(data), sig, &sig_len), CKR_OK, "Sign");
653 
654     if(eck != NULL) {
655       // External verification
656       construct_der_encoded_sig(sig, der_encoded, key_len);
657       asrt(ECDSA_verify(0, data, data_len, der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION");
658     } else {
659       // Internal verification
660       asrt(funcs->C_VerifyInit(session, &mech, get_public_key_handle(funcs, session, obj_pvtkey[i])), CKR_OK, "VerifyInit");
661       asrt(funcs->C_Verify(session, data, sizeof(data), sig, sig_len), CKR_OK, "Verify");
662     }
663   }
664   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
665 }
666 
test_ec_ecdh_simple(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,int curve)667 void test_ec_ecdh_simple(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
668                          CK_BYTE n_keys, int curve) {
669 
670   CK_BYTE     i;
671   CK_BYTE     pubkey[128]={0}, pubkey2[128]={0}, secret[128]={0}, secret2[128]={0};
672 
673   CK_ULONG    cls = CKO_SECRET_KEY;
674   CK_ULONG    kt = CKK_GENERIC_SECRET;
675 
676   CK_BBOOL    _false = CK_FALSE;
677   CK_BBOOL    _true = CK_TRUE;
678 
679   EC_KEY *tmpkey = EC_KEY_new_by_curve_name(curve);
680 
681   if (tmpkey == NULL)
682     exit(EXIT_FAILURE);
683 
684   asrt(EC_KEY_generate_key(tmpkey), 1, "GENERATE ECK");
685 
686   int bits = EC_GROUP_get_degree(EC_KEY_get0_group(tmpkey));
687   unsigned char *ptr = pubkey;
688   asrt(i2o_ECPublicKey(tmpkey, &ptr), bits / 4 + 1, "ENCODE ECK");
689 
690   CK_ECDH1_DERIVE_PARAMS params = {CKD_NULL, 0, NULL, ptr-pubkey, pubkey};
691   CK_MECHANISM mech = {CKM_ECDH1_DERIVE, &params, sizeof(params)};
692   CK_OBJECT_HANDLE sk;
693 
694   for (i = 0; i < n_keys; i++) {
695 
696     CK_ATTRIBUTE deriveKeyTemplate[] = {
697       {CKA_TOKEN, &_false, sizeof(_false)},
698       {CKA_CLASS, &cls, sizeof(cls)},
699       {CKA_KEY_TYPE, &kt, sizeof(kt)},
700       {CKA_EXTRACTABLE, &_true, sizeof(_true)},
701     };
702 
703     CK_ATTRIBUTE pointTemplate[] = {
704       {CKA_EC_POINT, pubkey2, sizeof(pubkey2)},
705     };
706 
707     CK_ATTRIBUTE valueTemplate[] = {
708       {CKA_VALUE, secret2, sizeof(secret2)},
709     };
710 
711     asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
712     asrt(funcs->C_GetAttributeValue(session, obj_pvtkey[i], pointTemplate, 1), CKR_OK, "GetAttributeValue");
713     asrt(funcs->C_DeriveKey(session, &mech, obj_pvtkey[i], deriveKeyTemplate, 4, &sk), CKR_OK, "DeriveKey");
714     asrt(funcs->C_GetAttributeValue(session, sk, valueTemplate, 1), CKR_OK, "GetAttributeValue");
715     asrt(funcs->C_DestroyObject(session, sk), CKR_OK, "DestroyObject");
716     asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
717     // Skip DER encoding
718     ptr = pointTemplate->pValue;
719     ptr += 2;
720     EC_KEY *pk = EC_KEY_new_by_curve_name(curve);
721     pk = o2i_ECPublicKey(&pk, &ptr, pointTemplate->ulValueLen - 2);
722     asrt(ECDH_compute_key(secret, sizeof(secret), EC_KEY_get0_public_key(pk), tmpkey, NULL), bits / 8, "ECDH_compute_key");
723     asrt(memcmp(secret, secret2, bits / 8), 0, "Compare secrets");
724     EC_KEY_free(pk);
725   }
726   EC_KEY_free(tmpkey);
727 }
728 
test_ec_sign_thorough(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_MECHANISM_TYPE mech_type,EC_KEY * eck,CK_ULONG key_len)729 void test_ec_sign_thorough(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
730                            CK_MECHANISM_TYPE mech_type, EC_KEY *eck, CK_ULONG key_len) {
731 
732   CK_BYTE       i, j;
733   CK_BYTE       data[32] = {0};
734   CK_ULONG      data_len;
735   CK_BYTE       hdata[64] = {0};
736   unsigned int  hdata_len;
737   CK_BYTE*      sig;
738   CK_ULONG      sig_len;
739 
740   CK_BYTE     der_encoded[116] = {0};
741   const EVP_MD *md;
742   EVP_MD_CTX *mdctx;
743 
744   CK_OBJECT_HANDLE obj_pubkey;
745   CK_MECHANISM mech = {mech_type, NULL, 0};
746 
747   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
748 
749   for (i = 0; i < 4; i++) {
750     obj_pubkey = get_public_key_handle(funcs, session, obj_pvtkey[i]);
751     for (j = 0; j < 4; j++) {
752       if(RAND_bytes(data, sizeof(data)) <= 0)
753         exit(EXIT_FAILURE);
754       data_len = sizeof(data);
755 
756       // Sign
757       asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SignInit");
758       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
759       sig_len = 0;
760       asrt(funcs->C_Sign(session, data, sizeof(data), NULL, &sig_len), CKR_OK, "Sign");
761       sig = malloc(sig_len);
762       asrt(funcs->C_Sign(session, data, sizeof(data), sig, &sig_len), CKR_OK, "Sign");
763       //Verify
764       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VerifyInit");
765       asrt(funcs->C_Verify(session, data, sizeof(data), sig, sig_len), CKR_OK, "Verify");
766 
767       // External verification
768       if(eck != NULL) {
769         if(mech_type == CKM_ECDSA) {
770           memcpy(hdata, data, data_len);
771           hdata_len = data_len;
772         } else if(mech_type == CKM_ECDSA_SHA384) {
773           SHA384(data, data_len, hdata);
774           hdata_len = 48;
775         } else {
776           md = get_md_type(mech_type);
777           mdctx = EVP_MD_CTX_create();
778           EVP_DigestInit_ex(mdctx, md, NULL);
779           EVP_DigestUpdate(mdctx, data, data_len);
780           EVP_DigestFinal_ex(mdctx, hdata, &hdata_len);
781           EVP_MD_CTX_destroy(mdctx);
782         }
783 
784         construct_der_encoded_sig(sig, der_encoded, key_len);
785 
786         asrt(ECDSA_verify(0, hdata, hdata_len, der_encoded, der_encoded[1] + 2, eck), 1, "ECDSA VERIFICATION");
787       }
788       free(sig);
789     }
790   }
791   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
792 }
793 
test_rsa_sign_simple(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,EVP_PKEY * evp)794 void test_rsa_sign_simple(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
795                           CK_BYTE n_keys, EVP_PKEY* evp) {
796   CK_BYTE     i;
797   CK_BYTE     data[32] = {0};
798   CK_BYTE     sig[256] = {0};
799   CK_ULONG    sig_len;
800   EVP_PKEY_CTX *ctx = NULL;
801 
802   CK_OBJECT_HANDLE obj_pubkey;
803   CK_MECHANISM mech = {CKM_RSA_PKCS, NULL, 0};
804 
805   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "LOGIN USER");
806 
807   for (i = 0; i < n_keys; i++) {
808     obj_pubkey = get_public_key_handle(funcs, session, obj_pvtkey[i]);
809 
810     if(RAND_bytes(data, sizeof(data)) <= 0)
811       exit(EXIT_FAILURE);
812 
813     // Sign
814     asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SIGN INIT");
815     asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
816     sig_len = sizeof(sig);
817     asrt(funcs->C_Sign(session, data, sizeof(data), sig, &sig_len), CKR_OK, "SIGN");
818 
819     if(evp != NULL) {
820       // External verification
821       ctx = EVP_PKEY_CTX_new(evp, NULL);
822       asrt(ctx != NULL, 1, "EVP_KEY_CTX_new");
823       asrt(EVP_PKEY_verify_init(ctx) > 0, 1, "EVP_KEY_verify_init");
824       asrt(EVP_PKEY_CTX_set_signature_md(ctx, NULL) > 0, 1, "EVP_PKEY_CTX_set_signature_md");
825       asrt(EVP_PKEY_verify(ctx, sig, sig_len, data, 32), 1, "EVP_PKEY_verify");
826       EVP_PKEY_CTX_free(ctx);
827     } else {
828       // Internal verification: Verify
829       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VERIFY INIT");
830       asrt(funcs->C_Verify(session, data, sizeof(data), sig, sig_len), CKR_OK, "VERIFY");
831     }
832   }
833 
834   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
835 }
836 
test_rsa_sign_thorough(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,EVP_PKEY * evp,CK_MECHANISM_TYPE mech_type)837 void test_rsa_sign_thorough(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
838                             CK_BYTE n_keys, EVP_PKEY* evp, CK_MECHANISM_TYPE mech_type) {
839   CK_BYTE     i, j;
840   CK_BYTE     data[32] = {0};
841   CK_BYTE*    sig;
842   CK_BYTE*    sig_update;
843   CK_ULONG    sig_len;
844   CK_ULONG    sig_update_len;
845   EVP_PKEY_CTX *ctx = NULL;
846 
847   CK_BYTE     hdata[512] = {0};
848   CK_ULONG    hdata_len;
849 
850   CK_OBJECT_HANDLE obj_pubkey;
851   CK_MECHANISM mech = {mech_type, NULL, 0};
852 
853   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "LOGIN USER");
854 
855   for (i = 0; i < n_keys; i++) {
856     obj_pubkey = get_public_key_handle(funcs, session, obj_pvtkey[i]);
857     for (j = 0; j < 4; j++) {
858 
859       if(RAND_bytes(data, sizeof(data)) <= 0)
860         exit(EXIT_FAILURE);
861 
862       // Sign
863       asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SIGN INIT");
864       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
865       sig_len = 0;
866       asrt(funcs->C_Sign(session, data, sizeof(data), NULL, &sig_len), CKR_OK, "SIGN");
867       sig = malloc(sig_len);
868       asrt(funcs->C_Sign(session, data, sizeof(data), sig, &sig_len), CKR_OK, "SIGN");
869 
870       // External verification
871       if(evp != NULL) {
872         asrt(get_digest(mech_type, data, sizeof(data), hdata, &hdata_len), CKR_OK, "GET DIGEST");
873         ctx = EVP_PKEY_CTX_new(evp, NULL);
874         asrt(ctx != NULL, 1, "EVP_KEY_CTX_new");
875         asrt(EVP_PKEY_verify_init(ctx) > 0, 1, "EVP_KEY_verify_init");
876         asrt(EVP_PKEY_CTX_set_signature_md(ctx, NULL) > 0, 1, "EVP_PKEY_CTX_set_signature_md");
877         asrt(EVP_PKEY_verify(ctx, sig, sig_len, hdata, hdata_len), 1, "EVP_PKEY_verify");
878         EVP_PKEY_CTX_free(ctx);
879       }
880 
881       // Internal verification: Verify
882       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VERIFY INIT");
883       asrt(funcs->C_Verify(session, data, sizeof(data), sig, sig_len), CKR_OK, "VERIFY");
884 
885       // Sign Update
886       asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SIGN INIT");
887       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
888       sig_update_len = 0;
889       asrt(funcs->C_SignUpdate(session, data, 16), CKR_OK, "SIGN UPDATE 1");
890       asrt(funcs->C_SignUpdate(session, data + 16, 10), CKR_OK, "SIGN UPDATE 2");
891       asrt(funcs->C_SignUpdate(session, data + 26, 6), CKR_OK, "SIGN UPDATE 3");
892       asrt(funcs->C_SignFinal(session, NULL, &sig_update_len), CKR_OK, "SIGN FINAL");
893       asrt(sig_update_len, sig_len, "SIGNATURE LENGTH");
894       sig_update = malloc(sig_update_len);
895       asrt(funcs->C_SignFinal(session, sig_update, &sig_update_len), CKR_OK, "SIGN FINAL");
896       // Compare signatures
897       asrt(memcmp(sig, sig_update, sig_len), 0, "SIGNATURE");
898 
899       // Internal verification: Verify Update
900       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VERIFY INIT");
901       asrt(funcs->C_VerifyUpdate(session, data, 10), CKR_OK, "VERIFY UPDATE 1");
902       asrt(funcs->C_VerifyUpdate(session, data+10, 22), CKR_OK, "VERIFY UPDATE 2");
903       asrt(funcs->C_VerifyFinal(session, sig_update, sig_update_len), CKR_OK, "VERIFY FINAL");
904 
905       free(sig);
906       free(sig_update);
907     }
908   }
909 
910   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
911 }
912 
test_rsa_sign_pss(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,RSA * rsak,CK_MECHANISM_TYPE mech_type)913 void test_rsa_sign_pss(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
914                        CK_BYTE n_keys, RSA* rsak, CK_MECHANISM_TYPE mech_type) {
915   CK_BYTE     i, j;
916   CK_BYTE*    data;
917   CK_BYTE*    sig;
918   CK_BYTE*    sig_update;
919   CK_ULONG    sig_len;
920   CK_ULONG    sig_update_len;
921 
922   CK_BYTE*     pss_buf;
923   CK_BYTE      digest_data[256] = {0};
924   unsigned int digest_data_len = sizeof(digest_data);
925   EVP_MD_CTX   *md_ctx;
926 
927   CK_OBJECT_HANDLE obj_pubkey;
928 
929   CK_RSA_PKCS_PSS_PARAMS pss_params = {get_md_of(mech_type), get_md_of(mech_type), EVP_MD_size(get_md_type(get_md_of(mech_type)))};
930   CK_MECHANISM mech = {mech_type, &pss_params, sizeof(pss_params)};
931 
932   data = malloc(pss_params.sLen);
933 
934   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "LOGIN USER");
935 
936   for (i = 0; i < n_keys; i++) {
937     obj_pubkey = get_public_key_handle(funcs, session, obj_pvtkey[i]);
938     for (j = 0; j < 4; j++) {
939 
940       if(RAND_bytes(data, pss_params.sLen) <= 0)
941         exit(EXIT_FAILURE);
942 
943       // Sign
944       asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SIGN INIT");
945       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
946       sig_len = 0;
947       asrt(funcs->C_Sign(session, data, pss_params.sLen, NULL, &sig_len), CKR_OK, "SIGN");
948       sig = malloc(sig_len);
949       asrt(funcs->C_Sign(session, data, pss_params.sLen, sig, &sig_len), CKR_OK, "SIGN");
950 
951       // External verification
952       if(rsak != NULL) {
953         pss_buf = malloc(sig_len);
954         asrt(RSA_public_decrypt(sig_len, sig, pss_buf, rsak, RSA_NO_PADDING), sig_len, "DECRYPT PSS SIGNATURE");
955 
956         if(mech_type == CKM_RSA_PKCS_PSS) {
957           asrt(RSA_verify_PKCS1_PSS_mgf1(rsak, data, get_md_type(pss_params.hashAlg), get_md_type(pss_params.mgf), pss_buf, pss_params.sLen), 1, "VERIFY PSS SIGNATURE");
958         } else {
959           md_ctx = EVP_MD_CTX_create();
960           asrt(EVP_DigestInit_ex(md_ctx, get_md_type(mech_type), NULL), 1, "DIGEST INIT");
961           asrt(EVP_DigestUpdate(md_ctx, data, pss_params.sLen), 1, "DIGEST UPDATE");
962           asrt(EVP_DigestFinal_ex(md_ctx, digest_data, &digest_data_len), 1, "DIGEST FINAL");
963           EVP_MD_CTX_destroy(md_ctx);
964 
965           asrt(RSA_verify_PKCS1_PSS_mgf1(rsak, digest_data, get_md_type(pss_params.hashAlg), get_md_type(pss_params.mgf), pss_buf, pss_params.sLen), 1, "VERIFY PSS SIGNATURE");
966         }
967         free(pss_buf);
968       }
969 
970       // Internal verification: Verify
971       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VERIFY INIT");
972       asrt(funcs->C_Verify(session, data, pss_params.sLen, sig, sig_len), CKR_OK, "VERIFY");
973 
974       // Sign Update
975       asrt(funcs->C_SignInit(session, &mech, obj_pvtkey[i]), CKR_OK, "SIGN INIT");
976       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
977       sig_update_len = 0;
978       asrt(funcs->C_SignUpdate(session, data, 10), CKR_OK, "SIGN UPDATE 1");
979       asrt(funcs->C_SignUpdate(session, data + 10, pss_params.sLen - 10), CKR_OK, "SIGN UPDATE 2");
980       asrt(funcs->C_SignFinal(session, NULL, &sig_update_len), CKR_OK, "SIGN FINAL");
981       asrt(sig_update_len, sig_len, "SIGNATURE LENGTH");
982       sig_update = malloc(sig_update_len);
983       asrt(funcs->C_SignFinal(session, sig_update, &sig_update_len), CKR_OK, "SIGN FINAL");
984 
985 
986       // External verification
987       if(rsak != NULL) {
988         pss_buf = malloc(sig_update_len);
989         asrt(RSA_public_decrypt(sig_update_len, sig_update, pss_buf, rsak, RSA_NO_PADDING), sig_update_len, "DECRYPT PSS SIGNATURE");
990 
991         if(mech_type == CKM_RSA_PKCS_PSS) {
992           asrt(RSA_verify_PKCS1_PSS_mgf1(rsak, data, get_md_type(pss_params.hashAlg), get_md_type(pss_params.mgf), pss_buf, pss_params.sLen), 1, "VERIFY PSS SIGNATURE");
993         } else {
994           md_ctx = EVP_MD_CTX_create();
995           asrt(EVP_DigestInit_ex(md_ctx, get_md_type(mech_type), NULL), 1, "DIGEST INIT");
996           asrt(EVP_DigestUpdate(md_ctx, data, pss_params.sLen), 1, "DIGEST UPDATE");
997           asrt(EVP_DigestFinal_ex(md_ctx, digest_data, &digest_data_len), 1, "DIGEST FINAL");
998           EVP_MD_CTX_destroy(md_ctx);
999 
1000           asrt(RSA_verify_PKCS1_PSS_mgf1(rsak, digest_data, get_md_type(pss_params.hashAlg), get_md_type(pss_params.mgf), pss_buf, pss_params.sLen), 1, "VERIFY PSS SIGNATURE");
1001         }
1002         free(pss_buf);
1003       }
1004 
1005       // Internal verification: Verify Update
1006       asrt(funcs->C_VerifyInit(session, &mech, obj_pubkey), CKR_OK, "VERIFY INIT");
1007       asrt(funcs->C_VerifyUpdate(session, data, 5), CKR_OK, "VERIFY UPDATE 1");
1008       asrt(funcs->C_VerifyUpdate(session, data+5, pss_params.sLen-5), CKR_OK, "VERIFY UPDATE 2");
1009       asrt(funcs->C_VerifyFinal(session, sig_update, sig_update_len), CKR_OK, "VERIFY FINAL");
1010 
1011       free(sig);
1012       free(sig_update);
1013     }
1014   }
1015   free(data);
1016   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
1017 }
1018 
is_data_too_large(int enc_ret)1019 static int is_data_too_large(int enc_ret) {
1020   if(enc_ret != -1) {
1021     return 0;
1022   }
1023 
1024   unsigned long err;
1025   ERR_load_crypto_strings();
1026   err = ERR_get_error();
1027   //char err_str[128] = {0};
1028   //ERR_error_string_n(err, err_str, 128);
1029   //printf("%ld    %s\n", err, err_str);
1030   if(err == 67534980) { // Error code for "data too large for modulus"
1031     return 1;
1032   }
1033   return 0;
1034 }
1035 
test_rsa_decrypt(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,RSA * rsak,CK_MECHANISM_TYPE mech_type,CK_ULONG padding)1036 void test_rsa_decrypt(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
1037                       CK_BYTE n_keys, RSA* rsak, CK_MECHANISM_TYPE mech_type, CK_ULONG padding) {
1038   CK_BYTE   i, j;
1039   int       data_len, enc_len;
1040   CK_BYTE*  data;
1041   CK_BYTE   enc[512] = {0};
1042   CK_BYTE*  dec;
1043   CK_ULONG  dec_len;
1044 
1045   if(padding == RSA_NO_PADDING) {
1046     data_len = RSA_size(rsak);
1047   } else {
1048     data_len = 32;
1049   }
1050   data = malloc(data_len);
1051 
1052   CK_RSA_PKCS_OAEP_PARAMS params = {0};
1053   CK_MECHANISM mech = {mech_type, &params, sizeof(params)};
1054   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
1055 
1056   for (i = 0; i < n_keys; i++) {
1057     for (j = 0; j < 4; j++) {
1058       if(RAND_bytes(data, data_len) <= 0)
1059         exit(EXIT_FAILURE);
1060 
1061       data[0] &= 0x7f; // Unset high bit to ensure it's less than modulus (required for raw RSA)
1062       enc_len = RSA_public_encrypt(data_len, data, enc, rsak, padding);
1063 
1064       // Decrypt
1065       asrt(funcs->C_DecryptInit(session, &mech, obj_pvtkey[i]), CKR_OK, "DECRYPT INIT");
1066       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
1067       dec_len = 0;
1068       asrt(funcs->C_Decrypt(session, enc, enc_len, NULL, &dec_len), CKR_OK, "DECRYPT");
1069       dec = malloc(dec_len);
1070       asrt(funcs->C_Decrypt(session, enc, enc_len, dec, &dec_len), CKR_OK, "DECRYPT");
1071       asrt(dec_len, data_len, "DECRYPTED DATA LEN");
1072       asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA");
1073       free(dec);
1074 
1075       // Decrypt Update
1076       asrt(funcs->C_DecryptInit(session, &mech, obj_pvtkey[i]), CKR_OK, "DECRYPT INIT");
1077       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
1078       dec_len = sizeof(dec);
1079       asrt(funcs->C_DecryptUpdate(session, enc, 100, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1080       dec_len = sizeof(dec);
1081       asrt(funcs->C_DecryptUpdate(session, enc+100, 8, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1082       dec_len = sizeof(dec);
1083       asrt(funcs->C_DecryptUpdate(session, enc+108, 20, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1084       dec_len = 0;
1085       asrt(funcs->C_DecryptFinal(session, NULL, &dec_len), CKR_OK, "DECRYPT FINAL");
1086       dec = malloc(dec_len);
1087       asrt(funcs->C_DecryptFinal(session, dec, &dec_len), CKR_OK, "DECRYPT FINAL");
1088       asrt(dec_len, data_len, "DECRYPTED DATA LEN");
1089       asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA");
1090       free(dec);
1091     }
1092   }
1093   free(data);
1094   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
1095 }
1096 
test_rsa_decrypt_oaep(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,CK_MECHANISM_TYPE mdhash,RSA * rsak)1097 void test_rsa_decrypt_oaep(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
1098                            CK_BYTE n_keys, CK_MECHANISM_TYPE mdhash,  RSA* rsak) {
1099   CK_ULONG  i, j;
1100   int       data_len;
1101   CK_BYTE   data[32] = {0};
1102   CK_BYTE   padded_data[512] = {0};
1103   CK_BYTE   padded_data_len;
1104   CK_BYTE   enc[512] = {0};
1105   CK_BYTE   dec[512] = {0};
1106   CK_ULONG  dec_len;
1107   size_t    enc_len;
1108   const EVP_MD *md;
1109 
1110   CK_RSA_PKCS_OAEP_PARAMS params = {mdhash, mdhash, 0, NULL, 0};
1111   CK_MECHANISM mech = {CKM_RSA_PKCS_OAEP, &params, sizeof(params)};
1112 
1113   data_len = sizeof(data);
1114   padded_data_len = RSA_size(rsak);
1115   md = get_md_type(mdhash);
1116 
1117   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
1118 
1119 
1120   for (i = 0; i < n_keys; i++) {
1121     for (j = 0; j < 4; j++) {
1122 
1123       if(RAND_bytes(data, data_len) <= 0)
1124         exit(EXIT_FAILURE);
1125 
1126       RSA_padding_add_PKCS1_OAEP_mgf1(padded_data, padded_data_len, data, data_len,
1127 					                            NULL, 0, md, md);
1128        enc_len = RSA_public_encrypt(padded_data_len, padded_data, enc, rsak, RSA_NO_PADDING);
1129 
1130       // Decrypt
1131       asrt(funcs->C_DecryptInit(session, &mech, obj_pvtkey[i]), CKR_OK, "DECRYPT INIT");
1132       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
1133       dec_len = sizeof(dec);
1134       asrt(funcs->C_Decrypt(session, enc, enc_len, dec, &dec_len), CKR_OK, "DECRYPT");
1135       asrt(dec_len, data_len, "DECRYPTED DATA LEN");
1136       asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA");
1137 
1138       // Decrypt Update
1139       asrt(funcs->C_DecryptInit(session, &mech, obj_pvtkey[i]), CKR_OK, "DECRYPT INIT");
1140       asrt(funcs->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Re-Login USER");
1141       dec_len = sizeof(dec);
1142       asrt(funcs->C_DecryptUpdate(session, enc, 100, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1143       dec_len = sizeof(dec);
1144       asrt(funcs->C_DecryptUpdate(session, enc+100, 8, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1145       dec_len = sizeof(dec);
1146       asrt(funcs->C_DecryptUpdate(session, enc+108, 20, dec, &dec_len), CKR_OK, "DECRYPT UPDATE");
1147       dec_len = sizeof(dec);
1148       asrt(funcs->C_DecryptFinal(session, dec, &dec_len), CKR_OK, "DECRYPT FINAL");
1149       asrt(dec_len, data_len, "DECRYPTED DATA LEN");
1150       asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA");
1151     }
1152   }
1153   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
1154 }
1155 
test_rsa_encrypt(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj_pvtkey,CK_BYTE n_keys,RSA * rsak,CK_MECHANISM_TYPE mech_type,CK_ULONG padding)1156 void test_rsa_encrypt(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR obj_pvtkey,
1157                       CK_BYTE n_keys, RSA* rsak, CK_MECHANISM_TYPE mech_type, CK_ULONG padding) {
1158   CK_BYTE   i,j;
1159   CK_BYTE   data[32] = {0};
1160   CK_ULONG  data_len = sizeof(data);
1161   CK_BYTE   enc[128] = {0};
1162   CK_ULONG  enc_len;
1163   CK_BYTE   dec[512] = {0};
1164   CK_ULONG  dec_len;
1165 
1166   CK_RSA_PKCS_OAEP_PARAMS params = {0};
1167   CK_MECHANISM mech = {mech_type, &params, sizeof(params)};
1168   CK_OBJECT_HANDLE pubkey;
1169 
1170   asrt(funcs->C_Login(session, CKU_USER, (CK_CHAR_PTR)"123456", 6), CKR_OK, "Login USER");
1171 
1172   for (i = 0; i < n_keys; i++) {
1173     pubkey = get_public_key_handle(funcs, session, obj_pvtkey[i]);
1174     for (j = 0; j < 4; j++) {
1175 
1176       if(RAND_bytes(data, data_len) <= 0)
1177         exit(EXIT_FAILURE);
1178 
1179       data[0] &= 0x7f; // Unset high bit to ensure it's less than modulus (required for raw RSA)
1180 
1181       // Encrypt
1182       asrt(funcs->C_EncryptInit(session, &mech, pubkey), CKR_OK, "ENCRYPT INIT CKM_RSA_PKCS");
1183       enc_len = 0;
1184       asrt(funcs->C_Encrypt(session, data, data_len, NULL, &enc_len), CKR_OK, "ENCRYPT CKM_RSA_PKCS");
1185       asrt(enc_len, 128, "ENCRYPTED DATA LEN");
1186       asrt(funcs->C_Encrypt(session, data, data_len, enc, &enc_len), CKR_OK, "ENCRYPT CKM_RSA_PKCS");
1187 
1188       dec_len = RSA_private_decrypt(enc_len, enc, dec, rsak, padding);
1189       if(padding == RSA_NO_PADDING) {
1190         asrt(dec_len, 128, "DECRYPTED DATA LEN CKM_RSA_X_509");
1191         asrt(memcmp(data, dec+128-data_len, data_len), 0, "DECRYPTED DATA CKM_RSA_X_509");
1192       } else {
1193         asrt(dec_len, data_len, "DECRYPTED DATA LEN CKM_RSA_PKCS");
1194         asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA CKM_RSA_PKCS");
1195       }
1196 
1197       // Encrypt Update
1198       asrt(funcs->C_EncryptInit(session, &mech, pubkey), CKR_OK, "ENCRYPT INIT CKM_RSA_PKCS");
1199       enc_len = sizeof(enc);
1200       asrt(funcs->C_EncryptUpdate(session, data, 10, enc, &enc_len), CKR_OK, "ENCRYPT UPDATE CKM_RSA_PKCS");
1201       enc_len = sizeof(enc);
1202       asrt(funcs->C_EncryptUpdate(session, data+10, 22, enc, &enc_len), CKR_OK, "ENCRYPT UPDATE CKM_RSA_PKCS");
1203       enc_len = 0;
1204       asrt(funcs->C_EncryptFinal(session, NULL, &enc_len), CKR_OK, "ENCRYPT FINAL CKM_RSA_PKCS");
1205       asrt(enc_len, 128, "ENCRYPTED DATA LEN");
1206       asrt(funcs->C_EncryptFinal(session, enc, &enc_len), CKR_OK, "ENCRYPT FINAL CKM_RSA_PKCS");
1207 
1208       dec_len = RSA_private_decrypt(enc_len, enc, dec, rsak, padding);
1209       if(padding == RSA_NO_PADDING) {
1210         asrt(dec_len, 128, "DECRYPTED DATA LEN CKM_RSA_X_509");
1211         asrt(memcmp(data, dec+128-data_len, data_len), 0, "DECRYPTED DATA CKM_RSA_X_509");
1212       } else {
1213         asrt(dec_len, data_len, "DECRYPTED DATA LEN CKM_RSA_PKCS");
1214         asrt(memcmp(data, dec, dec_len), 0, "DECRYPTED DATA CKM_RSA_PKCS");
1215       }
1216     }
1217   }
1218   asrt(funcs->C_Logout(session), CKR_OK, "Logout USER");
1219 }
1220 
test_pubkey_basic_attributes(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE pubkey,CK_ULONG key_type,CK_ULONG key_size,const unsigned char * label)1221 static void test_pubkey_basic_attributes(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1222                                          CK_OBJECT_HANDLE pubkey, CK_ULONG key_type, CK_ULONG key_size,
1223                                          const unsigned char* label) {
1224   CK_ULONG obj_class;
1225   CK_BBOOL obj_token;
1226   CK_BBOOL obj_private;
1227   CK_ULONG obj_key_type;
1228   CK_BBOOL obj_trusted;
1229   CK_BBOOL obj_local;
1230   CK_BBOOL obj_encrypt;
1231   CK_BBOOL obj_verify;
1232   CK_BBOOL obj_wrap;
1233   CK_BBOOL obj_derive;
1234   CK_ULONG obj_modulus_bits;
1235   CK_BBOOL obj_modifiable;
1236   char obj_label[1024] = {0};
1237   CK_ULONG obj_label_len;
1238 
1239   CK_ATTRIBUTE template[] = {
1240     {CKA_CLASS, &obj_class, sizeof(CK_ULONG)},
1241     {CKA_TOKEN, &obj_token, sizeof(CK_BBOOL)},
1242     {CKA_PRIVATE, &obj_private, sizeof(CK_BBOOL)},
1243     {CKA_KEY_TYPE, &obj_key_type, sizeof(CK_ULONG)},
1244     {CKA_TRUSTED, &obj_trusted, sizeof(CK_BBOOL)},
1245     {CKA_LOCAL, &obj_local, sizeof(CK_BBOOL)},
1246     {CKA_ENCRYPT, &obj_encrypt, sizeof(CK_BBOOL)},
1247     {CKA_VERIFY, &obj_verify, sizeof(CK_BBOOL)},
1248     {CKA_WRAP, &obj_wrap, sizeof(CK_BBOOL)},
1249     {CKA_DERIVE, &obj_derive, sizeof(CK_BBOOL)},
1250     {CKA_MODULUS_BITS, &obj_modulus_bits, sizeof(CK_ULONG)},
1251     {CKA_MODIFIABLE, &obj_modifiable, sizeof(CK_BBOOL)},
1252   };
1253 
1254   CK_ATTRIBUTE template_label[] = {
1255     {CKA_LABEL, obj_label, sizeof(obj_label)}
1256   };
1257 
1258   asrt(funcs->C_GetAttributeValue(session, pubkey, template, 12), CKR_OK, "GET BASIC ATTRIBUTES");
1259   asrt(obj_class, CKO_PUBLIC_KEY, "CLASS");
1260   asrt(obj_token, CK_TRUE, "TOKEN");
1261   asrt(obj_private, CK_FALSE, "PRIVATE");
1262   asrt(obj_key_type, key_type, "KEY_TYPE");
1263   asrt(obj_trusted, CK_FALSE, "TRUSTED");
1264   asrt(obj_local, CK_TRUE, "LOCAL");
1265   asrt(obj_encrypt, CK_TRUE, "ENCRYPT");
1266   asrt(obj_verify, CK_TRUE, "VERIFY");
1267   asrt(obj_wrap, CK_FALSE, "WRAP");
1268   asrt(obj_derive, CK_FALSE, "DERIVE");
1269   asrt(obj_modulus_bits, key_size, "MODULUS BITS");
1270   asrt(obj_modifiable, CK_FALSE, "MODIFIABLE");
1271   asrt(obj_trusted, CK_FALSE, "TRUSTED");
1272 
1273   asrt(funcs->C_GetAttributeValue(session, pubkey, template_label, 1), CKR_OK, "GET LABEL");
1274   obj_label_len = template_label[0].ulValueLen;
1275   asrt(obj_label_len, strlen((char*)label), "LABEL LEN");
1276   asrt(strncmp(obj_label, (char*)label, obj_label_len), 0, "LABEL");
1277 }
1278 
test_pubkey_attributes_rsa(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE pubkey,CK_ULONG key_size,const unsigned char * label,CK_ULONG modulus_len,CK_BYTE_PTR pubexp,CK_ULONG pubexp_len)1279 void test_pubkey_attributes_rsa(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1280                                 CK_OBJECT_HANDLE pubkey, CK_ULONG key_size,
1281                                 const unsigned char* label, CK_ULONG modulus_len,
1282                                 CK_BYTE_PTR pubexp, CK_ULONG pubexp_len) {
1283 
1284   CK_BYTE obj_pubexp[1024] = {0};
1285   CK_BYTE obj_modulus[1024] = {0};
1286 
1287   CK_ATTRIBUTE template[] = {
1288     {CKA_MODULUS, obj_modulus, sizeof(obj_modulus)},
1289     {CKA_PUBLIC_EXPONENT, &obj_pubexp, sizeof(obj_pubexp)},
1290   };
1291 
1292   test_pubkey_basic_attributes(funcs, session, pubkey, CKK_RSA, key_size, label);
1293 
1294   asrt(funcs->C_GetAttributeValue(session, pubkey, template, 2), CKR_OK, "GET RSA ATTRIBUTES");
1295   asrt(template[0].ulValueLen, modulus_len, "MODULUS LEN");
1296   asrt(template[1].ulValueLen, pubexp_len, "PUBLIC EXPONEN LEN");
1297   asrt(memcmp(obj_pubexp, pubexp, pubexp_len), 0, "PUBLIC EXPONENT");
1298 }
1299 
test_pubkey_attributes_ec(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE pubkey,CK_ULONG key_size,const unsigned char * label,CK_ULONG ec_point_len,CK_BYTE_PTR ec_params,CK_ULONG ec_params_len)1300 void test_pubkey_attributes_ec(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1301                                 CK_OBJECT_HANDLE pubkey, CK_ULONG key_size,
1302                                 const unsigned char* label, CK_ULONG ec_point_len,
1303                                 CK_BYTE_PTR ec_params, CK_ULONG ec_params_len) {
1304   CK_BYTE obj_ec_point[1024] = {0};
1305   CK_BYTE obj_ec_param[1024] = {0};
1306 
1307   CK_ATTRIBUTE template[] = {
1308     {CKA_EC_POINT, obj_ec_point, sizeof(obj_ec_point)},
1309     {CKA_EC_PARAMS, obj_ec_param, sizeof(obj_ec_param)}
1310   };
1311 
1312   test_pubkey_basic_attributes(funcs, session, pubkey, CKK_EC, key_size, label);
1313 
1314   asrt(funcs->C_GetAttributeValue(session, pubkey, template, 2), CKR_OK, "GET EC ATTRIBUTES");
1315   asrt(template[0].ulValueLen, ec_point_len, "EC POINT LEN");
1316   asrt(template[1].ulValueLen, ec_params_len, "EC PARAMS LEN");
1317   asrt(memcmp(obj_ec_param, ec_params, ec_params_len), 0, "EC PARAMS");
1318 }
1319 
test_privkey_basic_attributes(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE privkey,CK_ULONG key_type,CK_ULONG key_size,const unsigned char * label,CK_BBOOL always_authenticate)1320 static void test_privkey_basic_attributes(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1321                                           CK_OBJECT_HANDLE privkey, CK_ULONG key_type, CK_ULONG key_size,
1322                                          const unsigned char* label, CK_BBOOL always_authenticate) {
1323   CK_ULONG obj_class;
1324   CK_BBOOL obj_token;
1325   CK_BBOOL obj_private;
1326   CK_ULONG obj_key_type;
1327   CK_BBOOL obj_sensitive;
1328   CK_BBOOL obj_always_sensitive;
1329   CK_BBOOL obj_extractable;
1330   CK_BBOOL obj_never_extractable;
1331   CK_BBOOL obj_local;
1332   CK_BBOOL obj_decrypt;
1333   CK_BBOOL obj_unwrap;
1334   CK_BBOOL obj_sign;
1335   CK_BBOOL obj_derive;
1336   CK_ULONG obj_modulus_bits;
1337   CK_BBOOL obj_always_authenticate;
1338   CK_BBOOL obj_modifiable;
1339   char obj_label[1024] = {0};
1340   CK_ULONG obj_label_len;
1341 
1342   CK_ATTRIBUTE template[] = {
1343     {CKA_CLASS, &obj_class, sizeof(CK_ULONG)},
1344     {CKA_TOKEN, &obj_token, sizeof(CK_BBOOL)},
1345     {CKA_PRIVATE, &obj_private, sizeof(CK_BBOOL)},
1346     {CKA_KEY_TYPE, &obj_key_type, sizeof(CK_ULONG)},
1347     {CKA_SENSITIVE, &obj_sensitive, sizeof(CK_BBOOL)},
1348     {CKA_ALWAYS_SENSITIVE, &obj_always_sensitive, sizeof(CK_BBOOL)},
1349     {CKA_EXTRACTABLE, &obj_extractable, sizeof(CK_BBOOL)},
1350     {CKA_NEVER_EXTRACTABLE, &obj_never_extractable, sizeof(CK_BBOOL)},
1351     {CKA_LOCAL, &obj_local, sizeof(CK_BBOOL)},
1352     {CKA_DECRYPT, &obj_decrypt, sizeof(CK_BBOOL)},
1353     {CKA_UNWRAP, &obj_unwrap, sizeof(CK_BBOOL)},
1354     {CKA_SIGN, &obj_sign, sizeof(CK_BBOOL)},
1355     {CKA_DERIVE, &obj_derive, sizeof(CK_BBOOL)},
1356     {CKA_MODULUS_BITS, &obj_modulus_bits, sizeof(CK_ULONG)},
1357     {CKA_ALWAYS_AUTHENTICATE, &obj_always_authenticate, sizeof(CK_BBOOL)},
1358     {CKA_MODIFIABLE, &obj_modifiable, sizeof(CK_BBOOL)}
1359   };
1360 
1361   CK_ATTRIBUTE template_label[] = {
1362     {CKA_LABEL, obj_label, sizeof(obj_label)}
1363   };
1364 
1365   asrt(funcs->C_GetAttributeValue(session, privkey, template, 16), CKR_OK, "GET BASIC ATTRIBUTES");
1366   asrt(obj_class, CKO_PRIVATE_KEY, "CLASS");
1367   asrt(obj_token, CK_TRUE, "TOKEN");
1368   asrt(obj_private, CK_TRUE, "PRIVATE");
1369   asrt(obj_key_type, key_type, "KEY_TYPE");
1370   asrt(obj_sensitive, CK_TRUE, "SENSITIVE");
1371   asrt(obj_always_sensitive, CK_TRUE, "ALWAYS_SENSITIVE");
1372   asrt(obj_extractable, CK_FALSE, "EXTRACTABLE");
1373   asrt(obj_never_extractable, CK_TRUE, "NEVER_EXTRACTABLE");
1374   asrt(obj_local, CK_TRUE, "LOCAL");
1375   asrt(obj_decrypt, CK_TRUE, "DECRYPT");
1376   asrt(obj_unwrap, CK_FALSE, "UNWRAP");
1377   asrt(obj_sign, CK_TRUE, "SIGN");
1378   asrt(obj_derive, CK_FALSE, "DERIVE");
1379   asrt(obj_modulus_bits, key_size, "MODULUS BITS");
1380   asrt(obj_always_authenticate, always_authenticate, "ALWAYS AUTHENTICATE");
1381   asrt(obj_modifiable, CK_FALSE, "MODIFIABLE");
1382 
1383   asrt(funcs->C_GetAttributeValue(session, privkey, template_label, 1), CKR_OK, "GET LABEL");
1384   obj_label_len = template_label[0].ulValueLen;
1385   asrt(obj_label_len, strlen((char*)label), "LABEL LEN");
1386   asrt(strncmp(obj_label, (char*)label, obj_label_len), 0, "LABEL");
1387 }
1388 
test_privkey_attributes_rsa(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE pubkey,CK_ULONG key_size,const unsigned char * label,CK_ULONG modulus_len,CK_BYTE_PTR pubexp,CK_ULONG pubexp_len,CK_BBOOL always_authenticate)1389 void test_privkey_attributes_rsa(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1390                                 CK_OBJECT_HANDLE pubkey, CK_ULONG key_size,
1391                                 const unsigned char* label, CK_ULONG modulus_len,
1392                                 CK_BYTE_PTR pubexp, CK_ULONG pubexp_len,
1393                                 CK_BBOOL always_authenticate) {
1394 
1395   CK_BYTE obj_pubexp[1024] = {0};
1396   CK_BYTE obj_modulus[1024] = {0};
1397 
1398   CK_ATTRIBUTE template[] = {
1399     {CKA_MODULUS, obj_modulus, sizeof(obj_modulus)},
1400     {CKA_PUBLIC_EXPONENT, &obj_pubexp, sizeof(obj_pubexp)},
1401   };
1402 
1403   test_privkey_basic_attributes(funcs, session, pubkey, CKK_RSA, key_size, label, always_authenticate);
1404 
1405   asrt(funcs->C_GetAttributeValue(session, pubkey, template, 2), CKR_OK, "GET RSA ATTRIBUTES");
1406   asrt(template[0].ulValueLen, modulus_len, "MODULUS LEN");
1407   asrt(template[1].ulValueLen, pubexp_len, "PUBLIC EXPONEN LEN");
1408   asrt(memcmp(obj_pubexp, pubexp, pubexp_len), 0, "PUBLIC EXPONENT");
1409 }
1410 
test_privkey_attributes_ec(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_OBJECT_HANDLE pubkey,CK_ULONG key_size,const unsigned char * label,CK_ULONG ec_point_len,CK_BYTE_PTR ec_params,CK_ULONG ec_params_len,CK_BBOOL always_authenticate)1411 void test_privkey_attributes_ec(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1412                                 CK_OBJECT_HANDLE pubkey, CK_ULONG key_size,
1413                                 const unsigned char* label, CK_ULONG ec_point_len,
1414                                 CK_BYTE_PTR ec_params, CK_ULONG ec_params_len,
1415                                 CK_BBOOL always_authenticate) {
1416   CK_BYTE obj_ec_point[1024] = {0};
1417   CK_BYTE obj_ec_param[1024] = {0};
1418 
1419   CK_ATTRIBUTE template[] = {
1420     {CKA_EC_POINT, obj_ec_point, sizeof(obj_ec_point)},
1421     {CKA_EC_PARAMS, obj_ec_param, sizeof(obj_ec_param)}
1422   };
1423 
1424   test_privkey_basic_attributes(funcs, session, pubkey, CKK_EC, key_size, label, always_authenticate);
1425 
1426   asrt(funcs->C_GetAttributeValue(session, pubkey, template, 2), CKR_OK, "GET EC ATTRIBUTES");
1427   asrt(template[0].ulValueLen, ec_point_len, "EC POINT LEN");
1428   asrt(template[1].ulValueLen, ec_params_len, "EC PARAMS LEN");
1429   asrt(memcmp(obj_ec_param, ec_params, ec_params_len), 0, "EC PARAMS");
1430 }
1431 
test_find_objects_by_class(CK_FUNCTION_LIST_PTR funcs,CK_SESSION_HANDLE session,CK_ULONG class,CK_BYTE ckaid,CK_ULONG n_expected,CK_OBJECT_HANDLE obj_expected)1432 void test_find_objects_by_class(CK_FUNCTION_LIST_PTR funcs, CK_SESSION_HANDLE session,
1433                                 CK_ULONG class, CK_BYTE ckaid,
1434                                 CK_ULONG n_expected, CK_OBJECT_HANDLE obj_expected) {
1435   CK_ULONG i;
1436   CK_OBJECT_HANDLE obj[10] = {0};
1437   CK_ULONG n = 0;
1438   CK_BBOOL found = CK_FALSE;
1439 
1440   CK_ATTRIBUTE idClassTemplate[] = {
1441     {CKA_ID, &ckaid, sizeof(ckaid)},
1442     {CKA_CLASS, &class, sizeof(CK_ULONG)}
1443   };
1444 
1445   asrt(funcs->C_FindObjectsInit(session, idClassTemplate, 2), CKR_OK, "FIND INIT");
1446   asrt(funcs->C_FindObjects(session, obj, 10, &n), CKR_OK, "FIND");
1447   asrt(n, n_expected, "N FOUND OBJS");
1448   asrt(funcs->C_FindObjectsFinal(session), CKR_OK, "FIND FINAL");
1449   for(i=0; i<n; i++) {
1450     if(obj[i] == obj_expected) {
1451       found = CK_TRUE;
1452     }
1453   }
1454   asrt(found, CK_TRUE, "EXPECTED OBJECT FOUND");
1455 }