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