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