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