xref: /optee_os/ta/pkcs11/src/pkcs11_attributes.c (revision 63f89caa9022ecf51d1b82dc78af35ba9e38466d)
1*63f89caaSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2*63f89caaSJens Wiklander /*
3*63f89caaSJens Wiklander  * Copyright (c) 2017-2020, Linaro Limited
4*63f89caaSJens Wiklander  */
5*63f89caaSJens Wiklander 
6*63f89caaSJens Wiklander #include <assert.h>
7*63f89caaSJens Wiklander #include <inttypes.h>
8*63f89caaSJens Wiklander #include <pkcs11_ta.h>
9*63f89caaSJens Wiklander #include <stdlib.h>
10*63f89caaSJens Wiklander #include <string_ext.h>
11*63f89caaSJens Wiklander #include <tee_internal_api_extensions.h>
12*63f89caaSJens Wiklander #include <tee_internal_api.h>
13*63f89caaSJens Wiklander #include <util.h>
14*63f89caaSJens Wiklander 
15*63f89caaSJens Wiklander #include "attributes.h"
16*63f89caaSJens Wiklander #include "handle.h"
17*63f89caaSJens Wiklander #include "pkcs11_attributes.h"
18*63f89caaSJens Wiklander #include "pkcs11_helpers.h"
19*63f89caaSJens Wiklander #include "pkcs11_token.h"
20*63f89caaSJens Wiklander #include "sanitize_object.h"
21*63f89caaSJens Wiklander #include "serializer.h"
22*63f89caaSJens Wiklander #include "token_capabilities.h"
23*63f89caaSJens Wiklander 
24*63f89caaSJens Wiklander /* Byte size of CKA_ID attribute when generated locally */
25*63f89caaSJens Wiklander #define PKCS11_CKA_DEFAULT_SIZE		16
26*63f89caaSJens Wiklander 
27*63f89caaSJens Wiklander /*
28*63f89caaSJens Wiklander  * Object default boolean attributes as per PKCS#11
29*63f89caaSJens Wiklander  */
30*63f89caaSJens Wiklander static uint8_t *pkcs11_object_default_boolprop(uint32_t attribute)
31*63f89caaSJens Wiklander {
32*63f89caaSJens Wiklander 	static const uint8_t bool_true = 1;
33*63f89caaSJens Wiklander 	static const uint8_t bool_false;
34*63f89caaSJens Wiklander 
35*63f89caaSJens Wiklander 	switch (attribute) {
36*63f89caaSJens Wiklander 	/* As per PKCS#11 default value */
37*63f89caaSJens Wiklander 	case PKCS11_CKA_MODIFIABLE:
38*63f89caaSJens Wiklander 	case PKCS11_CKA_COPYABLE:
39*63f89caaSJens Wiklander 	case PKCS11_CKA_DESTROYABLE:
40*63f89caaSJens Wiklander 		return (uint8_t *)&bool_true;
41*63f89caaSJens Wiklander 	case PKCS11_CKA_TOKEN:
42*63f89caaSJens Wiklander 	case PKCS11_CKA_PRIVATE:
43*63f89caaSJens Wiklander 	/* symkey false, privkey: token specific */
44*63f89caaSJens Wiklander 	case PKCS11_CKA_SENSITIVE:
45*63f89caaSJens Wiklander 		return (uint8_t *)&bool_false;
46*63f89caaSJens Wiklander 	/* Token specific default value */
47*63f89caaSJens Wiklander 	case PKCS11_CKA_SIGN:
48*63f89caaSJens Wiklander 	case PKCS11_CKA_VERIFY:
49*63f89caaSJens Wiklander 		return (uint8_t *)&bool_true;
50*63f89caaSJens Wiklander 	case PKCS11_CKA_DERIVE:
51*63f89caaSJens Wiklander 	case PKCS11_CKA_ENCRYPT:
52*63f89caaSJens Wiklander 	case PKCS11_CKA_DECRYPT:
53*63f89caaSJens Wiklander 	case PKCS11_CKA_SIGN_RECOVER:
54*63f89caaSJens Wiklander 	case PKCS11_CKA_VERIFY_RECOVER:
55*63f89caaSJens Wiklander 	case PKCS11_CKA_WRAP:
56*63f89caaSJens Wiklander 	case PKCS11_CKA_UNWRAP:
57*63f89caaSJens Wiklander 	case PKCS11_CKA_EXTRACTABLE:
58*63f89caaSJens Wiklander 	case PKCS11_CKA_WRAP_WITH_TRUSTED:
59*63f89caaSJens Wiklander 	case PKCS11_CKA_ALWAYS_AUTHENTICATE:
60*63f89caaSJens Wiklander 	case PKCS11_CKA_TRUSTED:
61*63f89caaSJens Wiklander 		return (uint8_t *)&bool_false;
62*63f89caaSJens Wiklander 	default:
63*63f89caaSJens Wiklander 		DMSG("No default for boolprop attribute %#"PRIx32, attribute);
64*63f89caaSJens Wiklander 		return NULL;
65*63f89caaSJens Wiklander 	}
66*63f89caaSJens Wiklander }
67*63f89caaSJens Wiklander 
68*63f89caaSJens Wiklander /*
69*63f89caaSJens Wiklander  * Object expects several boolean attributes to be set to a default value
70*63f89caaSJens Wiklander  * or to a validate client configuration value. This function append the input
71*63f89caaSJens Wiklander  * attribute (id/size/value) in the serialized object.
72*63f89caaSJens Wiklander  */
73*63f89caaSJens Wiklander static enum pkcs11_rc pkcs11_import_object_boolprop(struct obj_attrs **out,
74*63f89caaSJens Wiklander 						    struct obj_attrs *templ,
75*63f89caaSJens Wiklander 						    uint32_t attribute)
76*63f89caaSJens Wiklander {
77*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
78*63f89caaSJens Wiklander 	uint8_t bbool = 0;
79*63f89caaSJens Wiklander 	uint32_t size = sizeof(uint8_t);
80*63f89caaSJens Wiklander 	void *attr = NULL;
81*63f89caaSJens Wiklander 
82*63f89caaSJens Wiklander 	rc = get_attribute(templ, attribute, &bbool, &size);
83*63f89caaSJens Wiklander 	if (rc) {
84*63f89caaSJens Wiklander 		if (rc != PKCS11_RV_NOT_FOUND)
85*63f89caaSJens Wiklander 			return rc;
86*63f89caaSJens Wiklander 		attr = pkcs11_object_default_boolprop(attribute);
87*63f89caaSJens Wiklander 		if (!attr)
88*63f89caaSJens Wiklander 			return PKCS11_CKR_TEMPLATE_INCOMPLETE;
89*63f89caaSJens Wiklander 	} else {
90*63f89caaSJens Wiklander 		attr = &bbool;
91*63f89caaSJens Wiklander 	}
92*63f89caaSJens Wiklander 
93*63f89caaSJens Wiklander 	/* Boolean attributes are 1byte in the ABI, no alignment issue */
94*63f89caaSJens Wiklander 	return add_attribute(out, attribute, attr, sizeof(uint8_t));
95*63f89caaSJens Wiklander }
96*63f89caaSJens Wiklander 
97*63f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_boolprops(struct obj_attrs **out,
98*63f89caaSJens Wiklander 					      struct obj_attrs *temp,
99*63f89caaSJens Wiklander 					      uint32_t const *bp,
100*63f89caaSJens Wiklander 					      size_t bp_count)
101*63f89caaSJens Wiklander {
102*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
103*63f89caaSJens Wiklander 	size_t n = 0;
104*63f89caaSJens Wiklander 
105*63f89caaSJens Wiklander 	for (n = 0; n < bp_count; n++) {
106*63f89caaSJens Wiklander 		rc = pkcs11_import_object_boolprop(out, temp, bp[n]);
107*63f89caaSJens Wiklander 		if (rc)
108*63f89caaSJens Wiklander 			return rc;
109*63f89caaSJens Wiklander 	}
110*63f89caaSJens Wiklander 
111*63f89caaSJens Wiklander 	return rc;
112*63f89caaSJens Wiklander }
113*63f89caaSJens Wiklander 
114*63f89caaSJens Wiklander static enum pkcs11_rc set_mandatory_attributes(struct obj_attrs **out,
115*63f89caaSJens Wiklander 					       struct obj_attrs *temp,
116*63f89caaSJens Wiklander 					       uint32_t const *bp,
117*63f89caaSJens Wiklander 					       size_t bp_count)
118*63f89caaSJens Wiklander {
119*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
120*63f89caaSJens Wiklander 	size_t n = 0;
121*63f89caaSJens Wiklander 
122*63f89caaSJens Wiklander 	for (n = 0; n < bp_count; n++) {
123*63f89caaSJens Wiklander 		uint32_t size = 0;
124*63f89caaSJens Wiklander 		void *value = NULL;
125*63f89caaSJens Wiklander 
126*63f89caaSJens Wiklander 		if (get_attribute_ptr(temp, bp[n], &value, &size))
127*63f89caaSJens Wiklander 			return PKCS11_CKR_TEMPLATE_INCOMPLETE;
128*63f89caaSJens Wiklander 
129*63f89caaSJens Wiklander 		rc = add_attribute(out, bp[n], value, size);
130*63f89caaSJens Wiklander 		if (rc)
131*63f89caaSJens Wiklander 			return rc;
132*63f89caaSJens Wiklander 	}
133*63f89caaSJens Wiklander 
134*63f89caaSJens Wiklander 	return rc;
135*63f89caaSJens Wiklander }
136*63f89caaSJens Wiklander 
137*63f89caaSJens Wiklander static enum pkcs11_rc get_default_value(enum pkcs11_attr_id id, void **value,
138*63f89caaSJens Wiklander 					uint32_t *size)
139*63f89caaSJens Wiklander {
140*63f89caaSJens Wiklander 	/* should have been taken care of already */
141*63f89caaSJens Wiklander 	assert(!pkcs11_attr_is_boolean(id));
142*63f89caaSJens Wiklander 
143*63f89caaSJens Wiklander 	if (id == PKCS11_CKA_PUBLIC_KEY_INFO) {
144*63f89caaSJens Wiklander 		EMSG("Cannot provide default PUBLIC_KEY_INFO");
145*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
146*63f89caaSJens Wiklander 	}
147*63f89caaSJens Wiklander 
148*63f89caaSJens Wiklander 	/* All other attributes have an empty default value */
149*63f89caaSJens Wiklander 	*value = NULL;
150*63f89caaSJens Wiklander 	*size = 0;
151*63f89caaSJens Wiklander 	return PKCS11_CKR_OK;
152*63f89caaSJens Wiklander }
153*63f89caaSJens Wiklander 
154*63f89caaSJens Wiklander static enum pkcs11_rc set_optional_attributes(struct obj_attrs **out,
155*63f89caaSJens Wiklander 					      struct obj_attrs *temp,
156*63f89caaSJens Wiklander 					      uint32_t const *bp,
157*63f89caaSJens Wiklander 					      size_t bp_count)
158*63f89caaSJens Wiklander {
159*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
160*63f89caaSJens Wiklander 	size_t n = 0;
161*63f89caaSJens Wiklander 
162*63f89caaSJens Wiklander 	for (n = 0; n < bp_count; n++) {
163*63f89caaSJens Wiklander 		uint32_t size = 0;
164*63f89caaSJens Wiklander 		void *value = NULL;
165*63f89caaSJens Wiklander 
166*63f89caaSJens Wiklander 		rc = get_attribute_ptr(temp, bp[n], &value, &size);
167*63f89caaSJens Wiklander 		if (rc == PKCS11_RV_NOT_FOUND)
168*63f89caaSJens Wiklander 			rc = get_default_value(bp[n], &value, &size);
169*63f89caaSJens Wiklander 		if (rc)
170*63f89caaSJens Wiklander 			return rc;
171*63f89caaSJens Wiklander 
172*63f89caaSJens Wiklander 		rc = add_attribute(out, bp[n], value, size);
173*63f89caaSJens Wiklander 		if (rc)
174*63f89caaSJens Wiklander 			return rc;
175*63f89caaSJens Wiklander 	}
176*63f89caaSJens Wiklander 
177*63f89caaSJens Wiklander 	return rc;
178*63f89caaSJens Wiklander }
179*63f89caaSJens Wiklander 
180*63f89caaSJens Wiklander /*
181*63f89caaSJens Wiklander  * Below are listed the mandated or optional expected attributes for
182*63f89caaSJens Wiklander  * PKCS#11 storage objects.
183*63f89caaSJens Wiklander  *
184*63f89caaSJens Wiklander  * Note: boolprops (mandated boolean attributes) PKCS11_CKA_ALWAYS_SENSITIVE,
185*63f89caaSJens Wiklander  * and PKCS11_CKA_NEVER_EXTRACTABLE are set by the token, not provided
186*63f89caaSJens Wiklander  * in the client template.
187*63f89caaSJens Wiklander  */
188*63f89caaSJens Wiklander 
189*63f89caaSJens Wiklander /* PKCS#11 specification for any object (session/token) of the storage */
190*63f89caaSJens Wiklander static const uint32_t pkcs11_any_object_boolprops[] = {
191*63f89caaSJens Wiklander 	PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE,
192*63f89caaSJens Wiklander 	PKCS11_CKA_MODIFIABLE, PKCS11_CKA_COPYABLE, PKCS11_CKA_DESTROYABLE,
193*63f89caaSJens Wiklander };
194*63f89caaSJens Wiklander 
195*63f89caaSJens Wiklander static const uint32_t pkcs11_any_object_optional[] = {
196*63f89caaSJens Wiklander 	PKCS11_CKA_LABEL,
197*63f89caaSJens Wiklander };
198*63f89caaSJens Wiklander 
199*63f89caaSJens Wiklander /* PKCS#11 specification for raw data object (+pkcs11_any_object_xxx) */
200*63f89caaSJens Wiklander const uint32_t pkcs11_raw_data_optional[] = {
201*63f89caaSJens Wiklander 	PKCS11_CKA_OBJECT_ID, PKCS11_CKA_APPLICATION, PKCS11_CKA_VALUE,
202*63f89caaSJens Wiklander };
203*63f89caaSJens Wiklander 
204*63f89caaSJens Wiklander /* PKCS#11 specification for any key object (+pkcs11_any_object_xxx) */
205*63f89caaSJens Wiklander static const uint32_t pkcs11_any_key_boolprops[] = {
206*63f89caaSJens Wiklander 	PKCS11_CKA_DERIVE,
207*63f89caaSJens Wiklander };
208*63f89caaSJens Wiklander 
209*63f89caaSJens Wiklander static const uint32_t pkcs11_any_key_optional[] = {
210*63f89caaSJens Wiklander 	PKCS11_CKA_ID,
211*63f89caaSJens Wiklander 	PKCS11_CKA_START_DATE, PKCS11_CKA_END_DATE,
212*63f89caaSJens Wiklander 	PKCS11_CKA_ALLOWED_MECHANISMS,
213*63f89caaSJens Wiklander };
214*63f89caaSJens Wiklander 
215*63f89caaSJens Wiklander /* PKCS#11 specification for any symmetric key (+pkcs11_any_key_xxx) */
216*63f89caaSJens Wiklander static const uint32_t pkcs11_symm_key_boolprops[] = {
217*63f89caaSJens Wiklander 	PKCS11_CKA_ENCRYPT, PKCS11_CKA_DECRYPT,
218*63f89caaSJens Wiklander 	PKCS11_CKA_SIGN, PKCS11_CKA_VERIFY,
219*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP, PKCS11_CKA_UNWRAP,
220*63f89caaSJens Wiklander 	PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE,
221*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_TRUSTED,
222*63f89caaSJens Wiklander };
223*63f89caaSJens Wiklander 
224*63f89caaSJens Wiklander static const uint32_t pkcs11_symm_key_optional[] = {
225*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_UNWRAP_TEMPLATE,
226*63f89caaSJens Wiklander 	PKCS11_CKA_DERIVE_TEMPLATE,
227*63f89caaSJens Wiklander 	PKCS11_CKA_VALUE, PKCS11_CKA_VALUE_LEN,
228*63f89caaSJens Wiklander };
229*63f89caaSJens Wiklander 
230*63f89caaSJens Wiklander /* PKCS#11 specification for any asymmetric public key (+pkcs11_any_key_xxx) */
231*63f89caaSJens Wiklander static const uint32_t pkcs11_public_key_boolprops[] = {
232*63f89caaSJens Wiklander 	PKCS11_CKA_ENCRYPT, PKCS11_CKA_VERIFY, PKCS11_CKA_VERIFY_RECOVER,
233*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP,
234*63f89caaSJens Wiklander 	PKCS11_CKA_TRUSTED,
235*63f89caaSJens Wiklander };
236*63f89caaSJens Wiklander 
237*63f89caaSJens Wiklander static const uint32_t pkcs11_public_key_mandated[] = {
238*63f89caaSJens Wiklander 	PKCS11_CKA_SUBJECT
239*63f89caaSJens Wiklander };
240*63f89caaSJens Wiklander 
241*63f89caaSJens Wiklander static const uint32_t pkcs11_public_key_optional[] = {
242*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP_TEMPLATE, PKCS11_CKA_PUBLIC_KEY_INFO,
243*63f89caaSJens Wiklander };
244*63f89caaSJens Wiklander 
245*63f89caaSJens Wiklander /* PKCS#11 specification for any asymmetric private key (+pkcs11_any_key_xxx) */
246*63f89caaSJens Wiklander static const uint32_t pkcs11_private_key_boolprops[] = {
247*63f89caaSJens Wiklander 	PKCS11_CKA_DECRYPT, PKCS11_CKA_SIGN, PKCS11_CKA_SIGN_RECOVER,
248*63f89caaSJens Wiklander 	PKCS11_CKA_UNWRAP,
249*63f89caaSJens Wiklander 	PKCS11_CKA_SENSITIVE, PKCS11_CKA_EXTRACTABLE,
250*63f89caaSJens Wiklander 	PKCS11_CKA_WRAP_WITH_TRUSTED, PKCS11_CKA_ALWAYS_AUTHENTICATE,
251*63f89caaSJens Wiklander };
252*63f89caaSJens Wiklander 
253*63f89caaSJens Wiklander static const uint32_t pkcs11_private_key_mandated[] = {
254*63f89caaSJens Wiklander 	PKCS11_CKA_SUBJECT
255*63f89caaSJens Wiklander };
256*63f89caaSJens Wiklander 
257*63f89caaSJens Wiklander static const uint32_t pkcs11_private_key_optional[] = {
258*63f89caaSJens Wiklander 	PKCS11_CKA_UNWRAP_TEMPLATE, PKCS11_CKA_PUBLIC_KEY_INFO,
259*63f89caaSJens Wiklander };
260*63f89caaSJens Wiklander 
261*63f89caaSJens Wiklander /* PKCS#11 specification for any RSA key (+pkcs11_public/private_key_xxx) */
262*63f89caaSJens Wiklander static const uint32_t pkcs11_rsa_public_key_mandated[] = {
263*63f89caaSJens Wiklander 	PKCS11_CKA_MODULUS_BITS,
264*63f89caaSJens Wiklander };
265*63f89caaSJens Wiklander 
266*63f89caaSJens Wiklander static const uint32_t pkcs11_rsa_public_key_optional[] = {
267*63f89caaSJens Wiklander 	PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT,
268*63f89caaSJens Wiklander };
269*63f89caaSJens Wiklander 
270*63f89caaSJens Wiklander static const uint32_t pkcs11_rsa_private_key_optional[] = {
271*63f89caaSJens Wiklander 	PKCS11_CKA_MODULUS, PKCS11_CKA_PUBLIC_EXPONENT,
272*63f89caaSJens Wiklander 	PKCS11_CKA_PRIVATE_EXPONENT,
273*63f89caaSJens Wiklander 	PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2,
274*63f89caaSJens Wiklander 	PKCS11_CKA_EXPONENT_1, PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT,
275*63f89caaSJens Wiklander };
276*63f89caaSJens Wiklander 
277*63f89caaSJens Wiklander /* PKCS#11 specification for any EC key (+pkcs11_public/private_key_xxx) */
278*63f89caaSJens Wiklander static const uint32_t pkcs11_ec_public_key_mandated[] = {
279*63f89caaSJens Wiklander 	PKCS11_CKA_EC_PARAMS,
280*63f89caaSJens Wiklander };
281*63f89caaSJens Wiklander 
282*63f89caaSJens Wiklander static const uint32_t pkcs11_ec_public_key_optional[] = {
283*63f89caaSJens Wiklander 	PKCS11_CKA_EC_POINT,
284*63f89caaSJens Wiklander };
285*63f89caaSJens Wiklander 
286*63f89caaSJens Wiklander static const uint32_t pkcs11_ec_private_key_mandated[] = {
287*63f89caaSJens Wiklander 	PKCS11_CKA_EC_PARAMS,
288*63f89caaSJens Wiklander };
289*63f89caaSJens Wiklander 
290*63f89caaSJens Wiklander static const uint32_t pkcs11_ec_private_key_optional[] = {
291*63f89caaSJens Wiklander 	PKCS11_CKA_VALUE,
292*63f89caaSJens Wiklander };
293*63f89caaSJens Wiklander 
294*63f89caaSJens Wiklander static enum pkcs11_rc create_storage_attributes(struct obj_attrs **out,
295*63f89caaSJens Wiklander 						struct obj_attrs *temp)
296*63f89caaSJens Wiklander {
297*63f89caaSJens Wiklander 	enum pkcs11_class_id class = PKCS11_CKO_UNDEFINED_ID;
298*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
299*63f89caaSJens Wiklander 
300*63f89caaSJens Wiklander 	rc = init_attributes_head(out);
301*63f89caaSJens Wiklander 	if (rc)
302*63f89caaSJens Wiklander 		return rc;
303*63f89caaSJens Wiklander 
304*63f89caaSJens Wiklander 	/* Object class is mandatory */
305*63f89caaSJens Wiklander 	class = get_class(temp);
306*63f89caaSJens Wiklander 	if (class == PKCS11_CKO_UNDEFINED_ID) {
307*63f89caaSJens Wiklander 		EMSG("Class attribute not found");
308*63f89caaSJens Wiklander 
309*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
310*63f89caaSJens Wiklander 	}
311*63f89caaSJens Wiklander 	rc = add_attribute(out, PKCS11_CKA_CLASS, &class, sizeof(uint32_t));
312*63f89caaSJens Wiklander 	if (rc)
313*63f89caaSJens Wiklander 		return rc;
314*63f89caaSJens Wiklander 
315*63f89caaSJens Wiklander 	rc = set_mandatory_boolprops(out, temp, pkcs11_any_object_boolprops,
316*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_any_object_boolprops));
317*63f89caaSJens Wiklander 	if (rc)
318*63f89caaSJens Wiklander 		return rc;
319*63f89caaSJens Wiklander 
320*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, pkcs11_any_object_optional,
321*63f89caaSJens Wiklander 				       ARRAY_SIZE(pkcs11_any_object_optional));
322*63f89caaSJens Wiklander }
323*63f89caaSJens Wiklander 
324*63f89caaSJens Wiklander static enum pkcs11_rc create_genkey_attributes(struct obj_attrs **out,
325*63f89caaSJens Wiklander 					       struct obj_attrs *temp)
326*63f89caaSJens Wiklander {
327*63f89caaSJens Wiklander 	uint32_t type = PKCS11_CKO_UNDEFINED_ID;
328*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
329*63f89caaSJens Wiklander 
330*63f89caaSJens Wiklander 	rc = create_storage_attributes(out, temp);
331*63f89caaSJens Wiklander 	if (rc)
332*63f89caaSJens Wiklander 		return rc;
333*63f89caaSJens Wiklander 
334*63f89caaSJens Wiklander 	type = get_key_type(temp);
335*63f89caaSJens Wiklander 	if (type == PKCS11_CKK_UNDEFINED_ID) {
336*63f89caaSJens Wiklander 		EMSG("Key type attribute not found");
337*63f89caaSJens Wiklander 
338*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
339*63f89caaSJens Wiklander 	}
340*63f89caaSJens Wiklander 	rc = add_attribute(out, PKCS11_CKA_KEY_TYPE, &type, sizeof(uint32_t));
341*63f89caaSJens Wiklander 	if (rc)
342*63f89caaSJens Wiklander 		return rc;
343*63f89caaSJens Wiklander 
344*63f89caaSJens Wiklander 	rc = set_mandatory_boolprops(out, temp, pkcs11_any_key_boolprops,
345*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_any_key_boolprops));
346*63f89caaSJens Wiklander 	if (rc)
347*63f89caaSJens Wiklander 		return rc;
348*63f89caaSJens Wiklander 
349*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, pkcs11_any_key_optional,
350*63f89caaSJens Wiklander 				       ARRAY_SIZE(pkcs11_any_key_optional));
351*63f89caaSJens Wiklander }
352*63f89caaSJens Wiklander 
353*63f89caaSJens Wiklander static enum pkcs11_rc create_symm_key_attributes(struct obj_attrs **out,
354*63f89caaSJens Wiklander 						 struct obj_attrs *temp)
355*63f89caaSJens Wiklander {
356*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
357*63f89caaSJens Wiklander 
358*63f89caaSJens Wiklander 	assert(get_class(temp) == PKCS11_CKO_SECRET_KEY);
359*63f89caaSJens Wiklander 
360*63f89caaSJens Wiklander 	rc = create_genkey_attributes(out, temp);
361*63f89caaSJens Wiklander 	if (rc)
362*63f89caaSJens Wiklander 		return rc;
363*63f89caaSJens Wiklander 
364*63f89caaSJens Wiklander 	assert(get_class(*out) == PKCS11_CKO_SECRET_KEY);
365*63f89caaSJens Wiklander 
366*63f89caaSJens Wiklander 	switch (get_key_type(*out)) {
367*63f89caaSJens Wiklander 	case PKCS11_CKK_GENERIC_SECRET:
368*63f89caaSJens Wiklander 	case PKCS11_CKK_AES:
369*63f89caaSJens Wiklander 	case PKCS11_CKK_MD5_HMAC:
370*63f89caaSJens Wiklander 	case PKCS11_CKK_SHA_1_HMAC:
371*63f89caaSJens Wiklander 	case PKCS11_CKK_SHA256_HMAC:
372*63f89caaSJens Wiklander 	case PKCS11_CKK_SHA384_HMAC:
373*63f89caaSJens Wiklander 	case PKCS11_CKK_SHA512_HMAC:
374*63f89caaSJens Wiklander 	case PKCS11_CKK_SHA224_HMAC:
375*63f89caaSJens Wiklander 		break;
376*63f89caaSJens Wiklander 	default:
377*63f89caaSJens Wiklander 		EMSG("Invalid key type %#"PRIx32"/%s",
378*63f89caaSJens Wiklander 		     get_key_type(*out), id2str_key_type(get_key_type(*out)));
379*63f89caaSJens Wiklander 
380*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
381*63f89caaSJens Wiklander 	}
382*63f89caaSJens Wiklander 
383*63f89caaSJens Wiklander 	rc = set_mandatory_boolprops(out, temp, pkcs11_symm_key_boolprops,
384*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_symm_key_boolprops));
385*63f89caaSJens Wiklander 	if (rc)
386*63f89caaSJens Wiklander 		return rc;
387*63f89caaSJens Wiklander 
388*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, pkcs11_symm_key_optional,
389*63f89caaSJens Wiklander 				       ARRAY_SIZE(pkcs11_symm_key_optional));
390*63f89caaSJens Wiklander }
391*63f89caaSJens Wiklander 
392*63f89caaSJens Wiklander static enum pkcs11_rc create_data_attributes(struct obj_attrs **out,
393*63f89caaSJens Wiklander 					     struct obj_attrs *temp)
394*63f89caaSJens Wiklander {
395*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
396*63f89caaSJens Wiklander 
397*63f89caaSJens Wiklander 	assert(get_class(temp) == PKCS11_CKO_DATA);
398*63f89caaSJens Wiklander 
399*63f89caaSJens Wiklander 	rc = create_storage_attributes(out, temp);
400*63f89caaSJens Wiklander 	if (rc)
401*63f89caaSJens Wiklander 		return rc;
402*63f89caaSJens Wiklander 
403*63f89caaSJens Wiklander 	assert(get_class(*out) == PKCS11_CKO_DATA);
404*63f89caaSJens Wiklander 
405*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, pkcs11_raw_data_optional,
406*63f89caaSJens Wiklander 				       ARRAY_SIZE(pkcs11_raw_data_optional));
407*63f89caaSJens Wiklander }
408*63f89caaSJens Wiklander 
409*63f89caaSJens Wiklander static enum pkcs11_rc create_pub_key_attributes(struct obj_attrs **out,
410*63f89caaSJens Wiklander 						struct obj_attrs *temp)
411*63f89caaSJens Wiklander {
412*63f89caaSJens Wiklander 	uint32_t const *mandated = NULL;
413*63f89caaSJens Wiklander 	uint32_t const *optional = NULL;
414*63f89caaSJens Wiklander 	size_t mandated_count = 0;
415*63f89caaSJens Wiklander 	size_t optional_count = 0;
416*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
417*63f89caaSJens Wiklander 
418*63f89caaSJens Wiklander 	assert(get_class(temp) == PKCS11_CKO_PUBLIC_KEY);
419*63f89caaSJens Wiklander 
420*63f89caaSJens Wiklander 	rc = create_genkey_attributes(out, temp);
421*63f89caaSJens Wiklander 	if (rc)
422*63f89caaSJens Wiklander 		return rc;
423*63f89caaSJens Wiklander 
424*63f89caaSJens Wiklander 	assert(get_class(*out) == PKCS11_CKO_PUBLIC_KEY);
425*63f89caaSJens Wiklander 
426*63f89caaSJens Wiklander 	rc = set_mandatory_boolprops(out, temp, pkcs11_public_key_boolprops,
427*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_public_key_boolprops));
428*63f89caaSJens Wiklander 	if (rc)
429*63f89caaSJens Wiklander 		return rc;
430*63f89caaSJens Wiklander 
431*63f89caaSJens Wiklander 	rc = set_mandatory_attributes(out, temp, pkcs11_public_key_mandated,
432*63f89caaSJens Wiklander 				      ARRAY_SIZE(pkcs11_public_key_mandated));
433*63f89caaSJens Wiklander 	if (rc)
434*63f89caaSJens Wiklander 		return rc;
435*63f89caaSJens Wiklander 
436*63f89caaSJens Wiklander 	rc = set_optional_attributes(out, temp, pkcs11_public_key_optional,
437*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_public_key_optional));
438*63f89caaSJens Wiklander 	if (rc)
439*63f89caaSJens Wiklander 		return rc;
440*63f89caaSJens Wiklander 
441*63f89caaSJens Wiklander 	switch (get_key_type(*out)) {
442*63f89caaSJens Wiklander 	case PKCS11_CKK_RSA:
443*63f89caaSJens Wiklander 		mandated = pkcs11_rsa_public_key_mandated;
444*63f89caaSJens Wiklander 		optional = pkcs11_rsa_public_key_optional;
445*63f89caaSJens Wiklander 		mandated_count = ARRAY_SIZE(pkcs11_rsa_public_key_mandated);
446*63f89caaSJens Wiklander 		optional_count = ARRAY_SIZE(pkcs11_rsa_public_key_optional);
447*63f89caaSJens Wiklander 		break;
448*63f89caaSJens Wiklander 	case PKCS11_CKK_EC:
449*63f89caaSJens Wiklander 		mandated = pkcs11_ec_public_key_mandated;
450*63f89caaSJens Wiklander 		optional = pkcs11_ec_public_key_optional;
451*63f89caaSJens Wiklander 		mandated_count = ARRAY_SIZE(pkcs11_ec_public_key_mandated);
452*63f89caaSJens Wiklander 		optional_count = ARRAY_SIZE(pkcs11_ec_public_key_optional);
453*63f89caaSJens Wiklander 		break;
454*63f89caaSJens Wiklander 	default:
455*63f89caaSJens Wiklander 		EMSG("Invalid key type %#"PRIx32"/%s",
456*63f89caaSJens Wiklander 		     get_key_type(*out), id2str_key_type(get_key_type(*out)));
457*63f89caaSJens Wiklander 
458*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
459*63f89caaSJens Wiklander 	}
460*63f89caaSJens Wiklander 
461*63f89caaSJens Wiklander 	rc = set_mandatory_attributes(out, temp, mandated, mandated_count);
462*63f89caaSJens Wiklander 	if (rc)
463*63f89caaSJens Wiklander 		return rc;
464*63f89caaSJens Wiklander 
465*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, optional, optional_count);
466*63f89caaSJens Wiklander }
467*63f89caaSJens Wiklander 
468*63f89caaSJens Wiklander static enum pkcs11_rc create_priv_key_attributes(struct obj_attrs **out,
469*63f89caaSJens Wiklander 						 struct obj_attrs *temp)
470*63f89caaSJens Wiklander {
471*63f89caaSJens Wiklander 	uint32_t const *mandated = NULL;
472*63f89caaSJens Wiklander 	uint32_t const *optional = NULL;
473*63f89caaSJens Wiklander 	size_t mandated_count = 0;
474*63f89caaSJens Wiklander 	size_t optional_count = 0;
475*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
476*63f89caaSJens Wiklander 
477*63f89caaSJens Wiklander 	assert(get_class(temp) == PKCS11_CKO_PRIVATE_KEY);
478*63f89caaSJens Wiklander 
479*63f89caaSJens Wiklander 	rc = create_genkey_attributes(out, temp);
480*63f89caaSJens Wiklander 	if (rc)
481*63f89caaSJens Wiklander 		return rc;
482*63f89caaSJens Wiklander 
483*63f89caaSJens Wiklander 	assert(get_class(*out) == PKCS11_CKO_PRIVATE_KEY);
484*63f89caaSJens Wiklander 
485*63f89caaSJens Wiklander 	rc = set_mandatory_boolprops(out, temp, pkcs11_private_key_boolprops,
486*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_private_key_boolprops));
487*63f89caaSJens Wiklander 	if (rc)
488*63f89caaSJens Wiklander 		return rc;
489*63f89caaSJens Wiklander 
490*63f89caaSJens Wiklander 	rc = set_mandatory_attributes(out, temp, pkcs11_private_key_mandated,
491*63f89caaSJens Wiklander 				      ARRAY_SIZE(pkcs11_private_key_mandated));
492*63f89caaSJens Wiklander 	if (rc)
493*63f89caaSJens Wiklander 		return rc;
494*63f89caaSJens Wiklander 
495*63f89caaSJens Wiklander 	rc = set_optional_attributes(out, temp, pkcs11_private_key_optional,
496*63f89caaSJens Wiklander 				     ARRAY_SIZE(pkcs11_private_key_optional));
497*63f89caaSJens Wiklander 	if (rc)
498*63f89caaSJens Wiklander 		return rc;
499*63f89caaSJens Wiklander 
500*63f89caaSJens Wiklander 	switch (get_key_type(*out)) {
501*63f89caaSJens Wiklander 	case PKCS11_CKK_RSA:
502*63f89caaSJens Wiklander 		optional = pkcs11_rsa_private_key_optional;
503*63f89caaSJens Wiklander 		optional_count = ARRAY_SIZE(pkcs11_rsa_private_key_optional);
504*63f89caaSJens Wiklander 		break;
505*63f89caaSJens Wiklander 	case PKCS11_CKK_EC:
506*63f89caaSJens Wiklander 		mandated = pkcs11_ec_private_key_mandated;
507*63f89caaSJens Wiklander 		optional = pkcs11_ec_private_key_optional;
508*63f89caaSJens Wiklander 		mandated_count = ARRAY_SIZE(pkcs11_ec_private_key_mandated);
509*63f89caaSJens Wiklander 		optional_count = ARRAY_SIZE(pkcs11_ec_private_key_optional);
510*63f89caaSJens Wiklander 		break;
511*63f89caaSJens Wiklander 	default:
512*63f89caaSJens Wiklander 		EMSG("Invalid key type %#"PRIx32"/%s",
513*63f89caaSJens Wiklander 		     get_key_type(*out), id2str_key_type(get_key_type(*out)));
514*63f89caaSJens Wiklander 
515*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
516*63f89caaSJens Wiklander 	}
517*63f89caaSJens Wiklander 
518*63f89caaSJens Wiklander 	rc = set_mandatory_attributes(out, temp, mandated, mandated_count);
519*63f89caaSJens Wiklander 	if (rc)
520*63f89caaSJens Wiklander 		return rc;
521*63f89caaSJens Wiklander 
522*63f89caaSJens Wiklander 	return set_optional_attributes(out, temp, optional, optional_count);
523*63f89caaSJens Wiklander }
524*63f89caaSJens Wiklander 
525*63f89caaSJens Wiklander /*
526*63f89caaSJens Wiklander  * Create an attribute list for a new object from a template and a parent
527*63f89caaSJens Wiklander  * object (optional) for an object generation function (generate, copy,
528*63f89caaSJens Wiklander  * derive...).
529*63f89caaSJens Wiklander  *
530*63f89caaSJens Wiklander  * PKCS#11 directives on the supplied template and expected return value:
531*63f89caaSJens Wiklander  * - template has an invalid attribute ID: ATTRIBUTE_TYPE_INVALID
532*63f89caaSJens Wiklander  * - template has an invalid value for an attribute: ATTRIBUTE_VALID_INVALID
533*63f89caaSJens Wiklander  * - template has value for a read-only attribute: ATTRIBUTE_READ_ONLY
534*63f89caaSJens Wiklander  * - template+default+parent => still miss an attribute: TEMPLATE_INCONSISTENT
535*63f89caaSJens Wiklander  *
536*63f89caaSJens Wiklander  * INFO on PKCS11_CMD_COPY_OBJECT:
537*63f89caaSJens Wiklander  * - parent PKCS11_CKA_COPYIABLE=false => return ACTION_PROHIBITED.
538*63f89caaSJens Wiklander  * - template can specify PKCS11_CKA_TOKEN, PKCS11_CKA_PRIVATE,
539*63f89caaSJens Wiklander  *   PKCS11_CKA_MODIFIABLE, PKCS11_CKA_DESTROYABLE.
540*63f89caaSJens Wiklander  * - SENSITIVE can change from false to true, not from true to false.
541*63f89caaSJens Wiklander  * - LOCAL is the parent LOCAL
542*63f89caaSJens Wiklander  */
543*63f89caaSJens Wiklander enum pkcs11_rc
544*63f89caaSJens Wiklander create_attributes_from_template(struct obj_attrs **out, void *template,
545*63f89caaSJens Wiklander 				size_t template_size,
546*63f89caaSJens Wiklander 				struct obj_attrs *parent __unused,
547*63f89caaSJens Wiklander 				enum processing_func function,
548*63f89caaSJens Wiklander 				enum pkcs11_mechanism_id mecha __unused)
549*63f89caaSJens Wiklander {
550*63f89caaSJens Wiklander 	struct obj_attrs *temp = NULL;
551*63f89caaSJens Wiklander 	struct obj_attrs *attrs = NULL;
552*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
553*63f89caaSJens Wiklander 	uint8_t local = 0;
554*63f89caaSJens Wiklander 	uint8_t always_sensitive = 0;
555*63f89caaSJens Wiklander 	uint8_t never_extract = 0;
556*63f89caaSJens Wiklander 	uint32_t mechanism_id = PKCS11_CKM_UNDEFINED_ID;
557*63f89caaSJens Wiklander 
558*63f89caaSJens Wiklander #ifdef DEBUG	/* Sanity: check function argument */
559*63f89caaSJens Wiklander 	trace_attributes_from_api_head("template", template, template_size);
560*63f89caaSJens Wiklander 	switch (function) {
561*63f89caaSJens Wiklander 	case PKCS11_FUNCTION_IMPORT:
562*63f89caaSJens Wiklander 		break;
563*63f89caaSJens Wiklander 	default:
564*63f89caaSJens Wiklander 		TEE_Panic(TEE_ERROR_NOT_SUPPORTED);
565*63f89caaSJens Wiklander 	}
566*63f89caaSJens Wiklander #endif
567*63f89caaSJens Wiklander 
568*63f89caaSJens Wiklander 	rc = sanitize_client_object(&temp, template, template_size);
569*63f89caaSJens Wiklander 	if (rc)
570*63f89caaSJens Wiklander 		goto out;
571*63f89caaSJens Wiklander 
572*63f89caaSJens Wiklander 	/* If class/type not defined, match from mechanism */
573*63f89caaSJens Wiklander 	if (get_class(temp) == PKCS11_UNDEFINED_ID &&
574*63f89caaSJens Wiklander 	    get_key_type(temp) == PKCS11_UNDEFINED_ID) {
575*63f89caaSJens Wiklander 		EMSG("Unable to define class/type from mechanism");
576*63f89caaSJens Wiklander 		rc = PKCS11_CKR_TEMPLATE_INCOMPLETE;
577*63f89caaSJens Wiklander 		goto out;
578*63f89caaSJens Wiklander 	}
579*63f89caaSJens Wiklander 
580*63f89caaSJens Wiklander 	if (!sanitize_consistent_class_and_type(temp)) {
581*63f89caaSJens Wiklander 		EMSG("Inconsistent class/type");
582*63f89caaSJens Wiklander 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
583*63f89caaSJens Wiklander 		goto out;
584*63f89caaSJens Wiklander 	}
585*63f89caaSJens Wiklander 
586*63f89caaSJens Wiklander 	switch (get_class(temp)) {
587*63f89caaSJens Wiklander 	case PKCS11_CKO_DATA:
588*63f89caaSJens Wiklander 		rc = create_data_attributes(&attrs, temp);
589*63f89caaSJens Wiklander 		break;
590*63f89caaSJens Wiklander 	case PKCS11_CKO_SECRET_KEY:
591*63f89caaSJens Wiklander 		rc = create_symm_key_attributes(&attrs, temp);
592*63f89caaSJens Wiklander 		break;
593*63f89caaSJens Wiklander 	case PKCS11_CKO_PUBLIC_KEY:
594*63f89caaSJens Wiklander 		rc = create_pub_key_attributes(&attrs, temp);
595*63f89caaSJens Wiklander 		break;
596*63f89caaSJens Wiklander 	case PKCS11_CKO_PRIVATE_KEY:
597*63f89caaSJens Wiklander 		rc = create_priv_key_attributes(&attrs, temp);
598*63f89caaSJens Wiklander 		break;
599*63f89caaSJens Wiklander 	default:
600*63f89caaSJens Wiklander 		DMSG("Invalid object class %#"PRIx32"/%s",
601*63f89caaSJens Wiklander 		     get_class(temp), id2str_class(get_class(temp)));
602*63f89caaSJens Wiklander 
603*63f89caaSJens Wiklander 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
604*63f89caaSJens Wiklander 		break;
605*63f89caaSJens Wiklander 	}
606*63f89caaSJens Wiklander 	if (rc)
607*63f89caaSJens Wiklander 		goto out;
608*63f89caaSJens Wiklander 
609*63f89caaSJens Wiklander 	if (get_attribute(attrs, PKCS11_CKA_LOCAL, NULL, NULL) !=
610*63f89caaSJens Wiklander 	    PKCS11_RV_NOT_FOUND)
611*63f89caaSJens Wiklander 		goto out;
612*63f89caaSJens Wiklander 
613*63f89caaSJens Wiklander 	if (get_attribute(attrs, PKCS11_CKA_KEY_GEN_MECHANISM, NULL, NULL) !=
614*63f89caaSJens Wiklander 	    PKCS11_RV_NOT_FOUND)
615*63f89caaSJens Wiklander 		goto out;
616*63f89caaSJens Wiklander 
617*63f89caaSJens Wiklander 	switch (function) {
618*63f89caaSJens Wiklander 	case PKCS11_FUNCTION_IMPORT:
619*63f89caaSJens Wiklander 	default:
620*63f89caaSJens Wiklander 		local = PKCS11_FALSE;
621*63f89caaSJens Wiklander 		break;
622*63f89caaSJens Wiklander 	}
623*63f89caaSJens Wiklander 	rc = add_attribute(&attrs, PKCS11_CKA_LOCAL, &local, sizeof(local));
624*63f89caaSJens Wiklander 	if (rc)
625*63f89caaSJens Wiklander 		goto out;
626*63f89caaSJens Wiklander 
627*63f89caaSJens Wiklander 	switch (get_class(attrs)) {
628*63f89caaSJens Wiklander 	case PKCS11_CKO_SECRET_KEY:
629*63f89caaSJens Wiklander 	case PKCS11_CKO_PRIVATE_KEY:
630*63f89caaSJens Wiklander 	case PKCS11_CKO_PUBLIC_KEY:
631*63f89caaSJens Wiklander 		always_sensitive = PKCS11_FALSE;
632*63f89caaSJens Wiklander 		never_extract = PKCS11_FALSE;
633*63f89caaSJens Wiklander 
634*63f89caaSJens Wiklander 		rc = add_attribute(&attrs, PKCS11_CKA_ALWAYS_SENSITIVE,
635*63f89caaSJens Wiklander 				   &always_sensitive, sizeof(always_sensitive));
636*63f89caaSJens Wiklander 		if (rc)
637*63f89caaSJens Wiklander 			goto out;
638*63f89caaSJens Wiklander 
639*63f89caaSJens Wiklander 		rc = add_attribute(&attrs, PKCS11_CKA_NEVER_EXTRACTABLE,
640*63f89caaSJens Wiklander 				   &never_extract, sizeof(never_extract));
641*63f89caaSJens Wiklander 		if (rc)
642*63f89caaSJens Wiklander 			goto out;
643*63f89caaSJens Wiklander 
644*63f89caaSJens Wiklander 		/* Keys mandate attribute PKCS11_CKA_KEY_GEN_MECHANISM */
645*63f89caaSJens Wiklander 		mechanism_id = PKCS11_CK_UNAVAILABLE_INFORMATION;
646*63f89caaSJens Wiklander 		rc = add_attribute(&attrs, PKCS11_CKA_KEY_GEN_MECHANISM,
647*63f89caaSJens Wiklander 				   &mechanism_id, sizeof(mechanism_id));
648*63f89caaSJens Wiklander 		if (rc)
649*63f89caaSJens Wiklander 			goto out;
650*63f89caaSJens Wiklander 		break;
651*63f89caaSJens Wiklander 
652*63f89caaSJens Wiklander 	default:
653*63f89caaSJens Wiklander 		break;
654*63f89caaSJens Wiklander 	}
655*63f89caaSJens Wiklander 
656*63f89caaSJens Wiklander 	*out = attrs;
657*63f89caaSJens Wiklander 
658*63f89caaSJens Wiklander #ifdef DEBUG
659*63f89caaSJens Wiklander 	trace_attributes("object", attrs);
660*63f89caaSJens Wiklander #endif
661*63f89caaSJens Wiklander 
662*63f89caaSJens Wiklander out:
663*63f89caaSJens Wiklander 	TEE_Free(temp);
664*63f89caaSJens Wiklander 	if (rc)
665*63f89caaSJens Wiklander 		TEE_Free(attrs);
666*63f89caaSJens Wiklander 
667*63f89caaSJens Wiklander 	return rc;
668*63f89caaSJens Wiklander }
669*63f89caaSJens Wiklander 
670*63f89caaSJens Wiklander static enum pkcs11_rc check_attrs_misc_integrity(struct obj_attrs *head)
671*63f89caaSJens Wiklander {
672*63f89caaSJens Wiklander 	if (get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE) &&
673*63f89caaSJens Wiklander 	    get_bool(head, PKCS11_CKA_EXTRACTABLE)) {
674*63f89caaSJens Wiklander 		DMSG("Never/Extractable attributes mismatch %d/%d",
675*63f89caaSJens Wiklander 		     get_bool(head, PKCS11_CKA_NEVER_EXTRACTABLE),
676*63f89caaSJens Wiklander 		     get_bool(head, PKCS11_CKA_EXTRACTABLE));
677*63f89caaSJens Wiklander 
678*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
679*63f89caaSJens Wiklander 	}
680*63f89caaSJens Wiklander 
681*63f89caaSJens Wiklander 	if (get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE) &&
682*63f89caaSJens Wiklander 	    !get_bool(head, PKCS11_CKA_SENSITIVE)) {
683*63f89caaSJens Wiklander 		DMSG("Sensitive/always attributes mismatch %d/%d",
684*63f89caaSJens Wiklander 		     get_bool(head, PKCS11_CKA_SENSITIVE),
685*63f89caaSJens Wiklander 		     get_bool(head, PKCS11_CKA_ALWAYS_SENSITIVE));
686*63f89caaSJens Wiklander 
687*63f89caaSJens Wiklander 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
688*63f89caaSJens Wiklander 	}
689*63f89caaSJens Wiklander 
690*63f89caaSJens Wiklander 	return PKCS11_CKR_OK;
691*63f89caaSJens Wiklander }
692*63f89caaSJens Wiklander 
693*63f89caaSJens Wiklander /*
694*63f89caaSJens Wiklander  * Check the attributes of a to-be-created object matches the token state
695*63f89caaSJens Wiklander  */
696*63f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_token(struct pkcs11_session *session,
697*63f89caaSJens Wiklander 						 struct obj_attrs *head)
698*63f89caaSJens Wiklander {
699*63f89caaSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
700*63f89caaSJens Wiklander 
701*63f89caaSJens Wiklander 	rc = check_attrs_misc_integrity(head);
702*63f89caaSJens Wiklander 	if (rc)
703*63f89caaSJens Wiklander 		return rc;
704*63f89caaSJens Wiklander 
705*63f89caaSJens Wiklander 	if (get_bool(head, PKCS11_CKA_TRUSTED) &&
706*63f89caaSJens Wiklander 	    !pkcs11_session_is_so(session)) {
707*63f89caaSJens Wiklander 		DMSG("Can't create trusted object");
708*63f89caaSJens Wiklander 
709*63f89caaSJens Wiklander 		return PKCS11_CKR_KEY_FUNCTION_NOT_PERMITTED;
710*63f89caaSJens Wiklander 	}
711*63f89caaSJens Wiklander 
712*63f89caaSJens Wiklander 	if (get_bool(head, PKCS11_CKA_TOKEN) &&
713*63f89caaSJens Wiklander 	    !pkcs11_session_is_read_write(session)) {
714*63f89caaSJens Wiklander 		DMSG("Can't create persistent object");
715*63f89caaSJens Wiklander 
716*63f89caaSJens Wiklander 		return PKCS11_CKR_SESSION_READ_ONLY;
717*63f89caaSJens Wiklander 	}
718*63f89caaSJens Wiklander 
719*63f89caaSJens Wiklander 	/*
720*63f89caaSJens Wiklander 	 * TODO: START_DATE and END_DATE: complies with current time?
721*63f89caaSJens Wiklander 	 */
722*63f89caaSJens Wiklander 	return PKCS11_CKR_OK;
723*63f89caaSJens Wiklander }
724*63f89caaSJens Wiklander 
725*63f89caaSJens Wiklander #define DMSG_BAD_BBOOL(attr, proc, head)				\
726*63f89caaSJens Wiklander 	do {								\
727*63f89caaSJens Wiklander 		uint32_t __maybe_unused _attr = (attr);			\
728*63f89caaSJens Wiklander 		uint8_t __maybe_unused _bvalue = 0;			\
729*63f89caaSJens Wiklander 		enum pkcs11_rc __maybe_unused _rc = PKCS11_CKR_OK;	\
730*63f89caaSJens Wiklander 									\
731*63f89caaSJens Wiklander 		_rc = get_attribute((head), _attr, &_bvalue, NULL);	\
732*63f89caaSJens Wiklander 		DMSG("%s issue for %s: %sfound, value %"PRIu8,		\
733*63f89caaSJens Wiklander 		     id2str_attr(_attr), id2str_proc((proc)),		\
734*63f89caaSJens Wiklander 		     _rc ? "not " : "", _bvalue);			\
735*63f89caaSJens Wiklander 	} while (0)
736*63f89caaSJens Wiklander 
737*63f89caaSJens Wiklander static bool __maybe_unused check_attr_bval(uint32_t proc_id __maybe_unused,
738*63f89caaSJens Wiklander 					   struct obj_attrs *head,
739*63f89caaSJens Wiklander 					   uint32_t attribute, bool val)
740*63f89caaSJens Wiklander {
741*63f89caaSJens Wiklander 	uint8_t bbool = 0;
742*63f89caaSJens Wiklander 	uint32_t sz = sizeof(bbool);
743*63f89caaSJens Wiklander 
744*63f89caaSJens Wiklander 	if (!get_attribute(head, attribute, &bbool, &sz) && !!bbool == val)
745*63f89caaSJens Wiklander 		return true;
746*63f89caaSJens Wiklander 
747*63f89caaSJens Wiklander 	DMSG_BAD_BBOOL(attribute, proc_id, head);
748*63f89caaSJens Wiklander 	return false;
749*63f89caaSJens Wiklander }
750*63f89caaSJens Wiklander 
751*63f89caaSJens Wiklander /*
752*63f89caaSJens Wiklander  * Check the attributes of a new secret match the processing/mechanism
753*63f89caaSJens Wiklander  * used to create it.
754*63f89caaSJens Wiklander  *
755*63f89caaSJens Wiklander  * @proc_id - PKCS11_CKM_xxx
756*63f89caaSJens Wiklander  * @head - head of the attributes of the to-be-created object.
757*63f89caaSJens Wiklander  */
758*63f89caaSJens Wiklander enum pkcs11_rc check_created_attrs_against_processing(uint32_t proc_id,
759*63f89caaSJens Wiklander 						      struct obj_attrs *head)
760*63f89caaSJens Wiklander {
761*63f89caaSJens Wiklander 	/*
762*63f89caaSJens Wiklander 	 * Processings that do not create secrets are not expected to call
763*63f89caaSJens Wiklander 	 * this function which would panic.
764*63f89caaSJens Wiklander 	 */
765*63f89caaSJens Wiklander 	switch (proc_id) {
766*63f89caaSJens Wiklander 	case PKCS11_PROCESSING_IMPORT:
767*63f89caaSJens Wiklander 		assert(check_attr_bval(proc_id, head, PKCS11_CKA_LOCAL, false));
768*63f89caaSJens Wiklander 		break;
769*63f89caaSJens Wiklander 	default:
770*63f89caaSJens Wiklander 		TEE_Panic(proc_id);
771*63f89caaSJens Wiklander 		break;
772*63f89caaSJens Wiklander 	}
773*63f89caaSJens Wiklander 
774*63f89caaSJens Wiklander 	return PKCS11_CKR_OK;
775*63f89caaSJens Wiklander }
776