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