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