xref: /optee_os/ta/pkcs11/src/token_capabilities.c (revision 8849c12619aee7069963595d8f85dae559daf2d8)
1*8849c126SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2*8849c126SEtienne Carriere /*
3*8849c126SEtienne Carriere  * Copyright (c) 2017-2020, Linaro Limited
4*8849c126SEtienne Carriere  */
5*8849c126SEtienne Carriere 
6*8849c126SEtienne Carriere #include <assert.h>
7*8849c126SEtienne Carriere #include <pkcs11_ta.h>
8*8849c126SEtienne Carriere #include <string.h>
9*8849c126SEtienne Carriere #include <util.h>
10*8849c126SEtienne Carriere #include <tee_api.h>
11*8849c126SEtienne Carriere #include <tee_internal_api_extensions.h>
12*8849c126SEtienne Carriere 
13*8849c126SEtienne Carriere #include "pkcs11_helpers.h"
14*8849c126SEtienne Carriere #include "token_capabilities.h"
15*8849c126SEtienne Carriere 
16*8849c126SEtienne Carriere #define ALLOWED_PKCS11_CKFM	\
17*8849c126SEtienne Carriere 	(PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT |		\
18*8849c126SEtienne Carriere 	 PKCS11_CKFM_DERIVE | PKCS11_CKFM_DIGEST |		\
19*8849c126SEtienne Carriere 	 PKCS11_CKFM_SIGN | PKCS11_CKFM_SIGN_RECOVER |		\
20*8849c126SEtienne Carriere 	 PKCS11_CKFM_VERIFY | PKCS11_CKFM_VERIFY_RECOVER |	\
21*8849c126SEtienne Carriere 	 PKCS11_CKFM_GENERATE |	PKCS11_CKFM_GENERATE_KEY_PAIR |	\
22*8849c126SEtienne Carriere 	 PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP)
23*8849c126SEtienne Carriere 
24*8849c126SEtienne Carriere /*
25*8849c126SEtienne Carriere  * Definition of supported processings for a PKCS#11 mechanisms
26*8849c126SEtienne Carriere  * @id: Mechanism ID
27*8849c126SEtienne Carriere  * @flags: Valid PKCS11_CKFM_* for a mechanism as per PKCS#11
28*8849c126SEtienne Carriere  * @one_shot: true of mechanism can be used for a one-short processing
29*8849c126SEtienne Carriere  * @string: Helper string of the mechanism ID for debug purpose
30*8849c126SEtienne Carriere  */
31*8849c126SEtienne Carriere struct pkcs11_mechachism_modes {
32*8849c126SEtienne Carriere 	uint32_t id;
33*8849c126SEtienne Carriere 	uint32_t flags;
34*8849c126SEtienne Carriere 	bool one_shot;
35*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0
36*8849c126SEtienne Carriere 	const char *string;
37*8849c126SEtienne Carriere #endif
38*8849c126SEtienne Carriere };
39*8849c126SEtienne Carriere 
40*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0
41*8849c126SEtienne Carriere #define MECHANISM(_label, _flags, _single_part)	\
42*8849c126SEtienne Carriere 	{					\
43*8849c126SEtienne Carriere 		.id = _label,			\
44*8849c126SEtienne Carriere 		.one_shot = (_single_part),	\
45*8849c126SEtienne Carriere 		.flags = (_flags),		\
46*8849c126SEtienne Carriere 		.string = #_label,		\
47*8849c126SEtienne Carriere 	}
48*8849c126SEtienne Carriere #else
49*8849c126SEtienne Carriere #define MECHANISM(_label, _flags, _single_part)	\
50*8849c126SEtienne Carriere 	{					\
51*8849c126SEtienne Carriere 		.id = _label,			\
52*8849c126SEtienne Carriere 		.one_shot = (_single_part),	\
53*8849c126SEtienne Carriere 		.flags = (_flags),		\
54*8849c126SEtienne Carriere 	}
55*8849c126SEtienne Carriere #endif
56*8849c126SEtienne Carriere 
57*8849c126SEtienne Carriere #define SINGLE_PART_ONLY	true
58*8849c126SEtienne Carriere #define ANY_PART		false
59*8849c126SEtienne Carriere 
60*8849c126SEtienne Carriere /* PKCS#11 specificies permitted operation for each mechanism  */
61*8849c126SEtienne Carriere static const struct pkcs11_mechachism_modes pkcs11_modes[] = {
62*8849c126SEtienne Carriere 	MECHANISM(PKCS11_CKM_AES_ECB,
63*8849c126SEtienne Carriere 		  PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT |
64*8849c126SEtienne Carriere 		  PKCS11_CKFM_DERIVE |
65*8849c126SEtienne Carriere 		  PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP,
66*8849c126SEtienne Carriere 		  ANY_PART),
67*8849c126SEtienne Carriere };
68*8849c126SEtienne Carriere 
69*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0
70*8849c126SEtienne Carriere const char *mechanism_string_id(enum pkcs11_mechanism_id id)
71*8849c126SEtienne Carriere {
72*8849c126SEtienne Carriere 	const size_t offset = sizeof("PKCS11_CKM_") - 1;
73*8849c126SEtienne Carriere 	size_t n = 0;
74*8849c126SEtienne Carriere 
75*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
76*8849c126SEtienne Carriere 		if (pkcs11_modes[n].id == id)
77*8849c126SEtienne Carriere 			return pkcs11_modes[n].string + offset;
78*8849c126SEtienne Carriere 
79*8849c126SEtienne Carriere 	return "Unknown ID";
80*8849c126SEtienne Carriere }
81*8849c126SEtienne Carriere #endif /*CFG_TEE_TA_LOG_LEVEL*/
82*8849c126SEtienne Carriere 
83*8849c126SEtienne Carriere /*
84*8849c126SEtienne Carriere  * Return true if @id is a valid mechanism ID
85*8849c126SEtienne Carriere  */
86*8849c126SEtienne Carriere bool mechanism_is_valid(enum pkcs11_mechanism_id id)
87*8849c126SEtienne Carriere {
88*8849c126SEtienne Carriere 	size_t n = 0;
89*8849c126SEtienne Carriere 
90*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++)
91*8849c126SEtienne Carriere 		if (id == pkcs11_modes[n].id)
92*8849c126SEtienne Carriere 			return true;
93*8849c126SEtienne Carriere 
94*8849c126SEtienne Carriere 	return false;
95*8849c126SEtienne Carriere }
96*8849c126SEtienne Carriere 
97*8849c126SEtienne Carriere /*
98*8849c126SEtienne Carriere  * Return true if mechanism ID is valid and flags matches PKCS#11 compliancy
99*8849c126SEtienne Carriere  */
100*8849c126SEtienne Carriere bool __maybe_unused mechanism_flags_complies_pkcs11(uint32_t mechanism_type,
101*8849c126SEtienne Carriere 						    uint32_t flags)
102*8849c126SEtienne Carriere {
103*8849c126SEtienne Carriere 	size_t n = 0;
104*8849c126SEtienne Carriere 
105*8849c126SEtienne Carriere 	assert((flags & ~ALLOWED_PKCS11_CKFM) == 0);
106*8849c126SEtienne Carriere 
107*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) {
108*8849c126SEtienne Carriere 		if (pkcs11_modes[n].id == mechanism_type) {
109*8849c126SEtienne Carriere 			if (flags & ~pkcs11_modes[n].flags)
110*8849c126SEtienne Carriere 				EMSG("%s flags: 0x%"PRIx32" vs 0x%"PRIx32,
111*8849c126SEtienne Carriere 				     id2str_mechanism(mechanism_type),
112*8849c126SEtienne Carriere 				     flags, pkcs11_modes[n].flags);
113*8849c126SEtienne Carriere 
114*8849c126SEtienne Carriere 			return (flags & ~pkcs11_modes[n].flags) == 0;
115*8849c126SEtienne Carriere 		}
116*8849c126SEtienne Carriere 	}
117*8849c126SEtienne Carriere 
118*8849c126SEtienne Carriere 	/* Mechanism ID unexpectedly not found */
119*8849c126SEtienne Carriere 	return false;
120*8849c126SEtienne Carriere }
121*8849c126SEtienne Carriere 
122*8849c126SEtienne Carriere /*
123*8849c126SEtienne Carriere  * Arrays that centralizes the IDs and processing flags for mechanisms
124*8849c126SEtienne Carriere  * supported by each embedded token. Currently none.
125*8849c126SEtienne Carriere  */
126*8849c126SEtienne Carriere const struct pkcs11_mechachism_modes token_mechanism[] = {
127*8849c126SEtienne Carriere 	MECHANISM(PKCS11_CKM_AES_ECB, 0, 0),
128*8849c126SEtienne Carriere };
129*8849c126SEtienne Carriere 
130*8849c126SEtienne Carriere /*
131*8849c126SEtienne Carriere  * tee_malloc_mechanism_array - Allocate and fill array of supported mechanisms
132*8849c126SEtienne Carriere  * @count: [in] [out] Pointer to number of mechanism IDs in client resource
133*8849c126SEtienne Carriere  * Return allocated array of the supported mechanism IDs
134*8849c126SEtienne Carriere  *
135*8849c126SEtienne Carriere  * Allocates array with 32bit cells mechanism IDs for the supported ones only
136*8849c126SEtienne Carriere  * if *@count covers number mechanism IDs exposed.
137*8849c126SEtienne Carriere  */
138*8849c126SEtienne Carriere uint32_t *tee_malloc_mechanism_list(size_t *out_count)
139*8849c126SEtienne Carriere {
140*8849c126SEtienne Carriere 	size_t n = 0;
141*8849c126SEtienne Carriere 	size_t count = 0;
142*8849c126SEtienne Carriere 	uint32_t *array = NULL;
143*8849c126SEtienne Carriere 
144*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++)
145*8849c126SEtienne Carriere 		if (token_mechanism[n].flags)
146*8849c126SEtienne Carriere 			count++;
147*8849c126SEtienne Carriere 
148*8849c126SEtienne Carriere 	if (*out_count >= count)
149*8849c126SEtienne Carriere 		array = TEE_Malloc(count * sizeof(*array),
150*8849c126SEtienne Carriere 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
151*8849c126SEtienne Carriere 
152*8849c126SEtienne Carriere 	*out_count = count;
153*8849c126SEtienne Carriere 
154*8849c126SEtienne Carriere 	if (!array)
155*8849c126SEtienne Carriere 		return NULL;
156*8849c126SEtienne Carriere 
157*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
158*8849c126SEtienne Carriere 		if (token_mechanism[n].flags) {
159*8849c126SEtienne Carriere 			count--;
160*8849c126SEtienne Carriere 			array[count] = token_mechanism[n].id;
161*8849c126SEtienne Carriere 		}
162*8849c126SEtienne Carriere 	}
163*8849c126SEtienne Carriere 	assert(!count);
164*8849c126SEtienne Carriere 
165*8849c126SEtienne Carriere 	return array;
166*8849c126SEtienne Carriere }
167*8849c126SEtienne Carriere 
168*8849c126SEtienne Carriere uint32_t mechanism_supported_flags(enum pkcs11_mechanism_id id)
169*8849c126SEtienne Carriere {
170*8849c126SEtienne Carriere 	size_t n = 0;
171*8849c126SEtienne Carriere 
172*8849c126SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) {
173*8849c126SEtienne Carriere 		if (id == token_mechanism[n].id) {
174*8849c126SEtienne Carriere 			uint32_t flags = token_mechanism[n].flags;
175*8849c126SEtienne Carriere 
176*8849c126SEtienne Carriere 			assert(mechanism_flags_complies_pkcs11(id, flags));
177*8849c126SEtienne Carriere 			return flags;
178*8849c126SEtienne Carriere 		}
179*8849c126SEtienne Carriere 	}
180*8849c126SEtienne Carriere 
181*8849c126SEtienne Carriere 	return 0;
182*8849c126SEtienne Carriere }
183