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, ¶ms, 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, ¶ms, 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, ¶ms, 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, ¶ms, 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 }