1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
14 * Copyright 2019 Joyent, Inc.
15 */
16
17 #include <errno.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <cryptoutil.h>
21 #include <security/cryptoki.h>
22 #include <sys/debug.h>
23
24 #include "cryptotest.h"
25
26 struct crypto_op {
27 CK_BYTE_PTR in;
28 CK_BYTE_PTR out;
29 CK_BYTE_PTR key;
30 CK_BYTE_PTR param;
31
32 size_t inlen;
33 size_t outlen;
34 size_t keylen;
35 size_t paramlen;
36 const size_t *updatelens;
37
38 char *mechname;
39
40 /* internal */
41 CK_MECHANISM_TYPE mech;
42 CK_OBJECT_HANDLE keyt;
43 CK_SESSION_HANDLE hsession;
44 size_t fg;
45 };
46
47 static void
cryptotest_error(char * name,CK_RV rv)48 cryptotest_error(char *name, CK_RV rv)
49 {
50 (void) fprintf(stderr, "%s: Error = 0x%.8lX '%s'\n",
51 name, rv, pkcs11_strerror(rv));
52 }
53
54 crypto_op_t *
cryptotest_init(cryptotest_t * arg,crypto_func_group_t fg)55 cryptotest_init(cryptotest_t *arg, crypto_func_group_t fg)
56 {
57 crypto_op_t *op = malloc(sizeof (*op));
58
59 if (op == NULL) {
60 (void) fprintf(stderr, "malloc failed: %s\n", strerror(errno));
61 return (NULL);
62 }
63
64 op->in = (CK_BYTE_PTR)arg->in;
65 op->out = (CK_BYTE_PTR)arg->out;
66 op->key = (CK_BYTE_PTR)arg->key;
67 op->param = (CK_BYTE_PTR)arg->param;
68
69 op->inlen = arg->inlen;
70 op->outlen = arg->outlen;
71 op->keylen = arg->keylen;
72 op->paramlen = arg->plen;
73 op->updatelens = arg->updatelens;
74
75 op->mechname = arg->mechname;
76
77 op->hsession = CK_INVALID_HANDLE;
78 op->keyt = CK_INVALID_HANDLE;
79 op->fg = fg;
80
81 if (op->out == NULL)
82 op->outlen = op->inlen;
83 return (op);
84 }
85
86 int
cryptotest_close_session(CK_SESSION_HANDLE hsession)87 cryptotest_close_session(CK_SESSION_HANDLE hsession)
88 {
89 CK_RV rv;
90 rv = C_CloseSession(hsession);
91 if (rv != CKR_OK)
92 cryptotest_error("cryptotest_close_session", rv);
93
94 return (rv);
95 }
96
97 void
cryptotest_close(crypto_op_t * op)98 cryptotest_close(crypto_op_t *op)
99 {
100 if (op->keyt != CK_INVALID_HANDLE)
101 (void) C_DestroyObject(op->hsession, op->keyt);
102
103 if (op->hsession != CK_INVALID_HANDLE)
104 (void) cryptotest_close_session(op->hsession);
105 free(op);
106 VERIFY0(C_Finalize(NULL));
107 }
108
109 int
get_mech_info(crypto_op_t * op)110 get_mech_info(crypto_op_t *op)
111 {
112 CK_RV rv;
113 rv = pkcs11_str2mech(op->mechname, &op->mech);
114 if (rv != CKR_OK) {
115 cryptotest_error("get_mech_info", rv);
116 (void) fprintf(stderr, "failed to resolve mechanism name %s\n",
117 op->mechname);
118 return (CTEST_NAME_RESOLVE_FAILED);
119 }
120 return (rv);
121 }
122
123
124 int
get_hsession_by_mech(crypto_op_t * op)125 get_hsession_by_mech(crypto_op_t *op)
126 {
127 CK_RV rv;
128 rv = SUNW_C_GetMechSession(op->mech, &op->hsession);
129 if (rv != CKR_OK) {
130 cryptotest_error("get_hsession_by_mech", rv);
131 (void) fprintf(stderr,
132 "could not find provider for mechanism %lu\n",
133 op->mech);
134 return (CTEST_MECH_NO_PROVIDER);
135 }
136 return (rv);
137 }
138
139 /*
140 * SIGN_* functions
141 */
142 int
sign_init(crypto_op_t * op)143 sign_init(crypto_op_t *op)
144 {
145 CK_MECHANISM mech;
146 CK_RV rv;
147
148 mech.mechanism = op->mech;
149 mech.pParameter = NULL;
150 mech.ulParameterLen = 0;
151
152 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
153 op->key, op->keylen, &op->keyt);
154
155 if (rv != CKR_OK)
156 cryptotest_error("SUNW_C_KeyToObject", rv);
157
158 rv = C_SignInit(op->hsession, &mech, op->keyt);
159
160 if (rv != CKR_OK)
161 cryptotest_error("C_SignInit", rv);
162
163 return (rv);
164 }
165
166 int
sign_single(crypto_op_t * op)167 sign_single(crypto_op_t *op)
168 {
169 CK_RV rv;
170
171 rv = C_Sign(op->hsession, op->in, op->inlen,
172 op->out, (CK_ULONG_PTR)&op->outlen);
173 if (rv != CKR_OK)
174 cryptotest_error("C_Sign", rv);
175 return (rv);
176 }
177
178 int
sign_update(crypto_op_t * op,size_t offset,size_t len)179 sign_update(crypto_op_t *op, size_t offset, size_t len)
180 {
181 CK_RV rv;
182 rv = C_SignUpdate(op->hsession, op->in + offset, len);
183 if (rv != CKR_OK)
184 cryptotest_error("C_SignUpdate", rv);
185
186 return (rv);
187 }
188
189 int
sign_final(crypto_op_t * op)190 sign_final(crypto_op_t *op)
191 {
192 CK_RV rv;
193 rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen);
194 if (rv != CKR_OK)
195 cryptotest_error("C_SignFinal", rv);
196 return (rv);
197 }
198
199 /*
200 * MAC_* functions
201 */
202 int
mac_init(crypto_op_t * op)203 mac_init(crypto_op_t *op)
204 {
205 return (sign_init(op));
206 }
207
208 int
mac_single(crypto_op_t * op)209 mac_single(crypto_op_t *op)
210 {
211 return (sign_single(op));
212 }
213
214 int
mac_update(crypto_op_t * op,size_t offset,size_t len,size_t * dummy __unused)215 mac_update(crypto_op_t *op, size_t offset, size_t len, size_t *dummy __unused)
216 {
217 return (sign_update(op, offset, len));
218 }
219
220 int
mac_final(crypto_op_t * op,size_t dummy __unused)221 mac_final(crypto_op_t *op, size_t dummy __unused)
222 {
223 return (sign_final(op));
224 }
225
226 /*
227 * VERIFY_* functions
228 */
229 int
verify_init(crypto_op_t * op)230 verify_init(crypto_op_t *op)
231 {
232 CK_MECHANISM mech;
233 CK_RV rv;
234
235 mech.mechanism = op->mech;
236 mech.pParameter = NULL;
237 mech.ulParameterLen = 0;
238
239 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
240 op->key, op->keylen, &op->keyt);
241
242 if (rv != CKR_OK)
243 cryptotest_error("SUNW_C_KeyToObject", rv);
244
245 rv = C_VerifyInit(op->hsession, &mech, op->keyt);
246
247 if (rv != CKR_OK)
248 cryptotest_error("C_VerifyInit", rv);
249
250 return (rv);
251 }
252
253 int
verify_single(crypto_op_t * op)254 verify_single(crypto_op_t *op)
255 {
256 CK_RV rv;
257
258 rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen);
259 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
260 rv != CKR_SIGNATURE_LEN_RANGE)
261 cryptotest_error("C_Verify", rv);
262 return (rv);
263 }
264
265 int
verify_update(crypto_op_t * op,size_t offset,size_t len)266 verify_update(crypto_op_t *op, size_t offset, size_t len)
267 {
268 CK_RV rv;
269 rv = C_VerifyUpdate(op->hsession, op->in + offset, len);
270 if (rv != CKR_OK)
271 cryptotest_error("C_VerifyUpdate", rv);
272 return (rv);
273 }
274
275 int
verify_final(crypto_op_t * op)276 verify_final(crypto_op_t *op)
277 {
278 CK_RV rv;
279 rv = C_VerifyFinal(op->hsession, op->out, op->outlen);
280 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
281 rv != CKR_SIGNATURE_LEN_RANGE)
282 cryptotest_error("C_VerifyFinal", rv);
283 return (rv);
284 }
285
286 /*
287 * ENCRYPT_* functions
288 */
289 int
encrypt_init(crypto_op_t * op)290 encrypt_init(crypto_op_t *op)
291 {
292 CK_MECHANISM mech;
293 CK_RV rv;
294
295 mech.mechanism = op->mech;
296 mech.pParameter = op->param;
297 mech.ulParameterLen = op->paramlen;
298
299 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
300 op->key, op->keylen, &op->keyt);
301
302 if (rv != CKR_OK)
303 cryptotest_error("SUNW_C_KeyToObject", rv);
304
305 rv = C_EncryptInit(op->hsession, &mech, op->keyt);
306
307 if (rv != CKR_OK)
308 cryptotest_error("C_EncryptInit", rv);
309
310 return (rv);
311 }
312
313 int
encrypt_single(crypto_op_t * op)314 encrypt_single(crypto_op_t *op)
315 {
316 CK_RV rv;
317
318 rv = C_Encrypt(op->hsession, op->in, op->inlen,
319 op->out, (CK_ULONG_PTR)&op->outlen);
320 if (rv != CKR_OK)
321 cryptotest_error("C_Encrypt", rv);
322 return (rv);
323 }
324
325 int
encrypt_update(crypto_op_t * op,size_t offset,size_t plainlen,size_t * encrlen)326 encrypt_update(crypto_op_t *op, size_t offset, size_t plainlen, size_t *encrlen)
327 {
328 CK_RV rv;
329 CK_ULONG outlen = op->outlen - *encrlen;
330 rv = C_EncryptUpdate(op->hsession, op->in + offset, plainlen,
331 op->out + *encrlen, &outlen);
332 if (rv != CKR_OK)
333 cryptotest_error("C_EncryptUpdate", rv);
334
335 *encrlen += outlen;
336 return (rv);
337 }
338
339 int
encrypt_final(crypto_op_t * op,size_t encrlen)340 encrypt_final(crypto_op_t *op, size_t encrlen)
341 {
342 CK_RV rv;
343 CK_ULONG outlen = op->outlen - encrlen;
344 rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen);
345 if (rv != CKR_OK)
346 cryptotest_error("C_EncryptFinal", rv);
347 return (rv);
348 }
349
350 /*
351 * DECRYPT_* functions
352 */
353 int
decrypt_init(crypto_op_t * op)354 decrypt_init(crypto_op_t *op)
355 {
356 CK_MECHANISM mech;
357 CK_RV rv;
358
359 mech.mechanism = op->mech;
360 mech.pParameter = op->param;
361 mech.ulParameterLen = op->paramlen;
362
363 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
364 op->key, op->keylen, &op->keyt);
365
366 if (rv != CKR_OK)
367 cryptotest_error("SUNW_C_KeyToObject", rv);
368
369 rv = C_DecryptInit(op->hsession, &mech, op->keyt);
370
371 if (rv != CKR_OK)
372 cryptotest_error("C_DecryptInit", rv);
373
374 return (rv);
375 }
376
377 int
decrypt_single(crypto_op_t * op)378 decrypt_single(crypto_op_t *op)
379 {
380 CK_RV rv;
381
382 rv = C_Decrypt(op->hsession, op->in, op->inlen,
383 op->out, (CK_ULONG_PTR)&op->outlen);
384 if (rv != CKR_OK)
385 cryptotest_error("C_Decrypt", rv);
386 return (rv);
387 }
388
389 int
decrypt_update(crypto_op_t * op,size_t offset,size_t len,size_t * encrlen)390 decrypt_update(crypto_op_t *op, size_t offset, size_t len, size_t *encrlen)
391 {
392 CK_RV rv;
393 CK_ULONG outlen = op->outlen - *encrlen;
394 rv = C_DecryptUpdate(op->hsession, op->in + offset, len,
395 op->out + *encrlen, &outlen);
396 if (rv != CKR_OK)
397 cryptotest_error("C_DecryptUpdate", rv);
398
399 *encrlen += outlen;
400 return (rv);
401 }
402
403 int
decrypt_final(crypto_op_t * op,size_t encrlen)404 decrypt_final(crypto_op_t *op, size_t encrlen)
405 {
406 CK_RV rv;
407 CK_ULONG outlen = op->outlen - encrlen;
408 rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen);
409 if (rv != CKR_OK)
410 cryptotest_error("C_DecryptFinal", rv);
411 return (rv);
412 }
413
414 /*
415 * DIGEST_ functions
416 */
417 int
digest_init(crypto_op_t * op)418 digest_init(crypto_op_t *op)
419 {
420 CK_MECHANISM mech;
421 CK_RV rv;
422
423 mech.mechanism = op->mech;
424 mech.pParameter = op->param;
425 mech.ulParameterLen = op->paramlen;
426
427 rv = C_DigestInit(op->hsession, &mech);
428 if (rv != CKR_OK)
429 cryptotest_error("C_DigestInit", rv);
430 return (rv);
431 }
432
433 int
digest_single(crypto_op_t * op)434 digest_single(crypto_op_t *op)
435 {
436 CK_RV rv;
437
438 rv = C_Digest(op->hsession, op->in, op->inlen,
439 op->out, (CK_ULONG_PTR)&op->outlen);
440 if (rv != CKR_OK)
441 cryptotest_error("C_Digest", rv);
442 return (rv);
443 }
444
445 int
digest_update(crypto_op_t * op,size_t offset,size_t len,size_t * dummy __unused)446 digest_update(crypto_op_t *op, size_t offset, size_t len,
447 size_t *dummy __unused)
448 {
449 CK_RV rv;
450
451 rv = C_DigestUpdate(op->hsession, op->in + offset, len);
452 if (rv != CKR_OK)
453 cryptotest_error("C_DigestUpdate", rv);
454 return (rv);
455 }
456
457 int
digest_final(crypto_op_t * op,size_t dummy __unused)458 digest_final(crypto_op_t *op, size_t dummy __unused)
459 {
460 CK_RV rv;
461
462 rv = C_DigestFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen);
463 if (rv != CKR_OK)
464 cryptotest_error("C_DigestFinal", rv);
465 return (rv);
466 }
467
468 void
ccm_init_params(void * buf,ulong_t ulDataLen,uchar_t * pNonce,ulong_t ulNonceLen,uchar_t * pAAD,ulong_t ulAADLen,ulong_t ulMACLen)469 ccm_init_params(void *buf, ulong_t ulDataLen, uchar_t *pNonce,
470 ulong_t ulNonceLen, uchar_t *pAAD, ulong_t ulAADLen, ulong_t ulMACLen)
471 {
472 CK_CCM_PARAMS *pp = buf;
473
474 pp->ulDataLen = ulDataLen;
475 pp->pNonce = pNonce;
476 pp->ulNonceLen = ulNonceLen;
477 pp->pAAD = pAAD;
478 pp->ulAADLen = ulAADLen;
479 pp->ulMACLen = ulMACLen;
480 }
481
482 size_t
ccm_param_len(void)483 ccm_param_len(void)
484 {
485 return (sizeof (CK_CCM_PARAMS));
486 }
487
488 const char *
cryptotest_errstr(int e,char * buf,size_t buflen)489 cryptotest_errstr(int e, char *buf, size_t buflen)
490 {
491 char *valstr = NULL;
492
493 valstr = pkcs11_strerror(e);
494
495 /*
496 * We'd like both the symbolic and numeric value for every error
497 * value. pkcs11_strerror() already includes the numeric value
498 * for unknown error values (but not for known values), so we take
499 * advantage of all known PKCS#11 error values starting with 'CKR_'
500 * to determine if we need to include the numeric value or not.
501 */
502 if (strcmp(valstr, "CKR_") == 0) {
503 (void) snprintf(buf, buflen, "%s (%08x)", valstr, e);
504 } else {
505 (void) strlcpy(buf, valstr, buflen);
506 }
507
508 return (buf);
509 }
510