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