xref: /optee_os/ta/pkcs11/src/pkcs11_token.c (revision e43ab7a8557a87604fc4fccc0ac03b0bcac81b83)
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 <string.h>
10 #include <string_ext.h>
11 #include <sys/queue.h>
12 #include <tee_api_types.h>
13 #include <tee_internal_api_extensions.h>
14 #include <util.h>
15 
16 #include "pkcs11_token.h"
17 #include "pkcs11_helpers.h"
18 #include "serializer.h"
19 
20 /* Provide 3 slots/tokens, ID is token index */
21 #ifndef CFG_PKCS11_TA_TOKEN_COUNT
22 #define TOKEN_COUNT		3
23 #else
24 #define TOKEN_COUNT		CFG_PKCS11_TA_TOKEN_COUNT
25 #endif
26 
27 /* Static allocation of tokens runtime instances (reset to 0 at load) */
28 struct ck_token ck_token[TOKEN_COUNT];
29 
30 struct ck_token *get_token(unsigned int token_id)
31 {
32 	if (token_id < TOKEN_COUNT)
33 		return &ck_token[confine_array_index(token_id, TOKEN_COUNT)];
34 
35 	return NULL;
36 }
37 
38 unsigned int get_token_id(struct ck_token *token)
39 {
40 	ptrdiff_t id = token - ck_token;
41 
42 	assert(id >= 0 && id < TOKEN_COUNT);
43 	return id;
44 }
45 
46 static TEE_Result pkcs11_token_init(unsigned int id)
47 {
48 	struct ck_token *token = init_persistent_db(id);
49 
50 	if (!token)
51 		return TEE_ERROR_SECURITY;
52 
53 	if (token->state == PKCS11_TOKEN_RESET) {
54 		/* As per PKCS#11 spec, token resets to read/write state */
55 		token->state = PKCS11_TOKEN_READ_WRITE;
56 		token->session_count = 0;
57 		token->rw_session_count = 0;
58 	}
59 
60 	return TEE_SUCCESS;
61 }
62 
63 TEE_Result pkcs11_init(void)
64 {
65 	unsigned int id = 0;
66 	TEE_Result ret = TEE_ERROR_GENERIC;
67 
68 	for (id = 0; id < TOKEN_COUNT; id++) {
69 		ret = pkcs11_token_init(id);
70 		if (ret)
71 			return ret;
72 	}
73 
74 	return ret;
75 }
76 
77 void pkcs11_deinit(void)
78 {
79 	unsigned int id = 0;
80 
81 	for (id = 0; id < TOKEN_COUNT; id++)
82 		close_persistent_db(get_token(id));
83 }
84 
85 uint32_t entry_ck_slot_list(uint32_t ptypes, TEE_Param *params)
86 {
87 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
88 						TEE_PARAM_TYPE_NONE,
89 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
90 						TEE_PARAM_TYPE_NONE);
91 	TEE_Param *out = &params[2];
92 	uint32_t token_id = 0;
93 	const size_t out_size = sizeof(token_id) * TOKEN_COUNT;
94 	uint8_t *id = NULL;
95 
96 	if (ptypes != exp_pt ||
97 	    params[0].memref.size != TEE_PARAM0_SIZE_MIN)
98 		return PKCS11_CKR_ARGUMENTS_BAD;
99 
100 	if (out->memref.size < out_size) {
101 		out->memref.size = out_size;
102 
103 		if (out->memref.buffer)
104 			return PKCS11_CKR_BUFFER_TOO_SMALL;
105 		else
106 			return PKCS11_CKR_OK;
107 	}
108 
109 	for (token_id = 0, id = out->memref.buffer; token_id < TOKEN_COUNT;
110 	     token_id++, id += sizeof(token_id))
111 		TEE_MemMove(id, &token_id, sizeof(token_id));
112 
113 	out->memref.size = out_size;
114 
115 	return PKCS11_CKR_OK;
116 }
117 
118 static void pad_str(uint8_t *str, size_t size)
119 {
120 	int n = strnlen((char *)str, size);
121 
122 	TEE_MemFill(str + n, ' ', size - n);
123 }
124 
125 uint32_t entry_ck_slot_info(uint32_t ptypes, TEE_Param *params)
126 {
127 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
128 						TEE_PARAM_TYPE_NONE,
129 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
130 						TEE_PARAM_TYPE_NONE);
131 	TEE_Param *ctrl = &params[0];
132 	TEE_Param *out = &params[2];
133 	uint32_t rv = 0;
134 	struct serialargs ctrlargs = { };
135 	uint32_t token_id = 0;
136 	struct ck_token *token = NULL;
137 	struct pkcs11_slot_info info = {
138 		.slot_description = PKCS11_SLOT_DESCRIPTION,
139 		.manufacturer_id = PKCS11_SLOT_MANUFACTURER,
140 		.flags = PKCS11_CKFS_TOKEN_PRESENT,
141 		.hardware_version = PKCS11_SLOT_HW_VERSION,
142 		.firmware_version = PKCS11_SLOT_FW_VERSION,
143 	};
144 
145 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_DESCRIPTION) <=
146 			    sizeof(info.slot_description));
147 	COMPILE_TIME_ASSERT(sizeof(PKCS11_SLOT_MANUFACTURER) <=
148 			    sizeof(info.manufacturer_id));
149 
150 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
151 		return PKCS11_CKR_ARGUMENTS_BAD;
152 
153 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
154 
155 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
156 	if (rv)
157 		return rv;
158 
159 	if (serialargs_remaining_bytes(&ctrlargs))
160 		return PKCS11_CKR_ARGUMENTS_BAD;
161 
162 	token = get_token(token_id);
163 	if (!token)
164 		return PKCS11_CKR_SLOT_ID_INVALID;
165 
166 	pad_str(info.slot_description, sizeof(info.slot_description));
167 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
168 
169 	out->memref.size = sizeof(info);
170 	TEE_MemMove(out->memref.buffer, &info, out->memref.size);
171 
172 	return PKCS11_CKR_OK;
173 }
174 
175 uint32_t entry_ck_token_info(uint32_t ptypes, TEE_Param *params)
176 {
177 	const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT,
178 						TEE_PARAM_TYPE_NONE,
179 						TEE_PARAM_TYPE_MEMREF_OUTPUT,
180 						TEE_PARAM_TYPE_NONE);
181 	TEE_Param *ctrl = &params[0];
182 	TEE_Param *out = &params[2];
183 	uint32_t rv = 0;
184 	struct serialargs ctrlargs = { };
185 	uint32_t token_id = 0;
186 	struct ck_token *token = NULL;
187 	struct pkcs11_token_info info = {
188 		.manufacturer_id = PKCS11_TOKEN_MANUFACTURER,
189 		.model = PKCS11_TOKEN_MODEL,
190 		.serial_number = PKCS11_TOKEN_SERIAL_NUMBER,
191 		.max_session_count = UINT32_MAX,
192 		.max_rw_session_count = UINT32_MAX,
193 		.max_pin_len = PKCS11_TOKEN_PIN_SIZE_MAX,
194 		.min_pin_len = PKCS11_TOKEN_PIN_SIZE_MIN,
195 		.total_public_memory = UINT32_MAX,
196 		.free_public_memory = UINT32_MAX,
197 		.total_private_memory = UINT32_MAX,
198 		.free_private_memory = UINT32_MAX,
199 		.hardware_version = PKCS11_TOKEN_HW_VERSION,
200 		.firmware_version = PKCS11_TOKEN_FW_VERSION,
201 	};
202 
203 	if (ptypes != exp_pt || out->memref.size != sizeof(info))
204 		return PKCS11_CKR_ARGUMENTS_BAD;
205 
206 	serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size);
207 
208 	rv = serialargs_get(&ctrlargs, &token_id, sizeof(token_id));
209 	if (rv)
210 		return rv;
211 
212 	if (serialargs_remaining_bytes(&ctrlargs))
213 		return PKCS11_CKR_ARGUMENTS_BAD;
214 
215 	token = get_token(token_id);
216 	if (!token)
217 		return PKCS11_CKR_SLOT_ID_INVALID;
218 
219 	pad_str(info.manufacturer_id, sizeof(info.manufacturer_id));
220 	pad_str(info.model, sizeof(info.model));
221 	pad_str(info.serial_number, sizeof(info.serial_number));
222 
223 	TEE_MemMove(info.label, token->db_main->label, sizeof(info.label));
224 
225 	info.flags = token->db_main->flags;
226 	info.session_count = token->session_count;
227 	info.rw_session_count = token->rw_session_count;
228 
229 	TEE_MemMove(out->memref.buffer, &info, sizeof(info));
230 
231 	return PKCS11_CKR_OK;
232 }
233