xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision 10b907910d58334cc5b1486cb2f91a08f764566e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <confine_array_index.h>
8 #include <pkcs11_ta.h>
9 #include <string.h>
10 #include <string_ext.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 #include <tee_internal_api_extensions.h>
14 #include <util.h>
15 
16 #include "pkcs11_helpers.h"
17 #include "pkcs11_token.h"
18 #include "serializer.h"
19 
20 /* Provide 3 slots/tokens, ID is token index */
21 #ifndef CFG_PKCS11_TA_TOKEN_COUNT
22 #define TOKEN_COUNT		3
23 #else
24 #define TOKEN_COUNT		CFG_PKCS11_TA_TOKEN_COUNT
25 #endif
26 
27 /*
28  * Structure tracking client applications
29  *
30  * @link - chained list of registered client applications
31  * @sessions - list of the PKCS11 sessions opened by the client application
32  */
33 struct pkcs11_client {
34 	TAILQ_ENTRY(pkcs11_client) link;
35 	struct session_list session_list;
36 	struct handle_db session_handle_db;
37 };
38 
39 /* Static allocation of tokens runtime instances (reset to 0 at load) */
40 struct ck_token ck_token[TOKEN_COUNT];
41 
42 static struct client_list pkcs11_client_list =
43 	TAILQ_HEAD_INITIALIZER(pkcs11_client_list);
44 
45 static void close_ck_session(struct pkcs11_session *session);
46 
47 struct ck_token *get_token(unsigned int token_id)
48 {
49 	if (token_id < TOKEN_COUNT)
50 		return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
51 
52 	return NULL;
53 }
54 
55 unsigned int get_token_id(struct ck_token *token)
56 {
57 	ptrdiff_t id = token - ck_token;
58 
59 	assert(id >= 0 && id < TOKEN_COUNT);
60 	return id;
61 }
62 
63 struct pkcs11_client *tee_session2client(void *tee_session)
64 {
65 	struct pkcs11_client *client = NULL;
66 
67 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
68 		if (client == tee_session)
69 			break;
70 
71 	return client;
72 }
73 
74 struct pkcs11_session *pkcs11_handle2session(uint32_t handle,
75 					     struct pkcs11_client *client)
76 {
77 	return handle_lookup(&client->session_handle_db, handle);
78 }
79 
80 struct pkcs11_client *register_client(void)
81 {
82 	struct pkcs11_client *client = NULL;
83 
84 	client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO);
85 	if (!client)
86 		return NULL;
87 
88 	TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link);
89 	TAILQ_INIT(&client->session_list);
90 	handle_db_init(&client->session_handle_db);
91 
92 	return client;
93 }
94 
95 void unregister_client(struct pkcs11_client *client)
96 {
97 	struct pkcs11_session *session = NULL;
98 	struct pkcs11_session *next = NULL;
99 
100 	if (!client) {
101 		EMSG("Invalid TEE session handle");
102 		return;
103 	}
104 
105 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
106 		close_ck_session(session);
107 
108 	TAILQ_REMOVE(&pkcs11_client_list, client, link);
109 	handle_db_destroy(&client->session_handle_db);
110 	TEE_Free(client);
111 }
112 
113 static TEE_Result pkcs11_token_init(unsigned int id)
114 {
115 	struct ck_token *token = init_persistent_db(id);
116 
117 	if (!token)
118 		return TEE_ERROR_SECURITY;
119 
120 	if (token->state == PKCS11_TOKEN_RESET) {
121 		/* As per PKCS#11 spec, token resets to read/write state */
122 		token->state = PKCS11_TOKEN_READ_WRITE;
123 		token->session_count = 0;
124 		token->rw_session_count = 0;
125 	}
126 
127 	return TEE_SUCCESS;
128 }
129 
130 TEE_Result pkcs11_init(void)
131 {
132 	unsigned int id = 0;
133 	TEE_Result ret = TEE_ERROR_GENERIC;
134 
135 	for (id = 0; id < TOKEN_COUNT; id++) {
136 		ret = pkcs11_token_init(id);
137 		if (ret)
138 			break;
139 	}
140 
141 	return ret;
142 }
143 
144 void pkcs11_deinit(void)
145 {
146 	unsigned int id = 0;
147 
148 	for (id = 0; id < TOKEN_COUNT; id++)
149 		close_persistent_db(get_token(id));
150 }
151 
152 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
153 {
154 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
155 						TEE_PARAM_TYPE_NONE,
156 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
157 						TEE_PARAM_TYPE_NONE);
158 	TEE_Param *out = &params[2];
159 	uint32_t token_id = 0;
160 	const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
161 	uint8_t *id = NULL;
162 
163 	if (ptypes != exp_pt ||
164 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN)
165 		return PKCS11_CKR_ARGUMENTS_BAD;
166 
167 	if (out->memref.size < out_size) {
168 		out->memref.size = out_size;
169 
170 		if (out->memref.buffer)
171 			return PKCS11_CKR_BUFFER_TOO_SMALL;
172 		else
173 			return PKCS11_CKR_OK;
174 	}
175 
176 	for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
177 	     token_id++, id += sizeof(token_id))
178 		TEE_MemMove(id, &token_id, sizeof(token_id));
179 
180 	out->memref.size = out_size;
181 
182 	return PKCS11_CKR_OK;
183 }
184 
185 static void pad_str(uint8_t *str, size_t size)
186 {
187 	int n = strnlen((char *)str, size);
188 
189 	TEE_MemFill(str + n, ' ', size - n);
190 }
191 
192 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params)
193 {
194 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
195 						TEE_PARAM_TYPE_NONE,
196 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
197 						TEE_PARAM_TYPE_NONE);
198 	TEE_Param *ctrl = &params[0];
199 	TEE_Param *out = &params[2];
200 	uint32_t rv = 0;
201 	struct serialargs ctrlargs = { };
202 	uint32_t token_id = 0;
203 	struct ck_token *token = NULL;
204 	struct pkcs11_slot_info info = {
205 		.slot_description = PKCS11_SLOT_DESCRIPTION,
206 		.manufacturer_id = PKCS11_SLOT_MANUFACTURER,
207 		.flags = PKCS11_CKFS_TOKEN_PRESENT,
208 		.hardware_version = PKCS11_SLOT_HW_VERSION,
209 		.firmware_version = PKCS11_SLOT_FW_VERSION,
210 	};
211 
212 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <=
213 			    sizeof(info.slot_description));
214 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <=
215 			    sizeof(info.manufacturer_id));
216 
217 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
218 		return PKCS11_CKR_ARGUMENTS_BAD;
219 
220 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
221 
222 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
223 	if (rv)
224 		return rv;
225 
226 	if (serialargs_remaining_bytes(&ctrlargs))
227 		return PKCS11_CKR_ARGUMENTS_BAD;
228 
229 	token = get_token(token_id);
230 	if (!token)
231 		return PKCS11_CKR_SLOT_ID_INVALID;
232 
233 	pad_str(info.slot_description, sizeof(info.slot_description));
234 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
235 
236 	out->memref.size = sizeof(info);
237 	TEE_MemMove(out->memref.buffer, &info, out->memref.size);
238 
239 	return PKCS11_CKR_OK;
240 }
241 
242 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params)
243 {
244 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
245 						TEE_PARAM_TYPE_NONE,
246 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
247 						TEE_PARAM_TYPE_NONE);
248 	TEE_Param *ctrl = &params[0];
249 	TEE_Param *out = &params[2];
250 	uint32_t rv = 0;
251 	struct serialargs ctrlargs = { };
252 	uint32_t token_id = 0;
253 	struct ck_token *token = NULL;
254 	struct pkcs11_token_info info = {
255 		.manufacturer_id = PKCS11_TOKEN_MANUFACTURER,
256 		.model = PKCS11_TOKEN_MODEL,
257 		.serial_number = PKCS11_TOKEN_SERIAL_NUMBER,
258 		.max_session_count = UINT32_MAX,
259 		.max_rw_session_count = UINT32_MAX,
260 		.max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX,
261 		.min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN,
262 		.total_public_memory = UINT32_MAX,
263 		.free_public_memory = UINT32_MAX,
264 		.total_private_memory = UINT32_MAX,
265 		.free_private_memory = UINT32_MAX,
266 		.hardware_version = PKCS11_TOKEN_HW_VERSION,
267 		.firmware_version = PKCS11_TOKEN_FW_VERSION,
268 	};
269 
270 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
271 		return PKCS11_CKR_ARGUMENTS_BAD;
272 
273 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
274 
275 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
276 	if (rv)
277 		return rv;
278 
279 	if (serialargs_remaining_bytes(&ctrlargs))
280 		return PKCS11_CKR_ARGUMENTS_BAD;
281 
282 	token = get_token(token_id);
283 	if (!token)
284 		return PKCS11_CKR_SLOT_ID_INVALID;
285 
286 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
287 	pad_str(info.model, sizeof(info.model));
288 	pad_str(info.serial_number, sizeof(info.serial_number));
289 
290 	TEE_MemMove(info.label, token->db_main->label, sizeof(info.label));
291 
292 	info.flags = token->db_main->flags;
293 	info.session_count = token->session_count;
294 	info.rw_session_count = token->rw_session_count;
295 
296 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
297 
298 	return PKCS11_CKR_OK;
299 }
300 
301 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused,
302 					   uint32_t *array __maybe_unused,
303 					   size_t count __maybe_unused)
304 {
305 	size_t __maybe_unused n = 0;
306 
307 	if (TRACE_LEVEL < TRACE_DEBUG)
308 		return;
309 
310 	for (n = 0; n < count; n++)
311 		DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s",
312 		     token_id, array[n], id2str_mechanism(array[n]));
313 }
314 
315 uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params)
316 {
317 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
318 						TEE_PARAM_TYPE_NONE,
319 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
320 						TEE_PARAM_TYPE_NONE);
321 	TEE_Param *ctrl = &params[0];
322 	TEE_Param *out = &params[2];
323 	uint32_t rv = 0;
324 	struct serialargs ctrlargs = { };
325 	uint32_t token_id = 0;
326 	struct ck_token __maybe_unused *token = NULL;
327 	size_t count = 0;
328 	uint32_t *array = NULL;
329 
330 	if (ptypes != exp_pt)
331 		return PKCS11_CKR_ARGUMENTS_BAD;
332 
333 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
334 
335 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
336 	if (rv)
337 		return rv;
338 
339 	if (serialargs_remaining_bytes(&ctrlargs))
340 		return PKCS11_CKR_ARGUMENTS_BAD;
341 
342 	token = get_token(token_id);
343 	if (!token)
344 		return PKCS11_CKR_SLOT_ID_INVALID;
345 
346 	count = out->memref.size / sizeof(*array);
347 	array = tee_malloc_mechanism_list(&count);
348 
349 	if (out->memref.size < count * sizeof(*array)) {
350 		assert(!array);
351 		out->memref.size = count * sizeof(*array);
352 		return PKCS11_CKR_BUFFER_TOO_SMALL;
353 	}
354 
355 	if (!array)
356 		return PKCS11_CKR_DEVICE_MEMORY;
357 
358 	dmsg_print_supported_mechanism(token_id, array, count);
359 
360 	out->memref.size = count * sizeof(*array);
361 	TEE_MemMove(out->memref.buffer, array, out->memref.size);
362 
363 	TEE_Free(array);
364 
365 	return rv;
366 }
367 
368 static void supported_mechanism_key_size(uint32_t proc_id,
369 					 uint32_t *max_key_size,
370 					 uint32_t *min_key_size)
371 {
372 	switch (proc_id) {
373 	/* Will be filled once TA supports mechanisms */
374 	default:
375 		*min_key_size = 0;
376 		*max_key_size = 0;
377 		break;
378 	}
379 }
380 
381 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params)
382 {
383 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
384 						TEE_PARAM_TYPE_NONE,
385 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
386 						TEE_PARAM_TYPE_NONE);
387 	TEE_Param *ctrl = &params[0];
388 	TEE_Param *out = &params[2];
389 	uint32_t rv = 0;
390 	struct serialargs ctrlargs = { };
391 	uint32_t token_id = 0;
392 	uint32_t type = 0;
393 	struct ck_token *token = NULL;
394 	struct pkcs11_mechanism_info info = { };
395 
396 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
397 		return PKCS11_CKR_ARGUMENTS_BAD;
398 
399 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
400 
401 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
402 	if (rv)
403 		return rv;
404 
405 	rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
406 	if (rv)
407 		return rv;
408 
409 	if (serialargs_remaining_bytes(&ctrlargs))
410 		return PKCS11_CKR_ARGUMENTS_BAD;
411 
412 	token = get_token(token_id);
413 	if (!token)
414 		return PKCS11_CKR_SLOT_ID_INVALID;
415 
416 	if (!mechanism_is_valid(type))
417 		return PKCS11_CKR_MECHANISM_INVALID;
418 
419 	info.flags = mechanism_supported_flags(type);
420 
421 	supported_mechanism_key_size(type, &info.min_key_size,
422 				     &info.max_key_size);
423 
424 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
425 
426 	DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info",
427 	     token_id, type);
428 
429 	return PKCS11_CKR_OK;
430 }
431 
432 /* Select the ReadOnly or ReadWrite state for session login state */
433 static void set_session_state(struct pkcs11_client *client,
434 			      struct pkcs11_session *session, bool readonly)
435 {
436 	struct pkcs11_session *sess = NULL;
437 	enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION;
438 
439 	/* Default to public session if no session already registered */
440 	if (readonly)
441 		state = PKCS11_CKS_RO_PUBLIC_SESSION;
442 	else
443 		state = PKCS11_CKS_RW_PUBLIC_SESSION;
444 
445 	/*
446 	 * No need to check all client sessions, the first found in
447 	 * target token gives client login configuration.
448 	 */
449 	TAILQ_FOREACH(sess, &client->session_list, link) {
450 		assert(sess != session);
451 
452 		if (sess->token == session->token) {
453 			switch (sess->state) {
454 			case PKCS11_CKS_RW_PUBLIC_SESSION:
455 			case PKCS11_CKS_RO_PUBLIC_SESSION:
456 				if (readonly)
457 					state = PKCS11_CKS_RO_PUBLIC_SESSION;
458 				else
459 					state = PKCS11_CKS_RW_PUBLIC_SESSION;
460 				break;
461 			case PKCS11_CKS_RO_USER_FUNCTIONS:
462 			case PKCS11_CKS_RW_USER_FUNCTIONS:
463 				if (readonly)
464 					state = PKCS11_CKS_RO_USER_FUNCTIONS;
465 				else
466 					state = PKCS11_CKS_RW_USER_FUNCTIONS;
467 				break;
468 			case PKCS11_CKS_RW_SO_FUNCTIONS:
469 				if (readonly)
470 					TEE_Panic(0);
471 				else
472 					state = PKCS11_CKS_RW_SO_FUNCTIONS;
473 				break;
474 			default:
475 				TEE_Panic(0);
476 			}
477 			break;
478 		}
479 	}
480 
481 	session->state = state;
482 }
483 
484 uint32_t entry_ck_open_session(struct pkcs11_client *client,
485 			       uint32_t ptypes, TEE_Param *params)
486 {
487 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
488 						TEE_PARAM_TYPE_NONE,
489 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
490 						TEE_PARAM_TYPE_NONE);
491 	TEE_Param *ctrl = &params[0];
492 	TEE_Param *out = &params[2];
493 	uint32_t rv = 0;
494 	struct serialargs ctrlargs = { };
495 	uint32_t token_id = 0;
496 	uint32_t flags = 0;
497 	struct ck_token *token = NULL;
498 	struct pkcs11_session *session = NULL;
499 	bool readonly = false;
500 
501 	if (!client || ptypes != exp_pt ||
502 	    out->memref.size != sizeof(session->handle))
503 		return PKCS11_CKR_ARGUMENTS_BAD;
504 
505 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
506 
507 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
508 	if (rv)
509 		return rv;
510 
511 	rv = serialargs_get(&ctrlargs, &flags, sizeof(flags));
512 	if (rv)
513 		return rv;
514 
515 	if (serialargs_remaining_bytes(&ctrlargs))
516 		return PKCS11_CKR_ARGUMENTS_BAD;
517 
518 	token = get_token(token_id);
519 	if (!token)
520 		return PKCS11_CKR_SLOT_ID_INVALID;
521 
522 	/* Sanitize session flags */
523 	if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) ||
524 	    (flags & ~(PKCS11_CKFSS_RW_SESSION |
525 		       PKCS11_CKFSS_SERIAL_SESSION)))
526 		return PKCS11_CKR_ARGUMENTS_BAD;
527 
528 	readonly = !(flags & PKCS11_CKFSS_RW_SESSION);
529 
530 	if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY)
531 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
532 
533 	if (readonly) {
534 		/* Specifically reject read-only session under SO login */
535 		TAILQ_FOREACH(session, &client->session_list, link)
536 			if (pkcs11_session_is_so(session))
537 				return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS;
538 	}
539 
540 	session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO);
541 	if (!session)
542 		return PKCS11_CKR_DEVICE_MEMORY;
543 
544 	session->handle = handle_get(&client->session_handle_db, session);
545 	if (!session->handle) {
546 		TEE_Free(session);
547 		return PKCS11_CKR_DEVICE_MEMORY;
548 	}
549 
550 	session->token = token;
551 	session->client = client;
552 
553 	set_session_state(client, session, readonly);
554 
555 	TAILQ_INSERT_HEAD(&client->session_list, session, link);
556 
557 	session->token->session_count++;
558 	if (!readonly)
559 		session->token->rw_session_count++;
560 
561 	TEE_MemMove(out->memref.buffer, &session->handle,
562 		    sizeof(session->handle));
563 
564 	DMSG("Open PKCS11 session %"PRIu32, session->handle);
565 
566 	return PKCS11_CKR_OK;
567 }
568 
569 static void close_ck_session(struct pkcs11_session *session)
570 {
571 	TAILQ_REMOVE(&session->client->session_list, session, link);
572 	handle_put(&session->client->session_handle_db, session->handle);
573 
574 	session->token->session_count--;
575 	if (pkcs11_session_is_read_write(session))
576 		session->token->rw_session_count--;
577 
578 	TEE_Free(session);
579 
580 	DMSG("Close PKCS11 session %"PRIu32, session->handle);
581 }
582 
583 uint32_t entry_ck_close_session(struct pkcs11_client *client,
584 				uint32_t ptypes, TEE_Param *params)
585 {
586 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
587 						TEE_PARAM_TYPE_NONE,
588 						TEE_PARAM_TYPE_NONE,
589 						TEE_PARAM_TYPE_NONE);
590 	TEE_Param *ctrl = &params[0];
591 	uint32_t rv = 0;
592 	struct serialargs ctrlargs = { };
593 	uint32_t session_handle = 0;
594 	struct pkcs11_session *session = NULL;
595 
596 	if (!client || ptypes != exp_pt)
597 		return PKCS11_CKR_ARGUMENTS_BAD;
598 
599 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
600 
601 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
602 	if (rv)
603 		return rv;
604 
605 	if (serialargs_remaining_bytes(&ctrlargs))
606 		return PKCS11_CKR_ARGUMENTS_BAD;
607 
608 	session = pkcs11_handle2session(session_handle, client);
609 	if (!session)
610 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
611 
612 	close_ck_session(session);
613 
614 	return PKCS11_CKR_OK;
615 }
616 
617 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client,
618 				     uint32_t ptypes, TEE_Param *params)
619 {
620 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
621 						TEE_PARAM_TYPE_NONE,
622 						TEE_PARAM_TYPE_NONE,
623 						TEE_PARAM_TYPE_NONE);
624 	TEE_Param *ctrl = &params[0];
625 	uint32_t rv = 0;
626 	struct serialargs ctrlargs = { };
627 	uint32_t token_id = 0;
628 	struct ck_token *token = NULL;
629 	struct pkcs11_session *session = NULL;
630 	struct pkcs11_session *next = NULL;
631 
632 	if (!client || ptypes != exp_pt)
633 		return PKCS11_CKR_ARGUMENTS_BAD;
634 
635 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
636 
637 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
638 	if (rv)
639 		return rv;
640 
641 	if (serialargs_remaining_bytes(&ctrlargs))
642 		return PKCS11_CKR_ARGUMENTS_BAD;
643 
644 	token = get_token(token_id);
645 	if (!token)
646 		return PKCS11_CKR_SLOT_ID_INVALID;
647 
648 	DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
649 
650 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
651 		if (session->token == token)
652 			close_ck_session(session);
653 
654 	return PKCS11_CKR_OK;
655 }
656 
657 uint32_t entry_ck_session_info(struct pkcs11_client *client,
658 			       uint32_t ptypes, TEE_Param *params)
659 {
660 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
661 						TEE_PARAM_TYPE_NONE,
662 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
663 						TEE_PARAM_TYPE_NONE);
664 	TEE_Param *ctrl = &params[0];
665 	TEE_Param *out = &params[2];
666 	uint32_t rv = 0;
667 	struct serialargs ctrlargs = { };
668 	uint32_t session_handle = 0;
669 	struct pkcs11_session *session = NULL;
670 	struct pkcs11_session_info info = {
671 		.flags = PKCS11_CKFSS_SERIAL_SESSION,
672 	};
673 
674 	if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
675 		return PKCS11_CKR_ARGUMENTS_BAD;
676 
677 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
678 
679 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
680 	if (rv)
681 		return rv;
682 
683 	if (serialargs_remaining_bytes(&ctrlargs))
684 		return PKCS11_CKR_ARGUMENTS_BAD;
685 
686 	session = pkcs11_handle2session(session_handle, client);
687 	if (!session)
688 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
689 
690 	info.slot_id = get_token_id(session->token);
691 	info.state = session->state;
692 	if (pkcs11_session_is_read_write(session))
693 		info.flags |= PKCS11_CKFSS_RW_SESSION;
694 
695 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
696 
697 	DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
698 
699 	return PKCS11_CKR_OK;
700 }
701