xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision 8182792a91f49b750ff196abdf038cb9d1827cc6)
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 <printk.h>
10 #include <string.h>
11 #include <string_ext.h>
12 #include <sys/queue.h>
13 #include <tee_api_types.h>
14 #include <tee_internal_api_extensions.h>
15 #include <util.h>
16 
17 #include "pkcs11_helpers.h"
18 #include "pkcs11_token.h"
19 #include "serializer.h"
20 
21 /* Provide 3 slots/tokens, ID is token index */
22 #ifndef CFG_PKCS11_TA_TOKEN_COUNT
23 #define TOKEN_COUNT		3
24 #else
25 #define TOKEN_COUNT		CFG_PKCS11_TA_TOKEN_COUNT
26 #endif
27 
28 /*
29  * Structure tracking client applications
30  *
31  * @link - chained list of registered client applications
32  * @sessions - list of the PKCS11 sessions opened by the client application
33  */
34 struct pkcs11_client {
35 	TAILQ_ENTRY(pkcs11_client) link;
36 	struct session_list session_list;
37 	struct handle_db session_handle_db;
38 };
39 
40 /* Static allocation of tokens runtime instances (reset to 0 at load) */
41 struct ck_token ck_token[TOKEN_COUNT];
42 
43 static struct client_list pkcs11_client_list =
44 	TAILQ_HEAD_INITIALIZER(pkcs11_client_list);
45 
46 static void close_ck_session(struct pkcs11_session *session);
47 
48 struct ck_token *get_token(unsigned int token_id)
49 {
50 	if (token_id < TOKEN_COUNT)
51 		return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
52 
53 	return NULL;
54 }
55 
56 unsigned int get_token_id(struct ck_token *token)
57 {
58 	ptrdiff_t id = token - ck_token;
59 
60 	assert(id >= 0 && id < TOKEN_COUNT);
61 	return id;
62 }
63 
64 struct pkcs11_client *tee_session2client(void *tee_session)
65 {
66 	struct pkcs11_client *client = NULL;
67 
68 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
69 		if (client == tee_session)
70 			break;
71 
72 	return client;
73 }
74 
75 struct pkcs11_session *pkcs11_handle2session(uint32_t handle,
76 					     struct pkcs11_client *client)
77 {
78 	return handle_lookup(&client->session_handle_db, handle);
79 }
80 
81 struct pkcs11_client *register_client(void)
82 {
83 	struct pkcs11_client *client = NULL;
84 
85 	client = TEE_Malloc(sizeof(*client), TEE_MALLOC_FILL_ZERO);
86 	if (!client)
87 		return NULL;
88 
89 	TAILQ_INSERT_HEAD(&pkcs11_client_list, client, link);
90 	TAILQ_INIT(&client->session_list);
91 	handle_db_init(&client->session_handle_db);
92 
93 	return client;
94 }
95 
96 void unregister_client(struct pkcs11_client *client)
97 {
98 	struct pkcs11_session *session = NULL;
99 	struct pkcs11_session *next = NULL;
100 
101 	if (!client) {
102 		EMSG("Invalid TEE session handle");
103 		return;
104 	}
105 
106 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
107 		close_ck_session(session);
108 
109 	TAILQ_REMOVE(&pkcs11_client_list, client, link);
110 	handle_db_destroy(&client->session_handle_db);
111 	TEE_Free(client);
112 }
113 
114 static TEE_Result pkcs11_token_init(unsigned int id)
115 {
116 	struct ck_token *token = init_persistent_db(id);
117 
118 	if (!token)
119 		return TEE_ERROR_SECURITY;
120 
121 	if (token->state == PKCS11_TOKEN_RESET) {
122 		/* As per PKCS#11 spec, token resets to read/write state */
123 		token->state = PKCS11_TOKEN_READ_WRITE;
124 		token->session_count = 0;
125 		token->rw_session_count = 0;
126 	}
127 
128 	return TEE_SUCCESS;
129 }
130 
131 TEE_Result pkcs11_init(void)
132 {
133 	unsigned int id = 0;
134 	TEE_Result ret = TEE_ERROR_GENERIC;
135 
136 	for (id = 0; id < TOKEN_COUNT; id++) {
137 		ret = pkcs11_token_init(id);
138 		if (ret)
139 			break;
140 	}
141 
142 	return ret;
143 }
144 
145 void pkcs11_deinit(void)
146 {
147 	unsigned int id = 0;
148 
149 	for (id = 0; id < TOKEN_COUNT; id++)
150 		close_persistent_db(get_token(id));
151 }
152 
153 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
154 {
155 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
156 						TEE_PARAM_TYPE_NONE,
157 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
158 						TEE_PARAM_TYPE_NONE);
159 	TEE_Param *out = &params[2];
160 	uint32_t token_id = 0;
161 	const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
162 	uint8_t *id = NULL;
163 
164 	if (ptypes != exp_pt ||
165 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN)
166 		return PKCS11_CKR_ARGUMENTS_BAD;
167 
168 	if (out->memref.size < out_size) {
169 		out->memref.size = out_size;
170 
171 		if (out->memref.buffer)
172 			return PKCS11_CKR_BUFFER_TOO_SMALL;
173 		else
174 			return PKCS11_CKR_OK;
175 	}
176 
177 	for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
178 	     token_id++, id += sizeof(token_id))
179 		TEE_MemMove(id, &token_id, sizeof(token_id));
180 
181 	out->memref.size = out_size;
182 
183 	return PKCS11_CKR_OK;
184 }
185 
186 static void pad_str(uint8_t *str, size_t size)
187 {
188 	int n = strnlen((char *)str, size);
189 
190 	TEE_MemFill(str + n, ' ', size - n);
191 }
192 
193 static void set_token_description(struct pkcs11_slot_info *info)
194 {
195 	char desc[sizeof(info->slot_description) + 1] = { 0 };
196 	TEE_UUID dev_id = { };
197 	TEE_Result res = TEE_ERROR_GENERIC;
198 	int n = 0;
199 
200 	res = TEE_GetPropertyAsUUID(TEE_PROPSET_TEE_IMPLEMENTATION,
201 				    "gpd.tee.deviceID", &dev_id);
202 	if (res == TEE_SUCCESS) {
203 		n = snprintk(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION
204 			     " - TEE UUID %pUl", (void *)&dev_id);
205 	} else {
206 		n = snprintf(desc, sizeof(desc), PKCS11_SLOT_DESCRIPTION
207 			     " - No TEE UUID");
208 	}
209 	if (n < 0 || n >= (int)sizeof(desc))
210 		TEE_Panic(0);
211 
212 	TEE_MemMove(info->slot_description, desc, n);
213 	pad_str(info->slot_description, sizeof(info->slot_description));
214 }
215 
216 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params)
217 {
218 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
219 						TEE_PARAM_TYPE_NONE,
220 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
221 						TEE_PARAM_TYPE_NONE);
222 	TEE_Param *ctrl = &params[0];
223 	TEE_Param *out = &params[2];
224 	uint32_t rv = 0;
225 	struct serialargs ctrlargs = { };
226 	uint32_t token_id = 0;
227 	struct pkcs11_slot_info info = {
228 		.slot_description = PKCS11_SLOT_DESCRIPTION,
229 		.manufacturer_id = PKCS11_SLOT_MANUFACTURER,
230 		.flags = PKCS11_CKFS_TOKEN_PRESENT,
231 		.hardware_version = PKCS11_SLOT_HW_VERSION,
232 		.firmware_version = PKCS11_SLOT_FW_VERSION,
233 	};
234 
235 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <=
236 			    sizeof(info.slot_description));
237 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <=
238 			    sizeof(info.manufacturer_id));
239 
240 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
241 		return PKCS11_CKR_ARGUMENTS_BAD;
242 
243 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
244 
245 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
246 	if (rv)
247 		return rv;
248 
249 	if (serialargs_remaining_bytes(&ctrlargs))
250 		return PKCS11_CKR_ARGUMENTS_BAD;
251 
252 	if (!get_token(token_id))
253 		return PKCS11_CKR_SLOT_ID_INVALID;
254 
255 	set_token_description(&info);
256 
257 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
258 
259 	out->memref.size = sizeof(info);
260 	TEE_MemMove(out->memref.buffer, &info, out->memref.size);
261 
262 	return PKCS11_CKR_OK;
263 }
264 
265 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params)
266 {
267 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
268 						TEE_PARAM_TYPE_NONE,
269 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
270 						TEE_PARAM_TYPE_NONE);
271 	TEE_Param *ctrl = &params[0];
272 	TEE_Param *out = &params[2];
273 	uint32_t rv = 0;
274 	struct serialargs ctrlargs = { };
275 	uint32_t token_id = 0;
276 	struct ck_token *token = NULL;
277 	struct pkcs11_token_info info = {
278 		.manufacturer_id = PKCS11_TOKEN_MANUFACTURER,
279 		.model = PKCS11_TOKEN_MODEL,
280 		.max_session_count = UINT32_MAX,
281 		.max_rw_session_count = UINT32_MAX,
282 		.max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX,
283 		.min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN,
284 		.total_public_memory = UINT32_MAX,
285 		.free_public_memory = UINT32_MAX,
286 		.total_private_memory = UINT32_MAX,
287 		.free_private_memory = UINT32_MAX,
288 		.hardware_version = PKCS11_TOKEN_HW_VERSION,
289 		.firmware_version = PKCS11_TOKEN_FW_VERSION,
290 	};
291 	char sn[sizeof(info.serial_number) + 1] = { 0 };
292 	int n = 0;
293 
294 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
295 		return PKCS11_CKR_ARGUMENTS_BAD;
296 
297 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
298 
299 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
300 	if (rv)
301 		return rv;
302 
303 	if (serialargs_remaining_bytes(&ctrlargs))
304 		return PKCS11_CKR_ARGUMENTS_BAD;
305 
306 	token = get_token(token_id);
307 	if (!token)
308 		return PKCS11_CKR_SLOT_ID_INVALID;
309 
310 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
311 	pad_str(info.model, sizeof(info.model));
312 
313 	n = snprintf(sn, sizeof(sn), "%0*"PRIu32,
314 		     (int)sizeof(info.serial_number), token_id);
315 	if (n != (int)sizeof(info.serial_number))
316 		TEE_Panic(0);
317 
318 	TEE_MemMove(info.serial_number, sn, sizeof(info.serial_number));
319 	pad_str(info.serial_number, sizeof(info.serial_number));
320 
321 	TEE_MemMove(info.label, token->db_main->label, sizeof(info.label));
322 
323 	info.flags = token->db_main->flags;
324 	info.session_count = token->session_count;
325 	info.rw_session_count = token->rw_session_count;
326 
327 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
328 
329 	return PKCS11_CKR_OK;
330 }
331 
332 static void dmsg_print_supported_mechanism(unsigned int token_id __maybe_unused,
333 					   uint32_t *array __maybe_unused,
334 					   size_t count __maybe_unused)
335 {
336 	size_t __maybe_unused n = 0;
337 
338 	if (TRACE_LEVEL < TRACE_DEBUG)
339 		return;
340 
341 	for (n = 0; n < count; n++)
342 		DMSG("PKCS11 token %"PRIu32": mechanism 0x%04"PRIx32": %s",
343 		     token_id, array[n], id2str_mechanism(array[n]));
344 }
345 
346 uint32_t entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params)
347 {
348 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
349 						TEE_PARAM_TYPE_NONE,
350 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
351 						TEE_PARAM_TYPE_NONE);
352 	TEE_Param *ctrl = &params[0];
353 	TEE_Param *out = &params[2];
354 	uint32_t rv = 0;
355 	struct serialargs ctrlargs = { };
356 	uint32_t token_id = 0;
357 	struct ck_token __maybe_unused *token = NULL;
358 	size_t count = 0;
359 	uint32_t *array = NULL;
360 
361 	if (ptypes != exp_pt)
362 		return PKCS11_CKR_ARGUMENTS_BAD;
363 
364 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
365 
366 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
367 	if (rv)
368 		return rv;
369 
370 	if (serialargs_remaining_bytes(&ctrlargs))
371 		return PKCS11_CKR_ARGUMENTS_BAD;
372 
373 	token = get_token(token_id);
374 	if (!token)
375 		return PKCS11_CKR_SLOT_ID_INVALID;
376 
377 	count = out->memref.size / sizeof(*array);
378 	array = tee_malloc_mechanism_list(&count);
379 
380 	if (out->memref.size < count * sizeof(*array)) {
381 		assert(!array);
382 		out->memref.size = count * sizeof(*array);
383 		if (out->memref.buffer)
384 			return PKCS11_CKR_BUFFER_TOO_SMALL;
385 		else
386 			return PKCS11_CKR_OK;
387 	}
388 
389 	if (!array)
390 		return PKCS11_CKR_DEVICE_MEMORY;
391 
392 	dmsg_print_supported_mechanism(token_id, array, count);
393 
394 	out->memref.size = count * sizeof(*array);
395 	TEE_MemMove(out->memref.buffer, array, out->memref.size);
396 
397 	TEE_Free(array);
398 
399 	return rv;
400 }
401 
402 static void supported_mechanism_key_size(uint32_t proc_id,
403 					 uint32_t *max_key_size,
404 					 uint32_t *min_key_size)
405 {
406 	switch (proc_id) {
407 	/* Will be filled once TA supports mechanisms */
408 	default:
409 		*min_key_size = 0;
410 		*max_key_size = 0;
411 		break;
412 	}
413 }
414 
415 uint32_t entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params)
416 {
417 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
418 						TEE_PARAM_TYPE_NONE,
419 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
420 						TEE_PARAM_TYPE_NONE);
421 	TEE_Param *ctrl = &params[0];
422 	TEE_Param *out = &params[2];
423 	uint32_t rv = 0;
424 	struct serialargs ctrlargs = { };
425 	uint32_t token_id = 0;
426 	uint32_t type = 0;
427 	struct ck_token *token = NULL;
428 	struct pkcs11_mechanism_info info = { };
429 
430 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
431 		return PKCS11_CKR_ARGUMENTS_BAD;
432 
433 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
434 
435 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
436 	if (rv)
437 		return rv;
438 
439 	rv = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
440 	if (rv)
441 		return rv;
442 
443 	if (serialargs_remaining_bytes(&ctrlargs))
444 		return PKCS11_CKR_ARGUMENTS_BAD;
445 
446 	token = get_token(token_id);
447 	if (!token)
448 		return PKCS11_CKR_SLOT_ID_INVALID;
449 
450 	if (!mechanism_is_valid(type))
451 		return PKCS11_CKR_MECHANISM_INVALID;
452 
453 	info.flags = mechanism_supported_flags(type);
454 
455 	supported_mechanism_key_size(type, &info.min_key_size,
456 				     &info.max_key_size);
457 
458 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
459 
460 	DMSG("PKCS11 token %"PRIu32": mechanism 0x%"PRIx32" info",
461 	     token_id, type);
462 
463 	return PKCS11_CKR_OK;
464 }
465 
466 /* Select the ReadOnly or ReadWrite state for session login state */
467 static void set_session_state(struct pkcs11_client *client,
468 			      struct pkcs11_session *session, bool readonly)
469 {
470 	struct pkcs11_session *sess = NULL;
471 	enum pkcs11_session_state state = PKCS11_CKS_RO_PUBLIC_SESSION;
472 
473 	/* Default to public session if no session already registered */
474 	if (readonly)
475 		state = PKCS11_CKS_RO_PUBLIC_SESSION;
476 	else
477 		state = PKCS11_CKS_RW_PUBLIC_SESSION;
478 
479 	/*
480 	 * No need to check all client sessions, the first found in
481 	 * target token gives client login configuration.
482 	 */
483 	TAILQ_FOREACH(sess, &client->session_list, link) {
484 		assert(sess != session);
485 
486 		if (sess->token == session->token) {
487 			switch (sess->state) {
488 			case PKCS11_CKS_RW_PUBLIC_SESSION:
489 			case PKCS11_CKS_RO_PUBLIC_SESSION:
490 				if (readonly)
491 					state = PKCS11_CKS_RO_PUBLIC_SESSION;
492 				else
493 					state = PKCS11_CKS_RW_PUBLIC_SESSION;
494 				break;
495 			case PKCS11_CKS_RO_USER_FUNCTIONS:
496 			case PKCS11_CKS_RW_USER_FUNCTIONS:
497 				if (readonly)
498 					state = PKCS11_CKS_RO_USER_FUNCTIONS;
499 				else
500 					state = PKCS11_CKS_RW_USER_FUNCTIONS;
501 				break;
502 			case PKCS11_CKS_RW_SO_FUNCTIONS:
503 				if (readonly)
504 					TEE_Panic(0);
505 				else
506 					state = PKCS11_CKS_RW_SO_FUNCTIONS;
507 				break;
508 			default:
509 				TEE_Panic(0);
510 			}
511 			break;
512 		}
513 	}
514 
515 	session->state = state;
516 }
517 
518 uint32_t entry_ck_open_session(struct pkcs11_client *client,
519 			       uint32_t ptypes, TEE_Param *params)
520 {
521 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
522 						TEE_PARAM_TYPE_NONE,
523 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
524 						TEE_PARAM_TYPE_NONE);
525 	TEE_Param *ctrl = &params[0];
526 	TEE_Param *out = &params[2];
527 	uint32_t rv = 0;
528 	struct serialargs ctrlargs = { };
529 	uint32_t token_id = 0;
530 	uint32_t flags = 0;
531 	struct ck_token *token = NULL;
532 	struct pkcs11_session *session = NULL;
533 	bool readonly = false;
534 
535 	if (!client || ptypes != exp_pt ||
536 	    out->memref.size != sizeof(session->handle))
537 		return PKCS11_CKR_ARGUMENTS_BAD;
538 
539 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
540 
541 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
542 	if (rv)
543 		return rv;
544 
545 	rv = serialargs_get(&ctrlargs, &flags, sizeof(flags));
546 	if (rv)
547 		return rv;
548 
549 	if (serialargs_remaining_bytes(&ctrlargs))
550 		return PKCS11_CKR_ARGUMENTS_BAD;
551 
552 	token = get_token(token_id);
553 	if (!token)
554 		return PKCS11_CKR_SLOT_ID_INVALID;
555 
556 	/* Sanitize session flags */
557 	if (!(flags & PKCS11_CKFSS_SERIAL_SESSION) ||
558 	    (flags & ~(PKCS11_CKFSS_RW_SESSION |
559 		       PKCS11_CKFSS_SERIAL_SESSION)))
560 		return PKCS11_CKR_ARGUMENTS_BAD;
561 
562 	readonly = !(flags & PKCS11_CKFSS_RW_SESSION);
563 
564 	if (!readonly && token->state == PKCS11_TOKEN_READ_ONLY)
565 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
566 
567 	if (readonly) {
568 		/* Specifically reject read-only session under SO login */
569 		TAILQ_FOREACH(session, &client->session_list, link)
570 			if (pkcs11_session_is_so(session))
571 				return PKCS11_CKR_SESSION_READ_WRITE_SO_EXISTS;
572 	}
573 
574 	session = TEE_Malloc(sizeof(*session), TEE_MALLOC_FILL_ZERO);
575 	if (!session)
576 		return PKCS11_CKR_DEVICE_MEMORY;
577 
578 	session->handle = handle_get(&client->session_handle_db, session);
579 	if (!session->handle) {
580 		TEE_Free(session);
581 		return PKCS11_CKR_DEVICE_MEMORY;
582 	}
583 
584 	session->token = token;
585 	session->client = client;
586 
587 	set_session_state(client, session, readonly);
588 
589 	TAILQ_INSERT_HEAD(&client->session_list, session, link);
590 
591 	session->token->session_count++;
592 	if (!readonly)
593 		session->token->rw_session_count++;
594 
595 	TEE_MemMove(out->memref.buffer, &session->handle,
596 		    sizeof(session->handle));
597 
598 	DMSG("Open PKCS11 session %"PRIu32, session->handle);
599 
600 	return PKCS11_CKR_OK;
601 }
602 
603 static void close_ck_session(struct pkcs11_session *session)
604 {
605 	TAILQ_REMOVE(&session->client->session_list, session, link);
606 	handle_put(&session->client->session_handle_db, session->handle);
607 
608 	session->token->session_count--;
609 	if (pkcs11_session_is_read_write(session))
610 		session->token->rw_session_count--;
611 
612 	TEE_Free(session);
613 
614 	DMSG("Close PKCS11 session %"PRIu32, session->handle);
615 }
616 
617 uint32_t entry_ck_close_session(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 session_handle = 0;
628 	struct pkcs11_session *session = NULL;
629 
630 	if (!client || ptypes != exp_pt)
631 		return PKCS11_CKR_ARGUMENTS_BAD;
632 
633 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
634 
635 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
636 	if (rv)
637 		return rv;
638 
639 	if (serialargs_remaining_bytes(&ctrlargs))
640 		return PKCS11_CKR_ARGUMENTS_BAD;
641 
642 	session = pkcs11_handle2session(session_handle, client);
643 	if (!session)
644 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
645 
646 	close_ck_session(session);
647 
648 	return PKCS11_CKR_OK;
649 }
650 
651 uint32_t entry_ck_close_all_sessions(struct pkcs11_client *client,
652 				     uint32_t ptypes, TEE_Param *params)
653 {
654 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
655 						TEE_PARAM_TYPE_NONE,
656 						TEE_PARAM_TYPE_NONE,
657 						TEE_PARAM_TYPE_NONE);
658 	TEE_Param *ctrl = &params[0];
659 	uint32_t rv = 0;
660 	struct serialargs ctrlargs = { };
661 	uint32_t token_id = 0;
662 	struct ck_token *token = NULL;
663 	struct pkcs11_session *session = NULL;
664 	struct pkcs11_session *next = NULL;
665 
666 	if (!client || ptypes != exp_pt)
667 		return PKCS11_CKR_ARGUMENTS_BAD;
668 
669 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
670 
671 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
672 	if (rv)
673 		return rv;
674 
675 	if (serialargs_remaining_bytes(&ctrlargs))
676 		return PKCS11_CKR_ARGUMENTS_BAD;
677 
678 	token = get_token(token_id);
679 	if (!token)
680 		return PKCS11_CKR_SLOT_ID_INVALID;
681 
682 	DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
683 
684 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
685 		if (session->token == token)
686 			close_ck_session(session);
687 
688 	return PKCS11_CKR_OK;
689 }
690 
691 uint32_t entry_ck_session_info(struct pkcs11_client *client,
692 			       uint32_t ptypes, TEE_Param *params)
693 {
694 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
695 						TEE_PARAM_TYPE_NONE,
696 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
697 						TEE_PARAM_TYPE_NONE);
698 	TEE_Param *ctrl = &params[0];
699 	TEE_Param *out = &params[2];
700 	uint32_t rv = 0;
701 	struct serialargs ctrlargs = { };
702 	uint32_t session_handle = 0;
703 	struct pkcs11_session *session = NULL;
704 	struct pkcs11_session_info info = {
705 		.flags = PKCS11_CKFSS_SERIAL_SESSION,
706 	};
707 
708 	if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
709 		return PKCS11_CKR_ARGUMENTS_BAD;
710 
711 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
712 
713 	rv = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
714 	if (rv)
715 		return rv;
716 
717 	if (serialargs_remaining_bytes(&ctrlargs))
718 		return PKCS11_CKR_ARGUMENTS_BAD;
719 
720 	session = pkcs11_handle2session(session_handle, client);
721 	if (!session)
722 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
723 
724 	info.slot_id = get_token_id(session->token);
725 	info.state = session->state;
726 	if (pkcs11_session_is_read_write(session))
727 		info.flags |= PKCS11_CKFSS_RW_SESSION;
728 
729 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
730 
731 	DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
732 
733 	return PKCS11_CKR_OK;
734 }
735 
736 uint32_t entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params)
737 {
738 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
739 						TEE_PARAM_TYPE_NONE,
740 						TEE_PARAM_TYPE_NONE,
741 						TEE_PARAM_TYPE_NONE);
742 	char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 };
743 	struct pkcs11_client *client = NULL;
744 	struct pkcs11_session *sess = NULL;
745 	enum pkcs11_rc rc = PKCS11_CKR_OK;
746 	struct serialargs ctrlargs = { };
747 	struct ck_token *token = NULL;
748 	TEE_Param *ctrl = params;
749 	uint32_t token_id = 0;
750 	uint32_t pin_size = 0;
751 	void *pin = NULL;
752 
753 	if (ptypes != exp_pt)
754 		return PKCS11_CKR_ARGUMENTS_BAD;
755 
756 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
757 
758 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
759 	if (rc)
760 		return rc;
761 
762 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
763 	if (rc)
764 		return rc;
765 
766 	rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE);
767 	if (rc)
768 		return rc;
769 
770 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
771 	if (rc)
772 		return rc;
773 
774 	if (serialargs_remaining_bytes(&ctrlargs))
775 		return PKCS11_CKR_ARGUMENTS_BAD;
776 
777 	token = get_token(token_id);
778 	if (!token)
779 		return PKCS11_CKR_SLOT_ID_INVALID;
780 
781 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) {
782 		IMSG("Token %"PRIu32": SO PIN locked", token_id);
783 		return PKCS11_CKR_PIN_LOCKED;
784 	}
785 
786 	/* Check there's no open session on this token */
787 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
788 		TAILQ_FOREACH(sess, &client->session_list, link)
789 			if (sess->token == token)
790 				return PKCS11_CKR_SESSION_EXISTS;
791 
792 	if (!token->db_main->so_pin_salt) {
793 		/*
794 		 * The spec doesn't permit returning
795 		 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another
796 		 * error code.
797 		 */
798 		if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
799 		    pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
800 			return PKCS11_CKR_ARGUMENTS_BAD;
801 
802 		rc = hash_pin(PKCS11_CKU_SO, pin, pin_size,
803 			      &token->db_main->so_pin_salt,
804 			      token->db_main->so_pin_hash);
805 		if (rc)
806 			return rc;
807 
808 		update_persistent_db(token);
809 
810 		goto inited;
811 	}
812 
813 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
814 			token->db_main->so_pin_salt,
815 			token->db_main->so_pin_hash);
816 	if (rc) {
817 		unsigned int pin_count = 0;
818 
819 		if (rc != PKCS11_CKR_PIN_INCORRECT)
820 			return rc;
821 
822 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
823 		token->db_main->so_pin_count++;
824 
825 		pin_count = token->db_main->so_pin_count;
826 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
827 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
828 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
829 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
830 
831 		update_persistent_db(token);
832 
833 		return PKCS11_CKR_PIN_INCORRECT;
834 	}
835 
836 	token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
837 				   PKCS11_CKFT_SO_PIN_FINAL_TRY);
838 	token->db_main->so_pin_count = 0;
839 
840 inited:
841 	TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE);
842 	token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED;
843 	/* Reset user PIN */
844 	token->db_main->user_pin_salt = 0;
845 	token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED |
846 				   PKCS11_CKFT_USER_PIN_COUNT_LOW |
847 				   PKCS11_CKFT_USER_PIN_FINAL_TRY |
848 				   PKCS11_CKFT_USER_PIN_LOCKED |
849 				   PKCS11_CKFT_USER_PIN_TO_BE_CHANGED);
850 
851 	update_persistent_db(token);
852 
853 	IMSG("PKCS11 token %"PRIu32": initialized", token_id);
854 
855 	return PKCS11_CKR_OK;
856 }
857 
858 static enum pkcs11_rc set_pin(struct pkcs11_session *session,
859 			      uint8_t *new_pin, size_t new_pin_size,
860 			      enum pkcs11_user_type user_type)
861 {
862 	enum pkcs11_rc rc = PKCS11_CKR_OK;
863 	uint32_t flags_clear = 0;
864 	uint32_t flags_set = 0;
865 
866 	if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED)
867 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
868 
869 	if (!pkcs11_session_is_read_write(session))
870 		return PKCS11_CKR_SESSION_READ_ONLY;
871 
872 	if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
873 	    new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
874 		return PKCS11_CKR_PIN_LEN_RANGE;
875 
876 	switch (user_type) {
877 	case PKCS11_CKU_SO:
878 		rc = hash_pin(user_type, new_pin, new_pin_size,
879 			      &session->token->db_main->so_pin_salt,
880 			      session->token->db_main->so_pin_hash);
881 		if (rc)
882 			return rc;
883 		session->token->db_main->so_pin_count = 0;
884 		flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW |
885 			      PKCS11_CKFT_SO_PIN_FINAL_TRY |
886 			      PKCS11_CKFT_SO_PIN_LOCKED |
887 			      PKCS11_CKFT_SO_PIN_TO_BE_CHANGED;
888 		break;
889 	case PKCS11_CKU_USER:
890 		rc = hash_pin(user_type, new_pin, new_pin_size,
891 			      &session->token->db_main->user_pin_salt,
892 			      session->token->db_main->user_pin_hash);
893 		if (rc)
894 			return rc;
895 		session->token->db_main->user_pin_count = 0;
896 		flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW |
897 			      PKCS11_CKFT_USER_PIN_FINAL_TRY |
898 			      PKCS11_CKFT_USER_PIN_LOCKED |
899 			      PKCS11_CKFT_USER_PIN_TO_BE_CHANGED;
900 		flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED;
901 		break;
902 	default:
903 		return PKCS11_CKR_FUNCTION_FAILED;
904 	}
905 
906 	session->token->db_main->flags &= ~flags_clear;
907 	session->token->db_main->flags |= flags_set;
908 
909 	update_persistent_db(session->token);
910 
911 	return PKCS11_CKR_OK;
912 }
913 
914 uint32_t entry_ck_init_pin(struct pkcs11_client *client,
915 			   uint32_t ptypes, TEE_Param *params)
916 {
917 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
918 						TEE_PARAM_TYPE_NONE,
919 						TEE_PARAM_TYPE_NONE,
920 						TEE_PARAM_TYPE_NONE);
921 	struct pkcs11_session *session = NULL;
922 	enum pkcs11_rc rc = PKCS11_CKR_OK;
923 	struct serialargs ctrlargs = { };
924 	uint32_t session_handle = 0;
925 	TEE_Param *ctrl = params;
926 	uint32_t pin_size = 0;
927 	void *pin = NULL;
928 
929 	if (!client || ptypes != exp_pt)
930 		return PKCS11_CKR_ARGUMENTS_BAD;
931 
932 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
933 
934 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
935 	if (rc)
936 		return rc;
937 
938 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
939 	if (rc)
940 		return rc;
941 
942 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
943 	if (rc)
944 		return rc;
945 
946 	if (serialargs_remaining_bytes(&ctrlargs))
947 		return PKCS11_CKR_ARGUMENTS_BAD;
948 
949 	session = pkcs11_handle2session(session_handle, client);
950 	if (!session)
951 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
952 
953 	if (!pkcs11_session_is_so(session))
954 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
955 
956 	assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
957 
958 	IMSG("PKCS11 session %"PRIu32": init PIN", session_handle);
959 
960 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
961 }
962 
963 static uint32_t check_so_pin(struct pkcs11_session *session,
964 			     uint8_t *pin, size_t pin_size)
965 {
966 	struct ck_token *token = session->token;
967 	enum pkcs11_rc rc = PKCS11_CKR_OK;
968 
969 	assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
970 
971 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
972 		return PKCS11_CKR_PIN_LOCKED;
973 
974 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
975 			token->db_main->so_pin_salt,
976 			token->db_main->so_pin_hash);
977 	if (rc) {
978 		unsigned int pin_count = 0;
979 
980 		if (rc != PKCS11_CKR_PIN_INCORRECT)
981 			return rc;
982 
983 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
984 		token->db_main->so_pin_count++;
985 
986 		pin_count = token->db_main->so_pin_count;
987 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
988 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
989 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
990 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
991 
992 		update_persistent_db(token);
993 
994 		if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
995 			return PKCS11_CKR_PIN_LOCKED;
996 
997 		return PKCS11_CKR_PIN_INCORRECT;
998 	}
999 
1000 	if (token->db_main->so_pin_count) {
1001 		token->db_main->so_pin_count = 0;
1002 
1003 		update_persistent_db(token);
1004 	}
1005 
1006 	if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW |
1007 				     PKCS11_CKFT_SO_PIN_FINAL_TRY)) {
1008 		token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
1009 					   PKCS11_CKFT_SO_PIN_FINAL_TRY);
1010 
1011 		update_persistent_db(token);
1012 	}
1013 
1014 	return PKCS11_CKR_OK;
1015 }
1016 
1017 static uint32_t check_user_pin(struct pkcs11_session *session,
1018 			       uint8_t *pin, size_t pin_size)
1019 {
1020 	struct ck_token *token = session->token;
1021 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1022 
1023 	if (!token->db_main->user_pin_salt)
1024 		return PKCS11_CKR_USER_PIN_NOT_INITIALIZED;
1025 
1026 	if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1027 		return PKCS11_CKR_PIN_LOCKED;
1028 
1029 	rc = verify_pin(PKCS11_CKU_USER, pin, pin_size,
1030 			token->db_main->user_pin_salt,
1031 			token->db_main->user_pin_hash);
1032 	if (rc) {
1033 		unsigned int pin_count = 0;
1034 
1035 		if (rc != PKCS11_CKR_PIN_INCORRECT)
1036 			return rc;
1037 
1038 		token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW;
1039 		token->db_main->user_pin_count++;
1040 
1041 		pin_count = token->db_main->user_pin_count;
1042 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1)
1043 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY;
1044 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX)
1045 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED;
1046 
1047 		update_persistent_db(token);
1048 
1049 		if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1050 			return PKCS11_CKR_PIN_LOCKED;
1051 
1052 		return PKCS11_CKR_PIN_INCORRECT;
1053 	}
1054 
1055 	if (token->db_main->user_pin_count) {
1056 		token->db_main->user_pin_count = 0;
1057 
1058 		update_persistent_db(token);
1059 	}
1060 
1061 	if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW |
1062 				     PKCS11_CKFT_USER_PIN_FINAL_TRY)) {
1063 		token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW |
1064 					   PKCS11_CKFT_USER_PIN_FINAL_TRY);
1065 
1066 		update_persistent_db(token);
1067 	}
1068 
1069 	return PKCS11_CKR_OK;
1070 }
1071 
1072 uint32_t entry_ck_set_pin(struct pkcs11_client *client,
1073 			  uint32_t ptypes, TEE_Param *params)
1074 {
1075 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1076 						TEE_PARAM_TYPE_NONE,
1077 						TEE_PARAM_TYPE_NONE,
1078 						TEE_PARAM_TYPE_NONE);
1079 	struct pkcs11_session *session = NULL;
1080 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1081 	struct serialargs ctrlargs = { };
1082 	uint32_t session_handle = 0;
1083 	uint32_t old_pin_size = 0;
1084 	TEE_Param *ctrl = params;
1085 	uint32_t pin_size = 0;
1086 	void *old_pin = NULL;
1087 	void *pin = NULL;
1088 
1089 	if (!client || ptypes != exp_pt)
1090 		return PKCS11_CKR_ARGUMENTS_BAD;
1091 
1092 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1093 
1094 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1095 	if (rc)
1096 		return rc;
1097 
1098 	rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t));
1099 	if (rc)
1100 		return rc;
1101 
1102 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1103 	if (rc)
1104 		return rc;
1105 
1106 	rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size);
1107 	if (rc)
1108 		return rc;
1109 
1110 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1111 	if (rc)
1112 		return rc;
1113 
1114 	if (serialargs_remaining_bytes(&ctrlargs))
1115 		return PKCS11_CKR_ARGUMENTS_BAD;
1116 
1117 	session = pkcs11_handle2session(session_handle, client);
1118 	if (!session)
1119 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1120 
1121 	if (!pkcs11_session_is_read_write(session))
1122 		return PKCS11_CKR_SESSION_READ_ONLY;
1123 
1124 	if (pkcs11_session_is_so(session)) {
1125 		if (!(session->token->db_main->flags &
1126 		      PKCS11_CKFT_TOKEN_INITIALIZED))
1127 			return PKCS11_CKR_GENERAL_ERROR;
1128 
1129 		rc = check_so_pin(session, old_pin, old_pin_size);
1130 		if (rc)
1131 			return rc;
1132 
1133 		IMSG("PKCS11 session %"PRIu32": set PIN", session_handle);
1134 
1135 		return set_pin(session, pin, pin_size, PKCS11_CKU_SO);
1136 	}
1137 
1138 	if (!(session->token->db_main->flags &
1139 	      PKCS11_CKFT_USER_PIN_INITIALIZED))
1140 		return PKCS11_CKR_GENERAL_ERROR;
1141 
1142 	rc = check_user_pin(session, old_pin, old_pin_size);
1143 	if (rc)
1144 		return rc;
1145 
1146 	IMSG("PKCS11 session %"PRIu32": set PIN", session_handle);
1147 
1148 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
1149 }
1150 
1151 static void session_login_user(struct pkcs11_session *session)
1152 {
1153 	struct pkcs11_client *client = session->client;
1154 	struct pkcs11_session *sess = NULL;
1155 
1156 	TAILQ_FOREACH(sess, &client->session_list, link) {
1157 		if (sess->token != session->token)
1158 			continue;
1159 
1160 		if (pkcs11_session_is_read_write(sess))
1161 			sess->state = PKCS11_CKS_RW_USER_FUNCTIONS;
1162 		else
1163 			sess->state = PKCS11_CKS_RO_USER_FUNCTIONS;
1164 	}
1165 }
1166 
1167 static void session_login_so(struct pkcs11_session *session)
1168 {
1169 	struct pkcs11_client *client = session->client;
1170 	struct pkcs11_session *sess = NULL;
1171 
1172 	TAILQ_FOREACH(sess, &client->session_list, link) {
1173 		if (sess->token != session->token)
1174 			continue;
1175 
1176 		if (pkcs11_session_is_read_write(sess))
1177 			sess->state = PKCS11_CKS_RW_SO_FUNCTIONS;
1178 		else
1179 			TEE_Panic(0);
1180 	}
1181 }
1182 
1183 static void session_logout(struct pkcs11_session *session)
1184 {
1185 	struct pkcs11_client *client = session->client;
1186 	struct pkcs11_session *sess = NULL;
1187 
1188 	TAILQ_FOREACH(sess, &client->session_list, link) {
1189 		if (sess->token != session->token)
1190 			continue;
1191 
1192 		if (pkcs11_session_is_read_write(sess))
1193 			sess->state = PKCS11_CKS_RW_PUBLIC_SESSION;
1194 		else
1195 			sess->state = PKCS11_CKS_RO_PUBLIC_SESSION;
1196 	}
1197 }
1198 
1199 uint32_t entry_ck_login(struct pkcs11_client *client,
1200 			uint32_t ptypes, TEE_Param *params)
1201 {
1202 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1203 						TEE_PARAM_TYPE_NONE,
1204 						TEE_PARAM_TYPE_NONE,
1205 						TEE_PARAM_TYPE_NONE);
1206 	struct pkcs11_session *session = NULL;
1207 	struct pkcs11_session *sess = NULL;
1208 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1209 	struct serialargs ctrlargs = { };
1210 	uint32_t session_handle = 0;
1211 	TEE_Param *ctrl = params;
1212 	uint32_t user_type = 0;
1213 	uint32_t pin_size = 0;
1214 	void *pin = NULL;
1215 
1216 	if (!client || ptypes != exp_pt)
1217 		return PKCS11_CKR_ARGUMENTS_BAD;
1218 
1219 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1220 
1221 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1222 	if (rc)
1223 		return rc;
1224 
1225 	rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t));
1226 	if (rc)
1227 		return rc;
1228 
1229 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1230 	if (rc)
1231 		return rc;
1232 
1233 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1234 	if (rc)
1235 		return rc;
1236 
1237 	if (serialargs_remaining_bytes(&ctrlargs))
1238 		return PKCS11_CKR_ARGUMENTS_BAD;
1239 
1240 	session = pkcs11_handle2session(session_handle, client);
1241 	if (!session)
1242 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1243 
1244 	switch (user_type) {
1245 	case PKCS11_CKU_SO:
1246 		if (pkcs11_session_is_so(session))
1247 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1248 
1249 		if (pkcs11_session_is_user(session))
1250 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1251 
1252 		TAILQ_FOREACH(sess, &client->session_list, link)
1253 			if (sess->token == session->token &&
1254 			    !pkcs11_session_is_read_write(sess))
1255 				return PKCS11_CKR_SESSION_READ_ONLY_EXISTS;
1256 
1257 		/*
1258 		 * This is the point where we could check if another client
1259 		 * has another user or SO logged in.
1260 		 *
1261 		 * The spec says:
1262 		 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have
1263 		 * more distinct users simultaneously logged into the token
1264 		 * than the token and/or library permits. For example, if
1265 		 * some application has an open SO session, and another
1266 		 * application attempts to log the normal user into a
1267 		 * session, the attempt may return this error. It is not
1268 		 * required to, however. Only if the simultaneous distinct
1269 		 * users cannot be supported does C_Login have to return
1270 		 * this value. Note that this error code generalizes to
1271 		 * true multi-user tokens.
1272 		 *
1273 		 * So it's permitted to have another user or SO logged in
1274 		 * from another client.
1275 		 */
1276 
1277 		rc = check_so_pin(session, pin, pin_size);
1278 		if (!rc)
1279 			session_login_so(session);
1280 
1281 		break;
1282 
1283 	case PKCS11_CKU_USER:
1284 		if (pkcs11_session_is_so(session))
1285 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1286 
1287 		if (pkcs11_session_is_user(session))
1288 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1289 
1290 		/*
1291 		 * This is the point where we could check if another client
1292 		 * has another user or SO logged in.
1293 		 * See comment on CKR_USER_TOO_MANY_TYPES above.
1294 		 */
1295 
1296 		rc = check_user_pin(session, pin, pin_size);
1297 		if (!rc)
1298 			session_login_user(session);
1299 
1300 		break;
1301 
1302 	case PKCS11_CKU_CONTEXT_SPECIFIC:
1303 		return PKCS11_CKR_OPERATION_NOT_INITIALIZED;
1304 
1305 	default:
1306 		return PKCS11_CKR_USER_TYPE_INVALID;
1307 	}
1308 
1309 	if (!rc)
1310 		IMSG("PKCS11 session %"PRIu32": login", session_handle);
1311 
1312 	return rc;
1313 }
1314 
1315 uint32_t entry_ck_logout(struct pkcs11_client *client,
1316 			 uint32_t ptypes, TEE_Param *params)
1317 {
1318 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1319 						TEE_PARAM_TYPE_NONE,
1320 						TEE_PARAM_TYPE_NONE,
1321 						TEE_PARAM_TYPE_NONE);
1322 	struct pkcs11_session *session = NULL;
1323 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1324 	struct serialargs ctrlargs = { };
1325 	uint32_t session_handle = 0;
1326 	TEE_Param *ctrl = params;
1327 
1328 	if (!client || ptypes != exp_pt)
1329 		return PKCS11_CKR_ARGUMENTS_BAD;
1330 
1331 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1332 
1333 	rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t));
1334 	if (rc)
1335 		return rc;
1336 
1337 	if (serialargs_remaining_bytes(&ctrlargs))
1338 		return PKCS11_CKR_ARGUMENTS_BAD;
1339 
1340 	session = pkcs11_handle2session(session_handle, client);
1341 	if (!session)
1342 		return PKCS11_CKR_SESSION_HANDLE_INVALID;
1343 
1344 	if (pkcs11_session_is_public(session))
1345 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
1346 
1347 	session_logout(session);
1348 
1349 	IMSG("PKCS11 session %"PRIu32": logout", session_handle);
1350 
1351 	return PKCS11_CKR_OK;
1352 }
1353