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 2018, Joyent, Inc.
15 */
16
17 #include <stdio.h>
18 #include <cryptoutil.h>
19 #include <security/cryptoki.h>
20
21 #include "cryptotest.h"
22
23 struct crypto_op {
24 CK_BYTE_PTR in;
25 CK_BYTE_PTR out;
26 CK_BYTE_PTR key;
27 CK_BYTE_PTR param;
28
29 size_t inlen;
30 size_t outlen;
31 size_t keylen;
32 size_t paramlen;
33 size_t updatelen;
34
35 char *mechname;
36
37 /* internal */
38 CK_MECHANISM_TYPE mech;
39 CK_OBJECT_HANDLE keyt;
40 CK_SESSION_HANDLE hsession;
41 size_t fg;
42 };
43
44 static void
45 cryptotest_error(char *name, CK_RV rv)
46 {
47 (void) fprintf(stderr, "%s: Error = 0x%.8lX '%s'\n",
48 name, rv, pkcs11_strerror(rv));
49 }
50
51 crypto_op_t *
52 cryptotest_init(cryptotest_t *arg, size_t fg)
53 {
54 crypto_op_t *op = malloc(sizeof (*op));
55
56 op->in = (CK_BYTE_PTR)arg->in;
57 op->out = (CK_BYTE_PTR)arg->out;
58 op->key = (CK_BYTE_PTR)arg->key;
59 op->param = (CK_BYTE_PTR)arg->param;
60
61 op->inlen = arg->inlen;
62 op->outlen = arg->outlen;
63 op->keylen = arg->keylen;
64 op->paramlen = arg->plen;
65 op->updatelen = arg->updatelen;
66
67 op->mechname = arg->mechname;
68
69 op->hsession = CK_INVALID_HANDLE;
70 op->fg = fg;
71
72 if (op->out == NULL)
73 op->outlen = op->inlen;
74 return (op);
75 }
76
77 int
78 cryptotest_close_session(CK_SESSION_HANDLE hsession)
79 {
80 CK_RV rv;
81 rv = C_CloseSession(hsession);
82 if (rv != CKR_OK)
83 cryptotest_error("cryptotest_close_session", rv);
84
85 return (rv);
86 }
87
88 int
89 cryptotest_close(crypto_op_t *op)
90 {
91 (void) C_DestroyObject(op->hsession, op->keyt);
92 if (op->hsession != CK_INVALID_HANDLE)
93 (void) cryptotest_close_session(op->hsession);
94 free(op);
95 return (C_Finalize(NULL));
96 }
97
98 int
99 get_mech_info(crypto_op_t *op)
100 {
101 CK_RV rv;
102 rv = pkcs11_str2mech(op->mechname, &op->mech);
103 if (rv != CKR_OK) {
104 cryptotest_error("get_mech_info", rv);
105 (void) fprintf(stderr, "failed to resolve mechanism name %s\n",
106 op->mechname);
107 return (CTEST_NAME_RESOLVE_FAILED);
108 }
109 return (rv);
110 }
111
112
113 int
114 get_hsession_by_mech(crypto_op_t *op)
115 {
116 CK_RV rv;
117 rv = SUNW_C_GetMechSession(op->mech, &op->hsession);
118 if (rv != CKR_OK) {
119 cryptotest_error("get_hsession_by_mech", rv);
120 (void) fprintf(stderr,
121 "could not find provider for mechanism %lu\n",
122 op->mech);
123 return (CTEST_MECH_NO_PROVIDER);
124 }
125 return (rv);
126 }
127
128 /*
129 * SIGN_* functions
130 */
131 int
132 sign_init(crypto_op_t *op)
133 {
134 CK_MECHANISM mech;
135 CK_RV rv;
136
137 mech.mechanism = op->mech;
138 mech.pParameter = NULL;
139 mech.ulParameterLen = 0;
140
141 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
142 op->key, op->keylen, &op->keyt);
143
144 if (rv != CKR_OK)
145 cryptotest_error("SUNW_C_KeyToObject", rv);
146
147 rv = C_SignInit(op->hsession, &mech, op->keyt);
148
149 if (rv != CKR_OK)
150 cryptotest_error("C_SignInit", rv);
151
152 return (rv);
153 }
154
155 int
156 sign_single(crypto_op_t *op)
157 {
158 CK_RV rv;
159
160 rv = C_Sign(op->hsession, op->in, op->inlen,
161 op->out, (CK_ULONG_PTR)&op->outlen);
162 if (rv != CKR_OK)
163 cryptotest_error("C_Sign", rv);
164 return (rv);
165 }
166
167 int
168 sign_update(crypto_op_t *op, int offset)
169 {
170 CK_RV rv;
171 rv = C_SignUpdate(op->hsession, op->in + offset, op->updatelen);
172 if (rv != CKR_OK)
173 cryptotest_error("C_SignUpdate", rv);
174
175 return (rv);
176 }
177
178 int
179 sign_final(crypto_op_t *op)
180 {
181 CK_RV rv;
182 rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen);
183 if (rv != CKR_OK)
184 cryptotest_error("C_SignFinal", rv);
185 return (rv);
186 }
187
188 /*
189 * MAC_* functions
190 */
191 int
192 mac_init(crypto_op_t *op)
193 {
194 return (sign_init(op));
195 }
196
197 int
198 mac_single(crypto_op_t *op)
199 {
200 return (sign_single(op));
201 }
202
203 int
204 mac_update(crypto_op_t *op, int offset)
205 {
206 return (sign_update(op, offset));
207 }
208
209 int
210 mac_final(crypto_op_t *op)
211 {
212 return (sign_final(op));
213 }
214
215 /*
216 * VERIFY_* functions
217 */
218 int
219 verify_init(crypto_op_t *op)
220 {
221 CK_MECHANISM mech;
222 CK_RV rv;
223
224 mech.mechanism = op->mech;
225 mech.pParameter = NULL;
226 mech.ulParameterLen = 0;
227
228 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
229 op->key, op->keylen, &op->keyt);
230
231 if (rv != CKR_OK)
232 cryptotest_error("SUNW_C_KeyToObject", rv);
233
234 rv = C_VerifyInit(op->hsession, &mech, op->keyt);
235
236 if (rv != CKR_OK)
237 cryptotest_error("C_VerifyInit", rv);
238
239 return (rv);
240 }
241
242 int
243 verify_single(crypto_op_t *op)
244 {
245 CK_RV rv;
246
247 rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen);
248 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
249 rv != CKR_SIGNATURE_LEN_RANGE)
250 cryptotest_error("C_Verify", rv);
251 return (rv);
252 }
253
254 int
255 verify_update(crypto_op_t *op, int offset)
256 {
257 CK_RV rv;
258 rv = C_VerifyUpdate(op->hsession, op->in + offset, op->updatelen);
259 if (rv != CKR_OK)
260 cryptotest_error("C_VerifyUpdate", rv);
261 return (rv);
262 }
263
264 int
265 verify_final(crypto_op_t *op)
266 {
267 CK_RV rv;
268 rv = C_VerifyFinal(op->hsession, op->out, op->outlen);
269 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
270 rv != CKR_SIGNATURE_LEN_RANGE)
271 cryptotest_error("C_VerifyFinal", rv);
272 return (rv);
273 }
274
275 /*
276 * ENCRYPT_* functions
277 */
278 int
279 encrypt_init(crypto_op_t *op)
280 {
281 CK_MECHANISM mech;
282 CK_RV rv;
283
284 mech.mechanism = op->mech;
285 mech.pParameter = op->param;
286 mech.ulParameterLen = op->paramlen;
287
288 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
289 op->key, op->keylen, &op->keyt);
290
291 if (rv != CKR_OK)
292 cryptotest_error("SUNW_C_KeyToObject", rv);
293
294 rv = C_EncryptInit(op->hsession, &mech, op->keyt);
295
296 if (rv != CKR_OK)
297 cryptotest_error("C_EncryptInit", rv);
298
299 return (rv);
300 }
301
302 int
303 encrypt_single(crypto_op_t *op)
304 {
305 CK_RV rv;
306
307 rv = C_Encrypt(op->hsession, op->in, op->inlen,
308 op->out, (CK_ULONG_PTR)&op->outlen);
309 if (rv != CKR_OK)
310 cryptotest_error("C_Encrypt", rv);
311 return (rv);
312 }
313
314 int
315 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
316 {
317 CK_RV rv;
318 CK_ULONG outlen = op->outlen - *encrlen;
319 rv = C_EncryptUpdate(op->hsession, op->in + offset, op->updatelen,
320 op->out + *encrlen, &outlen);
321 if (rv != CKR_OK)
322 cryptotest_error("C_EncryptUpdate", rv);
323
324 *encrlen += outlen;
325 return (rv);
326 }
327
328 int
329 encrypt_final(crypto_op_t *op, size_t encrlen)
330 {
331 CK_RV rv;
332 CK_ULONG outlen = op->outlen - encrlen;
333 rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen);
334 if (rv != CKR_OK)
335 cryptotest_error("C_EncryptFinal", rv);
336 return (rv);
337 }
338
339 /*
340 * DECRYPT_* functions
341 */
342 int
343 decrypt_init(crypto_op_t *op)
344 {
345 CK_MECHANISM mech;
346 CK_RV rv;
347
348 mech.mechanism = op->mech;
349 mech.pParameter = op->param;
350 mech.ulParameterLen = op->paramlen;
351
352 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
353 op->key, op->keylen, &op->keyt);
354
355 if (rv != CKR_OK)
356 cryptotest_error("SUNW_C_KeyToObject", rv);
357
358 rv = C_DecryptInit(op->hsession, &mech, op->keyt);
359
360 if (rv != CKR_OK)
361 cryptotest_error("C_DecryptInit", rv);
362
363 return (rv);
364 }
365
366 int
367 decrypt_single(crypto_op_t *op)
368 {
369 CK_RV rv;
370
371 rv = C_Decrypt(op->hsession, op->in, op->inlen,
372 op->out, (CK_ULONG_PTR)&op->outlen);
373 if (rv != CKR_OK)
374 cryptotest_error("C_Decrypt", rv);
375 return (rv);
376 }
377
378 int
379 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
380 {
381 CK_RV rv;
382 CK_ULONG outlen = op->outlen - *encrlen;
383 rv = C_DecryptUpdate(op->hsession, op->in + offset, op->updatelen,
384 op->out + *encrlen, &outlen);
385 if (rv != CKR_OK)
386 cryptotest_error("C_DecryptUpdate", rv);
387
388 *encrlen += outlen;
389 return (rv);
390 }
391
392 int
393 decrypt_final(crypto_op_t *op, size_t encrlen)
394 {
395 CK_RV rv;
396 CK_ULONG outlen = op->outlen - encrlen;
397 rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen);
398 if (rv != CKR_OK)
399 cryptotest_error("C_DecryptFinal", rv);
400 return (rv);
401 }