1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2017-2018, Linaro Limited
4 */
5
6 #include <pkcs11.h>
7 #include <pkcs11_ta.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <tee_client_api.h>
12
13 #include "pkcs11_processing.h"
14 #include "invoke_ta.h"
15 #include "serializer.h"
16 #include "serialize_ck.h"
17
ck_create_object(CK_SESSION_HANDLE session,CK_ATTRIBUTE_PTR attribs,CK_ULONG count,CK_OBJECT_HANDLE_PTR handle)18 CK_RV ck_create_object(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attribs,
19 CK_ULONG count, CK_OBJECT_HANDLE_PTR handle)
20 {
21 CK_RV rv = CKR_GENERAL_ERROR;
22 struct serializer obj = { 0 };
23 size_t ctrl_size = 0;
24 TEEC_SharedMemory *ctrl = NULL;
25 TEEC_SharedMemory *out_shm = NULL;
26 uint32_t session_handle = session;
27 uint32_t key_handle = 0;
28 char *buf = NULL;
29 size_t out_size = 0;
30
31 if (!handle || !attribs || !count)
32 return CKR_ARGUMENTS_BAD;
33
34 rv = serialize_ck_attributes(&obj, attribs, count);
35 if (rv)
36 goto out;
37
38 /* Shm io0: (i/o) [session-handle][serialized-attributes] / [status] */
39 ctrl_size = sizeof(session_handle) + obj.size;
40 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
41 if (!ctrl) {
42 rv = CKR_HOST_MEMORY;
43 goto out;
44 }
45
46 buf = ctrl->buffer;
47
48 memcpy(buf, &session_handle, sizeof(session_handle));
49 buf += sizeof(session_handle);
50
51 memcpy(buf, obj.buffer, obj.size);
52
53 /* Shm io2: (out) [object handle] */
54 out_shm = ckteec_alloc_shm(sizeof(key_handle), CKTEEC_SHM_OUT);
55 if (!out_shm) {
56 rv = CKR_HOST_MEMORY;
57 goto out;
58 }
59
60 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_CREATE_OBJECT,
61 ctrl, out_shm, &out_size);
62
63 if (rv != CKR_OK || out_size != out_shm->size) {
64 if (rv == CKR_OK)
65 rv = CKR_DEVICE_ERROR;
66 goto out;
67 }
68
69 memcpy(&key_handle, out_shm->buffer, sizeof(key_handle));
70 *handle = key_handle;
71
72 out:
73 release_serial_object(&obj);
74 ckteec_free_shm(out_shm);
75 ckteec_free_shm(ctrl);
76
77 return rv;
78 }
79
ck_destroy_object(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE obj)80 CK_RV ck_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj)
81 {
82 CK_RV rv = CKR_GENERAL_ERROR;
83 TEEC_SharedMemory *ctrl = NULL;
84 size_t ctrl_size = 0;
85 char *buf = NULL;
86 uint32_t session_handle = session;
87 uint32_t obj_id = obj;
88
89 /* Shm io0: (i/o) ctrl = [session-handle][object-handle] / [status] */
90 ctrl_size = sizeof(session_handle) + sizeof(obj_id);
91
92 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
93 if (!ctrl)
94 return CKR_HOST_MEMORY;
95
96 buf = ctrl->buffer;
97
98 memcpy(buf, &session_handle, sizeof(session_handle));
99 buf += sizeof(session_handle);
100
101 memcpy(buf, &obj_id, sizeof(obj_id));
102
103 rv = ckteec_invoke_ctrl(PKCS11_CMD_DESTROY_OBJECT, ctrl);
104
105 ckteec_free_shm(ctrl);
106
107 return rv;
108 }
109
ck_encdecrypt_init(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_OBJECT_HANDLE key,int decrypt)110 CK_RV ck_encdecrypt_init(CK_SESSION_HANDLE session,
111 CK_MECHANISM_PTR mechanism,
112 CK_OBJECT_HANDLE key,
113 int decrypt)
114 {
115 CK_RV rv = CKR_GENERAL_ERROR;
116 TEEC_SharedMemory *ctrl = NULL;
117 struct serializer obj = { 0 };
118 uint32_t session_handle = session;
119 uint32_t key_handle = key;
120 size_t ctrl_size = 0;
121 char *buf = NULL;
122
123 if (!mechanism)
124 return CKR_ARGUMENTS_BAD;
125
126 rv = serialize_ck_mecha_params(&obj, mechanism);
127 if (rv)
128 return rv;
129
130 /*
131 * Shm io0: (in/out) ctrl
132 * (in) [session-handle][key-handle][serialized-mechanism-blob]
133 * (out) [status]
134 */
135 ctrl_size = sizeof(session_handle) + sizeof(key_handle) + obj.size;
136
137 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
138 if (!ctrl) {
139 rv = CKR_HOST_MEMORY;
140 goto bail;
141 }
142
143 buf = ctrl->buffer;
144
145 memcpy(buf, &session_handle, sizeof(session_handle));
146 buf += sizeof(session_handle);
147
148 memcpy(buf, &key_handle, sizeof(key_handle));
149 buf += sizeof(key_handle);
150
151 memcpy(buf, obj.buffer, obj.size);
152
153 rv = ckteec_invoke_ctrl(decrypt ? PKCS11_CMD_DECRYPT_INIT :
154 PKCS11_CMD_ENCRYPT_INIT, ctrl);
155
156 bail:
157 ckteec_free_shm(ctrl);
158 release_serial_object(&obj);
159
160 return rv;
161 }
162
ck_encdecrypt_update(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR out,CK_ULONG_PTR out_len,int decrypt)163 CK_RV ck_encdecrypt_update(CK_SESSION_HANDLE session,
164 CK_BYTE_PTR in,
165 CK_ULONG in_len,
166 CK_BYTE_PTR out,
167 CK_ULONG_PTR out_len,
168 int decrypt)
169 {
170 CK_RV rv = CKR_GENERAL_ERROR;
171 TEEC_SharedMemory *ctrl = NULL;
172 TEEC_SharedMemory *in_shm = NULL;
173 TEEC_SharedMemory *out_shm = NULL;
174 uint32_t session_handle = session;
175 size_t out_size = 0;
176
177 if (!out_len || (in_len && !in)) {
178 rv = CKR_ARGUMENTS_BAD;
179 goto bail;
180 }
181
182 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
183 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
184 if (!ctrl) {
185 rv = CKR_HOST_MEMORY;
186 goto bail;
187 }
188 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
189
190 /* Shm io1: input data buffer if any */
191 if (in_len) {
192 in_shm = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
193 if (!in_shm) {
194 rv = CKR_HOST_MEMORY;
195 goto bail;
196 }
197 }
198
199 /* Shm io2: output data buffer */
200 if (out && out_len && *out_len) {
201 out_shm = ckteec_register_shm(out, *out_len, CKTEEC_SHM_OUT);
202 } else {
203 /* Query output data size */
204 out_shm = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
205 }
206
207 if (!out_shm) {
208 rv = CKR_HOST_MEMORY;
209 goto bail;
210 }
211
212 /* Invoke */
213 rv = ckteec_invoke_ta(decrypt ? PKCS11_CMD_DECRYPT_UPDATE :
214 PKCS11_CMD_ENCRYPT_UPDATE, ctrl,
215 in_shm, out_shm, &out_size, NULL, NULL);
216
217 if (out_len && (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL))
218 *out_len = out_size;
219
220 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !out)
221 rv = CKR_OK;
222
223 goto bail_invoked;
224
225 bail:
226 ck_release_active_processing(session, decrypt ?
227 PKCS11_CMD_DECRYPT_UPDATE :
228 PKCS11_CMD_ENCRYPT_UPDATE);
229 bail_invoked:
230 ckteec_free_shm(out_shm);
231 ckteec_free_shm(in_shm);
232 ckteec_free_shm(ctrl);
233
234 return rv;
235 }
236
ck_encdecrypt_oneshot(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR out,CK_ULONG_PTR out_len,int decrypt)237 CK_RV ck_encdecrypt_oneshot(CK_SESSION_HANDLE session,
238 CK_BYTE_PTR in,
239 CK_ULONG in_len,
240 CK_BYTE_PTR out,
241 CK_ULONG_PTR out_len,
242 int decrypt)
243 {
244 CK_RV rv = CKR_GENERAL_ERROR;
245 TEEC_SharedMemory *ctrl = NULL;
246 TEEC_SharedMemory *in_shm = NULL;
247 TEEC_SharedMemory *out_shm = NULL;
248 uint32_t session_handle = session;
249 size_t out_size = 0;
250
251 if (!out_len || (in_len && !in)) {
252 rv = CKR_ARGUMENTS_BAD;
253 goto bail;
254 }
255
256 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
257 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
258 if (!ctrl) {
259 rv = CKR_HOST_MEMORY;
260 goto bail;
261 }
262 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
263
264 /* Shm io1: input data buffer */
265 in_shm = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
266 if (!in_shm) {
267 rv = CKR_HOST_MEMORY;
268 goto bail;
269 }
270
271 /* Shm io2: output data buffer */
272 if (out && out_len && *out_len) {
273 out_shm = ckteec_register_shm(out, *out_len, CKTEEC_SHM_OUT);
274 } else {
275 /* Query output data size */
276 out_shm = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
277 }
278
279 if (!out_shm) {
280 rv = CKR_HOST_MEMORY;
281 goto bail;
282 }
283
284 rv = ckteec_invoke_ta(decrypt ? PKCS11_CMD_DECRYPT_ONESHOT :
285 PKCS11_CMD_ENCRYPT_ONESHOT, ctrl,
286 in_shm, out_shm, &out_size, NULL, NULL);
287
288 if (out_len && (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL))
289 *out_len = out_size;
290
291 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !out)
292 rv = CKR_OK;
293
294 goto bail_invoked;
295
296 bail:
297 ck_release_active_processing(session, decrypt ?
298 PKCS11_CMD_DECRYPT_ONESHOT :
299 PKCS11_CMD_ENCRYPT_ONESHOT);
300 bail_invoked:
301 ckteec_free_shm(out_shm);
302 ckteec_free_shm(in_shm);
303 ckteec_free_shm(ctrl);
304
305 return rv;
306 }
307
ck_encdecrypt_final(CK_SESSION_HANDLE session,CK_BYTE_PTR out,CK_ULONG_PTR out_len,int decrypt)308 CK_RV ck_encdecrypt_final(CK_SESSION_HANDLE session,
309 CK_BYTE_PTR out,
310 CK_ULONG_PTR out_len,
311 int decrypt)
312 {
313 CK_RV rv = CKR_GENERAL_ERROR;
314 TEEC_SharedMemory *ctrl = NULL;
315 TEEC_SharedMemory *out_shm = NULL;
316 uint32_t session_handle = session;
317 size_t out_size = 0;
318
319 if (!out_len) {
320 rv = CKR_ARGUMENTS_BAD;
321 goto bail;
322 }
323
324 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
325 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
326 if (!ctrl) {
327 rv = CKR_HOST_MEMORY;
328 goto bail;
329 }
330 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
331
332 /* Shm io2: output buffer reference */
333 if (out && out_len && *out_len) {
334 out_shm = ckteec_register_shm(out, *out_len, CKTEEC_SHM_OUT);
335 } else {
336 /* Query output data size */
337 out_shm = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
338 }
339
340 if (!out_shm) {
341 rv = CKR_HOST_MEMORY;
342 goto bail;
343 }
344
345 rv = ckteec_invoke_ctrl_out(decrypt ? PKCS11_CMD_DECRYPT_FINAL :
346 PKCS11_CMD_ENCRYPT_FINAL,
347 ctrl, out_shm, &out_size);
348
349 if (out_len && (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL))
350 *out_len = out_size;
351
352 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !out)
353 rv = CKR_OK;
354
355 goto bail_invoked;
356
357 bail:
358 ck_release_active_processing(session, decrypt ?
359 PKCS11_CMD_DECRYPT_FINAL :
360 PKCS11_CMD_ENCRYPT_FINAL);
361 bail_invoked:
362 ckteec_free_shm(out_shm);
363 ckteec_free_shm(ctrl);
364
365 return rv;
366 }
367
ck_digest_init(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism)368 CK_RV ck_digest_init(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism)
369 {
370 CK_RV rv = CKR_GENERAL_ERROR;
371 TEEC_SharedMemory *ctrl = NULL;
372 struct serializer obj = { 0 };
373 uint32_t session_handle = session;
374 size_t ctrl_size = 0;
375 uint8_t *buf = NULL;
376
377 if (!mechanism)
378 return CKR_ARGUMENTS_BAD;
379
380 rv = serialize_ck_mecha_params(&obj, mechanism);
381 if (rv)
382 return rv;
383
384 /*
385 * Shm io0: (in/out) ctrl
386 * (in) [session-handle][serialized-mechanism-blob]
387 * (out) [status]
388 */
389 ctrl_size = sizeof(session_handle) + obj.size;
390 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
391 if (!ctrl) {
392 rv = CKR_HOST_MEMORY;
393 goto bail;
394 }
395
396 buf = ctrl->buffer;
397
398 memcpy(buf, &session_handle, sizeof(session_handle));
399 buf += sizeof(session_handle);
400
401 memcpy(buf, obj.buffer, obj.size);
402
403 rv = ckteec_invoke_ctrl(PKCS11_CMD_DIGEST_INIT, ctrl);
404
405 bail:
406 ckteec_free_shm(ctrl);
407 release_serial_object(&obj);
408
409 return rv;
410 }
411
ck_digest_key(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE key)412 CK_RV ck_digest_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
413 {
414 CK_RV rv = CKR_GENERAL_ERROR;
415 TEEC_SharedMemory *ctrl = NULL;
416 uint32_t session_handle = session;
417 uint32_t key_handle = key;
418 size_t ctrl_size = 0;
419 uint8_t *buf = NULL;
420
421 /*
422 * Shm io0: (in/out) ctrl
423 * (in) [session-handle][key-handle]
424 * (out) [status]
425 */
426 ctrl_size = sizeof(session_handle) + sizeof(key_handle);
427 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
428 if (!ctrl)
429 return CKR_HOST_MEMORY;
430
431 buf = ctrl->buffer;
432
433 memcpy(buf, &session_handle, sizeof(session_handle));
434 buf += sizeof(session_handle);
435
436 memcpy(buf, &key_handle, sizeof(key_handle));
437
438 rv = ckteec_invoke_ctrl(PKCS11_CMD_DIGEST_KEY, ctrl);
439
440 ckteec_free_shm(ctrl);
441
442 return rv;
443 }
444
ck_digest_update(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len)445 CK_RV ck_digest_update(CK_SESSION_HANDLE session, CK_BYTE_PTR in,
446 CK_ULONG in_len)
447 {
448 CK_RV rv = CKR_GENERAL_ERROR;
449 TEEC_SharedMemory *ctrl = NULL;
450 TEEC_SharedMemory *io1 = NULL;
451 uint32_t session_handle = session;
452 uint8_t *buf = NULL;
453
454 if (!in && in_len) {
455 rv = CKR_ARGUMENTS_BAD;
456 goto bail;
457 }
458
459 /*
460 * Shm io0: (in/out) ctrl = [session-handle] / [status]
461 */
462 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
463 if (!ctrl) {
464 rv = CKR_HOST_MEMORY;
465 goto bail;
466 }
467 buf = ctrl->buffer;
468
469 memcpy(buf, &session_handle, sizeof(session_handle));
470
471 /* Shm io1: input payload */
472 if (in_len && in) {
473 io1 = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
474 if (!io1) {
475 rv = CKR_HOST_MEMORY;
476 goto bail;
477 }
478 }
479
480 rv = ckteec_invoke_ctrl_in(PKCS11_CMD_DIGEST_UPDATE, ctrl, io1);
481
482 goto bail_invoked;
483
484 bail:
485 ck_release_active_processing(session, PKCS11_CMD_DIGEST_UPDATE);
486 bail_invoked:
487 ckteec_free_shm(io1);
488 ckteec_free_shm(ctrl);
489
490 return rv;
491 }
492
ck_digest_oneshot(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR digest_ref,CK_ULONG_PTR digest_len)493 CK_RV ck_digest_oneshot(CK_SESSION_HANDLE session, CK_BYTE_PTR in,
494 CK_ULONG in_len, CK_BYTE_PTR digest_ref,
495 CK_ULONG_PTR digest_len)
496 {
497 CK_RV rv = CKR_GENERAL_ERROR;
498 TEEC_SharedMemory *ctrl = NULL;
499 TEEC_SharedMemory *io1 = NULL;
500 TEEC_SharedMemory *io2 = NULL;
501 uint32_t session_handle = session;
502 size_t out_size = 0;
503 uint8_t *buf = NULL;
504
505 if ((!in && in_len) || !digest_len) {
506 rv = CKR_ARGUMENTS_BAD;
507 goto bail;
508 }
509
510 /*
511 * Shm io0: (in/out) ctrl = [session-handle] / [status]
512 */
513 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
514 if (!ctrl) {
515 rv = CKR_HOST_MEMORY;
516 goto bail;
517 }
518 buf = ctrl->buffer;
519
520 memcpy(buf, &session_handle, sizeof(session_handle));
521
522 /* Shm io1: input payload */
523 if (in_len && in) {
524 io1 = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
525 if (!io1) {
526 rv = CKR_HOST_MEMORY;
527 goto bail;
528 }
529 }
530
531 /* Shm io2: output digest or null sized shm */
532 if (digest_ref) {
533 io2 = ckteec_register_shm(digest_ref, *digest_len,
534 CKTEEC_SHM_OUT);
535 } else {
536 /* Query size if output signature */
537 io2 = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
538 }
539
540 if (!io2) {
541 rv = CKR_HOST_MEMORY;
542 goto bail;
543 }
544
545 rv = ckteec_invoke_ta(PKCS11_CMD_DIGEST_ONESHOT, ctrl,
546 io1, io2, &out_size, NULL, NULL);
547
548 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL)
549 *digest_len = out_size;
550
551 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !digest_ref)
552 rv = CKR_OK;
553
554 goto bail_invoked;
555
556 bail:
557 ck_release_active_processing(session, PKCS11_CMD_DIGEST_ONESHOT);
558 bail_invoked:
559 ckteec_free_shm(io1);
560 ckteec_free_shm(io2);
561 ckteec_free_shm(ctrl);
562
563 return rv;
564 }
565
ck_digest_final(CK_SESSION_HANDLE session,CK_BYTE_PTR digest_ref,CK_ULONG_PTR digest_len)566 CK_RV ck_digest_final(CK_SESSION_HANDLE session, CK_BYTE_PTR digest_ref,
567 CK_ULONG_PTR digest_len)
568 {
569 CK_RV rv = CKR_GENERAL_ERROR;
570 TEEC_SharedMemory *ctrl = NULL;
571 TEEC_SharedMemory *io2 = NULL;
572 uint32_t session_handle = session;
573 size_t io2_size = 0;
574 uint8_t *buf = NULL;
575
576 /*
577 * - If digest_ref == NULL AND digest_len == NULL -> need to call TA to
578 * terminate session.
579 * - If digest_len == NULL -> need to call to TA to terminate session.
580 * - If digest_ref == NULL BUT digest_len != NULL just operate normally
581 * to get size of the required buffer
582 */
583 if (!digest_len) {
584 rv = CKR_ARGUMENTS_BAD;
585 goto bail;
586 }
587
588 /*
589 * Shm io0: (in/out) ctrl = [session-handle] / [status]
590 */
591 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
592 if (!ctrl) {
593 rv = CKR_HOST_MEMORY;
594 goto bail;
595 }
596 buf = ctrl->buffer;
597
598 memcpy(buf, &session_handle, sizeof(session_handle));
599
600 /* Shm io2: output digest or null sized shm */
601 if (digest_ref)
602 io2 = ckteec_register_shm(digest_ref, *digest_len,
603 CKTEEC_SHM_OUT);
604 else
605 io2 = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
606
607 if (!io2) {
608 rv = CKR_HOST_MEMORY;
609 goto bail;
610 }
611
612 rv = ckteec_invoke_ta(PKCS11_CMD_DIGEST_FINAL, ctrl, NULL, io2,
613 &io2_size, NULL, NULL);
614
615 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL)
616 *digest_len = io2_size;
617
618 if (rv == CKR_BUFFER_TOO_SMALL && io2_size && !digest_ref)
619 rv = CKR_OK;
620
621 goto bail_invoked;
622
623 bail:
624 ck_release_active_processing(session, PKCS11_CMD_DIGEST_FINAL);
625 bail_invoked:
626 ckteec_free_shm(io2);
627 ckteec_free_shm(ctrl);
628
629 return rv;
630 }
631
ck_signverify_init(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_OBJECT_HANDLE key,int sign)632 CK_RV ck_signverify_init(CK_SESSION_HANDLE session,
633 CK_MECHANISM_PTR mechanism,
634 CK_OBJECT_HANDLE key,
635 int sign)
636 {
637 CK_RV rv = CKR_GENERAL_ERROR;
638 TEEC_SharedMemory *ctrl = NULL;
639 struct serializer obj = { 0 };
640 uint32_t session_handle = session;
641 uint32_t key_handle = key;
642 size_t ctrl_size = 0;
643 char *buf = NULL;
644
645 if (!mechanism)
646 return CKR_ARGUMENTS_BAD;
647
648 rv = serialize_ck_mecha_params(&obj, mechanism);
649 if (rv)
650 return rv;
651
652 /*
653 * Shm io0: (in/out) ctrl
654 * (in) [session-handle][key-handle][serialized-mechanism-blob]
655 * (out) [status]
656 */
657 ctrl_size = sizeof(session_handle) + sizeof(key_handle) + obj.size;
658 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
659 if (!ctrl) {
660 rv = CKR_HOST_MEMORY;
661 goto bail;
662 }
663
664 buf = ctrl->buffer;
665
666 memcpy(buf, &session_handle, sizeof(session_handle));
667 buf += sizeof(session_handle);
668
669 memcpy(buf, &key_handle, sizeof(key_handle));
670 buf += sizeof(key_handle);
671
672 memcpy(buf, obj.buffer, obj.size);
673
674 rv = ckteec_invoke_ctrl(sign ? PKCS11_CMD_SIGN_INIT :
675 PKCS11_CMD_VERIFY_INIT, ctrl);
676
677 bail:
678 ckteec_free_shm(ctrl);
679 release_serial_object(&obj);
680
681 return rv;
682 }
683
ck_signverify_update(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len,int sign)684 CK_RV ck_signverify_update(CK_SESSION_HANDLE session,
685 CK_BYTE_PTR in,
686 CK_ULONG in_len,
687 int sign)
688 {
689 CK_RV rv = CKR_GENERAL_ERROR;
690 TEEC_SharedMemory *ctrl = NULL;
691 TEEC_SharedMemory *in_shm = NULL;
692 uint32_t session_handle = session;
693
694 if (!in && in_len) {
695 rv = CKR_ARGUMENTS_BAD;
696 goto bail;
697 }
698
699 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
700 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
701 if (!ctrl) {
702 rv = CKR_HOST_MEMORY;
703 goto bail;
704 }
705 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
706
707 /* Shm io1: input data */
708 in_shm = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
709 if (!in_shm) {
710 rv = CKR_HOST_MEMORY;
711 goto bail;
712 }
713
714 rv = ckteec_invoke_ctrl_in(sign ? PKCS11_CMD_SIGN_UPDATE :
715 PKCS11_CMD_VERIFY_UPDATE, ctrl, in_shm);
716
717 goto bail_invoked;
718
719 bail:
720 ck_release_active_processing(session, sign ? PKCS11_CMD_SIGN_UPDATE :
721 PKCS11_CMD_VERIFY_UPDATE);
722 bail_invoked:
723 ckteec_free_shm(in_shm);
724 ckteec_free_shm(ctrl);
725
726 return rv;
727 }
728
ck_signverify_oneshot(CK_SESSION_HANDLE session,CK_BYTE_PTR in,CK_ULONG in_len,CK_BYTE_PTR sign_ref,CK_ULONG_PTR sign_len,int sign)729 CK_RV ck_signverify_oneshot(CK_SESSION_HANDLE session,
730 CK_BYTE_PTR in,
731 CK_ULONG in_len,
732 CK_BYTE_PTR sign_ref,
733 CK_ULONG_PTR sign_len,
734 int sign)
735 {
736 CK_RV rv = CKR_GENERAL_ERROR;
737 TEEC_SharedMemory *ctrl = NULL;
738 TEEC_SharedMemory *io1 = NULL;
739 TEEC_SharedMemory *io2 = NULL;
740 uint32_t session_handle = session;
741 size_t out_size = 0;
742
743 if ((in_len && !in) || (!sign && sign_len && *sign_len && !sign_ref) ||
744 (sign && !sign_len)) {
745 rv = CKR_ARGUMENTS_BAD;
746 goto bail;
747 }
748
749 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
750 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
751 if (!ctrl) {
752 rv = CKR_HOST_MEMORY;
753 goto bail;
754 }
755 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
756
757 /* Shm io1: input payload */
758 if (in_len) {
759 io1 = ckteec_register_shm(in, in_len, CKTEEC_SHM_IN);
760 if (!io1) {
761 rv = CKR_HOST_MEMORY;
762 goto bail;
763 }
764 }
765
766 /*
767 * Shm io2: input signature (if verifying) or null sized shm
768 * or
769 * Shm io2: output signature (if signing) or null sized shm
770 */
771 if (sign_ref && sign_len && *sign_len) {
772 io2 = ckteec_register_shm(sign_ref, *sign_len,
773 sign ? CKTEEC_SHM_OUT : CKTEEC_SHM_IN);
774 } else {
775 /* Query size if output signature */
776 io2 = ckteec_alloc_shm(0, sign ? CKTEEC_SHM_OUT : CKTEEC_SHM_IN);
777 }
778
779 if (!io2) {
780 rv = CKR_HOST_MEMORY;
781 goto bail;
782 }
783
784 rv = ckteec_invoke_ta(sign ? PKCS11_CMD_SIGN_ONESHOT :
785 PKCS11_CMD_VERIFY_ONESHOT, ctrl,
786 io1, io2, &out_size, NULL, NULL);
787
788 if (sign && (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL))
789 *sign_len = out_size;
790
791 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !sign_ref)
792 rv = CKR_OK;
793
794 goto bail_invoked;
795
796 bail:
797 ck_release_active_processing(session, sign ? PKCS11_CMD_SIGN_ONESHOT :
798 PKCS11_CMD_VERIFY_ONESHOT);
799 bail_invoked:
800 ckteec_free_shm(io1);
801 ckteec_free_shm(io2);
802 ckteec_free_shm(ctrl);
803
804 return rv;
805 }
806
ck_signverify_final(CK_SESSION_HANDLE session,CK_BYTE_PTR sign_ref,CK_ULONG_PTR sign_len,int sign)807 CK_RV ck_signverify_final(CK_SESSION_HANDLE session,
808 CK_BYTE_PTR sign_ref,
809 CK_ULONG_PTR sign_len,
810 int sign)
811 {
812 CK_RV rv = CKR_GENERAL_ERROR;
813 TEEC_SharedMemory *ctrl = NULL;
814 TEEC_SharedMemory *io = NULL;
815 uint32_t session_handle = session;
816 size_t io_size = 0;
817
818 if ((!sign && sign_len && *sign_len && !sign_ref) ||
819 (sign && !sign_len)) {
820 rv = CKR_ARGUMENTS_BAD;
821 goto bail;
822 }
823
824 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
825 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
826 if (!ctrl) {
827 rv = CKR_HOST_MEMORY;
828 goto bail;
829 }
830 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
831
832 /*
833 * Shm io1: input signature (if verifying) or null sized shm
834 * or
835 * Shm io1: output signature (if signing) or null sized shm
836 */
837 if (sign_ref && sign_len && *sign_len)
838 io = ckteec_register_shm(sign_ref, *sign_len,
839 sign ? CKTEEC_SHM_OUT : CKTEEC_SHM_IN);
840 else
841 io = ckteec_alloc_shm(0, sign ? CKTEEC_SHM_OUT : CKTEEC_SHM_IN);
842
843 if (!io) {
844 rv = CKR_HOST_MEMORY;
845 goto bail;
846 }
847
848 rv = ckteec_invoke_ta(sign ? PKCS11_CMD_SIGN_FINAL :
849 PKCS11_CMD_VERIFY_FINAL, ctrl, NULL, io,
850 &io_size, NULL, NULL);
851
852 if (sign && sign_len && (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL))
853 *sign_len = io_size;
854
855 if (rv == CKR_BUFFER_TOO_SMALL && io_size && !sign_ref)
856 rv = CKR_OK;
857
858 goto bail_invoked;
859
860 bail:
861 ck_release_active_processing(session, sign ? PKCS11_CMD_SIGN_FINAL :
862 PKCS11_CMD_VERIFY_FINAL);
863 bail_invoked:
864 ckteec_free_shm(io);
865 ckteec_free_shm(ctrl);
866
867 return rv;
868 }
869
ck_generate_key(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_ATTRIBUTE_PTR attribs,CK_ULONG count,CK_OBJECT_HANDLE_PTR handle)870 CK_RV ck_generate_key(CK_SESSION_HANDLE session,
871 CK_MECHANISM_PTR mechanism,
872 CK_ATTRIBUTE_PTR attribs,
873 CK_ULONG count,
874 CK_OBJECT_HANDLE_PTR handle)
875 {
876 CK_RV rv = CKR_GENERAL_ERROR;
877 TEEC_SharedMemory *ctrl = NULL;
878 TEEC_SharedMemory *out_shm = NULL;
879 struct serializer smecha = { 0 };
880 struct serializer sattr = { 0 };
881 uint32_t session_handle = session;
882 size_t ctrl_size = 0;
883 uint32_t key_handle = 0;
884 char *buf = NULL;
885 size_t out_size = 0;
886
887 if (!handle || !mechanism || (count && !attribs))
888 return CKR_ARGUMENTS_BAD;
889
890 rv = serialize_ck_mecha_params(&smecha, mechanism);
891 if (rv)
892 return rv;
893
894 rv = serialize_ck_attributes(&sattr, attribs, count);
895 if (rv)
896 goto bail;
897
898 /*
899 * Shm io0: (in/out) ctrl
900 * (in) [session-handle][serialized-mecha][serialized-attributes]
901 * (out) [status]
902 */
903 ctrl_size = sizeof(session_handle) + smecha.size + sattr.size;
904
905 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
906 if (!ctrl) {
907 rv = CKR_HOST_MEMORY;
908 goto bail;
909 }
910
911 buf = ctrl->buffer;
912
913 memcpy(buf, &session_handle, sizeof(session_handle));
914 buf += sizeof(session_handle);
915
916 memcpy(buf, smecha.buffer, smecha.size);
917 buf += smecha.size;
918
919 memcpy(buf, sattr.buffer, sattr.size);
920
921 /* Shm io2: (out) [object handle] */
922 out_shm = ckteec_alloc_shm(sizeof(key_handle), CKTEEC_SHM_OUT);
923 if (!out_shm) {
924 rv = CKR_HOST_MEMORY;
925 goto bail;
926 }
927
928 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_GENERATE_KEY,
929 ctrl, out_shm, &out_size);
930
931 if (rv != CKR_OK || out_size != out_shm->size) {
932 if (rv == CKR_OK)
933 rv = CKR_DEVICE_ERROR;
934 goto bail;
935 }
936
937 memcpy(&key_handle, out_shm->buffer, sizeof(key_handle));
938 *handle = key_handle;
939
940 bail:
941 ckteec_free_shm(out_shm);
942 ckteec_free_shm(ctrl);
943 release_serial_object(&sattr);
944 release_serial_object(&smecha);
945
946 return rv;
947 }
948
ck_find_objects_init(CK_SESSION_HANDLE session,CK_ATTRIBUTE_PTR attribs,CK_ULONG count)949 CK_RV ck_find_objects_init(CK_SESSION_HANDLE session,
950 CK_ATTRIBUTE_PTR attribs,
951 CK_ULONG count)
952 {
953 CK_RV rv = CKR_GENERAL_ERROR;
954 TEEC_SharedMemory *ctrl = NULL;
955 uint32_t session_handle = session;
956 struct serializer obj = { 0 };
957 size_t ctrl_size = 0;
958 char *buf = NULL;
959
960 if (count && !attribs)
961 return CKR_ARGUMENTS_BAD;
962
963 rv = serialize_ck_attributes(&obj, attribs, count);
964 if (rv)
965 return rv;
966
967 /* Shm io0: (in/out) ctrl
968 * (in) [session-handle][headed-serialized-attributes]
969 * (out) [status]
970 */
971 ctrl_size = sizeof(session_handle) + obj.size;
972 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
973 if (!ctrl) {
974 rv = CKR_HOST_MEMORY;
975 goto bail;
976 }
977
978 buf = ctrl->buffer;
979
980 memcpy(buf, &session_handle, sizeof(session_handle));
981 buf += sizeof(session_handle);
982
983 memcpy(buf, obj.buffer, obj.size);
984
985 rv = ckteec_invoke_ctrl(PKCS11_CMD_FIND_OBJECTS_INIT, ctrl);
986
987 bail:
988 ckteec_free_shm(ctrl);
989 release_serial_object(&obj);
990
991 return rv;
992 }
993
ck_find_objects(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE_PTR obj,CK_ULONG max_count,CK_ULONG_PTR count)994 CK_RV ck_find_objects(CK_SESSION_HANDLE session,
995 CK_OBJECT_HANDLE_PTR obj,
996 CK_ULONG max_count,
997 CK_ULONG_PTR count)
998
999 {
1000 CK_RV rv = CKR_GENERAL_ERROR;
1001 TEEC_SharedMemory *ctrl = NULL;
1002 TEEC_SharedMemory *out_shm = NULL;
1003 uint32_t session_handle = session;
1004 uint32_t *handles = NULL;
1005 size_t handles_size = max_count * sizeof(uint32_t);
1006 CK_ULONG n = 0;
1007 CK_ULONG last = 0;
1008 size_t out_size = 0;
1009
1010 if (!count || (max_count && !obj))
1011 return CKR_ARGUMENTS_BAD;
1012
1013 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
1014 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
1015 if (!ctrl) {
1016 rv = CKR_HOST_MEMORY;
1017 goto bail;
1018 }
1019 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
1020
1021 /* Shm io2: (out) [object handle list] */
1022 out_shm = ckteec_alloc_shm(handles_size, CKTEEC_SHM_OUT);
1023 if (!out_shm) {
1024 rv = CKR_HOST_MEMORY;
1025 goto bail;
1026 }
1027
1028 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_FIND_OBJECTS,
1029 ctrl, out_shm, &out_size);
1030
1031 if (rv || out_size > out_shm->size) {
1032 if (rv == CKR_OK)
1033 rv = CKR_DEVICE_ERROR;
1034 goto bail;
1035 }
1036
1037 handles = out_shm->buffer;
1038 last = out_size / sizeof(uint32_t);
1039 *count = last;
1040
1041 for (n = 0; n < last; n++)
1042 obj[n] = handles[n];
1043
1044 bail:
1045 ckteec_free_shm(out_shm);
1046 ckteec_free_shm(ctrl);
1047
1048 return rv;
1049 }
1050
ck_find_objects_final(CK_SESSION_HANDLE session)1051 CK_RV ck_find_objects_final(CK_SESSION_HANDLE session)
1052 {
1053 CK_RV rv = CKR_GENERAL_ERROR;
1054 TEEC_SharedMemory *ctrl = NULL;
1055 uint32_t session_handle = session;
1056
1057 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
1058 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
1059 if (!ctrl)
1060 return CKR_HOST_MEMORY;
1061
1062 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
1063
1064 rv = ckteec_invoke_ctrl(PKCS11_CMD_FIND_OBJECTS_FINAL, ctrl);
1065
1066 ckteec_free_shm(ctrl);
1067
1068 return rv;
1069 }
1070
ck_get_object_size(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE obj,CK_ULONG_PTR p_size)1071 CK_RV ck_get_object_size(CK_SESSION_HANDLE session,
1072 CK_OBJECT_HANDLE obj,
1073 CK_ULONG_PTR p_size)
1074 {
1075 CK_RV rv = CKR_GENERAL_ERROR;
1076 TEEC_SharedMemory *ctrl = NULL;
1077 TEEC_SharedMemory *out_shm = NULL;
1078 size_t ctrl_size = 0;
1079 uint32_t session_handle = session;
1080 uint32_t obj_handle = obj;
1081 char *buf = NULL;
1082 size_t out_size = 0;
1083 uint32_t u32_sz = 0;
1084
1085 if (!p_size)
1086 return CKR_ARGUMENTS_BAD;
1087
1088 /* Shm io0: (in/out) [session][obj-handle] / [status] */
1089 ctrl_size = sizeof(session_handle) + sizeof(obj_handle);
1090
1091 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1092 if (!ctrl) {
1093 rv = CKR_HOST_MEMORY;
1094 goto bail;
1095 }
1096
1097 buf = ctrl->buffer;
1098
1099 memcpy(buf, &session_handle, sizeof(session_handle));
1100 buf += sizeof(session_handle);
1101
1102 memcpy(buf, &obj_handle, sizeof(obj_handle));
1103
1104 /* Shm io2: (out) [object size] */
1105 out_shm = ckteec_alloc_shm(sizeof(uint32_t), CKTEEC_SHM_OUT);
1106 if (!out_shm) {
1107 rv = CKR_HOST_MEMORY;
1108 goto bail;
1109 }
1110
1111 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_GET_OBJECT_SIZE,
1112 ctrl, out_shm, &out_size);
1113 if (rv)
1114 goto bail;
1115
1116 if (out_shm->size != sizeof(uint32_t)) {
1117 rv = CKR_DEVICE_ERROR;
1118 goto bail;
1119 }
1120
1121 memcpy(&u32_sz, out_shm->buffer, out_shm->size);
1122 *p_size = u32_sz;
1123
1124 bail:
1125 ckteec_free_shm(out_shm);
1126 ckteec_free_shm(ctrl);
1127
1128 return rv;
1129 }
1130
ck_get_attribute_value(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_PTR attribs,CK_ULONG count)1131 CK_RV ck_get_attribute_value(CK_SESSION_HANDLE session,
1132 CK_OBJECT_HANDLE obj,
1133 CK_ATTRIBUTE_PTR attribs,
1134 CK_ULONG count)
1135 {
1136 CK_RV rv = CKR_GENERAL_ERROR;
1137 CK_RV rv2 = CKR_GENERAL_ERROR;
1138 TEEC_SharedMemory *ctrl = NULL;
1139 TEEC_SharedMemory *out_shm = NULL;
1140 struct serializer sattr = { 0 };
1141 size_t ctrl_size = 0;
1142 uint32_t session_handle = session;
1143 uint32_t obj_handle = obj;
1144 char *buf = NULL;
1145 size_t out_size = 0;
1146
1147 if (count && !attribs)
1148 return CKR_ARGUMENTS_BAD;
1149
1150 rv = serialize_ck_attributes(&sattr, attribs, count);
1151 if (rv)
1152 goto bail;
1153
1154 /* Shm io0: (in/out) [session][obj-handle][attributes] / [status] */
1155 ctrl_size = sizeof(session_handle) + sizeof(obj_handle) + sattr.size;
1156
1157 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1158 if (!ctrl) {
1159 rv = CKR_HOST_MEMORY;
1160 goto bail;
1161 }
1162
1163 buf = ctrl->buffer;
1164
1165 memcpy(buf, &session_handle, sizeof(session_handle));
1166 buf += sizeof(session_handle);
1167
1168 memcpy(buf, &obj_handle, sizeof(obj_handle));
1169 buf += sizeof(obj_handle);
1170
1171 memcpy(buf, sattr.buffer, sattr.size);
1172
1173 /* Shm io2: (out) [attributes] */
1174 out_shm = ckteec_alloc_shm(sattr.size, CKTEEC_SHM_OUT);
1175 if (!out_shm) {
1176 rv = CKR_HOST_MEMORY;
1177 goto bail;
1178 }
1179
1180 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_GET_ATTRIBUTE_VALUE,
1181 ctrl, out_shm, &out_size);
1182
1183 if (rv == CKR_OK || rv == CKR_ATTRIBUTE_SENSITIVE ||
1184 rv == CKR_ATTRIBUTE_TYPE_INVALID || rv == CKR_BUFFER_TOO_SMALL) {
1185 rv2 = deserialize_ck_attributes(out_shm->buffer, attribs,
1186 count);
1187 if (rv2)
1188 rv = CKR_GENERAL_ERROR;
1189 }
1190
1191 bail:
1192 ckteec_free_shm(out_shm);
1193 ckteec_free_shm(ctrl);
1194 release_serial_object(&sattr);
1195
1196 return rv;
1197 }
1198
ck_set_attribute_value(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_PTR attribs,CK_ULONG count)1199 CK_RV ck_set_attribute_value(CK_SESSION_HANDLE session,
1200 CK_OBJECT_HANDLE obj,
1201 CK_ATTRIBUTE_PTR attribs,
1202 CK_ULONG count)
1203 {
1204 CK_RV rv = CKR_GENERAL_ERROR;
1205 TEEC_SharedMemory *ctrl = NULL;
1206 struct serializer sattr = { 0 };
1207 size_t ctrl_size = 0;
1208 uint32_t session_handle = session;
1209 uint32_t obj_handle = obj;
1210 char *buf = NULL;
1211
1212 if (count && !attribs)
1213 return CKR_ARGUMENTS_BAD;
1214
1215 rv = serialize_ck_attributes(&sattr, attribs, count);
1216 if (rv)
1217 goto bail;
1218
1219 /* Shm io0: (in/out) [session][obj-handle][attributes] / [status] */
1220 ctrl_size = sizeof(session_handle) + sizeof(obj_handle) + sattr.size;
1221
1222 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1223 if (!ctrl) {
1224 rv = CKR_HOST_MEMORY;
1225 goto bail;
1226 }
1227
1228 buf = ctrl->buffer;
1229
1230 memcpy(buf, &session_handle, sizeof(session_handle));
1231 buf += sizeof(session_handle);
1232
1233 memcpy(buf, &obj_handle, sizeof(obj_handle));
1234 buf += sizeof(obj_handle);
1235
1236 memcpy(buf, sattr.buffer, sattr.size);
1237
1238 rv = ckteec_invoke_ctrl(PKCS11_CMD_SET_ATTRIBUTE_VALUE, ctrl);
1239
1240 bail:
1241 ckteec_free_shm(ctrl);
1242 release_serial_object(&sattr);
1243
1244 return rv;
1245 }
1246
ck_copy_object(CK_SESSION_HANDLE session,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_PTR attribs,CK_ULONG count,CK_OBJECT_HANDLE_PTR handle)1247 CK_RV ck_copy_object(CK_SESSION_HANDLE session,
1248 CK_OBJECT_HANDLE obj,
1249 CK_ATTRIBUTE_PTR attribs,
1250 CK_ULONG count,
1251 CK_OBJECT_HANDLE_PTR handle)
1252 {
1253 CK_RV rv = CKR_GENERAL_ERROR;
1254 TEEC_SharedMemory *ctrl = NULL;
1255 TEEC_SharedMemory *out_shm = NULL;
1256 struct serializer sattr = { 0 };
1257 size_t ctrl_size = 0;
1258 uint32_t session_handle = session;
1259 uint32_t obj_handle = obj;
1260 uint32_t key_handle = 0;
1261 char *buf = NULL;
1262 size_t out_size = 0;
1263
1264 if (!handle || (count && !attribs))
1265 return CKR_ARGUMENTS_BAD;
1266
1267 rv = serialize_ck_attributes(&sattr, attribs, count);
1268 if (rv)
1269 goto bail;
1270
1271 /* Shm io0: (in/out) [session][obj-handle][attributes] / [status] */
1272 ctrl_size = sizeof(session_handle) + sizeof(obj_handle) + sattr.size;
1273
1274 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1275 if (!ctrl) {
1276 rv = CKR_HOST_MEMORY;
1277 goto bail;
1278 }
1279
1280 buf = ctrl->buffer;
1281
1282 memcpy(buf, &session_handle, sizeof(session_handle));
1283 buf += sizeof(session_handle);
1284
1285 memcpy(buf, &obj_handle, sizeof(obj_handle));
1286 buf += sizeof(obj_handle);
1287
1288 memcpy(buf, sattr.buffer, sattr.size);
1289
1290 /* Shm io2: (out) [object handle] */
1291 out_shm = ckteec_alloc_shm(sizeof(key_handle), CKTEEC_SHM_OUT);
1292 if (!out_shm) {
1293 rv = CKR_HOST_MEMORY;
1294 goto bail;
1295 }
1296
1297 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_COPY_OBJECT,
1298 ctrl, out_shm, &out_size);
1299 if (rv != CKR_OK || out_size != out_shm->size) {
1300 if (rv == CKR_OK)
1301 rv = CKR_DEVICE_ERROR;
1302 goto bail;
1303 }
1304
1305 memcpy(&key_handle, out_shm->buffer, sizeof(key_handle));
1306 *handle = key_handle;
1307
1308 bail:
1309 ckteec_free_shm(out_shm);
1310 ckteec_free_shm(ctrl);
1311 release_serial_object(&sattr);
1312
1313 return rv;
1314 }
1315
ck_derive_key(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_OBJECT_HANDLE parent_key,CK_ATTRIBUTE_PTR attribs,CK_ULONG count,CK_OBJECT_HANDLE_PTR handle)1316 CK_RV ck_derive_key(CK_SESSION_HANDLE session,
1317 CK_MECHANISM_PTR mechanism,
1318 CK_OBJECT_HANDLE parent_key,
1319 CK_ATTRIBUTE_PTR attribs,
1320 CK_ULONG count,
1321 CK_OBJECT_HANDLE_PTR handle)
1322 {
1323 CK_RV rv = CKR_GENERAL_ERROR;
1324 TEEC_SharedMemory *ctrl = NULL;
1325 TEEC_SharedMemory *out_shm = NULL;
1326 struct serializer smecha = { 0 };
1327 struct serializer sattr = { 0 };
1328 uint32_t session_handle = session;
1329 uint32_t obj_handle = parent_key;
1330 size_t ctrl_size = 0;
1331 uint32_t key_handle = 0;
1332 char *buf = NULL;
1333 size_t out_size = 0;
1334
1335 if (!handle || !mechanism || (count && !attribs))
1336 return CKR_ARGUMENTS_BAD;
1337
1338 rv = serialize_ck_mecha_params(&smecha, mechanism);
1339 if (rv)
1340 return rv;
1341
1342 rv = serialize_ck_attributes(&sattr, attribs, count);
1343 if (rv)
1344 goto bail;
1345
1346 /*
1347 * Shm io0: (in/out) ctrl
1348 * (in) [session-handle][obj-handle][serialized-mecha][serialized-attributes]
1349 * (out) [status]
1350 */
1351 ctrl_size = sizeof(session_handle) + sizeof(obj_handle) + smecha.size +
1352 sattr.size;
1353
1354 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1355 if (!ctrl) {
1356 rv = CKR_HOST_MEMORY;
1357 goto bail;
1358 }
1359
1360 buf = ctrl->buffer;
1361
1362 memcpy(buf, &session_handle, sizeof(session_handle));
1363 buf += sizeof(session_handle);
1364
1365 memcpy(buf, &obj_handle, sizeof(obj_handle));
1366 buf += sizeof(obj_handle);
1367
1368 memcpy(buf, smecha.buffer, smecha.size);
1369 buf += smecha.size;
1370
1371 memcpy(buf, sattr.buffer, sattr.size);
1372
1373 /* Shm io2: (out) [object handle] */
1374 out_shm = ckteec_alloc_shm(sizeof(key_handle), CKTEEC_SHM_OUT);
1375 if (!out_shm) {
1376 rv = CKR_HOST_MEMORY;
1377 goto bail;
1378 }
1379
1380 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_DERIVE_KEY,
1381 ctrl, out_shm, &out_size);
1382
1383 if (rv != CKR_OK || out_size != out_shm->size) {
1384 if (rv == CKR_OK)
1385 rv = CKR_DEVICE_ERROR;
1386 goto bail;
1387 }
1388
1389 memcpy(&key_handle, out_shm->buffer, sizeof(key_handle));
1390 *handle = key_handle;
1391
1392 bail:
1393 ckteec_free_shm(out_shm);
1394 ckteec_free_shm(ctrl);
1395 release_serial_object(&sattr);
1396 release_serial_object(&smecha);
1397
1398 return rv;
1399 }
1400
ck_release_active_processing(CK_SESSION_HANDLE session,enum pkcs11_ta_cmd command)1401 CK_RV ck_release_active_processing(CK_SESSION_HANDLE session,
1402 enum pkcs11_ta_cmd command)
1403 {
1404 CK_RV rv = CKR_GENERAL_ERROR;
1405 TEEC_SharedMemory *ctrl = NULL;
1406 uint32_t session_handle = session;
1407 uint32_t cmd = command;
1408 size_t ctrl_size = 0;
1409 char *buf = NULL;
1410
1411 /* Shm io0: (in/out) ctrl = [session-handle][command] / [status] */
1412 ctrl_size = sizeof(session_handle) + sizeof(cmd);
1413
1414 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1415 if (!ctrl)
1416 return CKR_HOST_MEMORY;
1417
1418 buf = ctrl->buffer;
1419
1420 memcpy(buf, &session_handle, sizeof(session_handle));
1421 buf += sizeof(session_handle);
1422
1423 memcpy(buf, &cmd, sizeof(cmd));
1424
1425 rv = ckteec_invoke_ctrl(PKCS11_CMD_RELEASE_ACTIVE_PROCESSING, ctrl);
1426
1427 ckteec_free_shm(ctrl);
1428
1429 return rv;
1430 }
1431
ck_generate_key_pair(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_ATTRIBUTE_PTR pub_attribs,CK_ULONG pub_count,CK_ATTRIBUTE_PTR priv_attribs,CK_ULONG priv_count,CK_OBJECT_HANDLE_PTR pub_key,CK_OBJECT_HANDLE_PTR priv_key)1432 CK_RV ck_generate_key_pair(CK_SESSION_HANDLE session,
1433 CK_MECHANISM_PTR mechanism,
1434 CK_ATTRIBUTE_PTR pub_attribs,
1435 CK_ULONG pub_count,
1436 CK_ATTRIBUTE_PTR priv_attribs,
1437 CK_ULONG priv_count,
1438 CK_OBJECT_HANDLE_PTR pub_key,
1439 CK_OBJECT_HANDLE_PTR priv_key)
1440 {
1441 CK_RV rv = CKR_GENERAL_ERROR;
1442 TEEC_SharedMemory *ctrl = NULL;
1443 TEEC_SharedMemory *out_shm = NULL;
1444 struct serializer smecha = { 0 };
1445 struct serializer pub_sattr = { 0 };
1446 struct serializer priv_sattr = { 0 };
1447 uint32_t session_handle = session;
1448 size_t ctrl_size = 0;
1449 uint32_t *key_handle = NULL;
1450 size_t key_handle_size = 2 * sizeof(*key_handle);
1451 char *buf = NULL;
1452 size_t out_size = 0;
1453
1454 if (!(mechanism && pub_attribs && priv_attribs && pub_key && priv_key))
1455 return CKR_ARGUMENTS_BAD;
1456
1457 rv = serialize_ck_mecha_params(&smecha, mechanism);
1458 if (rv)
1459 return rv;
1460
1461 rv = serialize_ck_attributes(&pub_sattr, pub_attribs, pub_count);
1462 if (rv)
1463 goto bail;
1464
1465 rv = serialize_ck_attributes(&priv_sattr, priv_attribs, priv_count);
1466 if (rv)
1467 goto bail;
1468
1469 /*
1470 * Shm io0: (in/out) ctrl
1471 * (in) [session-handle][serialized-mecha][serialized-pub_attribs]
1472 * [serialized-priv_attribs]
1473 * (out) [status]
1474 */
1475 ctrl_size = sizeof(session_handle) + smecha.size + pub_sattr.size +
1476 priv_sattr.size;
1477
1478 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1479 if (!ctrl) {
1480 rv = CKR_HOST_MEMORY;
1481 goto bail;
1482 }
1483
1484 buf = ctrl->buffer;
1485
1486 memcpy(buf, &session_handle, sizeof(session_handle));
1487 buf += sizeof(session_handle);
1488
1489 memcpy(buf, smecha.buffer, smecha.size);
1490 buf += smecha.size;
1491
1492 memcpy(buf, pub_sattr.buffer, pub_sattr.size);
1493 buf += pub_sattr.size;
1494
1495 memcpy(buf, priv_sattr.buffer, priv_sattr.size);
1496
1497 /*
1498 * Shm io2: (out) public key object handle][private key object handle]
1499 */
1500 out_shm = ckteec_alloc_shm(key_handle_size, CKTEEC_SHM_OUT);
1501 if (!out_shm) {
1502 rv = CKR_HOST_MEMORY;
1503 goto bail;
1504 }
1505
1506 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_GENERATE_KEY_PAIR,
1507 ctrl, out_shm, &out_size);
1508
1509 if (rv != CKR_OK || out_size != out_shm->size) {
1510 if (rv == CKR_OK)
1511 rv = CKR_DEVICE_ERROR;
1512 goto bail;
1513 }
1514
1515 key_handle = out_shm->buffer;
1516 *pub_key = key_handle[0];
1517 *priv_key = key_handle[1];
1518
1519 bail:
1520 ckteec_free_shm(out_shm);
1521 ckteec_free_shm(ctrl);
1522 release_serial_object(&priv_sattr);
1523 release_serial_object(&pub_sattr);
1524 release_serial_object(&smecha);
1525
1526 return rv;
1527 }
1528
ck_wrap_key(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_OBJECT_HANDLE wrapping_key,CK_OBJECT_HANDLE key,CK_BYTE_PTR wrapped_key,CK_ULONG_PTR wrapped_key_len)1529 CK_RV ck_wrap_key(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
1530 CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key,
1531 CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len)
1532 {
1533 CK_RV rv = CKR_GENERAL_ERROR;
1534 TEEC_SharedMemory *ctrl = NULL;
1535 TEEC_SharedMemory *out_shm = NULL;
1536 struct serializer smecha = { 0 };
1537 uint32_t session_handle = session;
1538 uint32_t wrp_key_handle = wrapping_key;
1539 uint32_t key_handle = key;
1540 size_t ctrl_size = 0;
1541 size_t out_size = 0;
1542 char *buf = NULL;
1543
1544 if (!mechanism || !wrapped_key_len)
1545 return CKR_ARGUMENTS_BAD;
1546
1547 rv = serialize_ck_mecha_params(&smecha, mechanism);
1548 if (rv)
1549 return rv;
1550
1551 /*
1552 * Shm io0: (in/out) ctrl
1553 * (in) [session-handle][wrapping-key-handle][key-handle]
1554 * [serialized-mecha]
1555 * (out) [status]
1556 */
1557 ctrl_size = sizeof(session_handle) + sizeof(wrp_key_handle) +
1558 sizeof(key_handle) + smecha.size;
1559
1560 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1561 if (!ctrl) {
1562 rv = CKR_HOST_MEMORY;
1563 goto bail;
1564 }
1565
1566 buf = ctrl->buffer;
1567
1568 memcpy(buf, &session_handle, sizeof(session_handle));
1569 buf += sizeof(session_handle);
1570
1571 memcpy(buf, &wrp_key_handle, sizeof(wrp_key_handle));
1572 buf += sizeof(wrp_key_handle);
1573
1574 memcpy(buf, &key_handle, sizeof(key_handle));
1575 buf += sizeof(key_handle);
1576
1577 memcpy(buf, smecha.buffer, smecha.size);
1578
1579 /* Shm io2: output buffer reference - wrapped key */
1580 if (wrapped_key && *wrapped_key_len)
1581 out_shm = ckteec_register_shm(wrapped_key, *wrapped_key_len,
1582 CKTEEC_SHM_OUT);
1583 else
1584 /* Query output data size */
1585 out_shm = ckteec_alloc_shm(0, CKTEEC_SHM_OUT);
1586
1587 if (!out_shm) {
1588 rv = CKR_HOST_MEMORY;
1589 goto bail;
1590 }
1591
1592 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_WRAP_KEY, ctrl, out_shm,
1593 &out_size);
1594
1595 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL)
1596 *wrapped_key_len = out_size;
1597
1598 if (rv == CKR_BUFFER_TOO_SMALL && out_size && !wrapped_key)
1599 rv = CKR_OK;
1600
1601 bail:
1602 ckteec_free_shm(out_shm);
1603 ckteec_free_shm(ctrl);
1604 release_serial_object(&smecha);
1605
1606 return rv;
1607 }
1608
ck_unwrap_key(CK_SESSION_HANDLE session,CK_MECHANISM_PTR mechanism,CK_OBJECT_HANDLE unwrapping_key,CK_BYTE_PTR wrapped_key,CK_ULONG wrapped_key_len,CK_ATTRIBUTE_PTR attribs,CK_ULONG count,CK_OBJECT_HANDLE_PTR handle)1609 CK_RV ck_unwrap_key(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
1610 CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key,
1611 CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR attribs,
1612 CK_ULONG count, CK_OBJECT_HANDLE_PTR handle)
1613 {
1614 CK_RV rv = CKR_GENERAL_ERROR;
1615 TEEC_SharedMemory *ctrl = NULL;
1616 TEEC_SharedMemory *in_shm = NULL;
1617 TEEC_SharedMemory *out_shm = NULL;
1618 struct serializer smecha = { 0 };
1619 struct serializer sattr = { 0 };
1620 uint32_t session_handle = session;
1621 uint32_t unwrapping_key_handle = unwrapping_key;
1622 size_t ctrl_size = 0;
1623 uint32_t key_handle = 0;
1624 char *buf = NULL;
1625 size_t out_size = 0;
1626
1627 if (!handle || !mechanism || (count && !attribs) ||
1628 (wrapped_key_len && !wrapped_key))
1629 return CKR_ARGUMENTS_BAD;
1630
1631 if (!unwrapping_key)
1632 return CKR_UNWRAPPING_KEY_HANDLE_INVALID;
1633
1634 rv = serialize_ck_mecha_params(&smecha, mechanism);
1635 if (rv)
1636 return rv;
1637
1638 rv = serialize_ck_attributes(&sattr, attribs, count);
1639 if (rv)
1640 goto bail;
1641
1642 /*
1643 * Shm io0: (in/out) ctrl
1644 * (in) [session-handle][unwrapping-key-handle][serialized-mecha]
1645 * [serialized-attributes]
1646 * (out) [status]
1647 */
1648 ctrl_size = sizeof(session_handle) + sizeof(unwrapping_key_handle) +
1649 smecha.size + sattr.size;
1650
1651 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
1652 if (!ctrl) {
1653 rv = CKR_HOST_MEMORY;
1654 goto bail;
1655 }
1656
1657 buf = ctrl->buffer;
1658
1659 memcpy(buf, &session_handle, sizeof(session_handle));
1660 buf += sizeof(session_handle);
1661
1662 memcpy(buf, &unwrapping_key_handle, sizeof(unwrapping_key_handle));
1663 buf += sizeof(unwrapping_key_handle);
1664
1665 memcpy(buf, smecha.buffer, smecha.size);
1666 buf += smecha.size;
1667
1668 memcpy(buf, sattr.buffer, sattr.size);
1669
1670 /* Shm io1: input - wrapped key buffer */
1671 in_shm = ckteec_register_shm(wrapped_key, wrapped_key_len,
1672 CKTEEC_SHM_IN);
1673 if (!in_shm) {
1674 rv = CKR_HOST_MEMORY;
1675 goto bail;
1676 }
1677
1678 /* Shm io2: (out) [object handle] */
1679 out_shm = ckteec_alloc_shm(sizeof(key_handle), CKTEEC_SHM_OUT);
1680 if (!out_shm) {
1681 rv = CKR_HOST_MEMORY;
1682 goto bail;
1683 }
1684
1685 rv = ckteec_invoke_ta(PKCS11_CMD_UNWRAP_KEY, ctrl, in_shm, out_shm,
1686 &out_size, NULL, NULL);
1687
1688 if (rv != CKR_OK || out_size != out_shm->size) {
1689 if (rv == CKR_OK)
1690 rv = CKR_DEVICE_ERROR;
1691 goto bail;
1692 }
1693
1694 memcpy(&key_handle, out_shm->buffer, sizeof(key_handle));
1695 *handle = key_handle;
1696
1697 bail:
1698 ckteec_free_shm(out_shm);
1699 ckteec_free_shm(in_shm);
1700 ckteec_free_shm(ctrl);
1701 release_serial_object(&sattr);
1702 release_serial_object(&smecha);
1703
1704 return rv;
1705 }
1706