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