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