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