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 (void) cryptotest_close(op);
108 return (CTEST_NAME_RESOLVE_FAILED);
109 }
110 return (rv);
111 }
112
113
114 int
115 get_hsession_by_mech(crypto_op_t *op)
116 {
117 CK_RV rv;
118 rv = SUNW_C_GetMechSession(op->mech, &op->hsession);
119 if (rv != CKR_OK) {
120 cryptotest_error("get_hsession_by_mech", rv);
121 (void) fprintf(stderr,
122 "could not find provider for mechanism %lu\n",
123 op->mech);
124 (void) cryptotest_close(op);
125 return (CTEST_MECH_NO_PROVIDER);
126 }
127 return (rv);
128 }
129
130 /*
131 * SIGN_* functions
132 */
133 int
134 sign_init(crypto_op_t *op)
135 {
136 CK_MECHANISM mech;
137 CK_RV rv;
138
139 mech.mechanism = op->mech;
140 mech.pParameter = NULL;
141 mech.ulParameterLen = 0;
142
143 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
144 op->key, op->keylen, &op->keyt);
145
146 if (rv != CKR_OK)
147 cryptotest_error("SUNW_C_KeyToObject", rv);
148
149 rv = C_SignInit(op->hsession, &mech, op->keyt);
150
151 if (rv != CKR_OK)
152 cryptotest_error("C_SignInit", rv);
153
154 return (rv);
155 }
156
157 int
158 sign_single(crypto_op_t *op)
159 {
160 CK_RV rv;
161
162 rv = C_Sign(op->hsession, op->in, op->inlen,
163 op->out, (CK_ULONG_PTR)&op->outlen);
164 if (rv != CKR_OK)
165 cryptotest_error("C_Sign", rv);
166 return (rv);
167 }
168
169 int
170 sign_update(crypto_op_t *op, int offset)
171 {
172 CK_RV rv;
173 rv = C_SignUpdate(op->hsession, op->in + offset, op->updatelen);
174 if (rv != CKR_OK)
175 cryptotest_error("C_SignUpdate", rv);
176
177 return (rv);
178 }
179
180 int
181 sign_final(crypto_op_t *op)
182 {
183 CK_RV rv;
184 rv = C_SignFinal(op->hsession, op->out, (CK_ULONG_PTR)&op->outlen);
185 if (rv != CKR_OK)
186 cryptotest_error("C_SignFinal", rv);
187 return (rv);
188 }
189
190 /*
191 * MAC_* functions
192 */
193 int
194 mac_init(crypto_op_t *op)
195 {
196 return (sign_init(op));
197 }
198
199 int
200 mac_single(crypto_op_t *op)
201 {
202 return (sign_single(op));
203 }
204
205 int
206 mac_update(crypto_op_t *op, int offset)
207 {
208 return (sign_update(op, offset));
209 }
210
211 int
212 mac_final(crypto_op_t *op)
213 {
214 return (sign_final(op));
215 }
216
217 /*
218 * VERIFY_* functions
219 */
220 int
221 verify_init(crypto_op_t *op)
222 {
223 CK_MECHANISM mech;
224 CK_RV rv;
225
226 mech.mechanism = op->mech;
227 mech.pParameter = NULL;
228 mech.ulParameterLen = 0;
229
230 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
231 op->key, op->keylen, &op->keyt);
232
233 if (rv != CKR_OK)
234 cryptotest_error("SUNW_C_KeyToObject", rv);
235
236 rv = C_VerifyInit(op->hsession, &mech, op->keyt);
237
238 if (rv != CKR_OK)
239 cryptotest_error("C_VerifyInit", rv);
240
241 return (rv);
242 }
243
244 int
245 verify_single(crypto_op_t *op)
246 {
247 CK_RV rv;
248
249 rv = C_Verify(op->hsession, op->in, op->inlen, op->out, op->outlen);
250 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
251 rv != CKR_SIGNATURE_LEN_RANGE)
252 cryptotest_error("C_Verify", rv);
253 return (rv);
254 }
255
256 int
257 verify_update(crypto_op_t *op, int offset)
258 {
259 CK_RV rv;
260 rv = C_VerifyUpdate(op->hsession, op->in + offset, op->updatelen);
261 if (rv != CKR_OK)
262 cryptotest_error("C_VerifyUpdate", rv);
263 return (rv);
264 }
265
266 int
267 verify_final(crypto_op_t *op)
268 {
269 CK_RV rv;
270 rv = C_VerifyFinal(op->hsession, op->out, op->outlen);
271 if (rv != CKR_OK && rv != CKR_SIGNATURE_INVALID &&
272 rv != CKR_SIGNATURE_LEN_RANGE)
273 cryptotest_error("C_VerifyFinal", rv);
274 return (rv);
275 }
276
277 /*
278 * ENCRYPT_* functions
279 */
280 int
281 encrypt_init(crypto_op_t *op)
282 {
283 CK_MECHANISM mech;
284 CK_RV rv;
285
286 mech.mechanism = op->mech;
287 mech.pParameter = op->param;
288 mech.ulParameterLen = op->paramlen;
289
290 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
291 op->key, op->keylen, &op->keyt);
292
293 if (rv != CKR_OK)
294 cryptotest_error("SUNW_C_KeyToObject", rv);
295
296 rv = C_EncryptInit(op->hsession, &mech, op->keyt);
297
298 if (rv != CKR_OK)
299 cryptotest_error("C_EncryptInit", rv);
300
301 return (rv);
302 }
303
304 int
305 encrypt_single(crypto_op_t *op)
306 {
307 CK_RV rv;
308
309 rv = C_Encrypt(op->hsession, op->in, op->inlen,
310 op->out, (CK_ULONG_PTR)&op->outlen);
311 if (rv != CKR_OK)
312 cryptotest_error("C_Encrypt", rv);
313 return (rv);
314 }
315
316 int
317 encrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
318 {
319 CK_RV rv;
320 CK_ULONG outlen = op->outlen - *encrlen;
321 rv = C_EncryptUpdate(op->hsession, op->in + offset, op->updatelen,
322 op->out + *encrlen, &outlen);
323 if (rv != CKR_OK)
324 cryptotest_error("C_EncryptUpdate", rv);
325
326 *encrlen += outlen;
327 return (rv);
328 }
329
330 int
331 encrypt_final(crypto_op_t *op, size_t encrlen)
332 {
333 CK_RV rv;
334 CK_ULONG outlen = op->outlen - encrlen;
335 rv = C_EncryptFinal(op->hsession, op->out + encrlen, &outlen);
336 if (rv != CKR_OK)
337 cryptotest_error("C_EncryptFinal", rv);
338 return (rv);
339 }
340
341 /*
342 * DECRYPT_* functions
343 */
344 int
345 decrypt_init(crypto_op_t *op)
346 {
347 CK_MECHANISM mech;
348 CK_RV rv;
349
350 mech.mechanism = op->mech;
351 mech.pParameter = op->param;
352 mech.ulParameterLen = op->paramlen;
353
354 rv = SUNW_C_KeyToObject(op->hsession, op->mech,
355 op->key, op->keylen, &op->keyt);
356
357 if (rv != CKR_OK)
358 cryptotest_error("SUNW_C_KeyToObject", rv);
359
360 rv = C_DecryptInit(op->hsession, &mech, op->keyt);
361
362 if (rv != CKR_OK)
363 cryptotest_error("C_DecryptInit", rv);
364
365 return (rv);
366 }
367
368 int
369 decrypt_single(crypto_op_t *op)
370 {
371 CK_RV rv;
372
373 rv = C_Decrypt(op->hsession, op->in, op->inlen,
374 op->out, (CK_ULONG_PTR)&op->outlen);
375 if (rv != CKR_OK)
376 cryptotest_error("C_Decrypt", rv);
377 return (rv);
378 }
379
380 int
381 decrypt_update(crypto_op_t *op, int offset, size_t *encrlen)
382 {
383 CK_RV rv;
384 CK_ULONG outlen = op->outlen - *encrlen;
385 rv = C_DecryptUpdate(op->hsession, op->in + offset, op->updatelen,
386 op->out + *encrlen, &outlen);
387 if (rv != CKR_OK)
388 cryptotest_error("C_DecryptUpdate", rv);
389
390 *encrlen += outlen;
391 return (rv);
392 }
393
394 int
395 decrypt_final(crypto_op_t *op, size_t encrlen)
396 {
397 CK_RV rv;
398 CK_ULONG outlen = op->outlen - encrlen;
399 rv = C_DecryptFinal(op->hsession, op->out + encrlen, &outlen);
400 if (rv != CKR_OK)
401 cryptotest_error("C_DecryptFinal", rv);
402 return (rv);
403 }