xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision d9c569c9c765ed6f0fe6e131d1a33c9c32c0ba08)
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 		if (out->memref.buffer)
353 			return PKCS11_CKR_BUFFER_TOO_SMALL;
354 		else
355 			return PKCS11_CKR_OK;
356 	}
357 
358 	if (!array)
359 		return PKCS11_CKR_DEVICE_MEMORY;
360 
361 	dmsg_print_supported_mechanism(token_id, array, count);
362 
363 	out->memref.size = count * sizeof(*array);
364 	TEE_MemMove(out->memref.buffer, array, out->memref.size);
365 
366 	TEE_Free(array);
367 
368 	return rv;
369 }
370 
371 static void supported_mechanism_key_size(uint32_t proc_id,
372 					 uint32_t *max_key_size,
373 					 uint32_t *min_key_size)
374 {
375 	switch (proc_id) {
376 	/* Will be filled once TA supports mechanisms */
377 	default:
378 		*min_key_size = 0;
379 		*max_key_size = 0;
380 		break;
381 	}
382 }
383 
384 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params)
385 {
386 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
387 						TEE_PARAM_TYPE_NONE,
388 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
389 						TEE_PARAM_TYPE_NONE);
390 	TEE_Param *ctrl = &params[0];
391 	TEE_Param *out = &params[2];
392 	uint32_t rv = 0;
393 	struct serialargs ctrlargs = { };
394 	uint32_t token_id = 0;
395 	uint32_t type = 0;
396 	struct ck_token *token = NULL;
397 	struct pkcs11_mechanism_info info = { };
398 
399 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
400 		return PKCS11_CKR_ARGUMENTS_BAD;
401 
402 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
403 
404 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
405 	if (rv)
406 		return rv;
407 
408 	rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
409 	if (rv)
410 		return rv;
411 
412 	if (serialargs_remaining_bytes(&ctrlargs))
413 		return PKCS11_CKR_ARGUMENTS_BAD;
414 
415 	token = get_token(token_id);
416 	if (!token)
417 		return PKCS11_CKR_SLOT_ID_INVALID;
418 
419 	if (!mechanism_is_valid(type))
420 		return PKCS11_CKR_MECHANISM_INVALID;
421 
422 	info.flags = mechanism_supported_flags(type);
423 
424 	supported_mechanism_key_size(type, &info.min_key_size,
425 				     &info.max_key_size);
426 
427 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
428 
429 	DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info",
430 	     token_id, type);
431 
432 	return PKCS11_CKR_OK;
433 }
434 
435 /* Select the ReadOnly or ReadWrite state for session login state */
436 static void set_session_state(struct pkcs11_client *client,
437 			      struct pkcs11_session *session, bool readonly)
438 {
439 	struct pkcs11_session *sess = NULL;
440 	enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION;
441 
442 	/* Default to public session if no session already registered */
443 	if (readonly)
444 		state = PKCS11_CKS_RO_PUBLIC_SESSION;
445 	else
446 		state = PKCS11_CKS_RW_PUBLIC_SESSION;
447 
448 	/*
449 	 * No need to check all client sessions, the first found in
450 	 * target token gives client login configuration.
451 	 */
452 	TAILQ_FOREACH(sess, &client->session_list, link) {
453 		assert(sess != session);
454 
455 		if (sess->token == session->token) {
456 			switch (sess->state) {
457 			case PKCS11_CKS_RW_PUBLIC_SESSION:
458 			case PKCS11_CKS_RO_PUBLIC_SESSION:
459 				if (readonly)
460 					state = PKCS11_CKS_RO_PUBLIC_SESSION;
461 				else
462 					state = PKCS11_CKS_RW_PUBLIC_SESSION;
463 				break;
464 			case PKCS11_CKS_RO_USER_FUNCTIONS:
465 			case PKCS11_CKS_RW_USER_FUNCTIONS:
466 				if (readonly)
467 					state = PKCS11_CKS_RO_USER_FUNCTIONS;
468 				else
469 					state = PKCS11_CKS_RW_USER_FUNCTIONS;
470 				break;
471 			case PKCS11_CKS_RW_SO_FUNCTIONS:
472 				if (readonly)
473 					TEE_Panic(0);
474 				else
475 					state = PKCS11_CKS_RW_SO_FUNCTIONS;
476 				break;
477 			default:
478 				TEE_Panic(0);
479 			}
480 			break;
481 		}
482 	}
483 
484 	session->state = state;
485 }
486 
487 uint32_t entry_ck_open_session(struct pkcs11_client *client,
488 			       uint32_t ptypes, TEE_Param *params)
489 {
490 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
491 						TEE_PARAM_TYPE_NONE,
492 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
493 						TEE_PARAM_TYPE_NONE);
494 	TEE_Param *ctrl = &params[0];
495 	TEE_Param *out = &params[2];
496 	uint32_t rv = 0;
497 	struct serialargs ctrlargs = { };
498 	uint32_t token_id = 0;
499 	uint32_t flags = 0;
500 	struct ck_token *token = NULL;
501 	struct pkcs11_session *session = NULL;
502 	bool readonly = false;
503 
504 	if (!client || ptypes != exp_pt ||
505 	    out->memref.size != sizeof(session->handle))
506 		return PKCS11_CKR_ARGUMENTS_BAD;
507 
508 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
509 
510 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
511 	if (rv)
512 		return rv;
513 
514 	rv = serialargs_get(&ctrlargs, &flags, sizeof(flags));
515 	if (rv)
516 		return rv;
517 
518 	if (serialargs_remaining_bytes(&ctrlargs))
519 		return PKCS11_CKR_ARGUMENTS_BAD;
520 
521 	token = get_token(token_id);
522 	if (!token)
523 		return PKCS11_CKR_SLOT_ID_INVALID;
524 
525 	/* Sanitize session flags */
526 	if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) ||
527 	    (flags & ~(PKCS11_CKFSS_RW_SESSION |
528 		       PKCS11_CKFSS_SERIAL_SESSION)))
529 		return PKCS11_CKR_ARGUMENTS_BAD;
530 
531 	readonly = !(flags & PKCS11_CKFSS_RW_SESSION);
532 
533 	if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY)
534 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
535 
536 	if (readonly) {
537 		/* Specifically reject read-only session under SO login */
538 		TAILQ_FOREACH(session, &client->session_list, link)
539 			if (pkcs11_session_is_so(session))
540 				return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS;
541 	}
542 
543 	session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO);
544 	if (!session)
545 		return PKCS11_CKR_DEVICE_MEMORY;
546 
547 	session->handle = handle_get(&client->session_handle_db, session);
548 	if (!session->handle) {
549 		TEE_Free(session);
550 		return PKCS11_CKR_DEVICE_MEMORY;
551 	}
552 
553 	session->token = token;
554 	session->client = client;
555 
556 	set_session_state(client, session, readonly);
557 
558 	TAILQ_INSERT_HEAD(&client->session_list, session, link);
559 
560 	session->token->session_count++;
561 	if (!readonly)
562 		session->token->rw_session_count++;
563 
564 	TEE_MemMove(out->memref.buffer, &session->handle,
565 		    sizeof(session->handle));
566 
567 	DMSG("Open PKCS11 session %"PRIu32, session->handle);
568 
569 	return PKCS11_CKR_OK;
570 }
571 
572 static void close_ck_session(struct pkcs11_session *session)
573 {
574 	TAILQ_REMOVE(&session->client->session_list, session, link);
575 	handle_put(&session->client->session_handle_db, session->handle);
576 
577 	session->token->session_count--;
578 	if (pkcs11_session_is_read_write(session))
579 		session->token->rw_session_count--;
580 
581 	TEE_Free(session);
582 
583 	DMSG("Close PKCS11 session %"PRIu32, session->handle);
584 }
585 
586 uint32_t entry_ck_close_session(struct pkcs11_client *client,
587 				uint32_t ptypes, TEE_Param *params)
588 {
589 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
590 						TEE_PARAM_TYPE_NONE,
591 						TEE_PARAM_TYPE_NONE,
592 						TEE_PARAM_TYPE_NONE);
593 	TEE_Param *ctrl = &params[0];
594 	uint32_t rv = 0;
595 	struct serialargs ctrlargs = { };
596 	uint32_t session_handle = 0;
597 	struct pkcs11_session *session = NULL;
598 
599 	if (!client || ptypes != exp_pt)
600 		return PKCS11_CKR_ARGUMENTS_BAD;
601 
602 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
603 
604 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
605 	if (rv)
606 		return rv;
607 
608 	if (serialargs_remaining_bytes(&ctrlargs))
609 		return PKCS11_CKR_ARGUMENTS_BAD;
610 
611 	session = pkcs11_handle2session(session_handle, client);
612 	if (!session)
613 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
614 
615 	close_ck_session(session);
616 
617 	return PKCS11_CKR_OK;
618 }
619 
620 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client,
621 				     uint32_t ptypes, TEE_Param *params)
622 {
623 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
624 						TEE_PARAM_TYPE_NONE,
625 						TEE_PARAM_TYPE_NONE,
626 						TEE_PARAM_TYPE_NONE);
627 	TEE_Param *ctrl = &params[0];
628 	uint32_t rv = 0;
629 	struct serialargs ctrlargs = { };
630 	uint32_t token_id = 0;
631 	struct ck_token *token = NULL;
632 	struct pkcs11_session *session = NULL;
633 	struct pkcs11_session *next = NULL;
634 
635 	if (!client || ptypes != exp_pt)
636 		return PKCS11_CKR_ARGUMENTS_BAD;
637 
638 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
639 
640 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
641 	if (rv)
642 		return rv;
643 
644 	if (serialargs_remaining_bytes(&ctrlargs))
645 		return PKCS11_CKR_ARGUMENTS_BAD;
646 
647 	token = get_token(token_id);
648 	if (!token)
649 		return PKCS11_CKR_SLOT_ID_INVALID;
650 
651 	DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
652 
653 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
654 		if (session->token == token)
655 			close_ck_session(session);
656 
657 	return PKCS11_CKR_OK;
658 }
659 
660 uint32_t entry_ck_session_info(struct pkcs11_client *client,
661 			       uint32_t ptypes, TEE_Param *params)
662 {
663 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
664 						TEE_PARAM_TYPE_NONE,
665 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
666 						TEE_PARAM_TYPE_NONE);
667 	TEE_Param *ctrl = &params[0];
668 	TEE_Param *out = &params[2];
669 	uint32_t rv = 0;
670 	struct serialargs ctrlargs = { };
671 	uint32_t session_handle = 0;
672 	struct pkcs11_session *session = NULL;
673 	struct pkcs11_session_info info = {
674 		.flags = PKCS11_CKFSS_SERIAL_SESSION,
675 	};
676 
677 	if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
678 		return PKCS11_CKR_ARGUMENTS_BAD;
679 
680 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
681 
682 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
683 	if (rv)
684 		return rv;
685 
686 	if (serialargs_remaining_bytes(&ctrlargs))
687 		return PKCS11_CKR_ARGUMENTS_BAD;
688 
689 	session = pkcs11_handle2session(session_handle, client);
690 	if (!session)
691 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
692 
693 	info.slot_id = get_token_id(session->token);
694 	info.state = session->state;
695 	if (pkcs11_session_is_read_write(session))
696 		info.flags |= PKCS11_CKFSS_RW_SESSION;
697 
698 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
699 
700 	DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
701 
702 	return PKCS11_CKR_OK;
703 }
704