1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2017-2020, Linaro Limited
4 */
5
6 #include <ck_debug.h>
7 #include <pkcs11.h>
8 #include <pkcs11_ta.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "ck_helpers.h"
13 #include "invoke_ta.h"
14 #include "local_utils.h"
15 #include "pkcs11_token.h"
16
17 #define PKCS11_LIB_MANUFACTURER "Linaro"
18 #define PKCS11_LIB_DESCRIPTION "OP-TEE PKCS11 Cryptoki library"
19
20 /**
21 * Converts uint32_t value to CK_ULONG with unavailable information support
22 *
23 * On 64 bit systems uint32_t cannot handle CK_ULONG defined
24 * CK_UNAVAILABLE_INFORMATION. Check for this specific situation and return
25 * correct value.
26 *
27 * @ta_value: Value form PKCS#11 TA
28 * @return Valid CK_ULONG value
29 */
maybe_unavail(uint32_t ta_value)30 static CK_ULONG maybe_unavail(uint32_t ta_value)
31 {
32 if (ta_value == PKCS11_CK_UNAVAILABLE_INFORMATION)
33 return CK_UNAVAILABLE_INFORMATION;
34 else
35 return ta_value;
36 }
37
38 /**
39 * ck_get_info - Get local information for C_GetInfo
40 */
ck_get_info(CK_INFO_PTR info)41 CK_RV ck_get_info(CK_INFO_PTR info)
42 {
43 const CK_INFO lib_info = {
44 .cryptokiVersion = {
45 CK_PKCS11_VERSION_MAJOR,
46 CK_PKCS11_VERSION_MINOR,
47 },
48 .manufacturerID = PKCS11_LIB_MANUFACTURER,
49 .flags = 0, /* must be zero per the PKCS#11 2.40 */
50 .libraryDescription = PKCS11_LIB_DESCRIPTION,
51 .libraryVersion = {
52 PKCS11_TA_VERSION_MAJOR,
53 PKCS11_TA_VERSION_MINOR
54 },
55 };
56 int n = 0;
57
58 if (!info)
59 return CKR_ARGUMENTS_BAD;
60
61 *info = lib_info;
62
63 /* Pad strings with blank characters */
64 n = strnlen((char *)info->manufacturerID,
65 sizeof(info->manufacturerID));
66 memset(&info->manufacturerID[n], ' ',
67 sizeof(info->manufacturerID) - n);
68
69 n = strnlen((char *)info->libraryDescription,
70 sizeof(info->libraryDescription));
71 memset(&info->libraryDescription[n], ' ',
72 sizeof(info->libraryDescription) - n);
73
74 return CKR_OK;
75 }
76
77 /**
78 * ck_slot_get_list - Wrap C_GetSlotList into PKCS11_CMD_SLOT_LIST
79 */
ck_slot_get_list(CK_BBOOL present,CK_SLOT_ID_PTR slots,CK_ULONG_PTR count)80 CK_RV ck_slot_get_list(CK_BBOOL present,
81 CK_SLOT_ID_PTR slots, CK_ULONG_PTR count)
82 {
83 CK_RV rv = CKR_GENERAL_ERROR;
84 TEEC_SharedMemory *shm = NULL;
85 uint32_t *slot_ids = NULL;
86 size_t client_count = 0;
87 size_t size = 0;
88 size_t n = 0;
89
90 /* Discard @present: all slots reported by TA are present */
91 (void)present;
92
93 if (!count)
94 return CKR_ARGUMENTS_BAD;
95
96 /*
97 * As per spec, if @slots is NULL, "The contents of *pulCount on
98 * entry to C_GetSlotList has no meaning in this case (...)"
99 */
100 if (slots)
101 client_count = *count;
102
103 size = client_count * sizeof(*slot_ids);
104
105 shm = ckteec_alloc_shm(size, CKTEEC_SHM_OUT);
106 if (!shm)
107 return CKR_HOST_MEMORY;
108
109 rv = ckteec_invoke_ta(PKCS11_CMD_SLOT_LIST, NULL,
110 NULL, shm, &size, NULL, NULL);
111
112 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL)
113 *count = size / sizeof(*slot_ids);
114
115 if (!slots && rv == CKR_BUFFER_TOO_SMALL)
116 rv = CKR_OK;
117 if (!slots || rv)
118 goto out;
119
120 slot_ids = shm->buffer;
121 for (n = 0; n < *count; n++)
122 slots[n] = slot_ids[n];
123
124 out:
125 ckteec_free_shm(shm);
126
127 return rv;
128 }
129
130 /**
131 * ck_slot_get_info - Wrap C_GetSlotInfo into PKCS11_CMD_SLOT_INFO
132 */
ck_slot_get_info(CK_SLOT_ID slot,CK_SLOT_INFO_PTR info)133 CK_RV ck_slot_get_info(CK_SLOT_ID slot, CK_SLOT_INFO_PTR info)
134 {
135 CK_RV rv = CKR_GENERAL_ERROR;
136 TEEC_SharedMemory *ctrl = NULL;
137 TEEC_SharedMemory *out = NULL;
138 uint32_t slot_id = slot;
139 struct pkcs11_slot_info *ta_info = NULL;
140 size_t out_size = 0;
141
142 if (!info)
143 return CKR_ARGUMENTS_BAD;
144
145 ctrl = ckteec_alloc_shm(sizeof(slot_id), CKTEEC_SHM_INOUT);
146 if (!ctrl) {
147 rv = CKR_HOST_MEMORY;
148 goto out;
149 }
150 memcpy(ctrl->buffer, &slot_id, sizeof(slot_id));
151
152 out = ckteec_alloc_shm(sizeof(*ta_info), CKTEEC_SHM_OUT);
153 if (!out) {
154 rv = CKR_HOST_MEMORY;
155 goto out;
156 }
157
158 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_SLOT_INFO, ctrl, out, &out_size);
159 if (rv != CKR_OK || out_size != out->size) {
160 if (rv == CKR_OK)
161 rv = CKR_DEVICE_ERROR;
162 goto out;
163 }
164
165 ta_info = out->buffer;
166
167 COMPILE_TIME_ASSERT(sizeof(info->slotDescription) ==
168 sizeof(ta_info->slot_description));
169 memcpy(info->slotDescription, ta_info->slot_description,
170 sizeof(info->slotDescription));
171
172 COMPILE_TIME_ASSERT(sizeof(info->manufacturerID) ==
173 sizeof(ta_info->manufacturer_id));
174 memcpy(info->manufacturerID, ta_info->manufacturer_id,
175 sizeof(info->manufacturerID));
176
177 info->flags = ta_info->flags;
178
179 COMPILE_TIME_ASSERT(sizeof(info->hardwareVersion) ==
180 sizeof(ta_info->hardware_version));
181 memcpy(&info->hardwareVersion, ta_info->hardware_version,
182 sizeof(info->hardwareVersion));
183
184 COMPILE_TIME_ASSERT(sizeof(info->firmwareVersion) ==
185 sizeof(ta_info->firmware_version));
186 memcpy(&info->firmwareVersion, ta_info->firmware_version,
187 sizeof(info->firmwareVersion));
188
189 out:
190 ckteec_free_shm(ctrl);
191 ckteec_free_shm(out);
192
193 return rv;
194 }
195
196 /**
197 * ck_token_get_info - Wrap C_GetTokenInfo into PKCS11_CMD_TOKEN_INFO
198 */
ck_token_get_info(CK_SLOT_ID slot,CK_TOKEN_INFO_PTR info)199 CK_RV ck_token_get_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info)
200 {
201 CK_RV rv = CKR_GENERAL_ERROR;
202 TEEC_SharedMemory *ctrl = NULL;
203 TEEC_SharedMemory *out_shm = NULL;
204 uint32_t slot_id = slot;
205 struct pkcs11_token_info *ta_info = NULL;
206 size_t out_size = 0;
207
208 if (!info)
209 return CKR_ARGUMENTS_BAD;
210
211 ctrl = ckteec_alloc_shm(sizeof(slot_id), CKTEEC_SHM_INOUT);
212 if (!ctrl) {
213 rv = CKR_HOST_MEMORY;
214 goto out;
215 }
216 memcpy(ctrl->buffer, &slot_id, sizeof(slot_id));
217
218 out_shm = ckteec_alloc_shm(sizeof(*ta_info), CKTEEC_SHM_OUT);
219 if (!out_shm) {
220 rv = CKR_HOST_MEMORY;
221 goto out;
222 }
223
224 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_TOKEN_INFO, ctrl,
225 out_shm, &out_size);
226 if (rv)
227 goto out;
228
229 if (out_size != out_shm->size) {
230 rv = CKR_DEVICE_ERROR;
231 goto out;
232 }
233
234 ta_info = out_shm->buffer;
235
236 COMPILE_TIME_ASSERT(sizeof(info->label) == sizeof(ta_info->label));
237 memcpy(info->label, ta_info->label, sizeof(info->label));
238
239 COMPILE_TIME_ASSERT(sizeof(info->manufacturerID) ==
240 sizeof(ta_info->manufacturer_id));
241 memcpy(info->manufacturerID, ta_info->manufacturer_id,
242 sizeof(info->manufacturerID));
243
244 COMPILE_TIME_ASSERT(sizeof(info->model) == sizeof(ta_info->model));
245 memcpy(info->model, ta_info->model, sizeof(info->model));
246
247 COMPILE_TIME_ASSERT(sizeof(info->serialNumber) ==
248 sizeof(ta_info->serial_number));
249 memcpy(info->serialNumber, ta_info->serial_number,
250 sizeof(info->serialNumber));
251
252 info->flags = ta_info->flags;
253 info->ulMaxSessionCount = maybe_unavail(ta_info->max_session_count);
254 info->ulSessionCount = maybe_unavail(ta_info->session_count);
255 info->ulMaxRwSessionCount =
256 maybe_unavail(ta_info->max_rw_session_count);
257 info->ulRwSessionCount = maybe_unavail(ta_info->rw_session_count);
258 info->ulMaxPinLen = ta_info->max_pin_len;
259 info->ulMinPinLen = ta_info->min_pin_len;
260 info->ulTotalPublicMemory =
261 maybe_unavail(ta_info->total_public_memory);
262 info->ulFreePublicMemory = maybe_unavail(ta_info->free_public_memory);
263 info->ulTotalPrivateMemory =
264 maybe_unavail(ta_info->total_private_memory);
265 info->ulFreePrivateMemory =
266 maybe_unavail(ta_info->free_private_memory);
267
268 COMPILE_TIME_ASSERT(sizeof(info->hardwareVersion) ==
269 sizeof(ta_info->hardware_version));
270 memcpy(&info->hardwareVersion, ta_info->hardware_version,
271 sizeof(info->hardwareVersion));
272
273 COMPILE_TIME_ASSERT(sizeof(info->firmwareVersion) ==
274 sizeof(ta_info->firmware_version));
275 memcpy(&info->firmwareVersion, ta_info->firmware_version,
276 sizeof(info->firmwareVersion));
277
278 COMPILE_TIME_ASSERT(sizeof(info->utcTime) == sizeof(ta_info->utc_time));
279 memcpy(&info->utcTime, ta_info->utc_time, sizeof(info->utcTime));
280
281 out:
282 ckteec_free_shm(ctrl);
283 ckteec_free_shm(out_shm);
284
285 return rv;
286 }
287
288 /**
289 * ck_token_mechanism_ids - Wrap C_GetMechanismList
290 */
ck_token_mechanism_ids(CK_SLOT_ID slot,CK_MECHANISM_TYPE_PTR mechanisms,CK_ULONG_PTR count)291 CK_RV ck_token_mechanism_ids(CK_SLOT_ID slot,
292 CK_MECHANISM_TYPE_PTR mechanisms,
293 CK_ULONG_PTR count)
294 {
295 CK_RV rv = CKR_GENERAL_ERROR;
296 TEEC_SharedMemory *ctrl = NULL;
297 TEEC_SharedMemory *out = NULL;
298 uint32_t slot_id = slot;
299 uint32_t *mecha_ids = NULL;
300 size_t out_size = 0;
301 size_t n = 0;
302
303 if (!count)
304 return CKR_ARGUMENTS_BAD;
305
306 /*
307 * As per spec, if @mechanism is NULL, "The contents of *pulCount on
308 * entry to C_GetMechanismList has no meaning in this case (...)"
309 */
310 if (mechanisms)
311 out_size = *count * sizeof(*mecha_ids);
312
313 ctrl = ckteec_alloc_shm(sizeof(slot_id), CKTEEC_SHM_INOUT);
314 if (!ctrl) {
315 rv = CKR_HOST_MEMORY;
316 goto out;
317 }
318 memcpy(ctrl->buffer, &slot_id, sizeof(slot_id));
319
320 out = ckteec_alloc_shm(out_size, CKTEEC_SHM_OUT);
321 if (!out) {
322 rv = CKR_HOST_MEMORY;
323 goto out;
324 }
325
326 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_MECHANISM_IDS,
327 ctrl, out, &out_size);
328
329 if (rv == CKR_OK || rv == CKR_BUFFER_TOO_SMALL)
330 *count = out_size / sizeof(*mecha_ids);
331
332 if (!mechanisms && rv == CKR_BUFFER_TOO_SMALL)
333 rv = CKR_OK;
334 if (!mechanisms || rv)
335 goto out;
336
337 mecha_ids = out->buffer;
338 for (n = 0; n < *count; n++)
339 mechanisms[n] = mecha_ids[n];
340
341 out:
342 ckteec_free_shm(ctrl);
343 ckteec_free_shm(out);
344
345 return rv;
346 }
347
348 /**
349 * ck_token_mechanism_info - Wrap C_GetMechanismInfo into command MECHANISM_INFO
350 */
ck_token_mechanism_info(CK_SLOT_ID slot,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR info)351 CK_RV ck_token_mechanism_info(CK_SLOT_ID slot, CK_MECHANISM_TYPE type,
352 CK_MECHANISM_INFO_PTR info)
353 {
354 CK_RV rv = CKR_GENERAL_ERROR;
355 TEEC_SharedMemory *ctrl = NULL;
356 TEEC_SharedMemory *out = NULL;
357 uint32_t slot_id = slot;
358 uint32_t mecha_type = type;
359 struct pkcs11_mechanism_info *ta_info = NULL;
360 char *buf = NULL;
361 size_t out_size = 0;
362
363 if (!info)
364 return CKR_ARGUMENTS_BAD;
365
366 ctrl = ckteec_alloc_shm(sizeof(slot_id) + sizeof(mecha_type),
367 CKTEEC_SHM_INOUT);
368 if (!ctrl) {
369 rv = CKR_HOST_MEMORY;
370 goto out;
371 }
372
373 buf = ctrl->buffer;
374
375 memcpy(buf, &slot_id, sizeof(slot_id));
376 buf += sizeof(slot_id);
377
378 memcpy(buf, &mecha_type, sizeof(mecha_type));
379
380 out = ckteec_alloc_shm(sizeof(*ta_info), CKTEEC_SHM_OUT);
381 if (!out) {
382 rv = CKR_HOST_MEMORY;
383 goto out;
384 }
385
386 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_MECHANISM_INFO,
387 ctrl, out, &out_size);
388
389 if (rv != CKR_OK || out_size != out->size) {
390 if (rv == CKR_OK)
391 rv = CKR_DEVICE_ERROR;
392 goto out;
393 }
394
395 ta_info = out->buffer;
396
397 info->ulMinKeySize = ta_info->min_key_size;
398 info->ulMaxKeySize = ta_info->max_key_size;
399 info->flags = ta_info->flags;
400
401 out:
402 ckteec_free_shm(ctrl);
403 ckteec_free_shm(out);
404
405 return rv;
406 }
407
408 /**
409 * ck_open_session - Wrap C_OpenSession into PKCS11_CMD_OPEN_{RW|RO}_SESSION
410 *
411 * Note: cookie and callback are not utilized by libckteec and are silently
412 * sinked in to have better out-of-box compatibility with 3rd party libraries
413 * and applications which provides the callback.
414 */
ck_open_session(CK_SLOT_ID slot,CK_FLAGS flags,CK_VOID_PTR cookie,CK_NOTIFY callback,CK_SESSION_HANDLE_PTR session)415 CK_RV ck_open_session(CK_SLOT_ID slot, CK_FLAGS flags, CK_VOID_PTR cookie,
416 CK_NOTIFY callback, CK_SESSION_HANDLE_PTR session)
417 {
418 CK_RV rv = CKR_GENERAL_ERROR;
419 TEEC_SharedMemory *ctrl = NULL;
420 TEEC_SharedMemory *out = NULL;
421 uint32_t slot_id = slot;
422 uint32_t u32_flags = flags;
423 uint32_t handle = 0;
424 size_t out_size = 0;
425 uint8_t *buf;
426
427 /* Ignore notify callback */
428 (void)cookie;
429 (void)callback;
430
431 if ((flags & ~(CKF_RW_SESSION | CKF_SERIAL_SESSION)) || !session)
432 return CKR_ARGUMENTS_BAD;
433
434 /* Shm io0: (in/out) ctrl = [slot-id][flags] / [status] */
435 ctrl = ckteec_alloc_shm(sizeof(slot_id) + sizeof(u32_flags),
436 CKTEEC_SHM_INOUT);
437 if (!ctrl) {
438 rv = CKR_HOST_MEMORY;
439 goto out;
440 }
441 buf = (uint8_t *)ctrl->buffer;
442 memcpy(buf, &slot_id, sizeof(slot_id));
443 buf += sizeof(slot_id);
444 memcpy(buf, &u32_flags, sizeof(u32_flags));
445
446 /* Shm io2: (out) [session handle] */
447 out = ckteec_alloc_shm(sizeof(handle), CKTEEC_SHM_OUT);
448 if (!out) {
449 rv = CKR_HOST_MEMORY;
450 goto out;
451 }
452
453 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_OPEN_SESSION,
454 ctrl, out, &out_size);
455 if (rv != CKR_OK || out_size != out->size) {
456 if (rv == CKR_OK)
457 rv = CKR_DEVICE_ERROR;
458 goto out;
459 }
460
461 memcpy(&handle, out->buffer, sizeof(handle));
462 *session = handle;
463
464 out:
465 ckteec_free_shm(ctrl);
466 ckteec_free_shm(out);
467
468 return rv;
469 }
470
471 /**
472 * ck_open_session - Wrap C_OpenSession into PKCS11_CMD_CLOSE_SESSION
473 */
ck_close_session(CK_SESSION_HANDLE session)474 CK_RV ck_close_session(CK_SESSION_HANDLE session)
475 {
476 CK_RV rv = CKR_GENERAL_ERROR;
477 TEEC_SharedMemory *ctrl = NULL;
478 uint32_t session_handle = session;
479
480 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
481 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
482 if (!ctrl) {
483 rv = CKR_HOST_MEMORY;
484 goto out;
485 }
486 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
487
488 rv = ckteec_invoke_ctrl(PKCS11_CMD_CLOSE_SESSION, ctrl);
489
490 out:
491 ckteec_free_shm(ctrl);
492
493 return rv;
494 }
495
496 /**
497 * ck_close_all_sessions - Wrap C_CloseAllSessions into TA command
498 */
ck_close_all_sessions(CK_SLOT_ID slot)499 CK_RV ck_close_all_sessions(CK_SLOT_ID slot)
500 {
501 CK_RV rv = CKR_GENERAL_ERROR;
502 TEEC_SharedMemory *ctrl = NULL;
503 uint32_t slot_id = slot;
504
505 /* Shm io0: (in/out) ctrl = [slot-id] / [status] */
506 ctrl = ckteec_alloc_shm(sizeof(slot_id), CKTEEC_SHM_INOUT);
507 if (!ctrl) {
508 rv = CKR_HOST_MEMORY;
509 goto out;
510 }
511 memcpy(ctrl->buffer, &slot_id, sizeof(slot_id));
512
513 rv = ckteec_invoke_ctrl(PKCS11_CMD_CLOSE_ALL_SESSIONS, ctrl);
514
515 out:
516 ckteec_free_shm(ctrl);
517
518 return rv;
519 }
520
521 /**
522 * ck_get_session_info - Wrap C_GetSessionInfo into PKCS11_CMD_SESSION_INFO
523 */
ck_get_session_info(CK_SESSION_HANDLE session,CK_SESSION_INFO_PTR info)524 CK_RV ck_get_session_info(CK_SESSION_HANDLE session,
525 CK_SESSION_INFO_PTR info)
526 {
527 CK_RV rv = CKR_GENERAL_ERROR;
528 TEEC_SharedMemory *ctrl = NULL;
529 TEEC_SharedMemory *out = NULL;
530 uint32_t session_handle = session;
531 struct pkcs11_session_info *ta_info = NULL;
532 size_t out_size = 0;
533
534 if (!info)
535 return CKR_ARGUMENTS_BAD;
536
537 /* Shm io0: (in/out) ctrl = [session-handle] / [status] */
538 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
539 if (!ctrl) {
540 rv = CKR_HOST_MEMORY;
541 goto out;
542 }
543 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
544
545 /* Shm io2: (out) [session info] */
546 out = ckteec_alloc_shm(sizeof(struct pkcs11_session_info),
547 CKTEEC_SHM_OUT);
548 if (!out) {
549 rv = CKR_HOST_MEMORY;
550 goto out;
551 }
552
553 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_SESSION_INFO,
554 ctrl, out, &out_size);
555
556 if (rv != CKR_OK || out_size != out->size) {
557 if (rv == CKR_OK)
558 rv = CKR_DEVICE_ERROR;
559 goto out;
560 }
561
562 ta_info = (struct pkcs11_session_info *)out->buffer;
563 info->slotID = ta_info->slot_id;
564 info->state = ta_info->state;
565 info->flags = ta_info->flags;
566 info->ulDeviceError = ta_info->device_error;
567
568 out:
569 ckteec_free_shm(ctrl);
570 ckteec_free_shm(out);
571
572 return rv;
573 }
574
575 /**
576 * ck_init_token - Wrap C_InitToken into PKCS11_CMD_INIT_TOKEN
577 */
ck_init_token(CK_SLOT_ID slot,CK_UTF8CHAR_PTR pin,CK_ULONG pin_len,CK_UTF8CHAR_PTR label)578 CK_RV ck_init_token(CK_SLOT_ID slot, CK_UTF8CHAR_PTR pin,
579 CK_ULONG pin_len, CK_UTF8CHAR_PTR label)
580 {
581 CK_RV rv = CKR_GENERAL_ERROR;
582 TEEC_SharedMemory *ctrl = NULL;
583 uint32_t slot_id = slot;
584 uint32_t pkcs11_pin_len = pin_len;
585 size_t ctrl_size = 0;
586 char *buf = NULL;
587
588 if (!pin && pin_len)
589 return CKR_ARGUMENTS_BAD;
590
591 if (!label)
592 return CKR_ARGUMENTS_BAD;
593
594 /* Shm io0: (in/out) ctrl = [slot-id][pin_len][label][pin] / [status] */
595 ctrl_size = sizeof(slot_id) + sizeof(pkcs11_pin_len) +
596 32 * sizeof(uint8_t) + pkcs11_pin_len;
597
598 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
599 if (!ctrl)
600 return CKR_HOST_MEMORY;
601
602 buf = ctrl->buffer;
603
604 memcpy(buf, &slot_id, sizeof(slot_id));
605 buf += sizeof(slot_id);
606
607 memcpy(buf, &pkcs11_pin_len, sizeof(pkcs11_pin_len));
608 buf += sizeof(pkcs11_pin_len);
609
610 memcpy(buf, label, 32 * sizeof(uint8_t));
611 buf += 32 * sizeof(uint8_t);
612
613 memcpy(buf, pin, pkcs11_pin_len);
614
615 rv = ckteec_invoke_ctrl(PKCS11_CMD_INIT_TOKEN, ctrl);
616
617 ckteec_free_shm(ctrl);
618
619 return rv;
620 }
621
622 /**
623 * ck_init_pin - Wrap C_InitPIN into PKCS11_CMD_INIT_PIN
624 */
ck_init_pin(CK_SESSION_HANDLE session,CK_UTF8CHAR_PTR pin,CK_ULONG pin_len)625 CK_RV ck_init_pin(CK_SESSION_HANDLE session,
626 CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
627 {
628 CK_RV rv = CKR_GENERAL_ERROR;
629 TEEC_SharedMemory *ctrl = NULL;
630 uint32_t pkcs11_session = session;
631 uint32_t pkcs11_pin_len = pin_len;
632 size_t ctrl_size = 0;
633 char *buf = NULL;
634
635 if (!pin && pin_len)
636 return CKR_ARGUMENTS_BAD;
637
638 /* Shm io0: (in/out) ctrl = [session][pin_len][pin] / [status] */
639 ctrl_size = sizeof(pkcs11_session) + sizeof(pkcs11_pin_len) +
640 pkcs11_pin_len;
641
642 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
643 if (!ctrl)
644 return CKR_HOST_MEMORY;
645
646 buf = ctrl->buffer;
647
648 memcpy(buf, &pkcs11_session, sizeof(pkcs11_session));
649 buf += sizeof(pkcs11_session);
650
651 memcpy(buf, &pkcs11_pin_len, sizeof(pkcs11_pin_len));
652 buf += sizeof(pkcs11_pin_len);
653
654 memcpy(buf, pin, pkcs11_pin_len);
655
656 rv = ckteec_invoke_ctrl(PKCS11_CMD_INIT_PIN, ctrl);
657
658 ckteec_free_shm(ctrl);
659
660 return rv;
661 }
662
663 /**
664 * ck_set_pin - Wrap C_SetPIN into PKCS11_CMD_SET_PIN
665 */
ck_set_pin(CK_SESSION_HANDLE session,CK_UTF8CHAR_PTR old,CK_ULONG old_len,CK_UTF8CHAR_PTR new,CK_ULONG new_len)666 CK_RV ck_set_pin(CK_SESSION_HANDLE session,
667 CK_UTF8CHAR_PTR old, CK_ULONG old_len,
668 CK_UTF8CHAR_PTR new, CK_ULONG new_len)
669 {
670 CK_RV rv = CKR_GENERAL_ERROR;
671 TEEC_SharedMemory *ctrl = NULL;
672 uint32_t pkcs11_session = session;
673 uint32_t pkcs11_old_len = old_len;
674 uint32_t pkcs11_new_len = new_len;
675 size_t ctrl_size = 0;
676 char *buf;
677
678 if ((!old && old_len) || (!new && new_len))
679 return CKR_ARGUMENTS_BAD;
680
681 /*
682 * Shm io0: (in/out) ctrl
683 * (in) [session][old_pin_len][new_pin_len][old pin][new pin]
684 * (out) [status]
685 */
686 ctrl_size = sizeof(pkcs11_session) + sizeof(pkcs11_old_len) +
687 sizeof(pkcs11_new_len) + pkcs11_old_len + pkcs11_new_len;
688
689 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
690 if (!ctrl)
691 return CKR_HOST_MEMORY;
692
693 buf = ctrl->buffer;
694
695 memcpy(buf, &pkcs11_session, sizeof(pkcs11_session));
696 buf += sizeof(pkcs11_session);
697
698 memcpy(buf, &pkcs11_old_len, sizeof(pkcs11_old_len));
699 buf += sizeof(pkcs11_old_len);
700
701 memcpy(buf, &pkcs11_new_len, sizeof(pkcs11_new_len));
702 buf += sizeof(pkcs11_new_len);
703
704 memcpy(buf, old, pkcs11_old_len);
705 buf += pkcs11_old_len;
706
707 memcpy(buf, new, pkcs11_new_len);
708
709 rv = ckteec_invoke_ctrl(PKCS11_CMD_SET_PIN, ctrl);
710
711 ckteec_free_shm(ctrl);
712
713 return rv;
714 }
715
716 /**
717 * ck_login - Wrap C_Login into PKCS11_CMD_LOGIN
718 */
ck_login(CK_SESSION_HANDLE session,CK_USER_TYPE user_type,CK_UTF8CHAR_PTR pin,CK_ULONG pin_len)719 CK_RV ck_login(CK_SESSION_HANDLE session, CK_USER_TYPE user_type,
720 CK_UTF8CHAR_PTR pin, CK_ULONG pin_len)
721
722 {
723 CK_RV rv = CKR_GENERAL_ERROR;
724 TEEC_SharedMemory *ctrl = NULL;
725 uint32_t pkcs11_session = session;
726 uint32_t pkcs11_user = user_type;
727 uint32_t pkcs11_pin_len = pin_len;
728 size_t ctrl_size = 0;
729 char *buf = NULL;
730
731 if (!pin && pin_len)
732 return CKR_ARGUMENTS_BAD;
733
734 /* Shm io0: (i/o) ctrl = [session][user][pin length][pin] / [status] */
735 ctrl_size = sizeof(pkcs11_session) + sizeof(pkcs11_user) +
736 sizeof(pkcs11_pin_len) + pkcs11_pin_len;
737
738 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
739 if (!ctrl)
740 return CKR_HOST_MEMORY;
741
742 buf = ctrl->buffer;
743
744 memcpy(buf, &pkcs11_session, sizeof(pkcs11_session));
745 buf += sizeof(pkcs11_session);
746
747 memcpy(buf, &pkcs11_user, sizeof(pkcs11_user));
748 buf += sizeof(pkcs11_user);
749
750 memcpy(buf, &pkcs11_pin_len, sizeof(pkcs11_pin_len));
751 buf += sizeof(pkcs11_pin_len);
752
753 memcpy(buf, pin, pkcs11_pin_len);
754
755 rv = ckteec_invoke_ctrl(PKCS11_CMD_LOGIN, ctrl);
756
757 ckteec_free_shm(ctrl);
758
759 return rv;
760 }
761
762 /**
763 * ck_logout - Wrap C_Logout into PKCS11_CMD_LOGOUT
764 */
ck_logout(CK_SESSION_HANDLE session)765 CK_RV ck_logout(CK_SESSION_HANDLE session)
766 {
767 CK_RV rv = CKR_GENERAL_ERROR;
768 TEEC_SharedMemory *ctrl = NULL;
769 uint32_t session_handle = session;
770
771 /* io0 = [session-handle] */
772 ctrl = ckteec_alloc_shm(sizeof(session_handle), CKTEEC_SHM_INOUT);
773 if (!ctrl)
774 return CKR_HOST_MEMORY;
775
776 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
777
778 rv = ckteec_invoke_ctrl(PKCS11_CMD_LOGOUT, ctrl);
779
780 ckteec_free_shm(ctrl);
781
782 return rv;
783 }
784
ck_seed_random(CK_SESSION_HANDLE session,CK_BYTE_PTR seed,CK_ULONG length)785 CK_RV ck_seed_random(CK_SESSION_HANDLE session, CK_BYTE_PTR seed,
786 CK_ULONG length)
787 {
788 CK_RV rv = CKR_GENERAL_ERROR;
789 size_t ctrl_size = 0;
790 TEEC_SharedMemory *ctrl = NULL;
791 TEEC_SharedMemory *in_shm = NULL;
792 uint32_t session_handle = session;
793
794 if (!seed && length)
795 return CKR_ARGUMENTS_BAD;
796
797 if (!seed)
798 return CKR_OK;
799
800 /* Shm io0: (i/o) [session-handle] / [status] */
801 ctrl_size = sizeof(session_handle);
802 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
803 if (!ctrl)
804 return CKR_HOST_MEMORY;
805
806 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
807
808 /* Shm io1: (in) [seed data] */
809 in_shm = ckteec_register_shm(seed, length, CKTEEC_SHM_IN);
810 if (!in_shm) {
811 rv = CKR_HOST_MEMORY;
812 goto out;
813 }
814
815 rv = ckteec_invoke_ctrl_in(PKCS11_CMD_SEED_RANDOM, ctrl, in_shm);
816
817 out:
818 ckteec_free_shm(in_shm);
819 ckteec_free_shm(ctrl);
820
821 return rv;
822 }
823
ck_generate_random(CK_SESSION_HANDLE session,CK_BYTE_PTR data,CK_ULONG length)824 CK_RV ck_generate_random(CK_SESSION_HANDLE session, CK_BYTE_PTR data,
825 CK_ULONG length)
826 {
827 CK_RV rv = CKR_GENERAL_ERROR;
828 size_t ctrl_size = 0;
829 TEEC_SharedMemory *ctrl = NULL;
830 TEEC_SharedMemory *out_shm = NULL;
831 uint32_t session_handle = session;
832 size_t out_size = 0;
833
834 if (!data && length)
835 return CKR_ARGUMENTS_BAD;
836
837 if (!data)
838 return CKR_OK;
839
840 /* Shm io0: (i/o) [session-handle] / [status] */
841 ctrl_size = sizeof(session_handle);
842 ctrl = ckteec_alloc_shm(ctrl_size, CKTEEC_SHM_INOUT);
843 if (!ctrl)
844 return CKR_HOST_MEMORY;
845
846 memcpy(ctrl->buffer, &session_handle, sizeof(session_handle));
847
848 /* Shm io2: (out) [generated random] */
849 out_shm = ckteec_register_shm(data, length, CKTEEC_SHM_OUT);
850 if (!out_shm) {
851 rv = CKR_HOST_MEMORY;
852 goto out;
853 }
854
855 rv = ckteec_invoke_ctrl_out(PKCS11_CMD_GENERATE_RANDOM, ctrl, out_shm,
856 &out_size);
857
858 out:
859 ckteec_free_shm(out_shm);
860 ckteec_free_shm(ctrl);
861
862 return rv;
863 }
864