xref: /optee_os/ta/pkcs11/src/token_capabilities.c (revision 145ae446b961c32d566596c90d6a9e167c6591e0)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2017-2020, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <string.h>
9 #include <util.h>
10 #include <tee_api.h>
11 #include <tee_internal_api_extensions.h>
12 
13 #include "pkcs11_helpers.h"
14 #include "token_capabilities.h"
15 
16 #define ALLOWED_PKCS11_CKFM	\
17 	(PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT |		\
18 	 PKCS11_CKFM_DERIVE | PKCS11_CKFM_DIGEST |		\
19 	 PKCS11_CKFM_SIGN | PKCS11_CKFM_SIGN_RECOVER |		\
20 	 PKCS11_CKFM_VERIFY | PKCS11_CKFM_VERIFY_RECOVER |	\
21 	 PKCS11_CKFM_GENERATE |	PKCS11_CKFM_GENERATE_KEY_PAIR |	\
22 	 PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP)
23 
24 /*
25  * Definition of supported processings for a PKCS#11 mechanisms
26  * @id: Mechanism ID
27  * @flags: Valid PKCS11_CKFM_* for a mechanism as per PKCS#11
28  * @one_shot: true of mechanism can be used for a one-short processing
29  * @string: Helper string of the mechanism ID for debug purpose
30  */
31 struct pkcs11_mechachism_modes {
32 	uint32_t id;
33 	uint32_t flags;
34 	bool one_shot;
35 #if CFG_TEE_TA_LOG_LEVEL > 0
36 	const char *string;
37 #endif
38 };
39 
40 #if CFG_TEE_TA_LOG_LEVEL > 0
41 #define MECHANISM(_label, _flags, _single_part)	\
42 	{					\
43 		.id = _label,			\
44 		.one_shot = (_single_part),	\
45 		.flags = (_flags),		\
46 		.string = #_label,		\
47 	}
48 #else
49 #define MECHANISM(_label, _flags, _single_part)	\
50 	{					\
51 		.id = _label,			\
52 		.one_shot = (_single_part),	\
53 		.flags = (_flags),		\
54 	}
55 #endif
56 
57 #define SINGLE_PART_ONLY	true
58 #define ANY_PART		false
59 
60 #define CKFM_CIPHER		(PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT)
61 #define CKFM_WRAP_UNWRAP	(PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP)
62 #define CKFM_CIPHER_WRAP	(CKFM_CIPHER | CKFM_WRAP_UNWRAP)
63 #define CKFM_CIPHER_WRAP_DERIVE	(CKFM_CIPHER_WRAP | PKCS11_CKFM_DERIVE)
64 #define CKFM_AUTH_NO_RECOVER	(PKCS11_CKFM_SIGN | PKCS11_CKFM_VERIFY)
65 #define CKFM_AUTH_WITH_RECOVER	(PKCS11_CKFM_SIGN_RECOVER | \
66 				 PKCS11_CKFM_VERIFY_RECOVER)
67 
68 /* PKCS#11 specificies permitted operation for each mechanism  */
69 static const struct pkcs11_mechachism_modes pkcs11_modes[] = {
70 	/* AES */
71 	MECHANISM(PKCS11_CKM_AES_ECB, CKFM_CIPHER_WRAP, ANY_PART),
72 	MECHANISM(PKCS11_CKM_AES_CBC, CKFM_CIPHER_WRAP, ANY_PART),
73 	MECHANISM(PKCS11_CKM_AES_CBC_PAD, CKFM_CIPHER_WRAP, ANY_PART),
74 	MECHANISM(PKCS11_CKM_AES_CTS, CKFM_CIPHER_WRAP, ANY_PART),
75 	MECHANISM(PKCS11_CKM_AES_CTR, CKFM_CIPHER_WRAP, ANY_PART),
76 	MECHANISM(PKCS11_CKM_AES_ECB_ENCRYPT_DATA, PKCS11_CKFM_DERIVE,
77 		  ANY_PART),
78 	MECHANISM(PKCS11_CKM_AES_CBC_ENCRYPT_DATA, PKCS11_CKFM_DERIVE,
79 		  ANY_PART),
80 	MECHANISM(PKCS11_CKM_AES_KEY_GEN, PKCS11_CKFM_GENERATE, ANY_PART),
81 	/* HMAC */
82 	MECHANISM(PKCS11_CKM_MD5_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
83 	MECHANISM(PKCS11_CKM_SHA_1_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
84 	MECHANISM(PKCS11_CKM_SHA224_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
85 	MECHANISM(PKCS11_CKM_SHA256_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
86 	MECHANISM(PKCS11_CKM_SHA384_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
87 	MECHANISM(PKCS11_CKM_SHA512_HMAC, CKFM_AUTH_NO_RECOVER, ANY_PART),
88 };
89 
90 #if CFG_TEE_TA_LOG_LEVEL > 0
91 const char *mechanism_string_id(enum pkcs11_mechanism_id id)
92 {
93 	const size_t offset = sizeof("PKCS11_CKM_") - 1;
94 	size_t n = 0;
95 
96 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
97 		if (pkcs11_modes[n].id == id)
98 			return pkcs11_modes[n].string + offset;
99 
100 	return "Unknown ID";
101 }
102 #endif /*CFG_TEE_TA_LOG_LEVEL*/
103 
104 /*
105  * Return true if @id is a valid mechanism ID
106  */
107 bool mechanism_is_valid(enum pkcs11_mechanism_id id)
108 {
109 	size_t n = 0;
110 
111 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
112 		if (id == pkcs11_modes[n].id)
113 			return true;
114 
115 	return false;
116 }
117 
118 /*
119  * Return true if mechanism ID is valid and flags matches PKCS#11 compliancy
120  */
121 bool __maybe_unused mechanism_flags_complies_pkcs11(uint32_t mechanism_type,
122 						    uint32_t flags)
123 {
124 	size_t n = 0;
125 
126 	assert((flags & ~ALLOWED_PKCS11_CKFM) == 0);
127 
128 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) {
129 		if (pkcs11_modes[n].id == mechanism_type) {
130 			if (flags & ~pkcs11_modes[n].flags)
131 				EMSG("%s flags: 0x%"PRIx32" vs 0x%"PRIx32,
132 				     id2str_mechanism(mechanism_type),
133 				     flags, pkcs11_modes[n].flags);
134 
135 			return (flags & ~pkcs11_modes[n].flags) == 0;
136 		}
137 	}
138 
139 	/* Mechanism ID unexpectedly not found */
140 	return false;
141 }
142 
143 bool mechanism_is_one_shot_only(uint32_t mechanism_type)
144 {
145 	size_t n = 0;
146 
147 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
148 		if (pkcs11_modes[n].id == mechanism_type)
149 			return pkcs11_modes[n].one_shot;
150 
151 	/* Mechanism ID unexpectedly not found */
152 	TEE_Panic(PKCS11_RV_NOT_FOUND);
153 	/* Dummy return to keep compiler happy */
154 	return false;
155 }
156 
157 /*
158  * Field single_part_only is unused from array token_mechanism[], hence
159  * simply use ANY_PART for all mechanism there.
160  */
161 #define TA_MECHANISM(_label, _flags)	MECHANISM((_label), (_flags), ANY_PART)
162 
163 /*
164  * Arrays that centralizes the IDs and processing flags for mechanisms
165  * supported by each embedded token. Currently none.
166  */
167 const struct pkcs11_mechachism_modes token_mechanism[] = {
168 	TA_MECHANISM(PKCS11_CKM_AES_ECB, CKFM_CIPHER),
169 	TA_MECHANISM(PKCS11_CKM_AES_CBC, CKFM_CIPHER),
170 	TA_MECHANISM(PKCS11_CKM_AES_CBC_PAD, CKFM_CIPHER),
171 	TA_MECHANISM(PKCS11_CKM_AES_CTR, CKFM_CIPHER),
172 	TA_MECHANISM(PKCS11_CKM_AES_CTS, CKFM_CIPHER),
173 	TA_MECHANISM(PKCS11_CKM_AES_ECB_ENCRYPT_DATA, PKCS11_CKFM_DERIVE),
174 	TA_MECHANISM(PKCS11_CKM_AES_CBC_ENCRYPT_DATA, PKCS11_CKFM_DERIVE),
175 	TA_MECHANISM(PKCS11_CKM_MD5_HMAC, CKFM_AUTH_NO_RECOVER),
176 	TA_MECHANISM(PKCS11_CKM_SHA_1_HMAC, CKFM_AUTH_NO_RECOVER),
177 	TA_MECHANISM(PKCS11_CKM_SHA224_HMAC, CKFM_AUTH_NO_RECOVER),
178 	TA_MECHANISM(PKCS11_CKM_SHA256_HMAC, CKFM_AUTH_NO_RECOVER),
179 	TA_MECHANISM(PKCS11_CKM_SHA384_HMAC, CKFM_AUTH_NO_RECOVER),
180 	TA_MECHANISM(PKCS11_CKM_SHA512_HMAC, CKFM_AUTH_NO_RECOVER),
181 };
182 
183 /*
184  * tee_malloc_mechanism_array - Allocate and fill array of supported mechanisms
185  * @count: [in] [out] Pointer to number of mechanism IDs in client resource
186  * Return allocated array of the supported mechanism IDs
187  *
188  * Allocates array with 32bit cells mechanism IDs for the supported ones only
189  * if *@count covers number mechanism IDs exposed.
190  */
191 uint32_t *tee_malloc_mechanism_list(size_t *out_count)
192 {
193 	size_t n = 0;
194 	size_t count = 0;
195 	uint32_t *array = NULL;
196 
197 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++)
198 		if (token_mechanism[n].flags)
199 			count++;
200 
201 	if (*out_count >= count)
202 		array = TEE_Malloc(count * sizeof(*array),
203 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
204 
205 	*out_count = count;
206 
207 	if (!array)
208 		return NULL;
209 
210 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
211 		if (token_mechanism[n].flags) {
212 			count--;
213 			array[count] = token_mechanism[n].id;
214 		}
215 	}
216 	assert(!count);
217 
218 	return array;
219 }
220 
221 uint32_t mechanism_supported_flags(enum pkcs11_mechanism_id id)
222 {
223 	size_t n = 0;
224 
225 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
226 		if (id == token_mechanism[n].id) {
227 			uint32_t flags = token_mechanism[n].flags;
228 
229 			assert(mechanism_flags_complies_pkcs11(id, flags));
230 			return flags;
231 		}
232 	}
233 
234 	return 0;
235 }
236 
237 void mechanism_supported_key_sizes(uint32_t proc_id, uint32_t *min_key_size,
238 				   uint32_t *max_key_size)
239 {
240 	switch (proc_id) {
241 	case PKCS11_CKM_MD5_HMAC:
242 		*min_key_size = 8;
243 		*max_key_size = 64;
244 		break;
245 	case PKCS11_CKM_SHA_1_HMAC:
246 		*min_key_size = 10;
247 		*max_key_size = 64;
248 		break;
249 	case PKCS11_CKM_SHA224_HMAC:
250 		*min_key_size = 14;
251 		*max_key_size = 64;
252 		break;
253 	case PKCS11_CKM_SHA256_HMAC:
254 		*min_key_size = 24;
255 		*max_key_size = 128;
256 		break;
257 	case PKCS11_CKM_SHA384_HMAC:
258 		*min_key_size = 32;
259 		*max_key_size = 128;
260 		break;
261 	case PKCS11_CKM_SHA512_HMAC:
262 		*min_key_size = 32;
263 		*max_key_size = 128;
264 		break;
265 	case PKCS11_CKM_AES_KEY_GEN:
266 	case PKCS11_CKM_AES_ECB:
267 	case PKCS11_CKM_AES_CBC:
268 	case PKCS11_CKM_AES_CBC_PAD:
269 	case PKCS11_CKM_AES_CTR:
270 	case PKCS11_CKM_AES_CTS:
271 		*min_key_size = 16;
272 		*max_key_size = 32;
273 		break;
274 	default:
275 		*min_key_size = 0;
276 		*max_key_size = 0;
277 		break;
278 	}
279 }
280