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