xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision f86aa9e1925ef129e92324b3d5e1d4c7f0a03e87)
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 enum pkcs11_rc 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 enum pkcs11_rc 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;
223 	TEE_Param *out = params + 2;
224 	enum pkcs11_rc rc = PKCS11_CKR_OK;
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 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
246 	if (rc)
247 		return rc;
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 enum pkcs11_rc 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;
272 	TEE_Param *out = params + 2;
273 	enum pkcs11_rc rc = PKCS11_CKR_OK;
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 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
300 	if (rc)
301 		return rc;
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 enum pkcs11_rc 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;
353 	TEE_Param *out = params + 2;
354 	enum pkcs11_rc rc = PKCS11_CKR_OK;
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 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
367 	if (rc)
368 		return rc;
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 rc;
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 enum pkcs11_rc 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;
422 	TEE_Param *out = params + 2;
423 	enum pkcs11_rc rc = PKCS11_CKR_OK;
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 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
436 	if (rc)
437 		return rc;
438 
439 	rc = serialargs_get(&ctrlargs, &type, sizeof(uint32_t));
440 	if (rc)
441 		return rc;
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 enum pkcs11_rc 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;
526 	TEE_Param *out = params + 2;
527 	enum pkcs11_rc rc = PKCS11_CKR_OK;
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 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
542 	if (rc)
543 		return rc;
544 
545 	rc = serialargs_get(&ctrlargs, &flags, sizeof(flags));
546 	if (rc)
547 		return rc;
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 	LIST_INIT(&session->object_list);
588 	handle_db_init(&session->object_handle_db);
589 
590 	set_session_state(client, session, readonly);
591 
592 	TAILQ_INSERT_HEAD(&client->session_list, session, link);
593 
594 	session->token->session_count++;
595 	if (!readonly)
596 		session->token->rw_session_count++;
597 
598 	TEE_MemMove(out->memref.buffer, &session->handle,
599 		    sizeof(session->handle));
600 
601 	DMSG("Open PKCS11 session %"PRIu32, session->handle);
602 
603 	return PKCS11_CKR_OK;
604 }
605 
606 static void close_ck_session(struct pkcs11_session *session)
607 {
608 	/* No need to put object handles, the whole database is destroyed */
609 	while (!LIST_EMPTY(&session->object_list))
610 		destroy_object(session,
611 			       LIST_FIRST(&session->object_list), true);
612 
613 	TAILQ_REMOVE(&session->client->session_list, session, link);
614 	handle_put(&session->client->session_handle_db, session->handle);
615 	handle_db_destroy(&session->object_handle_db);
616 
617 	session->token->session_count--;
618 	if (pkcs11_session_is_read_write(session))
619 		session->token->rw_session_count--;
620 
621 	TEE_Free(session);
622 
623 	DMSG("Close PKCS11 session %"PRIu32, session->handle);
624 }
625 
626 enum pkcs11_rc entry_ck_close_session(struct pkcs11_client *client,
627 				      uint32_t ptypes, TEE_Param *params)
628 {
629 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
630 						TEE_PARAM_TYPE_NONE,
631 						TEE_PARAM_TYPE_NONE,
632 						TEE_PARAM_TYPE_NONE);
633 	TEE_Param *ctrl = params;
634 	enum pkcs11_rc rc = PKCS11_CKR_OK;
635 	struct serialargs ctrlargs = { };
636 	struct pkcs11_session *session = NULL;
637 
638 	if (!client || ptypes != exp_pt)
639 		return PKCS11_CKR_ARGUMENTS_BAD;
640 
641 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
642 
643 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
644 	if (rc)
645 		return rc;
646 
647 	if (serialargs_remaining_bytes(&ctrlargs))
648 		return PKCS11_CKR_ARGUMENTS_BAD;
649 
650 	close_ck_session(session);
651 
652 	return PKCS11_CKR_OK;
653 }
654 
655 enum pkcs11_rc entry_ck_close_all_sessions(struct pkcs11_client *client,
656 					   uint32_t ptypes, TEE_Param *params)
657 {
658 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
659 						TEE_PARAM_TYPE_NONE,
660 						TEE_PARAM_TYPE_NONE,
661 						TEE_PARAM_TYPE_NONE);
662 	TEE_Param *ctrl = params;
663 	enum pkcs11_rc rc = PKCS11_CKR_OK;
664 	struct serialargs ctrlargs = { };
665 	uint32_t token_id = 0;
666 	struct ck_token *token = NULL;
667 	struct pkcs11_session *session = NULL;
668 	struct pkcs11_session *next = NULL;
669 
670 	if (!client || ptypes != exp_pt)
671 		return PKCS11_CKR_ARGUMENTS_BAD;
672 
673 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
674 
675 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
676 	if (rc)
677 		return rc;
678 
679 	if (serialargs_remaining_bytes(&ctrlargs))
680 		return PKCS11_CKR_ARGUMENTS_BAD;
681 
682 	token = get_token(token_id);
683 	if (!token)
684 		return PKCS11_CKR_SLOT_ID_INVALID;
685 
686 	DMSG("Close all sessions for PKCS11 token %"PRIu32, token_id);
687 
688 	TAILQ_FOREACH_SAFE(session, &client->session_list, link, next)
689 		if (session->token == token)
690 			close_ck_session(session);
691 
692 	return PKCS11_CKR_OK;
693 }
694 
695 enum pkcs11_rc entry_ck_session_info(struct pkcs11_client *client,
696 				     uint32_t ptypes, TEE_Param *params)
697 {
698 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
699 						TEE_PARAM_TYPE_NONE,
700 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
701 						TEE_PARAM_TYPE_NONE);
702 	TEE_Param *ctrl = params;
703 	TEE_Param *out = params + 2;
704 	enum pkcs11_rc rc = PKCS11_CKR_OK;
705 	struct serialargs ctrlargs = { };
706 	struct pkcs11_session *session = NULL;
707 	struct pkcs11_session_info info = {
708 		.flags = PKCS11_CKFSS_SERIAL_SESSION,
709 	};
710 
711 	if (!client || ptypes != exp_pt || out->memref.size != sizeof(info))
712 		return PKCS11_CKR_ARGUMENTS_BAD;
713 
714 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
715 
716 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
717 	if (rc)
718 		return rc;
719 
720 	if (serialargs_remaining_bytes(&ctrlargs))
721 		return PKCS11_CKR_ARGUMENTS_BAD;
722 
723 	info.slot_id = get_token_id(session->token);
724 	info.state = session->state;
725 	if (pkcs11_session_is_read_write(session))
726 		info.flags |= PKCS11_CKFSS_RW_SESSION;
727 
728 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
729 
730 	DMSG("Get find on PKCS11 session %"PRIu32, session->handle);
731 
732 	return PKCS11_CKR_OK;
733 }
734 
735 enum pkcs11_rc entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params)
736 {
737 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
738 						TEE_PARAM_TYPE_NONE,
739 						TEE_PARAM_TYPE_NONE,
740 						TEE_PARAM_TYPE_NONE);
741 	char label[PKCS11_TOKEN_LABEL_SIZE] = { 0 };
742 	struct pkcs11_client *client = NULL;
743 	struct pkcs11_session *sess = NULL;
744 	enum pkcs11_rc rc = PKCS11_CKR_OK;
745 	struct serialargs ctrlargs = { };
746 	struct ck_token *token = NULL;
747 	TEE_Param *ctrl = params;
748 	uint32_t token_id = 0;
749 	uint32_t pin_size = 0;
750 	void *pin = NULL;
751 
752 	if (ptypes != exp_pt)
753 		return PKCS11_CKR_ARGUMENTS_BAD;
754 
755 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
756 
757 	rc = serialargs_get(&ctrlargs, &token_id, sizeof(uint32_t));
758 	if (rc)
759 		return rc;
760 
761 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
762 	if (rc)
763 		return rc;
764 
765 	rc = serialargs_get(&ctrlargs, &label, PKCS11_TOKEN_LABEL_SIZE);
766 	if (rc)
767 		return rc;
768 
769 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
770 	if (rc)
771 		return rc;
772 
773 	if (serialargs_remaining_bytes(&ctrlargs))
774 		return PKCS11_CKR_ARGUMENTS_BAD;
775 
776 	token = get_token(token_id);
777 	if (!token)
778 		return PKCS11_CKR_SLOT_ID_INVALID;
779 
780 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED) {
781 		IMSG("Token %"PRIu32": SO PIN locked", token_id);
782 		return PKCS11_CKR_PIN_LOCKED;
783 	}
784 
785 	/* Check there's no open session on this token */
786 	TAILQ_FOREACH(client, &pkcs11_client_list, link)
787 		TAILQ_FOREACH(sess, &client->session_list, link)
788 			if (sess->token == token)
789 				return PKCS11_CKR_SESSION_EXISTS;
790 
791 	if (!token->db_main->so_pin_salt) {
792 		/*
793 		 * The spec doesn't permit returning
794 		 * PKCS11_CKR_PIN_LEN_RANGE for this function, take another
795 		 * error code.
796 		 */
797 		if (pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
798 		    pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
799 			return PKCS11_CKR_ARGUMENTS_BAD;
800 
801 		rc = hash_pin(PKCS11_CKU_SO, pin, pin_size,
802 			      &token->db_main->so_pin_salt,
803 			      token->db_main->so_pin_hash);
804 		if (rc)
805 			return rc;
806 
807 		update_persistent_db(token);
808 
809 		goto inited;
810 	}
811 
812 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
813 			token->db_main->so_pin_salt,
814 			token->db_main->so_pin_hash);
815 	if (rc) {
816 		unsigned int pin_count = 0;
817 
818 		if (rc != PKCS11_CKR_PIN_INCORRECT)
819 			return rc;
820 
821 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
822 		token->db_main->so_pin_count++;
823 
824 		pin_count = token->db_main->so_pin_count;
825 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
826 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
827 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
828 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
829 
830 		update_persistent_db(token);
831 
832 		return PKCS11_CKR_PIN_INCORRECT;
833 	}
834 
835 	token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
836 				   PKCS11_CKFT_SO_PIN_FINAL_TRY);
837 	token->db_main->so_pin_count = 0;
838 
839 inited:
840 	TEE_MemMove(token->db_main->label, label, PKCS11_TOKEN_LABEL_SIZE);
841 	token->db_main->flags |= PKCS11_CKFT_TOKEN_INITIALIZED;
842 	/* Reset user PIN */
843 	token->db_main->user_pin_salt = 0;
844 	token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_INITIALIZED |
845 				   PKCS11_CKFT_USER_PIN_COUNT_LOW |
846 				   PKCS11_CKFT_USER_PIN_FINAL_TRY |
847 				   PKCS11_CKFT_USER_PIN_LOCKED |
848 				   PKCS11_CKFT_USER_PIN_TO_BE_CHANGED);
849 
850 	update_persistent_db(token);
851 
852 	IMSG("PKCS11 token %"PRIu32": initialized", token_id);
853 
854 	return PKCS11_CKR_OK;
855 }
856 
857 static enum pkcs11_rc set_pin(struct pkcs11_session *session,
858 			      uint8_t *new_pin, size_t new_pin_size,
859 			      enum pkcs11_user_type user_type)
860 {
861 	enum pkcs11_rc rc = PKCS11_CKR_OK;
862 	uint32_t flags_clear = 0;
863 	uint32_t flags_set = 0;
864 
865 	if (session->token->db_main->flags & PKCS11_CKFT_WRITE_PROTECTED)
866 		return PKCS11_CKR_TOKEN_WRITE_PROTECTED;
867 
868 	if (!pkcs11_session_is_read_write(session))
869 		return PKCS11_CKR_SESSION_READ_ONLY;
870 
871 	if (new_pin_size < PKCS11_TOKEN_PIN_SIZE_MIN ||
872 	    new_pin_size > PKCS11_TOKEN_PIN_SIZE_MAX)
873 		return PKCS11_CKR_PIN_LEN_RANGE;
874 
875 	switch (user_type) {
876 	case PKCS11_CKU_SO:
877 		rc = hash_pin(user_type, new_pin, new_pin_size,
878 			      &session->token->db_main->so_pin_salt,
879 			      session->token->db_main->so_pin_hash);
880 		if (rc)
881 			return rc;
882 		session->token->db_main->so_pin_count = 0;
883 		flags_clear = PKCS11_CKFT_SO_PIN_COUNT_LOW |
884 			      PKCS11_CKFT_SO_PIN_FINAL_TRY |
885 			      PKCS11_CKFT_SO_PIN_LOCKED |
886 			      PKCS11_CKFT_SO_PIN_TO_BE_CHANGED;
887 		break;
888 	case PKCS11_CKU_USER:
889 		rc = hash_pin(user_type, new_pin, new_pin_size,
890 			      &session->token->db_main->user_pin_salt,
891 			      session->token->db_main->user_pin_hash);
892 		if (rc)
893 			return rc;
894 		session->token->db_main->user_pin_count = 0;
895 		flags_clear = PKCS11_CKFT_USER_PIN_COUNT_LOW |
896 			      PKCS11_CKFT_USER_PIN_FINAL_TRY |
897 			      PKCS11_CKFT_USER_PIN_LOCKED |
898 			      PKCS11_CKFT_USER_PIN_TO_BE_CHANGED;
899 		flags_set = PKCS11_CKFT_USER_PIN_INITIALIZED;
900 		break;
901 	default:
902 		return PKCS11_CKR_FUNCTION_FAILED;
903 	}
904 
905 	session->token->db_main->flags &= ~flags_clear;
906 	session->token->db_main->flags |= flags_set;
907 
908 	update_persistent_db(session->token);
909 
910 	return PKCS11_CKR_OK;
911 }
912 
913 enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client,
914 				 uint32_t ptypes, TEE_Param *params)
915 {
916 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
917 						TEE_PARAM_TYPE_NONE,
918 						TEE_PARAM_TYPE_NONE,
919 						TEE_PARAM_TYPE_NONE);
920 	struct pkcs11_session *session = NULL;
921 	enum pkcs11_rc rc = PKCS11_CKR_OK;
922 	struct serialargs ctrlargs = { };
923 	TEE_Param *ctrl = params;
924 	uint32_t pin_size = 0;
925 	void *pin = NULL;
926 
927 	if (!client || ptypes != exp_pt)
928 		return PKCS11_CKR_ARGUMENTS_BAD;
929 
930 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
931 
932 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
933 	if (rc)
934 		return rc;
935 
936 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
937 	if (rc)
938 		return rc;
939 
940 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
941 	if (rc)
942 		return rc;
943 
944 	if (serialargs_remaining_bytes(&ctrlargs))
945 		return PKCS11_CKR_ARGUMENTS_BAD;
946 
947 	if (!pkcs11_session_is_so(session))
948 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
949 
950 	assert(session->token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
951 
952 	IMSG("PKCS11 session %"PRIu32": init PIN", session->handle);
953 
954 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
955 }
956 
957 static enum pkcs11_rc check_so_pin(struct pkcs11_session *session,
958 				   uint8_t *pin, size_t pin_size)
959 {
960 	struct ck_token *token = session->token;
961 	enum pkcs11_rc rc = PKCS11_CKR_OK;
962 
963 	assert(token->db_main->flags & PKCS11_CKFT_TOKEN_INITIALIZED);
964 
965 	if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
966 		return PKCS11_CKR_PIN_LOCKED;
967 
968 	rc = verify_pin(PKCS11_CKU_SO, pin, pin_size,
969 			token->db_main->so_pin_salt,
970 			token->db_main->so_pin_hash);
971 	if (rc) {
972 		unsigned int pin_count = 0;
973 
974 		if (rc != PKCS11_CKR_PIN_INCORRECT)
975 			return rc;
976 
977 		token->db_main->flags |= PKCS11_CKFT_SO_PIN_COUNT_LOW;
978 		token->db_main->so_pin_count++;
979 
980 		pin_count = token->db_main->so_pin_count;
981 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX - 1)
982 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_FINAL_TRY;
983 		if (pin_count == PKCS11_TOKEN_SO_PIN_COUNT_MAX)
984 			token->db_main->flags |= PKCS11_CKFT_SO_PIN_LOCKED;
985 
986 		update_persistent_db(token);
987 
988 		if (token->db_main->flags & PKCS11_CKFT_SO_PIN_LOCKED)
989 			return PKCS11_CKR_PIN_LOCKED;
990 
991 		return PKCS11_CKR_PIN_INCORRECT;
992 	}
993 
994 	if (token->db_main->so_pin_count) {
995 		token->db_main->so_pin_count = 0;
996 
997 		update_persistent_db(token);
998 	}
999 
1000 	if (token->db_main->flags & (PKCS11_CKFT_SO_PIN_COUNT_LOW |
1001 				     PKCS11_CKFT_SO_PIN_FINAL_TRY)) {
1002 		token->db_main->flags &= ~(PKCS11_CKFT_SO_PIN_COUNT_LOW |
1003 					   PKCS11_CKFT_SO_PIN_FINAL_TRY);
1004 
1005 		update_persistent_db(token);
1006 	}
1007 
1008 	return PKCS11_CKR_OK;
1009 }
1010 
1011 static enum pkcs11_rc check_user_pin(struct pkcs11_session *session,
1012 				     uint8_t *pin, size_t pin_size)
1013 {
1014 	struct ck_token *token = session->token;
1015 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1016 
1017 	if (!token->db_main->user_pin_salt)
1018 		return PKCS11_CKR_USER_PIN_NOT_INITIALIZED;
1019 
1020 	if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1021 		return PKCS11_CKR_PIN_LOCKED;
1022 
1023 	rc = verify_pin(PKCS11_CKU_USER, pin, pin_size,
1024 			token->db_main->user_pin_salt,
1025 			token->db_main->user_pin_hash);
1026 	if (rc) {
1027 		unsigned int pin_count = 0;
1028 
1029 		if (rc != PKCS11_CKR_PIN_INCORRECT)
1030 			return rc;
1031 
1032 		token->db_main->flags |= PKCS11_CKFT_USER_PIN_COUNT_LOW;
1033 		token->db_main->user_pin_count++;
1034 
1035 		pin_count = token->db_main->user_pin_count;
1036 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX - 1)
1037 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_FINAL_TRY;
1038 		if (pin_count == PKCS11_TOKEN_USER_PIN_COUNT_MAX)
1039 			token->db_main->flags |= PKCS11_CKFT_USER_PIN_LOCKED;
1040 
1041 		update_persistent_db(token);
1042 
1043 		if (token->db_main->flags & PKCS11_CKFT_USER_PIN_LOCKED)
1044 			return PKCS11_CKR_PIN_LOCKED;
1045 
1046 		return PKCS11_CKR_PIN_INCORRECT;
1047 	}
1048 
1049 	if (token->db_main->user_pin_count) {
1050 		token->db_main->user_pin_count = 0;
1051 
1052 		update_persistent_db(token);
1053 	}
1054 
1055 	if (token->db_main->flags & (PKCS11_CKFT_USER_PIN_COUNT_LOW |
1056 				     PKCS11_CKFT_USER_PIN_FINAL_TRY)) {
1057 		token->db_main->flags &= ~(PKCS11_CKFT_USER_PIN_COUNT_LOW |
1058 					   PKCS11_CKFT_USER_PIN_FINAL_TRY);
1059 
1060 		update_persistent_db(token);
1061 	}
1062 
1063 	return PKCS11_CKR_OK;
1064 }
1065 
1066 enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client,
1067 				uint32_t ptypes, TEE_Param *params)
1068 {
1069 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1070 						TEE_PARAM_TYPE_NONE,
1071 						TEE_PARAM_TYPE_NONE,
1072 						TEE_PARAM_TYPE_NONE);
1073 	struct pkcs11_session *session = NULL;
1074 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1075 	struct serialargs ctrlargs = { };
1076 	uint32_t old_pin_size = 0;
1077 	TEE_Param *ctrl = params;
1078 	uint32_t pin_size = 0;
1079 	void *old_pin = NULL;
1080 	void *pin = NULL;
1081 
1082 	if (!client || ptypes != exp_pt)
1083 		return PKCS11_CKR_ARGUMENTS_BAD;
1084 
1085 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1086 
1087 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1088 	if (rc)
1089 		return rc;
1090 
1091 	rc = serialargs_get(&ctrlargs, &old_pin_size, sizeof(uint32_t));
1092 	if (rc)
1093 		return rc;
1094 
1095 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1096 	if (rc)
1097 		return rc;
1098 
1099 	rc = serialargs_get_ptr(&ctrlargs, &old_pin, old_pin_size);
1100 	if (rc)
1101 		return rc;
1102 
1103 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1104 	if (rc)
1105 		return rc;
1106 
1107 	if (serialargs_remaining_bytes(&ctrlargs))
1108 		return PKCS11_CKR_ARGUMENTS_BAD;
1109 
1110 	if (!pkcs11_session_is_read_write(session))
1111 		return PKCS11_CKR_SESSION_READ_ONLY;
1112 
1113 	if (pkcs11_session_is_so(session)) {
1114 		if (!(session->token->db_main->flags &
1115 		      PKCS11_CKFT_TOKEN_INITIALIZED))
1116 			return PKCS11_CKR_GENERAL_ERROR;
1117 
1118 		rc = check_so_pin(session, old_pin, old_pin_size);
1119 		if (rc)
1120 			return rc;
1121 
1122 		IMSG("PKCS11 session %"PRIu32": set PIN", session->handle);
1123 
1124 		return set_pin(session, pin, pin_size, PKCS11_CKU_SO);
1125 	}
1126 
1127 	if (!(session->token->db_main->flags &
1128 	      PKCS11_CKFT_USER_PIN_INITIALIZED))
1129 		return PKCS11_CKR_GENERAL_ERROR;
1130 
1131 	rc = check_user_pin(session, old_pin, old_pin_size);
1132 	if (rc)
1133 		return rc;
1134 
1135 	IMSG("PKCS11 session %"PRIu32": set PIN", session->handle);
1136 
1137 	return set_pin(session, pin, pin_size, PKCS11_CKU_USER);
1138 }
1139 
1140 static void session_login_user(struct pkcs11_session *session)
1141 {
1142 	struct pkcs11_client *client = session->client;
1143 	struct pkcs11_session *sess = NULL;
1144 
1145 	TAILQ_FOREACH(sess, &client->session_list, link) {
1146 		if (sess->token != session->token)
1147 			continue;
1148 
1149 		if (pkcs11_session_is_read_write(sess))
1150 			sess->state = PKCS11_CKS_RW_USER_FUNCTIONS;
1151 		else
1152 			sess->state = PKCS11_CKS_RO_USER_FUNCTIONS;
1153 	}
1154 }
1155 
1156 static void session_login_so(struct pkcs11_session *session)
1157 {
1158 	struct pkcs11_client *client = session->client;
1159 	struct pkcs11_session *sess = NULL;
1160 
1161 	TAILQ_FOREACH(sess, &client->session_list, link) {
1162 		if (sess->token != session->token)
1163 			continue;
1164 
1165 		if (pkcs11_session_is_read_write(sess))
1166 			sess->state = PKCS11_CKS_RW_SO_FUNCTIONS;
1167 		else
1168 			TEE_Panic(0);
1169 	}
1170 }
1171 
1172 static void session_logout(struct pkcs11_session *session)
1173 {
1174 	struct pkcs11_client *client = session->client;
1175 	struct pkcs11_session *sess = NULL;
1176 
1177 	TAILQ_FOREACH(sess, &client->session_list, link) {
1178 		if (sess->token != session->token)
1179 			continue;
1180 
1181 		if (pkcs11_session_is_read_write(sess))
1182 			sess->state = PKCS11_CKS_RW_PUBLIC_SESSION;
1183 		else
1184 			sess->state = PKCS11_CKS_RO_PUBLIC_SESSION;
1185 	}
1186 }
1187 
1188 enum pkcs11_rc entry_ck_login(struct pkcs11_client *client,
1189 			      uint32_t ptypes, TEE_Param *params)
1190 {
1191 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1192 						TEE_PARAM_TYPE_NONE,
1193 						TEE_PARAM_TYPE_NONE,
1194 						TEE_PARAM_TYPE_NONE);
1195 	struct pkcs11_session *session = NULL;
1196 	struct pkcs11_session *sess = NULL;
1197 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1198 	struct serialargs ctrlargs = { };
1199 	TEE_Param *ctrl = params;
1200 	uint32_t user_type = 0;
1201 	uint32_t pin_size = 0;
1202 	void *pin = NULL;
1203 
1204 	if (!client || ptypes != exp_pt)
1205 		return PKCS11_CKR_ARGUMENTS_BAD;
1206 
1207 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1208 
1209 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1210 	if (rc)
1211 		return rc;
1212 
1213 	rc = serialargs_get(&ctrlargs, &user_type, sizeof(uint32_t));
1214 	if (rc)
1215 		return rc;
1216 
1217 	rc = serialargs_get(&ctrlargs, &pin_size, sizeof(uint32_t));
1218 	if (rc)
1219 		return rc;
1220 
1221 	rc = serialargs_get_ptr(&ctrlargs, &pin, pin_size);
1222 	if (rc)
1223 		return rc;
1224 
1225 	if (serialargs_remaining_bytes(&ctrlargs))
1226 		return PKCS11_CKR_ARGUMENTS_BAD;
1227 
1228 	switch (user_type) {
1229 	case PKCS11_CKU_SO:
1230 		if (pkcs11_session_is_so(session))
1231 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1232 
1233 		if (pkcs11_session_is_user(session))
1234 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1235 
1236 		TAILQ_FOREACH(sess, &client->session_list, link)
1237 			if (sess->token == session->token &&
1238 			    !pkcs11_session_is_read_write(sess))
1239 				return PKCS11_CKR_SESSION_READ_ONLY_EXISTS;
1240 
1241 		/*
1242 		 * This is the point where we could check if another client
1243 		 * has another user or SO logged in.
1244 		 *
1245 		 * The spec says:
1246 		 * CKR_USER_TOO_MANY_TYPES: An attempt was made to have
1247 		 * more distinct users simultaneously logged into the token
1248 		 * than the token and/or library permits. For example, if
1249 		 * some application has an open SO session, and another
1250 		 * application attempts to log the normal user into a
1251 		 * session, the attempt may return this error. It is not
1252 		 * required to, however. Only if the simultaneous distinct
1253 		 * users cannot be supported does C_Login have to return
1254 		 * this value. Note that this error code generalizes to
1255 		 * true multi-user tokens.
1256 		 *
1257 		 * So it's permitted to have another user or SO logged in
1258 		 * from another client.
1259 		 */
1260 
1261 		rc = check_so_pin(session, pin, pin_size);
1262 		if (!rc)
1263 			session_login_so(session);
1264 
1265 		break;
1266 
1267 	case PKCS11_CKU_USER:
1268 		if (pkcs11_session_is_so(session))
1269 			return PKCS11_CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
1270 
1271 		if (pkcs11_session_is_user(session))
1272 			return PKCS11_CKR_USER_ALREADY_LOGGED_IN;
1273 
1274 		/*
1275 		 * This is the point where we could check if another client
1276 		 * has another user or SO logged in.
1277 		 * See comment on CKR_USER_TOO_MANY_TYPES above.
1278 		 */
1279 
1280 		rc = check_user_pin(session, pin, pin_size);
1281 		if (!rc)
1282 			session_login_user(session);
1283 
1284 		break;
1285 
1286 	case PKCS11_CKU_CONTEXT_SPECIFIC:
1287 		return PKCS11_CKR_OPERATION_NOT_INITIALIZED;
1288 
1289 	default:
1290 		return PKCS11_CKR_USER_TYPE_INVALID;
1291 	}
1292 
1293 	if (!rc)
1294 		IMSG("PKCS11 session %"PRIu32": login", session->handle);
1295 
1296 	return rc;
1297 }
1298 
1299 enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client,
1300 			       uint32_t ptypes, TEE_Param *params)
1301 {
1302 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
1303 						TEE_PARAM_TYPE_NONE,
1304 						TEE_PARAM_TYPE_NONE,
1305 						TEE_PARAM_TYPE_NONE);
1306 	struct pkcs11_session *session = NULL;
1307 	enum pkcs11_rc rc = PKCS11_CKR_OK;
1308 	struct serialargs ctrlargs = { };
1309 	TEE_Param *ctrl = params;
1310 
1311 	if (!client || ptypes != exp_pt)
1312 		return PKCS11_CKR_ARGUMENTS_BAD;
1313 
1314 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
1315 
1316 	rc = serialargs_get_session_from_handle(&ctrlargs, client, &session);
1317 	if (rc)
1318 		return rc;
1319 
1320 	if (serialargs_remaining_bytes(&ctrlargs))
1321 		return PKCS11_CKR_ARGUMENTS_BAD;
1322 
1323 	if (pkcs11_session_is_public(session))
1324 		return PKCS11_CKR_USER_NOT_LOGGED_IN;
1325 
1326 	session_logout(session);
1327 
1328 	IMSG("PKCS11 session %"PRIu32": logout", session->handle);
1329 
1330 	return PKCS11_CKR_OK;
1331 }
1332