xref: /optee_os/core/tee/tee_svc_cryp.c (revision 8e81e2f5366a971afdd2ac47fb8529d1def5feb0)
1 /*
2  * Copyright (c) 2014, STMicroelectronics International N.V.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <assert.h>
29 #include <tee_api_types.h>
30 #include <kernel/tee_ta_manager.h>
31 #include <utee_defines.h>
32 #include <mm/tee_mmu.h>
33 #include <tee/tee_svc.h>
34 #include <tee/tee_svc_cryp.h>
35 #include <tee/tee_cryp_utl.h>
36 #include <sys/queue.h>
37 #include <tee/tee_obj.h>
38 #include <tee/tee_cryp_provider.h>
39 #include <trace.h>
40 #include <string_ext.h>
41 #include <string.h>
42 #include <util.h>
43 #if defined(CFG_CRYPTO_HKDF) || defined(CFG_CRYPTO_CONCAT_KDF) || \
44 	defined(CFG_CRYPTO_PBKDF2)
45 #include <tee_api_defines_extensions.h>
46 #endif
47 #if defined(CFG_CRYPTO_HKDF)
48 #include <tee/tee_cryp_hkdf.h>
49 #endif
50 #if defined(CFG_CRYPTO_CONCAT_KDF)
51 #include <tee/tee_cryp_concat_kdf.h>
52 #endif
53 #if defined(CFG_CRYPTO_PBKDF2)
54 #include <tee/tee_cryp_pbkdf2.h>
55 #endif
56 
57 typedef void (*tee_cryp_ctx_finalize_func_t) (void *ctx, uint32_t algo);
58 struct tee_cryp_state {
59 	TAILQ_ENTRY(tee_cryp_state) link;
60 	uint32_t algo;
61 	uint32_t mode;
62 	vaddr_t key1;
63 	vaddr_t key2;
64 	size_t ctx_size;
65 	void *ctx;
66 	tee_cryp_ctx_finalize_func_t ctx_finalize;
67 };
68 
69 struct tee_cryp_obj_secret {
70 	uint32_t key_size;
71 	uint32_t alloc_size;
72 
73 	/*
74 	 * Pseudo code visualize layout of structure
75 	 * Next follows data, such as:
76 	 *	uint8_t data[alloc_size]
77 	 * key_size must never exceed alloc_size
78 	 */
79 };
80 
81 #define TEE_TYPE_ATTR_OPTIONAL       0x0
82 #define TEE_TYPE_ATTR_REQUIRED       0x1
83 #define TEE_TYPE_ATTR_OPTIONAL_GROUP 0x2
84 #define TEE_TYPE_ATTR_SIZE_INDICATOR 0x4
85 #define TEE_TYPE_ATTR_GEN_KEY_OPT    0x8
86 #define TEE_TYPE_ATTR_GEN_KEY_REQ    0x10
87 
88     /* Handle storing of generic secret keys of varying lengths */
89 #define ATTR_OPS_INDEX_SECRET     0
90     /* Convert to/from big-endian byte array and provider-specific bignum */
91 #define ATTR_OPS_INDEX_BIGNUM     1
92     /* Convert to/from value attribute depending on direction */
93 #define ATTR_OPS_INDEX_VALUE      2
94 
95 struct tee_cryp_obj_type_attrs {
96 	uint32_t attr_id;
97 	uint16_t flags;
98 	uint16_t ops_index;
99 	uint16_t raw_offs;
100 	uint16_t raw_size;
101 };
102 
103 #define RAW_DATA(_x, _y)	\
104 	.raw_offs = offsetof(_x, _y), .raw_size = MEMBER_SIZE(_x, _y)
105 
106 static const struct tee_cryp_obj_type_attrs
107 	tee_cryp_obj_secret_value_attrs[] = {
108 	{
109 	.attr_id = TEE_ATTR_SECRET_VALUE,
110 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
111 	.ops_index = ATTR_OPS_INDEX_SECRET,
112 	.raw_offs = 0,
113 	.raw_size = 0
114 	},
115 };
116 
117 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_pub_key_attrs[] = {
118 	{
119 	.attr_id = TEE_ATTR_RSA_MODULUS,
120 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
121 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
122 	RAW_DATA(struct rsa_public_key, n)
123 	},
124 
125 	{
126 	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
127 	.flags = TEE_TYPE_ATTR_REQUIRED,
128 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
129 	RAW_DATA(struct rsa_public_key, e)
130 	},
131 };
132 
133 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_keypair_attrs[] = {
134 	{
135 	.attr_id = TEE_ATTR_RSA_MODULUS,
136 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
137 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
138 	RAW_DATA(struct rsa_keypair, n)
139 	},
140 
141 	{
142 	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
143 	.flags = TEE_TYPE_ATTR_REQUIRED,
144 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
145 	RAW_DATA(struct rsa_keypair, e)
146 	},
147 
148 	{
149 	.attr_id = TEE_ATTR_RSA_PRIVATE_EXPONENT,
150 	.flags = TEE_TYPE_ATTR_REQUIRED,
151 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
152 	RAW_DATA(struct rsa_keypair, d)
153 	},
154 
155 	{
156 	.attr_id = TEE_ATTR_RSA_PRIME1,
157 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
158 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
159 	RAW_DATA(struct rsa_keypair, p)
160 	},
161 
162 	{
163 	.attr_id = TEE_ATTR_RSA_PRIME2,
164 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
165 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
166 	RAW_DATA(struct rsa_keypair, q)
167 	},
168 
169 	{
170 	.attr_id = TEE_ATTR_RSA_EXPONENT1,
171 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
172 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
173 	RAW_DATA(struct rsa_keypair, dp)
174 	},
175 
176 	{
177 	.attr_id = TEE_ATTR_RSA_EXPONENT2,
178 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
179 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
180 	RAW_DATA(struct rsa_keypair, dq)
181 	},
182 
183 	{
184 	.attr_id = TEE_ATTR_RSA_COEFFICIENT,
185 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
186 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
187 	RAW_DATA(struct rsa_keypair, qp)
188 	},
189 };
190 
191 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_pub_key_attrs[] = {
192 	{
193 	.attr_id = TEE_ATTR_DSA_PRIME,
194 	.flags = TEE_TYPE_ATTR_REQUIRED,
195 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
196 	RAW_DATA(struct dsa_public_key, p)
197 	},
198 
199 	{
200 	.attr_id = TEE_ATTR_DSA_SUBPRIME,
201 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
202 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
203 	RAW_DATA(struct dsa_public_key, q)
204 	},
205 
206 	{
207 	.attr_id = TEE_ATTR_DSA_BASE,
208 	.flags = TEE_TYPE_ATTR_REQUIRED,
209 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
210 	RAW_DATA(struct dsa_public_key, g)
211 	},
212 
213 	{
214 	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
215 	.flags = TEE_TYPE_ATTR_REQUIRED,
216 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
217 	RAW_DATA(struct dsa_public_key, y)
218 	},
219 };
220 
221 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_keypair_attrs[] = {
222 	{
223 	.attr_id = TEE_ATTR_DSA_PRIME,
224 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
225 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
226 	RAW_DATA(struct dsa_keypair, p)
227 	},
228 
229 	{
230 	.attr_id = TEE_ATTR_DSA_SUBPRIME,
231 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
232 		 TEE_TYPE_ATTR_GEN_KEY_REQ,
233 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
234 	RAW_DATA(struct dsa_keypair, q)
235 	},
236 
237 	{
238 	.attr_id = TEE_ATTR_DSA_BASE,
239 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
240 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
241 	RAW_DATA(struct dsa_keypair, g)
242 	},
243 
244 	{
245 	.attr_id = TEE_ATTR_DSA_PRIVATE_VALUE,
246 	.flags = TEE_TYPE_ATTR_REQUIRED,
247 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
248 	RAW_DATA(struct dsa_keypair, x)
249 	},
250 
251 	{
252 	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
253 	.flags = TEE_TYPE_ATTR_REQUIRED,
254 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
255 	RAW_DATA(struct dsa_keypair, y)
256 	},
257 };
258 
259 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dh_keypair_attrs[] = {
260 	{
261 	.attr_id = TEE_ATTR_DH_PRIME,
262 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
263 		 TEE_TYPE_ATTR_GEN_KEY_REQ,
264 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
265 	RAW_DATA(struct dh_keypair, p)
266 	},
267 
268 	{
269 	.attr_id = TEE_ATTR_DH_BASE,
270 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
271 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
272 	RAW_DATA(struct dh_keypair, g)
273 	},
274 
275 	{
276 	.attr_id = TEE_ATTR_DH_PUBLIC_VALUE,
277 	.flags = TEE_TYPE_ATTR_REQUIRED,
278 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
279 	RAW_DATA(struct dh_keypair, y)
280 	},
281 
282 	{
283 	.attr_id = TEE_ATTR_DH_PRIVATE_VALUE,
284 	.flags = TEE_TYPE_ATTR_REQUIRED,
285 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
286 	RAW_DATA(struct dh_keypair, x)
287 	},
288 
289 	{
290 	.attr_id = TEE_ATTR_DH_SUBPRIME,
291 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP |	 TEE_TYPE_ATTR_GEN_KEY_OPT,
292 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
293 	RAW_DATA(struct dh_keypair, q)
294 	},
295 
296 	{
297 	.attr_id = TEE_ATTR_DH_X_BITS,
298 	.flags = TEE_TYPE_ATTR_GEN_KEY_OPT,
299 	.ops_index = ATTR_OPS_INDEX_VALUE,
300 	RAW_DATA(struct dh_keypair, xbits)
301 	},
302 };
303 
304 #if defined(CFG_CRYPTO_HKDF)
305 static const struct tee_cryp_obj_type_attrs
306 	tee_cryp_obj_hkdf_ikm_attrs[] = {
307 	{
308 	.attr_id = TEE_ATTR_HKDF_IKM,
309 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
310 	.ops_index = ATTR_OPS_INDEX_SECRET,
311 	.raw_offs = 0,
312 	.raw_size = 0
313 	},
314 };
315 #endif
316 
317 #if defined(CFG_CRYPTO_CONCAT_KDF)
318 static const struct tee_cryp_obj_type_attrs
319 	tee_cryp_obj_concat_kdf_z_attrs[] = {
320 	{
321 	.attr_id = TEE_ATTR_CONCAT_KDF_Z,
322 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
323 	.ops_index = ATTR_OPS_INDEX_SECRET,
324 	.raw_offs = 0,
325 	.raw_size = 0
326 	},
327 };
328 #endif
329 
330 #if defined(CFG_CRYPTO_PBKDF2)
331 static const struct tee_cryp_obj_type_attrs
332 	tee_cryp_obj_pbkdf2_passwd_attrs[] = {
333 	{
334 	.attr_id = TEE_ATTR_PBKDF2_PASSWORD,
335 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
336 	.ops_index = ATTR_OPS_INDEX_SECRET,
337 	.raw_offs = 0,
338 	.raw_size = 0
339 	},
340 };
341 #endif
342 
343 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_ecc_pub_key_attrs[] = {
344 	{
345 	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_X,
346 	.flags = TEE_TYPE_ATTR_REQUIRED,
347 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
348 	RAW_DATA(struct ecc_public_key, x)
349 	},
350 
351 	{
352 	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_Y,
353 	.flags = TEE_TYPE_ATTR_REQUIRED,
354 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
355 	RAW_DATA(struct ecc_public_key, y)
356 	},
357 
358 	{
359 	.attr_id = TEE_ATTR_ECC_CURVE,
360 	.flags = TEE_TYPE_ATTR_REQUIRED,
361 	.ops_index = ATTR_OPS_INDEX_VALUE,
362 	RAW_DATA(struct ecc_public_key, curve)
363 	},
364 };
365 
366 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_ecc_keypair_attrs[] = {
367 	{
368 	.attr_id = TEE_ATTR_ECC_PRIVATE_VALUE,
369 	.flags = TEE_TYPE_ATTR_REQUIRED,
370 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
371 	RAW_DATA(struct ecc_keypair, d)
372 	},
373 
374 	{
375 	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_X,
376 	.flags = TEE_TYPE_ATTR_REQUIRED,
377 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
378 	RAW_DATA(struct ecc_keypair, x)
379 	},
380 
381 	{
382 	.attr_id = TEE_ATTR_ECC_PUBLIC_VALUE_Y,
383 	.flags = TEE_TYPE_ATTR_REQUIRED,
384 	.ops_index = ATTR_OPS_INDEX_BIGNUM,
385 	RAW_DATA(struct ecc_keypair, y)
386 	},
387 
388 	{
389 	.attr_id = TEE_ATTR_ECC_CURVE,
390 	.flags = TEE_TYPE_ATTR_REQUIRED,
391 	.ops_index = ATTR_OPS_INDEX_VALUE,
392 	RAW_DATA(struct ecc_keypair, curve)
393 	},
394 };
395 
396 struct tee_cryp_obj_type_props {
397 	TEE_ObjectType obj_type;
398 	uint16_t min_size;	/* may not be smaller than this */
399 	uint16_t max_size;	/* may not be larger than this */
400 	uint16_t alloc_size;	/* this many bytes are allocated to hold data */
401 	uint8_t quanta;		/* may only be an multiple of this */
402 
403 	uint8_t num_type_attrs;
404 	const struct tee_cryp_obj_type_attrs *type_attrs;
405 };
406 
407 #define PROP(obj_type, quanta, min_size, max_size, alloc_size, type_attrs) \
408 		{ (obj_type), (min_size), (max_size), (alloc_size), (quanta), \
409 		  ARRAY_SIZE(type_attrs), (type_attrs) }
410 
411 static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = {
412 	PROP(TEE_TYPE_AES, 64, 128, 256,	/* valid sizes 128, 192, 256 */
413 		256 / 8 + sizeof(struct tee_cryp_obj_secret),
414 		tee_cryp_obj_secret_value_attrs),
415 	PROP(TEE_TYPE_DES, 56, 56, 56,
416 		/*
417 		* Valid size 56 without parity, note that we still allocate
418 		* for 64 bits since the key is supplied with parity.
419 		*/
420 		64 / 8 + sizeof(struct tee_cryp_obj_secret),
421 		tee_cryp_obj_secret_value_attrs),
422 	PROP(TEE_TYPE_DES3, 56, 112, 168,
423 		/*
424 		* Valid sizes 112, 168 without parity, note that we still
425 		* allocate for with space for the parity since the key is
426 		* supplied with parity.
427 		*/
428 		192 / 8 + sizeof(struct tee_cryp_obj_secret),
429 		tee_cryp_obj_secret_value_attrs),
430 	PROP(TEE_TYPE_HMAC_MD5, 8, 64, 512,
431 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
432 		tee_cryp_obj_secret_value_attrs),
433 	PROP(TEE_TYPE_HMAC_SHA1, 8, 80, 512,
434 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
435 		tee_cryp_obj_secret_value_attrs),
436 	PROP(TEE_TYPE_HMAC_SHA224, 8, 112, 512,
437 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
438 		tee_cryp_obj_secret_value_attrs),
439 	PROP(TEE_TYPE_HMAC_SHA256, 8, 192, 1024,
440 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
441 		tee_cryp_obj_secret_value_attrs),
442 	PROP(TEE_TYPE_HMAC_SHA384, 8, 256, 1024,
443 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
444 		tee_cryp_obj_secret_value_attrs),
445 	PROP(TEE_TYPE_HMAC_SHA512, 8, 256, 1024,
446 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
447 		tee_cryp_obj_secret_value_attrs),
448 	PROP(TEE_TYPE_GENERIC_SECRET, 8, 0, 4096,
449 		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
450 		tee_cryp_obj_secret_value_attrs),
451 #if defined(CFG_CRYPTO_HKDF)
452 	PROP(TEE_TYPE_HKDF_IKM, 8, 0, 4096,
453 		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
454 		tee_cryp_obj_hkdf_ikm_attrs),
455 #endif
456 #if defined(CFG_CRYPTO_CONCAT_KDF)
457 	PROP(TEE_TYPE_CONCAT_KDF_Z, 8, 0, 4096,
458 		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
459 		tee_cryp_obj_concat_kdf_z_attrs),
460 #endif
461 #if defined(CFG_CRYPTO_PBKDF2)
462 	PROP(TEE_TYPE_PBKDF2_PASSWORD, 8, 0, 4096,
463 		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
464 		tee_cryp_obj_pbkdf2_passwd_attrs),
465 #endif
466 	PROP(TEE_TYPE_RSA_PUBLIC_KEY, 1, 256, 2048,
467 		sizeof(struct rsa_public_key),
468 		tee_cryp_obj_rsa_pub_key_attrs),
469 
470 	PROP(TEE_TYPE_RSA_KEYPAIR, 1, 256, 2048,
471 		sizeof(struct rsa_keypair),
472 		tee_cryp_obj_rsa_keypair_attrs),
473 
474 	PROP(TEE_TYPE_DSA_PUBLIC_KEY, 64, 512, 3072,
475 		sizeof(struct dsa_public_key),
476 		tee_cryp_obj_dsa_pub_key_attrs),
477 
478 	PROP(TEE_TYPE_DSA_KEYPAIR, 64, 512, 3072,
479 		sizeof(struct dsa_keypair),
480 		tee_cryp_obj_dsa_keypair_attrs),
481 
482 	PROP(TEE_TYPE_DH_KEYPAIR, 1, 256, 2048,
483 		sizeof(struct dh_keypair),
484 		tee_cryp_obj_dh_keypair_attrs),
485 
486 	PROP(TEE_TYPE_ECDSA_PUBLIC_KEY, 1, 192, 521,
487 		sizeof(struct ecc_public_key),
488 		tee_cryp_obj_ecc_pub_key_attrs),
489 
490 	PROP(TEE_TYPE_ECDSA_KEYPAIR, 1, 192, 521,
491 		sizeof(struct ecc_keypair),
492 		tee_cryp_obj_ecc_keypair_attrs),
493 
494 	PROP(TEE_TYPE_ECDH_PUBLIC_KEY, 1, 192, 521,
495 		sizeof(struct ecc_public_key),
496 		tee_cryp_obj_ecc_pub_key_attrs),
497 
498 	PROP(TEE_TYPE_ECDH_KEYPAIR, 1, 192, 521,
499 		sizeof(struct ecc_keypair),
500 		tee_cryp_obj_ecc_keypair_attrs),
501 };
502 
503 struct attr_ops {
504 	TEE_Result (*from_user)(void *attr, const void *buffer, size_t size);
505 	TEE_Result (*to_user)(void *attr, struct tee_ta_session *sess,
506 			      void *buffer, uint64_t *size);
507 	void (*to_binary)(void *attr, void *data, size_t data_len,
508 			  size_t *offs);
509 	bool (*from_binary)(void *attr, const void *data, size_t data_len,
510 			    size_t *offs);
511 	TEE_Result (*from_obj)(void *attr, void *src_attr);
512 	void (*free)(void *attr);
513 	void (*clear)(void *attr);
514 };
515 
516 static void op_u32_to_binary_helper(uint32_t v, uint8_t *data,
517 				    size_t data_len, size_t *offs)
518 {
519 	uint32_t field;
520 
521 	if (data && (*offs + sizeof(field)) <= data_len) {
522 		field = TEE_U32_TO_BIG_ENDIAN(v);
523 		memcpy(data + *offs, &field, sizeof(field));
524 	}
525 	(*offs) += sizeof(field);
526 }
527 
528 static bool op_u32_from_binary_helper(uint32_t *v, const uint8_t *data,
529 				      size_t data_len, size_t *offs)
530 {
531 	uint32_t field;
532 
533 	if (!data || (*offs + sizeof(field)) > data_len)
534 		return false;
535 
536 	memcpy(&field, data + *offs, sizeof(field));
537 	*v = TEE_U32_FROM_BIG_ENDIAN(field);
538 	(*offs) += sizeof(field);
539 	return true;
540 }
541 
542 static TEE_Result op_attr_secret_value_from_user(void *attr, const void *buffer,
543 						 size_t size)
544 {
545 	struct tee_cryp_obj_secret *key = attr;
546 
547 	/* Data size has to fit in allocated buffer */
548 	if (size > key->alloc_size)
549 		return TEE_ERROR_SECURITY;
550 	memcpy(key + 1, buffer, size);
551 	key->key_size = size;
552 	return TEE_SUCCESS;
553 }
554 
555 static TEE_Result op_attr_secret_value_to_user(void *attr,
556 			struct tee_ta_session *sess __unused,
557 			void *buffer, uint64_t *size)
558 {
559 	TEE_Result res;
560 	struct tee_cryp_obj_secret *key = attr;
561 	uint64_t s;
562 	uint64_t key_size;
563 
564 	res = tee_svc_copy_from_user(&s, size, sizeof(s));
565 	if (res != TEE_SUCCESS)
566 		return res;
567 
568 	key_size = key->key_size;
569 	res = tee_svc_copy_to_user(size, &key_size, sizeof(key_size));
570 	if (res != TEE_SUCCESS)
571 		return res;
572 
573 	if (s < key->key_size)
574 		return TEE_ERROR_SHORT_BUFFER;
575 
576 	return tee_svc_copy_to_user(buffer, key + 1, key->key_size);
577 }
578 
579 static void op_attr_secret_value_to_binary(void *attr, void *data,
580 					   size_t data_len, size_t *offs)
581 {
582 	struct tee_cryp_obj_secret *key = attr;
583 
584 	op_u32_to_binary_helper(key->key_size, data, data_len, offs);
585 	if (data && (*offs + key->key_size) <= data_len)
586 		memcpy((uint8_t *)data + *offs, key + 1, key->key_size);
587 	(*offs) += key->key_size;
588 }
589 
590 static bool op_attr_secret_value_from_binary(void *attr, const void *data,
591 					     size_t data_len, size_t *offs)
592 {
593 	struct tee_cryp_obj_secret *key = attr;
594 	uint32_t s;
595 
596 	if (!op_u32_from_binary_helper(&s, data, data_len, offs))
597 		return false;
598 
599 	if ((*offs + s) > data_len)
600 		return false;
601 
602 	/* Data size has to fit in allocated buffer */
603 	if (s > key->alloc_size)
604 		return false;
605 	key->key_size = s;
606 	memcpy(key + 1, (const uint8_t *)data + *offs, s);
607 	(*offs) += s;
608 	return true;
609 }
610 
611 
612 static TEE_Result op_attr_secret_value_from_obj(void *attr, void *src_attr)
613 {
614 	struct tee_cryp_obj_secret *key = attr;
615 	struct tee_cryp_obj_secret *src_key = src_attr;
616 
617 	if (src_key->key_size > key->alloc_size)
618 		return TEE_ERROR_BAD_STATE;
619 	memcpy(key + 1, src_key + 1, src_key->key_size);
620 	key->key_size = src_key->key_size;
621 	return TEE_SUCCESS;
622 }
623 
624 static void op_attr_secret_value_clear(void *attr)
625 {
626 	struct tee_cryp_obj_secret *key = attr;
627 
628 	key->key_size = 0;
629 	memset(key + 1, 0, key->alloc_size);
630 }
631 
632 static TEE_Result op_attr_bignum_from_user(void *attr, const void *buffer,
633 					   size_t size)
634 {
635 	struct bignum **bn = attr;
636 
637 	if (!crypto_ops.bignum.bin2bn)
638 		return TEE_ERROR_NOT_IMPLEMENTED;
639 	return crypto_ops.bignum.bin2bn(buffer, size, *bn);
640 }
641 
642 static TEE_Result op_attr_bignum_to_user(void *attr,
643 					 struct tee_ta_session *sess,
644 					 void *buffer, uint64_t *size)
645 {
646 	TEE_Result res;
647 	struct bignum **bn = attr;
648 	uint64_t req_size;
649 	uint64_t s;
650 
651 	res = tee_svc_copy_from_user(&s, size, sizeof(s));
652 	if (res != TEE_SUCCESS)
653 		return res;
654 
655 	req_size = crypto_ops.bignum.num_bytes(*bn);
656 	res = tee_svc_copy_to_user(size, &req_size, sizeof(req_size));
657 	if (res != TEE_SUCCESS)
658 		return res;
659 	if (!req_size)
660 		return TEE_SUCCESS;
661 	if (s < req_size)
662 		return TEE_ERROR_SHORT_BUFFER;
663 
664 	/* Check we can access data using supplied user mode pointer */
665 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
666 					  TEE_MEMORY_ACCESS_READ |
667 					  TEE_MEMORY_ACCESS_WRITE |
668 					  TEE_MEMORY_ACCESS_ANY_OWNER,
669 					  (uaddr_t)buffer, req_size);
670 	if (res != TEE_SUCCESS)
671 		return res;
672 	/*
673 	* Write the bignum (wich raw data points to) into an array of
674 	* bytes (stored in buffer)
675 	*/
676 	crypto_ops.bignum.bn2bin(*bn, buffer);
677 	return TEE_SUCCESS;
678 }
679 
680 static void op_attr_bignum_to_binary(void *attr, void *data, size_t data_len,
681 				     size_t *offs)
682 {
683 	struct bignum **bn = attr;
684 	uint32_t n = crypto_ops.bignum.num_bytes(*bn);
685 
686 	op_u32_to_binary_helper(n, data, data_len, offs);
687 
688 	if (data && (*offs + n) <= data_len)
689 		crypto_ops.bignum.bn2bin(*bn, (uint8_t *)data + *offs);
690 	(*offs) += n;
691 }
692 
693 static bool op_attr_bignum_from_binary(void *attr, const void *data,
694 				       size_t data_len, size_t *offs)
695 {
696 	struct bignum **bn = attr;
697 	uint32_t n;
698 
699 	if (!op_u32_from_binary_helper(&n, data, data_len, offs))
700 		return false;
701 
702 	if ((*offs + n) > data_len)
703 		return false;
704 	if (crypto_ops.bignum.bin2bn((const uint8_t *)data + *offs,
705 				     n, *bn) != TEE_SUCCESS)
706 		return false;
707 	(*offs) += n;
708 	return true;
709 }
710 
711 static TEE_Result op_attr_bignum_from_obj(void *attr, void *src_attr)
712 {
713 	struct bignum **bn = attr;
714 	struct bignum **src_bn = src_attr;
715 
716 	crypto_ops.bignum.copy(*bn, *src_bn);
717 	return TEE_SUCCESS;
718 }
719 
720 static void op_attr_bignum_clear(void *attr)
721 {
722 	struct bignum **bn = attr;
723 
724 	crypto_ops.bignum.clear(*bn);
725 }
726 
727 static void op_attr_bignum_free(void *attr)
728 {
729 	struct bignum **bn = attr;
730 
731 	crypto_ops.bignum.free(*bn);
732 	*bn = NULL;
733 }
734 
735 static TEE_Result op_attr_value_from_user(void *attr, const void *buffer,
736 					  size_t size)
737 {
738 	uint32_t *v = attr;
739 
740 	if (size != sizeof(uint32_t) * 2)
741 		return TEE_ERROR_GENERIC; /* "can't happen */
742 
743 	/* Note that only the first value is copied */
744 	memcpy(v, buffer, sizeof(uint32_t));
745 	return TEE_SUCCESS;
746 }
747 
748 static TEE_Result op_attr_value_to_user(void *attr,
749 					struct tee_ta_session *sess __unused,
750 					void *buffer, uint64_t *size)
751 {
752 	TEE_Result res;
753 	uint32_t *v = attr;
754 	uint64_t s;
755 	uint32_t value[2] = { *v };
756 	uint64_t req_size = sizeof(value);
757 
758 	res = tee_svc_copy_from_user(&s, size, sizeof(s));
759 	if (res != TEE_SUCCESS)
760 		return res;
761 
762 	if (s < req_size)
763 		return TEE_ERROR_SHORT_BUFFER;
764 
765 	return tee_svc_copy_to_user(buffer, value, req_size);
766 }
767 
768 static void op_attr_value_to_binary(void *attr, void *data, size_t data_len,
769 				    size_t *offs)
770 {
771 	uint32_t *v = attr;
772 
773 	op_u32_to_binary_helper(*v, data, data_len, offs);
774 }
775 
776 static bool op_attr_value_from_binary(void *attr, const void *data,
777 				      size_t data_len, size_t *offs)
778 {
779 	uint32_t *v = attr;
780 
781 	return op_u32_from_binary_helper(v, data, data_len, offs);
782 }
783 
784 static TEE_Result op_attr_value_from_obj(void *attr, void *src_attr)
785 {
786 	uint32_t *v = attr;
787 	uint32_t *src_v = src_attr;
788 
789 	*v = *src_v;
790 	return TEE_SUCCESS;
791 }
792 
793 static void op_attr_value_clear(void *attr)
794 {
795 	uint32_t *v = attr;
796 
797 	*v = 0;
798 }
799 
800 static const struct attr_ops attr_ops[] = {
801 	[ATTR_OPS_INDEX_SECRET] = {
802 		.from_user = op_attr_secret_value_from_user,
803 		.to_user = op_attr_secret_value_to_user,
804 		.to_binary = op_attr_secret_value_to_binary,
805 		.from_binary = op_attr_secret_value_from_binary,
806 		.from_obj = op_attr_secret_value_from_obj,
807 		.free = op_attr_secret_value_clear, /* not a typo */
808 		.clear = op_attr_secret_value_clear,
809 	},
810 	[ATTR_OPS_INDEX_BIGNUM] = {
811 		.from_user = op_attr_bignum_from_user,
812 		.to_user = op_attr_bignum_to_user,
813 		.to_binary = op_attr_bignum_to_binary,
814 		.from_binary = op_attr_bignum_from_binary,
815 		.from_obj = op_attr_bignum_from_obj,
816 		.free = op_attr_bignum_free,
817 		.clear = op_attr_bignum_clear,
818 	},
819 	[ATTR_OPS_INDEX_VALUE] = {
820 		.from_user = op_attr_value_from_user,
821 		.to_user = op_attr_value_to_user,
822 		.to_binary = op_attr_value_to_binary,
823 		.from_binary = op_attr_value_from_binary,
824 		.from_obj = op_attr_value_from_obj,
825 		.free = op_attr_value_clear, /* not a typo */
826 		.clear = op_attr_value_clear,
827 	},
828 };
829 
830 TEE_Result syscall_cryp_obj_get_info(unsigned long obj, TEE_ObjectInfo *info)
831 {
832 	TEE_Result res;
833 	struct tee_ta_session *sess;
834 	struct tee_obj *o;
835 
836 	res = tee_ta_get_current_session(&sess);
837 	if (res != TEE_SUCCESS)
838 		goto exit;
839 
840 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
841 			  tee_svc_uref_to_vaddr(obj), &o);
842 	if (res != TEE_SUCCESS)
843 		goto exit;
844 
845 	res = tee_svc_copy_to_user(info, &o->info, sizeof(o->info));
846 
847 exit:
848 	return res;
849 }
850 
851 TEE_Result syscall_cryp_obj_restrict_usage(unsigned long obj,
852 			unsigned long usage)
853 {
854 	TEE_Result res;
855 	struct tee_ta_session *sess;
856 	struct tee_obj *o;
857 
858 	res = tee_ta_get_current_session(&sess);
859 	if (res != TEE_SUCCESS)
860 		goto exit;
861 
862 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
863 			  tee_svc_uref_to_vaddr(obj), &o);
864 	if (res != TEE_SUCCESS)
865 		goto exit;
866 
867 	o->info.objectUsage &= usage;
868 
869 exit:
870 	return res;
871 }
872 
873 static int tee_svc_cryp_obj_find_type_attr_idx(
874 		uint32_t attr_id,
875 		const struct tee_cryp_obj_type_props *type_props)
876 {
877 	size_t n;
878 
879 	for (n = 0; n < type_props->num_type_attrs; n++) {
880 		if (attr_id == type_props->type_attrs[n].attr_id)
881 			return n;
882 	}
883 	return -1;
884 }
885 
886 static const struct tee_cryp_obj_type_props *tee_svc_find_type_props(
887 		TEE_ObjectType obj_type)
888 {
889 	size_t n;
890 
891 	for (n = 0; n < ARRAY_SIZE(tee_cryp_obj_props); n++) {
892 		if (tee_cryp_obj_props[n].obj_type == obj_type)
893 			return tee_cryp_obj_props + n;
894 	}
895 
896 	return NULL;
897 }
898 
899 /* Set an attribute on an object */
900 static void set_attribute(struct tee_obj *o,
901 			  const struct tee_cryp_obj_type_props *props,
902 			  uint32_t attr)
903 {
904 	int idx = tee_svc_cryp_obj_find_type_attr_idx(attr, props);
905 
906 	if (idx < 0)
907 		return;
908 	o->have_attrs |= BIT(idx);
909 }
910 
911 /* Get an attribute on an object */
912 static uint32_t get_attribute(const struct tee_obj *o,
913 			      const struct tee_cryp_obj_type_props *props,
914 			      uint32_t attr)
915 {
916 	int idx = tee_svc_cryp_obj_find_type_attr_idx(attr, props);
917 
918 	if (idx < 0)
919 		return 0;
920 	return o->have_attrs & BIT(idx);
921 }
922 
923 TEE_Result syscall_cryp_obj_get_attr(unsigned long obj, unsigned long attr_id,
924 			void *buffer, uint64_t *size)
925 {
926 	TEE_Result res;
927 	struct tee_ta_session *sess;
928 	struct tee_obj *o;
929 	const struct tee_cryp_obj_type_props *type_props;
930 	int idx;
931 	const struct attr_ops *ops;
932 	void *attr;
933 
934 	res = tee_ta_get_current_session(&sess);
935 	if (res != TEE_SUCCESS)
936 		return res;
937 
938 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
939 			  tee_svc_uref_to_vaddr(obj), &o);
940 	if (res != TEE_SUCCESS)
941 		return TEE_ERROR_ITEM_NOT_FOUND;
942 
943 	/* Check that the object is initialized */
944 	if (!(o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
945 		return TEE_ERROR_BAD_PARAMETERS;
946 
947 	/* Check that getting the attribute is allowed */
948 	if (!(attr_id & TEE_ATTR_BIT_PROTECTED) &&
949 	    !(o->info.objectUsage & TEE_USAGE_EXTRACTABLE))
950 		return TEE_ERROR_BAD_PARAMETERS;
951 
952 	type_props = tee_svc_find_type_props(o->info.objectType);
953 	if (!type_props) {
954 		/* Unknown object type, "can't happen" */
955 		return TEE_ERROR_BAD_STATE;
956 	}
957 
958 	idx = tee_svc_cryp_obj_find_type_attr_idx(attr_id, type_props);
959 	if ((idx < 0) || ((o->have_attrs & (1 << idx)) == 0))
960 		return TEE_ERROR_ITEM_NOT_FOUND;
961 
962 	ops = attr_ops + type_props->type_attrs[idx].ops_index;
963 	attr = (uint8_t *)o->attr + type_props->type_attrs[idx].raw_offs;
964 	return ops->to_user(attr, sess, buffer, size);
965 }
966 
967 void tee_obj_attr_free(struct tee_obj *o)
968 {
969 	const struct tee_cryp_obj_type_props *tp;
970 	size_t n;
971 
972 	if (!o->attr)
973 		return;
974 	tp = tee_svc_find_type_props(o->info.objectType);
975 	if (!tp)
976 		return;
977 
978 	for (n = 0; n < tp->num_type_attrs; n++) {
979 		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
980 
981 		attr_ops[ta->ops_index].free((uint8_t *)o->attr + ta->raw_offs);
982 	}
983 }
984 
985 void tee_obj_attr_clear(struct tee_obj *o)
986 {
987 	const struct tee_cryp_obj_type_props *tp;
988 	size_t n;
989 
990 	if (!o->attr)
991 		return;
992 	tp = tee_svc_find_type_props(o->info.objectType);
993 	if (!tp)
994 		return;
995 
996 	for (n = 0; n < tp->num_type_attrs; n++) {
997 		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
998 
999 		attr_ops[ta->ops_index].clear((uint8_t *)o->attr +
1000 					      ta->raw_offs);
1001 	}
1002 }
1003 
1004 TEE_Result tee_obj_attr_to_binary(struct tee_obj *o, void *data,
1005 				  size_t *data_len)
1006 {
1007 	const struct tee_cryp_obj_type_props *tp;
1008 	size_t n;
1009 	size_t offs = 0;
1010 	size_t len = data ? *data_len : 0;
1011 
1012 	if (o->info.objectType == TEE_TYPE_DATA) {
1013 		*data_len = 0;
1014 		return TEE_SUCCESS; /* pure data object */
1015 	}
1016 	if (!o->attr)
1017 		return TEE_ERROR_BAD_STATE;
1018 	tp = tee_svc_find_type_props(o->info.objectType);
1019 	if (!tp)
1020 		return TEE_ERROR_BAD_STATE;
1021 
1022 	for (n = 0; n < tp->num_type_attrs; n++) {
1023 		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
1024 		void *attr = (uint8_t *)o->attr + ta->raw_offs;
1025 
1026 		attr_ops[ta->ops_index].to_binary(attr, data, len, &offs);
1027 	}
1028 
1029 	*data_len = offs;
1030 	if (data && offs > len)
1031 		return TEE_ERROR_SHORT_BUFFER;
1032 	return TEE_SUCCESS;
1033 }
1034 
1035 TEE_Result tee_obj_attr_from_binary(struct tee_obj *o, const void *data,
1036 				    size_t data_len)
1037 {
1038 	const struct tee_cryp_obj_type_props *tp;
1039 	size_t n;
1040 	size_t offs = 0;
1041 
1042 	if (o->info.objectType == TEE_TYPE_DATA)
1043 		return TEE_SUCCESS; /* pure data object */
1044 	if (!o->attr)
1045 		return TEE_ERROR_BAD_STATE;
1046 	tp = tee_svc_find_type_props(o->info.objectType);
1047 	if (!tp)
1048 		return TEE_ERROR_BAD_STATE;
1049 
1050 	for (n = 0; n < tp->num_type_attrs; n++) {
1051 		const struct tee_cryp_obj_type_attrs *ta = tp->type_attrs + n;
1052 		void *attr = (uint8_t *)o->attr + ta->raw_offs;
1053 
1054 		if (!attr_ops[ta->ops_index].from_binary(attr, data, data_len,
1055 							 &offs))
1056 			return TEE_ERROR_CORRUPT_OBJECT;
1057 	}
1058 	return TEE_SUCCESS;
1059 }
1060 
1061 TEE_Result tee_obj_attr_copy_from(struct tee_obj *o, const struct tee_obj *src)
1062 {
1063 	TEE_Result res;
1064 	const struct tee_cryp_obj_type_props *tp;
1065 	const struct tee_cryp_obj_type_attrs *ta;
1066 	size_t n;
1067 	uint32_t have_attrs = 0;
1068 	void *attr;
1069 	void *src_attr;
1070 
1071 	if (o->info.objectType == TEE_TYPE_DATA)
1072 		return TEE_SUCCESS; /* pure data object */
1073 	if (!o->attr)
1074 		return TEE_ERROR_BAD_STATE;
1075 	tp = tee_svc_find_type_props(o->info.objectType);
1076 	if (!tp)
1077 		return TEE_ERROR_BAD_STATE;
1078 
1079 	if (o->info.objectType == src->info.objectType) {
1080 		have_attrs = src->have_attrs;
1081 		for (n = 0; n < tp->num_type_attrs; n++) {
1082 			ta = tp->type_attrs + n;
1083 			attr = (uint8_t *)o->attr + ta->raw_offs;
1084 			src_attr = (uint8_t *)src->attr + ta->raw_offs;
1085 			res = attr_ops[ta->ops_index].from_obj(attr, src_attr);
1086 			if (res != TEE_SUCCESS)
1087 				return res;
1088 		}
1089 	} else {
1090 		const struct tee_cryp_obj_type_props *tp_src;
1091 		int idx;
1092 
1093 		if (o->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY) {
1094 			if (src->info.objectType != TEE_TYPE_RSA_KEYPAIR)
1095 				return TEE_ERROR_BAD_PARAMETERS;
1096 		} else if (o->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY) {
1097 			if (src->info.objectType != TEE_TYPE_DSA_KEYPAIR)
1098 				return TEE_ERROR_BAD_PARAMETERS;
1099 		} else if (o->info.objectType == TEE_TYPE_ECDSA_PUBLIC_KEY) {
1100 			if (src->info.objectType != TEE_TYPE_ECDSA_KEYPAIR)
1101 				return TEE_ERROR_BAD_PARAMETERS;
1102 		} else if (o->info.objectType == TEE_TYPE_ECDH_PUBLIC_KEY) {
1103 			if (src->info.objectType != TEE_TYPE_ECDH_KEYPAIR)
1104 				return TEE_ERROR_BAD_PARAMETERS;
1105 		} else {
1106 			return TEE_ERROR_BAD_PARAMETERS;
1107 		}
1108 
1109 		tp_src = tee_svc_find_type_props(src->info.objectType);
1110 		if (!tp_src)
1111 			return TEE_ERROR_BAD_STATE;
1112 
1113 		have_attrs = BIT32(tp->num_type_attrs) - 1;
1114 		for (n = 0; n < tp->num_type_attrs; n++) {
1115 			ta = tp->type_attrs + n;
1116 
1117 			idx = tee_svc_cryp_obj_find_type_attr_idx(ta->attr_id,
1118 								  tp_src);
1119 			if (idx < 0)
1120 				return TEE_ERROR_BAD_STATE;
1121 
1122 			attr = (uint8_t *)o->attr + ta->raw_offs;
1123 			src_attr = (uint8_t *)src->attr +
1124 				   tp_src->type_attrs[idx].raw_offs;
1125 			res = attr_ops[ta->ops_index].from_obj(attr, src_attr);
1126 			if (res != TEE_SUCCESS)
1127 				return res;
1128 		}
1129 	}
1130 
1131 	o->have_attrs = have_attrs;
1132 	return TEE_SUCCESS;
1133 }
1134 
1135 TEE_Result tee_obj_set_type(struct tee_obj *o, uint32_t obj_type,
1136 			    size_t max_key_size)
1137 {
1138 	TEE_Result res = TEE_SUCCESS;
1139 	const struct tee_cryp_obj_type_props *type_props;
1140 
1141 	/* Can only set type for newly allocated objs */
1142 	if (o->attr)
1143 		return TEE_ERROR_BAD_STATE;
1144 
1145 	/*
1146 	 * Verify that maxKeySize is supported and find out how
1147 	 * much should be allocated.
1148 	 */
1149 
1150 	if (obj_type == TEE_TYPE_DATA) {
1151 		if (max_key_size)
1152 			return TEE_ERROR_NOT_SUPPORTED;
1153 	} else {
1154 		/* Find description of object */
1155 		type_props = tee_svc_find_type_props(obj_type);
1156 		if (!type_props)
1157 			return TEE_ERROR_NOT_SUPPORTED;
1158 
1159 		/* Check that maxKeySize follows restrictions */
1160 		if (max_key_size % type_props->quanta != 0)
1161 			return TEE_ERROR_NOT_SUPPORTED;
1162 		if (max_key_size < type_props->min_size)
1163 			return TEE_ERROR_NOT_SUPPORTED;
1164 		if (max_key_size > type_props->max_size)
1165 			return TEE_ERROR_NOT_SUPPORTED;
1166 
1167 		o->attr = calloc(1, type_props->alloc_size);
1168 		if (!o->attr)
1169 			return TEE_ERROR_OUT_OF_MEMORY;
1170 	}
1171 
1172 	/* If we have a key structure, pre-allocate the bignums inside */
1173 	switch (obj_type) {
1174 	case TEE_TYPE_RSA_PUBLIC_KEY:
1175 		if (!crypto_ops.acipher.alloc_rsa_public_key)
1176 			return TEE_ERROR_NOT_IMPLEMENTED;
1177 		res = crypto_ops.acipher.alloc_rsa_public_key(o->attr,
1178 							      max_key_size);
1179 		break;
1180 	case TEE_TYPE_RSA_KEYPAIR:
1181 		if (!crypto_ops.acipher.alloc_rsa_keypair)
1182 			return TEE_ERROR_NOT_IMPLEMENTED;
1183 		res = crypto_ops.acipher.alloc_rsa_keypair(o->attr,
1184 							   max_key_size);
1185 		break;
1186 	case TEE_TYPE_DSA_PUBLIC_KEY:
1187 		if (!crypto_ops.acipher.alloc_dsa_public_key)
1188 			return TEE_ERROR_NOT_IMPLEMENTED;
1189 		res = crypto_ops.acipher.alloc_dsa_public_key(o->attr,
1190 							      max_key_size);
1191 		break;
1192 	case TEE_TYPE_DSA_KEYPAIR:
1193 		if (!crypto_ops.acipher.alloc_dsa_keypair)
1194 			return TEE_ERROR_NOT_IMPLEMENTED;
1195 		res = crypto_ops.acipher.alloc_dsa_keypair(o->attr,
1196 							   max_key_size);
1197 		break;
1198 	case TEE_TYPE_DH_KEYPAIR:
1199 		if (!crypto_ops.acipher.alloc_dh_keypair)
1200 			return TEE_ERROR_NOT_IMPLEMENTED;
1201 		res = crypto_ops.acipher.alloc_dh_keypair(o->attr,
1202 							  max_key_size);
1203 		break;
1204 	case TEE_TYPE_ECDSA_PUBLIC_KEY:
1205 	case TEE_TYPE_ECDH_PUBLIC_KEY:
1206 		if (!crypto_ops.acipher.alloc_ecc_public_key)
1207 			return TEE_ERROR_NOT_IMPLEMENTED;
1208 		res = crypto_ops.acipher.alloc_ecc_public_key(o->attr,
1209 							      max_key_size);
1210 		break;
1211 	case TEE_TYPE_ECDSA_KEYPAIR:
1212 	case TEE_TYPE_ECDH_KEYPAIR:
1213 		if (!crypto_ops.acipher.alloc_ecc_keypair)
1214 			return TEE_ERROR_NOT_IMPLEMENTED;
1215 		res = crypto_ops.acipher.alloc_ecc_keypair(o->attr,
1216 							   max_key_size);
1217 		break;
1218 	default:
1219 		if (obj_type != TEE_TYPE_DATA) {
1220 			struct tee_cryp_obj_secret *key = o->attr;
1221 
1222 			key->alloc_size = type_props->alloc_size -
1223 					  sizeof(*key);
1224 		}
1225 		break;
1226 	}
1227 
1228 	if (res != TEE_SUCCESS)
1229 		return res;
1230 
1231 	o->info.objectType = obj_type;
1232 	o->info.maxKeySize = max_key_size;
1233 	o->info.objectUsage = TEE_USAGE_DEFAULT;
1234 
1235 	return TEE_SUCCESS;
1236 }
1237 
1238 TEE_Result syscall_cryp_obj_alloc(unsigned long obj_type,
1239 			unsigned long max_key_size, uint32_t *obj)
1240 {
1241 	TEE_Result res;
1242 	struct tee_ta_session *sess;
1243 	struct tee_obj *o;
1244 
1245 	if (obj_type == TEE_TYPE_DATA)
1246 		return TEE_ERROR_NOT_SUPPORTED;
1247 
1248 	res = tee_ta_get_current_session(&sess);
1249 	if (res != TEE_SUCCESS)
1250 		return res;
1251 
1252 	o = tee_obj_alloc();
1253 	if (!o)
1254 		return TEE_ERROR_OUT_OF_MEMORY;
1255 
1256 	res = tee_obj_set_type(o, obj_type, max_key_size);
1257 	if (res != TEE_SUCCESS) {
1258 		tee_obj_free(o);
1259 		return res;
1260 	}
1261 
1262 	tee_obj_add(to_user_ta_ctx(sess->ctx), o);
1263 
1264 	res = tee_svc_copy_kaddr_to_uref(obj, o);
1265 	if (res != TEE_SUCCESS)
1266 		tee_obj_close(to_user_ta_ctx(sess->ctx), o);
1267 	return res;
1268 }
1269 
1270 TEE_Result syscall_cryp_obj_close(unsigned long obj)
1271 {
1272 	TEE_Result res;
1273 	struct tee_ta_session *sess;
1274 	struct tee_obj *o;
1275 
1276 	res = tee_ta_get_current_session(&sess);
1277 	if (res != TEE_SUCCESS)
1278 		return res;
1279 
1280 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1281 			  tee_svc_uref_to_vaddr(obj), &o);
1282 	if (res != TEE_SUCCESS)
1283 		return res;
1284 
1285 	/*
1286 	 * If it's busy it's used by an operation, a client should never have
1287 	 * this handle.
1288 	 */
1289 	if (o->busy)
1290 		return TEE_ERROR_ITEM_NOT_FOUND;
1291 
1292 	tee_obj_close(to_user_ta_ctx(sess->ctx), o);
1293 	return TEE_SUCCESS;
1294 }
1295 
1296 TEE_Result syscall_cryp_obj_reset(unsigned long obj)
1297 {
1298 	TEE_Result res;
1299 	struct tee_ta_session *sess;
1300 	struct tee_obj *o;
1301 
1302 	res = tee_ta_get_current_session(&sess);
1303 	if (res != TEE_SUCCESS)
1304 		return res;
1305 
1306 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1307 			  tee_svc_uref_to_vaddr(obj), &o);
1308 	if (res != TEE_SUCCESS)
1309 		return res;
1310 
1311 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) == 0) {
1312 		tee_obj_attr_clear(o);
1313 		o->info.keySize = 0;
1314 		o->info.objectUsage = TEE_USAGE_DEFAULT;
1315 	} else {
1316 		return TEE_ERROR_BAD_PARAMETERS;
1317 	}
1318 
1319 	/* the object is no more initialized */
1320 	o->info.handleFlags &= ~TEE_HANDLE_FLAG_INITIALIZED;
1321 
1322 	return TEE_SUCCESS;
1323 }
1324 
1325 static TEE_Result copy_in_attrs(struct user_ta_ctx *utc,
1326 			const struct utee_attribute *usr_attrs,
1327 			uint32_t attr_count, TEE_Attribute *attrs)
1328 {
1329 	TEE_Result res;
1330 	uint32_t n;
1331 
1332 	res = tee_mmu_check_access_rights(utc,
1333 			TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER,
1334 			(uaddr_t)usr_attrs,
1335 			attr_count * sizeof(struct utee_attribute));
1336 	if (res != TEE_SUCCESS)
1337 		return res;
1338 
1339 	for (n = 0; n < attr_count; n++) {
1340 		attrs[n].attributeID = usr_attrs[n].attribute_id;
1341 		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
1342 			attrs[n].content.value.a = usr_attrs[n].a;
1343 			attrs[n].content.value.b = usr_attrs[n].b;
1344 		} else {
1345 			uintptr_t buf = usr_attrs[n].a;
1346 			size_t len = usr_attrs[n].b;
1347 
1348 			res = tee_mmu_check_access_rights(utc,
1349 				TEE_MEMORY_ACCESS_READ |
1350 				TEE_MEMORY_ACCESS_ANY_OWNER, buf, len);
1351 			if (res != TEE_SUCCESS)
1352 				return res;
1353 			attrs[n].content.ref.buffer = (void *)buf;
1354 			attrs[n].content.ref.length = len;
1355 		}
1356 	}
1357 
1358 	return TEE_SUCCESS;
1359 }
1360 
1361 enum attr_usage {
1362 	ATTR_USAGE_POPULATE,
1363 	ATTR_USAGE_GENERATE_KEY
1364 };
1365 
1366 static TEE_Result tee_svc_cryp_check_attr(enum attr_usage usage,
1367 					  const struct tee_cryp_obj_type_props
1368 						*type_props,
1369 					  const TEE_Attribute *attrs,
1370 					  uint32_t attr_count)
1371 {
1372 	uint32_t required_flag;
1373 	uint32_t opt_flag;
1374 	bool all_opt_needed;
1375 	uint32_t req_attrs = 0;
1376 	uint32_t opt_grp_attrs = 0;
1377 	uint32_t attrs_found = 0;
1378 	size_t n;
1379 	uint32_t bit;
1380 	uint32_t flags;
1381 	int idx;
1382 
1383 	if (usage == ATTR_USAGE_POPULATE) {
1384 		required_flag = TEE_TYPE_ATTR_REQUIRED;
1385 		opt_flag = TEE_TYPE_ATTR_OPTIONAL_GROUP;
1386 		all_opt_needed = true;
1387 	} else {
1388 		required_flag = TEE_TYPE_ATTR_GEN_KEY_REQ;
1389 		opt_flag = TEE_TYPE_ATTR_GEN_KEY_OPT;
1390 		all_opt_needed = false;
1391 	}
1392 
1393 	/*
1394 	 * First find out which attributes are required and which belong to
1395 	 * the optional group
1396 	 */
1397 	for (n = 0; n < type_props->num_type_attrs; n++) {
1398 		bit = 1 << n;
1399 		flags = type_props->type_attrs[n].flags;
1400 
1401 		if (flags & required_flag)
1402 			req_attrs |= bit;
1403 		else if (flags & opt_flag)
1404 			opt_grp_attrs |= bit;
1405 	}
1406 
1407 	/*
1408 	 * Verify that all required attributes are in place and
1409 	 * that the same attribute isn't repeated.
1410 	 */
1411 	for (n = 0; n < attr_count; n++) {
1412 		idx = tee_svc_cryp_obj_find_type_attr_idx(
1413 							attrs[n].attributeID,
1414 							type_props);
1415 
1416 		/* attribute not defined in current object type */
1417 		if (idx < 0)
1418 			return TEE_ERROR_ITEM_NOT_FOUND;
1419 
1420 		bit = 1 << idx;
1421 
1422 		/* attribute not repeated */
1423 		if ((attrs_found & bit) != 0)
1424 			return TEE_ERROR_ITEM_NOT_FOUND;
1425 
1426 		attrs_found |= bit;
1427 	}
1428 	/* Required attribute missing */
1429 	if ((attrs_found & req_attrs) != req_attrs)
1430 		return TEE_ERROR_ITEM_NOT_FOUND;
1431 
1432 	/*
1433 	 * If the flag says that "if one of the optional attributes are included
1434 	 * all of them has to be included" this must be checked.
1435 	 */
1436 	if (all_opt_needed && (attrs_found & opt_grp_attrs) != 0 &&
1437 	    (attrs_found & opt_grp_attrs) != opt_grp_attrs)
1438 		return TEE_ERROR_ITEM_NOT_FOUND;
1439 
1440 	return TEE_SUCCESS;
1441 }
1442 
1443 static TEE_Result tee_svc_cryp_obj_populate_type(
1444 		struct tee_obj *o,
1445 		const struct tee_cryp_obj_type_props *type_props,
1446 		const TEE_Attribute *attrs,
1447 		uint32_t attr_count)
1448 {
1449 	TEE_Result res;
1450 	uint32_t have_attrs = 0;
1451 	size_t obj_size = 0;
1452 	size_t n;
1453 	int idx;
1454 	const struct attr_ops *ops;
1455 	void *attr;
1456 
1457 	for (n = 0; n < attr_count; n++) {
1458 		idx = tee_svc_cryp_obj_find_type_attr_idx(
1459 							attrs[n].attributeID,
1460 							type_props);
1461 		/* attribute not defined in current object type */
1462 		if (idx < 0)
1463 			return TEE_ERROR_ITEM_NOT_FOUND;
1464 
1465 		have_attrs |= BIT32(idx);
1466 		ops = attr_ops + type_props->type_attrs[idx].ops_index;
1467 		attr = (uint8_t *)o->attr +
1468 		       type_props->type_attrs[idx].raw_offs;
1469 		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE)
1470 			res = ops->from_user(attr, &attrs[n].content.value,
1471 					     sizeof(attrs[n].content.value));
1472 		else
1473 			res = ops->from_user(attr, attrs[n].content.ref.buffer,
1474 					     attrs[n].content.ref.length);
1475 		if (res != TEE_SUCCESS)
1476 			return res;
1477 
1478 		/*
1479 		 * First attr_idx signifies the attribute that gives the size
1480 		 * of the object
1481 		 */
1482 		if (type_props->type_attrs[idx].flags &
1483 		    TEE_TYPE_ATTR_SIZE_INDICATOR)
1484 			obj_size += attrs[n].content.ref.length * 8;
1485 	}
1486 
1487 	/*
1488 	 * We have to do it like this because the parity bits aren't counted
1489 	 * when telling the size of the key in bits.
1490 	 */
1491 	if (o->info.objectType == TEE_TYPE_DES ||
1492 	    o->info.objectType == TEE_TYPE_DES3)
1493 		obj_size -= obj_size / 8; /* Exclude parity in size of key */
1494 
1495 	o->have_attrs = have_attrs;
1496 	o->info.keySize = obj_size;
1497 
1498 	return TEE_SUCCESS;
1499 }
1500 
1501 TEE_Result syscall_cryp_obj_populate(unsigned long obj,
1502 			struct utee_attribute *usr_attrs,
1503 			unsigned long attr_count)
1504 {
1505 	TEE_Result res;
1506 	struct tee_ta_session *sess;
1507 	struct tee_obj *o;
1508 	const struct tee_cryp_obj_type_props *type_props;
1509 	TEE_Attribute *attrs = NULL;
1510 
1511 	res = tee_ta_get_current_session(&sess);
1512 	if (res != TEE_SUCCESS)
1513 		return res;
1514 
1515 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1516 			  tee_svc_uref_to_vaddr(obj), &o);
1517 	if (res != TEE_SUCCESS)
1518 		return res;
1519 
1520 	/* Must be a transient object */
1521 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1522 		return TEE_ERROR_BAD_PARAMETERS;
1523 
1524 	/* Must not be initialized already */
1525 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1526 		return TEE_ERROR_BAD_PARAMETERS;
1527 
1528 	type_props = tee_svc_find_type_props(o->info.objectType);
1529 	if (!type_props)
1530 		return TEE_ERROR_NOT_IMPLEMENTED;
1531 
1532 	attrs = malloc(sizeof(TEE_Attribute) * attr_count);
1533 	if (!attrs)
1534 		return TEE_ERROR_OUT_OF_MEMORY;
1535 	res = copy_in_attrs(to_user_ta_ctx(sess->ctx), usr_attrs, attr_count,
1536 			    attrs);
1537 	if (res != TEE_SUCCESS)
1538 		goto out;
1539 
1540 	res = tee_svc_cryp_check_attr(ATTR_USAGE_POPULATE, type_props,
1541 				      attrs, attr_count);
1542 	if (res != TEE_SUCCESS)
1543 		goto out;
1544 
1545 	res = tee_svc_cryp_obj_populate_type(o, type_props, attrs, attr_count);
1546 	if (res == TEE_SUCCESS)
1547 		o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1548 
1549 out:
1550 	free(attrs);
1551 	return res;
1552 }
1553 
1554 TEE_Result syscall_cryp_obj_copy(unsigned long dst, unsigned long src)
1555 {
1556 	TEE_Result res;
1557 	struct tee_ta_session *sess;
1558 	struct tee_obj *dst_o;
1559 	struct tee_obj *src_o;
1560 
1561 	res = tee_ta_get_current_session(&sess);
1562 	if (res != TEE_SUCCESS)
1563 		return res;
1564 
1565 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1566 			  tee_svc_uref_to_vaddr(dst), &dst_o);
1567 	if (res != TEE_SUCCESS)
1568 		return res;
1569 
1570 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1571 			  tee_svc_uref_to_vaddr(src), &src_o);
1572 	if (res != TEE_SUCCESS)
1573 		return res;
1574 
1575 	if ((src_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1576 		return TEE_ERROR_BAD_PARAMETERS;
1577 	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1578 		return TEE_ERROR_BAD_PARAMETERS;
1579 	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1580 		return TEE_ERROR_BAD_PARAMETERS;
1581 
1582 	res = tee_obj_attr_copy_from(dst_o, src_o);
1583 	if (res != TEE_SUCCESS)
1584 		return res;
1585 
1586 	dst_o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1587 	dst_o->info.keySize = src_o->info.keySize;
1588 	dst_o->info.objectUsage = src_o->info.objectUsage;
1589 	return TEE_SUCCESS;
1590 }
1591 
1592 static TEE_Result tee_svc_obj_generate_key_rsa(
1593 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1594 	uint32_t key_size,
1595 	const TEE_Attribute *params, uint32_t param_count)
1596 {
1597 	TEE_Result res;
1598 	struct rsa_keypair *key = o->attr;
1599 	uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537);
1600 
1601 	if (!crypto_ops.acipher.gen_rsa_key || !crypto_ops.bignum.bin2bn)
1602 		return TEE_ERROR_NOT_IMPLEMENTED;
1603 
1604 	/* Copy the present attributes into the obj before starting */
1605 	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
1606 					     param_count);
1607 	if (res != TEE_SUCCESS)
1608 		return res;
1609 	if (!get_attribute(o, type_props, TEE_ATTR_RSA_PUBLIC_EXPONENT))
1610 		crypto_ops.bignum.bin2bn((const uint8_t *)&e, sizeof(e),
1611 					 key->e);
1612 	res = crypto_ops.acipher.gen_rsa_key(key, key_size);
1613 	if (res != TEE_SUCCESS)
1614 		return res;
1615 
1616 	/* Set bits for all known attributes for this object type */
1617 	o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1618 
1619 	return TEE_SUCCESS;
1620 }
1621 
1622 static TEE_Result tee_svc_obj_generate_key_dsa(
1623 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1624 	uint32_t key_size)
1625 {
1626 	TEE_Result res;
1627 
1628 	if (!crypto_ops.acipher.gen_dsa_key)
1629 		return TEE_ERROR_NOT_IMPLEMENTED;
1630 	res = crypto_ops.acipher.gen_dsa_key(o->attr, key_size);
1631 	if (res != TEE_SUCCESS)
1632 		return res;
1633 
1634 	/* Set bits for all known attributes for this object type */
1635 	o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1636 
1637 	return TEE_SUCCESS;
1638 }
1639 
1640 static TEE_Result tee_svc_obj_generate_key_dh(
1641 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1642 	uint32_t key_size __unused,
1643 	const TEE_Attribute *params, uint32_t param_count)
1644 {
1645 	TEE_Result res;
1646 	struct dh_keypair *tee_dh_key;
1647 	struct bignum *dh_q = NULL;
1648 	uint32_t dh_xbits = 0;
1649 
1650 	/* Copy the present attributes into the obj before starting */
1651 	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
1652 					     param_count);
1653 	if (res != TEE_SUCCESS)
1654 		return res;
1655 
1656 	tee_dh_key = (struct dh_keypair *)o->attr;
1657 
1658 	if (get_attribute(o, type_props, TEE_ATTR_DH_SUBPRIME))
1659 		dh_q = tee_dh_key->q;
1660 	if (get_attribute(o, type_props, TEE_ATTR_DH_X_BITS))
1661 		dh_xbits = tee_dh_key->xbits;
1662 	if (!crypto_ops.acipher.gen_dh_key)
1663 		return TEE_ERROR_NOT_IMPLEMENTED;
1664 	res = crypto_ops.acipher.gen_dh_key(tee_dh_key, dh_q, dh_xbits);
1665 	if (res != TEE_SUCCESS)
1666 		return res;
1667 
1668 	/* Set bits for the generated public and private key */
1669 	set_attribute(o, type_props, TEE_ATTR_DH_PUBLIC_VALUE);
1670 	set_attribute(o, type_props, TEE_ATTR_DH_PRIVATE_VALUE);
1671 	set_attribute(o, type_props, TEE_ATTR_DH_X_BITS);
1672 	return TEE_SUCCESS;
1673 }
1674 
1675 static TEE_Result tee_svc_obj_generate_key_ecc(
1676 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1677 	uint32_t key_size __unused,
1678 	const TEE_Attribute *params, uint32_t param_count)
1679 {
1680 	TEE_Result res;
1681 	struct ecc_keypair *tee_ecc_key;
1682 
1683 	/* Copy the present attributes into the obj before starting */
1684 	res = tee_svc_cryp_obj_populate_type(o, type_props, params,
1685 					     param_count);
1686 	if (res != TEE_SUCCESS)
1687 		return res;
1688 
1689 	tee_ecc_key = (struct ecc_keypair *)o->attr;
1690 
1691 	if (!crypto_ops.acipher.gen_ecc_key)
1692 		return TEE_ERROR_NOT_IMPLEMENTED;
1693 	res = crypto_ops.acipher.gen_ecc_key(tee_ecc_key);
1694 	if (res != TEE_SUCCESS)
1695 		return res;
1696 
1697 	/* Set bits for the generated public and private key */
1698 	set_attribute(o, type_props, TEE_ATTR_ECC_PRIVATE_VALUE);
1699 	set_attribute(o, type_props, TEE_ATTR_ECC_PUBLIC_VALUE_X);
1700 	set_attribute(o, type_props, TEE_ATTR_ECC_PUBLIC_VALUE_Y);
1701 	set_attribute(o, type_props, TEE_ATTR_ECC_CURVE);
1702 	return TEE_SUCCESS;
1703 }
1704 
1705 TEE_Result syscall_obj_generate_key(unsigned long obj, unsigned long key_size,
1706 			const struct utee_attribute *usr_params,
1707 			unsigned long param_count)
1708 {
1709 	TEE_Result res;
1710 	struct tee_ta_session *sess;
1711 	const struct tee_cryp_obj_type_props *type_props;
1712 	struct tee_obj *o;
1713 	struct tee_cryp_obj_secret *key;
1714 	size_t byte_size;
1715 	TEE_Attribute *params = NULL;
1716 
1717 	res = tee_ta_get_current_session(&sess);
1718 	if (res != TEE_SUCCESS)
1719 		return res;
1720 
1721 	res = tee_obj_get(to_user_ta_ctx(sess->ctx),
1722 			  tee_svc_uref_to_vaddr(obj), &o);
1723 	if (res != TEE_SUCCESS)
1724 		return res;
1725 
1726 	/* Must be a transient object */
1727 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1728 		return TEE_ERROR_BAD_STATE;
1729 
1730 	/* Must not be initialized already */
1731 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1732 		return TEE_ERROR_BAD_STATE;
1733 
1734 	/* Find description of object */
1735 	type_props = tee_svc_find_type_props(o->info.objectType);
1736 	if (!type_props)
1737 		return TEE_ERROR_NOT_SUPPORTED;
1738 
1739 	/* Check that maxKeySize follows restrictions */
1740 	if (key_size % type_props->quanta != 0)
1741 		return TEE_ERROR_NOT_SUPPORTED;
1742 	if (key_size < type_props->min_size)
1743 		return TEE_ERROR_NOT_SUPPORTED;
1744 	if (key_size > type_props->max_size)
1745 		return TEE_ERROR_NOT_SUPPORTED;
1746 
1747 	params = malloc(sizeof(TEE_Attribute) * param_count);
1748 	if (!params)
1749 		return TEE_ERROR_OUT_OF_MEMORY;
1750 	res = copy_in_attrs(to_user_ta_ctx(sess->ctx), usr_params, param_count,
1751 			    params);
1752 	if (res != TEE_SUCCESS)
1753 		goto out;
1754 
1755 	res = tee_svc_cryp_check_attr(ATTR_USAGE_GENERATE_KEY, type_props,
1756 				      params, param_count);
1757 	if (res != TEE_SUCCESS)
1758 		goto out;
1759 
1760 	switch (o->info.objectType) {
1761 	case TEE_TYPE_AES:
1762 	case TEE_TYPE_DES:
1763 	case TEE_TYPE_DES3:
1764 	case TEE_TYPE_HMAC_MD5:
1765 	case TEE_TYPE_HMAC_SHA1:
1766 	case TEE_TYPE_HMAC_SHA224:
1767 	case TEE_TYPE_HMAC_SHA256:
1768 	case TEE_TYPE_HMAC_SHA384:
1769 	case TEE_TYPE_HMAC_SHA512:
1770 	case TEE_TYPE_GENERIC_SECRET:
1771 		byte_size = key_size / 8;
1772 
1773 		/*
1774 		 * We have to do it like this because the parity bits aren't
1775 		 * counted when telling the size of the key in bits.
1776 		 */
1777 		if (o->info.objectType == TEE_TYPE_DES ||
1778 		    o->info.objectType == TEE_TYPE_DES3) {
1779 			byte_size = (key_size + key_size / 7) / 8;
1780 		}
1781 
1782 		key = (struct tee_cryp_obj_secret *)o->attr;
1783 		if (byte_size > key->alloc_size) {
1784 			res = TEE_ERROR_EXCESS_DATA;
1785 			goto out;
1786 		}
1787 
1788 		res = crypto_rng_read((void *)(key + 1), byte_size);
1789 		if (res != TEE_SUCCESS)
1790 			goto out;
1791 
1792 		key->key_size = byte_size;
1793 
1794 		/* Set bits for all known attributes for this object type */
1795 		o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1796 
1797 		break;
1798 
1799 	case TEE_TYPE_RSA_KEYPAIR:
1800 		res = tee_svc_obj_generate_key_rsa(o, type_props, key_size,
1801 						   params, param_count);
1802 		if (res != TEE_SUCCESS)
1803 			goto out;
1804 		break;
1805 
1806 	case TEE_TYPE_DSA_KEYPAIR:
1807 		res = tee_svc_obj_generate_key_dsa(o, type_props, key_size);
1808 		if (res != TEE_SUCCESS)
1809 			goto out;
1810 		break;
1811 
1812 	case TEE_TYPE_DH_KEYPAIR:
1813 		res = tee_svc_obj_generate_key_dh(o, type_props, key_size,
1814 						  params, param_count);
1815 		if (res != TEE_SUCCESS)
1816 			goto out;
1817 		break;
1818 
1819 	case TEE_TYPE_ECDSA_KEYPAIR:
1820 	case TEE_TYPE_ECDH_KEYPAIR:
1821 		res = tee_svc_obj_generate_key_ecc(o, type_props, key_size,
1822 						  params, param_count);
1823 		if (res != TEE_SUCCESS)
1824 			goto out;
1825 		break;
1826 
1827 	default:
1828 		res = TEE_ERROR_BAD_FORMAT;
1829 	}
1830 
1831 out:
1832 	free(params);
1833 	if (res == TEE_SUCCESS) {
1834 		o->info.keySize = key_size;
1835 		o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1836 	}
1837 	return res;
1838 }
1839 
1840 static TEE_Result tee_svc_cryp_get_state(struct tee_ta_session *sess,
1841 					 uint32_t state_id,
1842 					 struct tee_cryp_state **state)
1843 {
1844 	struct tee_cryp_state *s;
1845 	struct user_ta_ctx *utc = to_user_ta_ctx(sess->ctx);
1846 
1847 	TAILQ_FOREACH(s, &utc->cryp_states, link) {
1848 		if (state_id == (vaddr_t)s) {
1849 			*state = s;
1850 			return TEE_SUCCESS;
1851 		}
1852 	}
1853 	return TEE_ERROR_BAD_PARAMETERS;
1854 }
1855 
1856 static void cryp_state_free(struct user_ta_ctx *utc, struct tee_cryp_state *cs)
1857 {
1858 	struct tee_obj *o;
1859 
1860 	if (tee_obj_get(utc, cs->key1, &o) == TEE_SUCCESS)
1861 		tee_obj_close(utc, o);
1862 	if (tee_obj_get(utc, cs->key2, &o) == TEE_SUCCESS)
1863 		tee_obj_close(utc, o);
1864 
1865 	TAILQ_REMOVE(&utc->cryp_states, cs, link);
1866 	if (cs->ctx_finalize != NULL)
1867 		cs->ctx_finalize(cs->ctx, cs->algo);
1868 	free(cs->ctx);
1869 	free(cs);
1870 }
1871 
1872 static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o,
1873 					      uint32_t algo,
1874 					      TEE_OperationMode mode)
1875 {
1876 	uint32_t req_key_type;
1877 	uint32_t req_key_type2 = 0;
1878 
1879 	switch (TEE_ALG_GET_MAIN_ALG(algo)) {
1880 	case TEE_MAIN_ALGO_MD5:
1881 		req_key_type = TEE_TYPE_HMAC_MD5;
1882 		break;
1883 	case TEE_MAIN_ALGO_SHA1:
1884 		req_key_type = TEE_TYPE_HMAC_SHA1;
1885 		break;
1886 	case TEE_MAIN_ALGO_SHA224:
1887 		req_key_type = TEE_TYPE_HMAC_SHA224;
1888 		break;
1889 	case TEE_MAIN_ALGO_SHA256:
1890 		req_key_type = TEE_TYPE_HMAC_SHA256;
1891 		break;
1892 	case TEE_MAIN_ALGO_SHA384:
1893 		req_key_type = TEE_TYPE_HMAC_SHA384;
1894 		break;
1895 	case TEE_MAIN_ALGO_SHA512:
1896 		req_key_type = TEE_TYPE_HMAC_SHA512;
1897 		break;
1898 	case TEE_MAIN_ALGO_AES:
1899 		req_key_type = TEE_TYPE_AES;
1900 		break;
1901 	case TEE_MAIN_ALGO_DES:
1902 		req_key_type = TEE_TYPE_DES;
1903 		break;
1904 	case TEE_MAIN_ALGO_DES3:
1905 		req_key_type = TEE_TYPE_DES3;
1906 		break;
1907 	case TEE_MAIN_ALGO_RSA:
1908 		req_key_type = TEE_TYPE_RSA_KEYPAIR;
1909 		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
1910 			req_key_type2 = TEE_TYPE_RSA_PUBLIC_KEY;
1911 		break;
1912 	case TEE_MAIN_ALGO_DSA:
1913 		req_key_type = TEE_TYPE_DSA_KEYPAIR;
1914 		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
1915 			req_key_type2 = TEE_TYPE_DSA_PUBLIC_KEY;
1916 		break;
1917 	case TEE_MAIN_ALGO_DH:
1918 		req_key_type = TEE_TYPE_DH_KEYPAIR;
1919 		break;
1920 	case TEE_MAIN_ALGO_ECDSA:
1921 		req_key_type = TEE_TYPE_ECDSA_KEYPAIR;
1922 		if (mode == TEE_MODE_VERIFY)
1923 			req_key_type2 = TEE_TYPE_ECDSA_PUBLIC_KEY;
1924 		break;
1925 	case TEE_MAIN_ALGO_ECDH:
1926 		req_key_type = TEE_TYPE_ECDH_KEYPAIR;
1927 		break;
1928 #if defined(CFG_CRYPTO_HKDF)
1929 	case TEE_MAIN_ALGO_HKDF:
1930 		req_key_type = TEE_TYPE_HKDF_IKM;
1931 		break;
1932 #endif
1933 #if defined(CFG_CRYPTO_CONCAT_KDF)
1934 	case TEE_MAIN_ALGO_CONCAT_KDF:
1935 		req_key_type = TEE_TYPE_CONCAT_KDF_Z;
1936 		break;
1937 #endif
1938 #if defined(CFG_CRYPTO_PBKDF2)
1939 	case TEE_MAIN_ALGO_PBKDF2:
1940 		req_key_type = TEE_TYPE_PBKDF2_PASSWORD;
1941 		break;
1942 #endif
1943 	default:
1944 		return TEE_ERROR_BAD_PARAMETERS;
1945 	}
1946 
1947 	if (req_key_type != o->info.objectType &&
1948 	    req_key_type2 != o->info.objectType)
1949 		return TEE_ERROR_BAD_PARAMETERS;
1950 	return TEE_SUCCESS;
1951 }
1952 
1953 TEE_Result syscall_cryp_state_alloc(unsigned long algo, unsigned long mode,
1954 			unsigned long key1, unsigned long key2,
1955 			uint32_t *state)
1956 {
1957 	TEE_Result res;
1958 	struct tee_cryp_state *cs;
1959 	struct tee_ta_session *sess;
1960 	struct tee_obj *o1 = NULL;
1961 	struct tee_obj *o2 = NULL;
1962 	struct user_ta_ctx *utc;
1963 
1964 	res = tee_ta_get_current_session(&sess);
1965 	if (res != TEE_SUCCESS)
1966 		return res;
1967 	utc = to_user_ta_ctx(sess->ctx);
1968 
1969 	if (key1 != 0) {
1970 		res = tee_obj_get(utc, tee_svc_uref_to_vaddr(key1), &o1);
1971 		if (res != TEE_SUCCESS)
1972 			return res;
1973 		if (o1->busy)
1974 			return TEE_ERROR_BAD_PARAMETERS;
1975 		res = tee_svc_cryp_check_key_type(o1, algo, mode);
1976 		if (res != TEE_SUCCESS)
1977 			return res;
1978 	}
1979 	if (key2 != 0) {
1980 		res = tee_obj_get(utc, tee_svc_uref_to_vaddr(key2), &o2);
1981 		if (res != TEE_SUCCESS)
1982 			return res;
1983 		if (o2->busy)
1984 			return TEE_ERROR_BAD_PARAMETERS;
1985 		res = tee_svc_cryp_check_key_type(o2, algo, mode);
1986 		if (res != TEE_SUCCESS)
1987 			return res;
1988 	}
1989 
1990 	cs = calloc(1, sizeof(struct tee_cryp_state));
1991 	if (!cs)
1992 		return TEE_ERROR_OUT_OF_MEMORY;
1993 	TAILQ_INSERT_TAIL(&utc->cryp_states, cs, link);
1994 	cs->algo = algo;
1995 	cs->mode = mode;
1996 
1997 	switch (TEE_ALG_GET_CLASS(algo)) {
1998 	case TEE_OPERATION_CIPHER:
1999 		if ((algo == TEE_ALG_AES_XTS && (key1 == 0 || key2 == 0)) ||
2000 		    (algo != TEE_ALG_AES_XTS && (key1 == 0 || key2 != 0))) {
2001 			res = TEE_ERROR_BAD_PARAMETERS;
2002 		} else {
2003 			if (crypto_ops.cipher.get_ctx_size)
2004 				res = crypto_ops.cipher.get_ctx_size(algo,
2005 								&cs->ctx_size);
2006 			else
2007 				res = TEE_ERROR_NOT_IMPLEMENTED;
2008 			if (res != TEE_SUCCESS)
2009 				break;
2010 			cs->ctx = calloc(1, cs->ctx_size);
2011 			if (!cs->ctx)
2012 				res = TEE_ERROR_OUT_OF_MEMORY;
2013 		}
2014 		break;
2015 	case TEE_OPERATION_AE:
2016 		if (key1 == 0 || key2 != 0) {
2017 			res = TEE_ERROR_BAD_PARAMETERS;
2018 		} else {
2019 			if (crypto_ops.authenc.get_ctx_size)
2020 				res = crypto_ops.authenc.get_ctx_size(algo,
2021 								&cs->ctx_size);
2022 			else
2023 				res = TEE_ERROR_NOT_IMPLEMENTED;
2024 			if (res != TEE_SUCCESS)
2025 				break;
2026 			cs->ctx = calloc(1, cs->ctx_size);
2027 			if (!cs->ctx)
2028 				res = TEE_ERROR_OUT_OF_MEMORY;
2029 		}
2030 		break;
2031 	case TEE_OPERATION_MAC:
2032 		if (key1 == 0 || key2 != 0) {
2033 			res = TEE_ERROR_BAD_PARAMETERS;
2034 		} else {
2035 			if (crypto_ops.mac.get_ctx_size)
2036 				res = crypto_ops.mac.get_ctx_size(algo,
2037 								&cs->ctx_size);
2038 			else
2039 				res = TEE_ERROR_NOT_IMPLEMENTED;
2040 			if (res != TEE_SUCCESS)
2041 				break;
2042 			cs->ctx = calloc(1, cs->ctx_size);
2043 			if (!cs->ctx)
2044 				res = TEE_ERROR_OUT_OF_MEMORY;
2045 		}
2046 		break;
2047 	case TEE_OPERATION_DIGEST:
2048 		if (key1 != 0 || key2 != 0) {
2049 			res = TEE_ERROR_BAD_PARAMETERS;
2050 		} else {
2051 			if (crypto_ops.hash.get_ctx_size)
2052 				res = crypto_ops.hash.get_ctx_size(algo,
2053 								&cs->ctx_size);
2054 			else
2055 				res = TEE_ERROR_NOT_IMPLEMENTED;
2056 			if (res != TEE_SUCCESS)
2057 				break;
2058 			cs->ctx = calloc(1, cs->ctx_size);
2059 			if (!cs->ctx)
2060 				res = TEE_ERROR_OUT_OF_MEMORY;
2061 		}
2062 		break;
2063 	case TEE_OPERATION_ASYMMETRIC_CIPHER:
2064 	case TEE_OPERATION_ASYMMETRIC_SIGNATURE:
2065 		if (key1 == 0 || key2 != 0)
2066 			res = TEE_ERROR_BAD_PARAMETERS;
2067 		break;
2068 	case TEE_OPERATION_KEY_DERIVATION:
2069 		if (key1 == 0 || key2 != 0)
2070 			res = TEE_ERROR_BAD_PARAMETERS;
2071 		break;
2072 	default:
2073 		res = TEE_ERROR_NOT_SUPPORTED;
2074 		break;
2075 	}
2076 	if (res != TEE_SUCCESS)
2077 		goto out;
2078 
2079 	res = tee_svc_copy_kaddr_to_uref(state, cs);
2080 	if (res != TEE_SUCCESS)
2081 		goto out;
2082 
2083 	/* Register keys */
2084 	if (o1 != NULL) {
2085 		o1->busy = true;
2086 		cs->key1 = (vaddr_t)o1;
2087 	}
2088 	if (o2 != NULL) {
2089 		o2->busy = true;
2090 		cs->key2 = (vaddr_t)o2;
2091 	}
2092 
2093 out:
2094 	if (res != TEE_SUCCESS)
2095 		cryp_state_free(utc, cs);
2096 	return res;
2097 }
2098 
2099 TEE_Result syscall_cryp_state_copy(unsigned long dst, unsigned long src)
2100 {
2101 	TEE_Result res;
2102 	struct tee_cryp_state *cs_dst;
2103 	struct tee_cryp_state *cs_src;
2104 	struct tee_ta_session *sess;
2105 
2106 	res = tee_ta_get_current_session(&sess);
2107 	if (res != TEE_SUCCESS)
2108 		return res;
2109 
2110 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(dst), &cs_dst);
2111 	if (res != TEE_SUCCESS)
2112 		return res;
2113 
2114 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(src), &cs_src);
2115 	if (res != TEE_SUCCESS)
2116 		return res;
2117 	if (cs_dst->algo != cs_src->algo || cs_dst->mode != cs_src->mode)
2118 		return TEE_ERROR_BAD_PARAMETERS;
2119 	/* "Can't happen" */
2120 	if (cs_dst->ctx_size != cs_src->ctx_size)
2121 		return TEE_ERROR_BAD_STATE;
2122 
2123 	memcpy(cs_dst->ctx, cs_src->ctx, cs_src->ctx_size);
2124 	return TEE_SUCCESS;
2125 }
2126 
2127 void tee_svc_cryp_free_states(struct user_ta_ctx *utc)
2128 {
2129 	struct tee_cryp_state_head *states = &utc->cryp_states;
2130 
2131 	while (!TAILQ_EMPTY(states))
2132 		cryp_state_free(utc, TAILQ_FIRST(states));
2133 }
2134 
2135 TEE_Result syscall_cryp_state_free(unsigned long state)
2136 {
2137 	TEE_Result res;
2138 	struct tee_cryp_state *cs;
2139 	struct tee_ta_session *sess;
2140 
2141 	res = tee_ta_get_current_session(&sess);
2142 	if (res != TEE_SUCCESS)
2143 		return res;
2144 
2145 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2146 	if (res != TEE_SUCCESS)
2147 		return res;
2148 	cryp_state_free(to_user_ta_ctx(sess->ctx), cs);
2149 	return TEE_SUCCESS;
2150 }
2151 
2152 TEE_Result syscall_hash_init(unsigned long state,
2153 			     const void *iv __maybe_unused,
2154 			     size_t iv_len __maybe_unused)
2155 {
2156 	TEE_Result res;
2157 	struct tee_cryp_state *cs;
2158 	struct tee_ta_session *sess;
2159 
2160 	res = tee_ta_get_current_session(&sess);
2161 	if (res != TEE_SUCCESS)
2162 		return res;
2163 
2164 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2165 	if (res != TEE_SUCCESS)
2166 		return res;
2167 
2168 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
2169 	case TEE_OPERATION_DIGEST:
2170 		if (!crypto_ops.hash.init)
2171 			return TEE_ERROR_NOT_IMPLEMENTED;
2172 		res = crypto_ops.hash.init(cs->ctx, cs->algo);
2173 		if (res != TEE_SUCCESS)
2174 			return res;
2175 		break;
2176 	case TEE_OPERATION_MAC:
2177 		{
2178 			struct tee_obj *o;
2179 			struct tee_cryp_obj_secret *key;
2180 
2181 			res = tee_obj_get(to_user_ta_ctx(sess->ctx),
2182 					  cs->key1, &o);
2183 			if (res != TEE_SUCCESS)
2184 				return res;
2185 			if ((o->info.handleFlags &
2186 			     TEE_HANDLE_FLAG_INITIALIZED) == 0)
2187 				return TEE_ERROR_BAD_PARAMETERS;
2188 
2189 			key = (struct tee_cryp_obj_secret *)o->attr;
2190 			if (!crypto_ops.mac.init)
2191 				return TEE_ERROR_NOT_IMPLEMENTED;
2192 			res = crypto_ops.mac.init(cs->ctx, cs->algo,
2193 						  (void *)(key + 1),
2194 						  key->key_size);
2195 			if (res != TEE_SUCCESS)
2196 				return res;
2197 			break;
2198 		}
2199 	default:
2200 		return TEE_ERROR_BAD_PARAMETERS;
2201 	}
2202 
2203 	return TEE_SUCCESS;
2204 }
2205 
2206 TEE_Result syscall_hash_update(unsigned long state, const void *chunk,
2207 			size_t chunk_size)
2208 {
2209 	TEE_Result res;
2210 	struct tee_cryp_state *cs;
2211 	struct tee_ta_session *sess;
2212 
2213 	/* No data, but size provided isn't valid parameters. */
2214 	if (!chunk && chunk_size)
2215 		return TEE_ERROR_BAD_PARAMETERS;
2216 
2217 	/* Zero length hash is valid, but nothing we need to do. */
2218 	if (!chunk_size)
2219 		return TEE_SUCCESS;
2220 
2221 	res = tee_ta_get_current_session(&sess);
2222 	if (res != TEE_SUCCESS)
2223 		return res;
2224 
2225 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2226 					  TEE_MEMORY_ACCESS_READ |
2227 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2228 					  (uaddr_t)chunk, chunk_size);
2229 	if (res != TEE_SUCCESS)
2230 		return res;
2231 
2232 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2233 	if (res != TEE_SUCCESS)
2234 		return res;
2235 
2236 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
2237 	case TEE_OPERATION_DIGEST:
2238 		if (!crypto_ops.hash.update)
2239 			return TEE_ERROR_NOT_IMPLEMENTED;
2240 		res = crypto_ops.hash.update(cs->ctx, cs->algo, chunk,
2241 					     chunk_size);
2242 		if (res != TEE_SUCCESS)
2243 			return res;
2244 		break;
2245 	case TEE_OPERATION_MAC:
2246 		if (!crypto_ops.mac.update)
2247 			return TEE_ERROR_NOT_IMPLEMENTED;
2248 		res = crypto_ops.mac.update(cs->ctx, cs->algo, chunk,
2249 					    chunk_size);
2250 		if (res != TEE_SUCCESS)
2251 			return res;
2252 		break;
2253 	default:
2254 		return TEE_ERROR_BAD_PARAMETERS;
2255 	}
2256 
2257 	return TEE_SUCCESS;
2258 }
2259 
2260 TEE_Result syscall_hash_final(unsigned long state, const void *chunk,
2261 			size_t chunk_size, void *hash, uint64_t *hash_len)
2262 {
2263 	TEE_Result res, res2;
2264 	size_t hash_size;
2265 	uint64_t hlen;
2266 	struct tee_cryp_state *cs;
2267 	struct tee_ta_session *sess;
2268 
2269 	/* No data, but size provided isn't valid parameters. */
2270 	if (!chunk && chunk_size)
2271 		return TEE_ERROR_BAD_PARAMETERS;
2272 
2273 	res = tee_ta_get_current_session(&sess);
2274 	if (res != TEE_SUCCESS)
2275 		return res;
2276 
2277 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2278 					  TEE_MEMORY_ACCESS_READ |
2279 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2280 					  (uaddr_t)chunk, chunk_size);
2281 	if (res != TEE_SUCCESS)
2282 		return res;
2283 
2284 	res = tee_svc_copy_from_user(&hlen, hash_len, sizeof(hlen));
2285 	if (res != TEE_SUCCESS)
2286 		return res;
2287 
2288 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2289 					  TEE_MEMORY_ACCESS_READ |
2290 					  TEE_MEMORY_ACCESS_WRITE |
2291 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2292 					  (uaddr_t)hash, hlen);
2293 	if (res != TEE_SUCCESS)
2294 		return res;
2295 
2296 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2297 	if (res != TEE_SUCCESS)
2298 		return res;
2299 
2300 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
2301 	case TEE_OPERATION_DIGEST:
2302 		if (!crypto_ops.hash.update || !crypto_ops.hash.final)
2303 			return TEE_ERROR_NOT_IMPLEMENTED;
2304 		res = tee_hash_get_digest_size(cs->algo, &hash_size);
2305 		if (res != TEE_SUCCESS)
2306 			return res;
2307 		if (*hash_len < hash_size) {
2308 			res = TEE_ERROR_SHORT_BUFFER;
2309 			goto out;
2310 		}
2311 
2312 		if (chunk_size) {
2313 			res = crypto_ops.hash.update(cs->ctx, cs->algo, chunk,
2314 						     chunk_size);
2315 			if (res != TEE_SUCCESS)
2316 				return res;
2317 		}
2318 
2319 		res = crypto_ops.hash.final(cs->ctx, cs->algo, hash,
2320 					    hash_size);
2321 		if (res != TEE_SUCCESS)
2322 			return res;
2323 		break;
2324 
2325 	case TEE_OPERATION_MAC:
2326 		if (!crypto_ops.mac.update || !crypto_ops.mac.final)
2327 			return TEE_ERROR_NOT_IMPLEMENTED;
2328 		res = tee_mac_get_digest_size(cs->algo, &hash_size);
2329 		if (res != TEE_SUCCESS)
2330 			return res;
2331 		if (*hash_len < hash_size) {
2332 			res = TEE_ERROR_SHORT_BUFFER;
2333 			goto out;
2334 		}
2335 
2336 		if (chunk_size) {
2337 			res = crypto_ops.mac.update(cs->ctx, cs->algo, chunk,
2338 						    chunk_size);
2339 			if (res != TEE_SUCCESS)
2340 				return res;
2341 		}
2342 
2343 		res = crypto_ops.mac.final(cs->ctx, cs->algo, hash, hash_size);
2344 		if (res != TEE_SUCCESS)
2345 			return res;
2346 		break;
2347 
2348 	default:
2349 		return TEE_ERROR_BAD_PARAMETERS;
2350 	}
2351 out:
2352 	hlen = hash_size;
2353 	res2 = tee_svc_copy_to_user(hash_len, &hlen, sizeof(*hash_len));
2354 	if (res2 != TEE_SUCCESS)
2355 		return res2;
2356 	return res;
2357 }
2358 
2359 TEE_Result syscall_cipher_init(unsigned long state, const void *iv,
2360 			size_t iv_len)
2361 {
2362 	TEE_Result res;
2363 	struct tee_cryp_state *cs;
2364 	struct tee_ta_session *sess;
2365 	struct tee_obj *o;
2366 	struct tee_cryp_obj_secret *key1;
2367 	struct user_ta_ctx *utc;
2368 
2369 	res = tee_ta_get_current_session(&sess);
2370 	if (res != TEE_SUCCESS)
2371 		return res;
2372 	utc = to_user_ta_ctx(sess->ctx);
2373 
2374 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2375 	if (res != TEE_SUCCESS)
2376 		return res;
2377 
2378 	res = tee_mmu_check_access_rights(utc,
2379 					  TEE_MEMORY_ACCESS_READ |
2380 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2381 					  (uaddr_t) iv, iv_len);
2382 	if (res != TEE_SUCCESS)
2383 		return res;
2384 
2385 	res = tee_obj_get(utc, cs->key1, &o);
2386 	if (res != TEE_SUCCESS)
2387 		return res;
2388 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2389 		return TEE_ERROR_BAD_PARAMETERS;
2390 
2391 	key1 = o->attr;
2392 
2393 	if (!crypto_ops.cipher.init)
2394 		return TEE_ERROR_NOT_IMPLEMENTED;
2395 
2396 	if (tee_obj_get(utc, cs->key2, &o) == TEE_SUCCESS) {
2397 		struct tee_cryp_obj_secret *key2 = o->attr;
2398 
2399 		if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2400 			return TEE_ERROR_BAD_PARAMETERS;
2401 
2402 		res = crypto_ops.cipher.init(cs->ctx, cs->algo, cs->mode,
2403 					     (uint8_t *)(key1 + 1),
2404 					     key1->key_size,
2405 					     (uint8_t *)(key2 + 1),
2406 					     key2->key_size,
2407 					     iv, iv_len);
2408 	} else {
2409 		res = crypto_ops.cipher.init(cs->ctx, cs->algo, cs->mode,
2410 					     (uint8_t *)(key1 + 1),
2411 					     key1->key_size,
2412 					     NULL,
2413 					     0,
2414 					     iv, iv_len);
2415 	}
2416 	if (res != TEE_SUCCESS)
2417 		return res;
2418 
2419 	cs->ctx_finalize = crypto_ops.cipher.final;
2420 	return TEE_SUCCESS;
2421 }
2422 
2423 static TEE_Result tee_svc_cipher_update_helper(unsigned long state,
2424 			bool last_block, const void *src, size_t src_len,
2425 			void *dst, uint64_t *dst_len)
2426 {
2427 	TEE_Result res;
2428 	struct tee_cryp_state *cs;
2429 	struct tee_ta_session *sess;
2430 	uint64_t dlen;
2431 
2432 	res = tee_ta_get_current_session(&sess);
2433 	if (res != TEE_SUCCESS)
2434 		return res;
2435 
2436 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2437 	if (res != TEE_SUCCESS)
2438 		return res;
2439 
2440 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2441 					  TEE_MEMORY_ACCESS_READ |
2442 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2443 					  (uaddr_t)src, src_len);
2444 	if (res != TEE_SUCCESS)
2445 		return res;
2446 
2447 	if (!dst_len) {
2448 		dlen = 0;
2449 	} else {
2450 		res = tee_svc_copy_from_user(&dlen, dst_len, sizeof(dlen));
2451 		if (res != TEE_SUCCESS)
2452 			return res;
2453 
2454 		res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2455 						  TEE_MEMORY_ACCESS_READ |
2456 						  TEE_MEMORY_ACCESS_WRITE |
2457 						  TEE_MEMORY_ACCESS_ANY_OWNER,
2458 						  (uaddr_t)dst, dlen);
2459 		if (res != TEE_SUCCESS)
2460 			return res;
2461 	}
2462 
2463 	if (dlen < src_len) {
2464 		res = TEE_ERROR_SHORT_BUFFER;
2465 		goto out;
2466 	}
2467 
2468 	if (src_len > 0) {
2469 		/* Permit src_len == 0 to finalize the operation */
2470 		res = tee_do_cipher_update(cs->ctx, cs->algo, cs->mode,
2471 					   last_block, src, src_len, dst);
2472 	}
2473 
2474 	if (last_block && cs->ctx_finalize != NULL) {
2475 		cs->ctx_finalize(cs->ctx, cs->algo);
2476 		cs->ctx_finalize = NULL;
2477 	}
2478 
2479 out:
2480 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
2481 	    dst_len != NULL) {
2482 		TEE_Result res2;
2483 
2484 		dlen = src_len;
2485 		res2 = tee_svc_copy_to_user(dst_len, &dlen, sizeof(*dst_len));
2486 		if (res2 != TEE_SUCCESS)
2487 			res = res2;
2488 	}
2489 
2490 	return res;
2491 }
2492 
2493 TEE_Result syscall_cipher_update(unsigned long state, const void *src,
2494 			size_t src_len, void *dst, uint64_t *dst_len)
2495 {
2496 	return tee_svc_cipher_update_helper(state, false /* last_block */,
2497 					    src, src_len, dst, dst_len);
2498 }
2499 
2500 TEE_Result syscall_cipher_final(unsigned long state, const void *src,
2501 			size_t src_len, void *dst, uint64_t *dst_len)
2502 {
2503 	return tee_svc_cipher_update_helper(state, true /* last_block */,
2504 					    src, src_len, dst, dst_len);
2505 }
2506 
2507 #if defined(CFG_CRYPTO_HKDF)
2508 static TEE_Result get_hkdf_params(const TEE_Attribute *params,
2509 				  uint32_t param_count,
2510 				  void **salt, size_t *salt_len, void **info,
2511 				  size_t *info_len, size_t *okm_len)
2512 {
2513 	size_t n;
2514 	enum { SALT = 0x1, LENGTH = 0x2, INFO = 0x4 };
2515 	uint8_t found = 0;
2516 
2517 	*salt = *info = NULL;
2518 	*salt_len = *info_len = *okm_len = 0;
2519 
2520 	for (n = 0; n < param_count; n++) {
2521 		switch (params[n].attributeID) {
2522 		case TEE_ATTR_HKDF_SALT:
2523 			if (!(found & SALT)) {
2524 				*salt = params[n].content.ref.buffer;
2525 				*salt_len = params[n].content.ref.length;
2526 				found |= SALT;
2527 			}
2528 			break;
2529 		case TEE_ATTR_HKDF_OKM_LENGTH:
2530 			if (!(found & LENGTH)) {
2531 				*okm_len = params[n].content.value.a;
2532 				found |= LENGTH;
2533 			}
2534 			break;
2535 		case TEE_ATTR_HKDF_INFO:
2536 			if (!(found & INFO)) {
2537 				*info = params[n].content.ref.buffer;
2538 				*info_len = params[n].content.ref.length;
2539 				found |= INFO;
2540 			}
2541 			break;
2542 		default:
2543 			/* Unexpected attribute */
2544 			return TEE_ERROR_BAD_PARAMETERS;
2545 		}
2546 
2547 	}
2548 
2549 	if (!(found & LENGTH))
2550 		return TEE_ERROR_BAD_PARAMETERS;
2551 
2552 	return TEE_SUCCESS;
2553 }
2554 #endif
2555 
2556 #if defined(CFG_CRYPTO_CONCAT_KDF)
2557 static TEE_Result get_concat_kdf_params(const TEE_Attribute *params,
2558 					uint32_t param_count,
2559 					void **other_info,
2560 					size_t *other_info_len,
2561 					size_t *derived_key_len)
2562 {
2563 	size_t n;
2564 	enum { LENGTH = 0x1, INFO = 0x2 };
2565 	uint8_t found = 0;
2566 
2567 	*other_info = NULL;
2568 	*other_info_len = *derived_key_len = 0;
2569 
2570 	for (n = 0; n < param_count; n++) {
2571 		switch (params[n].attributeID) {
2572 		case TEE_ATTR_CONCAT_KDF_OTHER_INFO:
2573 			if (!(found & INFO)) {
2574 				*other_info = params[n].content.ref.buffer;
2575 				*other_info_len = params[n].content.ref.length;
2576 				found |= INFO;
2577 			}
2578 			break;
2579 		case TEE_ATTR_CONCAT_KDF_DKM_LENGTH:
2580 			if (!(found & LENGTH)) {
2581 				*derived_key_len = params[n].content.value.a;
2582 				found |= LENGTH;
2583 			}
2584 			break;
2585 		default:
2586 			/* Unexpected attribute */
2587 			return TEE_ERROR_BAD_PARAMETERS;
2588 		}
2589 	}
2590 
2591 	if (!(found & LENGTH))
2592 		return TEE_ERROR_BAD_PARAMETERS;
2593 
2594 	return TEE_SUCCESS;
2595 }
2596 #endif
2597 
2598 #if defined(CFG_CRYPTO_PBKDF2)
2599 static TEE_Result get_pbkdf2_params(const TEE_Attribute *params,
2600 				   uint32_t param_count, void **salt,
2601 				   size_t *salt_len, size_t *derived_key_len,
2602 				   size_t *iteration_count)
2603 {
2604 	size_t n;
2605 	enum { SALT = 0x1, LENGTH = 0x2, COUNT = 0x4 };
2606 	uint8_t found = 0;
2607 
2608 	*salt = NULL;
2609 	*salt_len = *derived_key_len = *iteration_count = 0;
2610 
2611 	for (n = 0; n < param_count; n++) {
2612 		switch (params[n].attributeID) {
2613 		case TEE_ATTR_PBKDF2_SALT:
2614 			if (!(found & SALT)) {
2615 				*salt = params[n].content.ref.buffer;
2616 				*salt_len = params[n].content.ref.length;
2617 				found |= SALT;
2618 			}
2619 			break;
2620 		case TEE_ATTR_PBKDF2_DKM_LENGTH:
2621 			if (!(found & LENGTH)) {
2622 				*derived_key_len = params[n].content.value.a;
2623 				found |= LENGTH;
2624 			}
2625 			break;
2626 		case TEE_ATTR_PBKDF2_ITERATION_COUNT:
2627 			if (!(found & COUNT)) {
2628 				*iteration_count = params[n].content.value.a;
2629 				found |= COUNT;
2630 			}
2631 			break;
2632 		default:
2633 			/* Unexpected attribute */
2634 			return TEE_ERROR_BAD_PARAMETERS;
2635 		}
2636 	}
2637 
2638 	if ((found & (LENGTH|COUNT)) != (LENGTH|COUNT))
2639 		return TEE_ERROR_BAD_PARAMETERS;
2640 
2641 	return TEE_SUCCESS;
2642 }
2643 #endif
2644 
2645 TEE_Result syscall_cryp_derive_key(unsigned long state,
2646 			const struct utee_attribute *usr_params,
2647 			unsigned long param_count, unsigned long derived_key)
2648 {
2649 	TEE_Result res = TEE_ERROR_NOT_SUPPORTED;
2650 	struct tee_ta_session *sess;
2651 	struct tee_obj *ko;
2652 	struct tee_obj *so;
2653 	struct tee_cryp_state *cs;
2654 	struct tee_cryp_obj_secret *sk;
2655 	const struct tee_cryp_obj_type_props *type_props;
2656 	TEE_Attribute *params = NULL;
2657 	struct user_ta_ctx *utc;
2658 
2659 	res = tee_ta_get_current_session(&sess);
2660 	if (res != TEE_SUCCESS)
2661 		return res;
2662 	utc = to_user_ta_ctx(sess->ctx);
2663 
2664 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2665 	if (res != TEE_SUCCESS)
2666 		return res;
2667 
2668 	params = malloc(sizeof(TEE_Attribute) * param_count);
2669 	if (!params)
2670 		return TEE_ERROR_OUT_OF_MEMORY;
2671 	res = copy_in_attrs(utc, usr_params, param_count, params);
2672 	if (res != TEE_SUCCESS)
2673 		goto out;
2674 
2675 	/* Get key set in operation */
2676 	res = tee_obj_get(utc, cs->key1, &ko);
2677 	if (res != TEE_SUCCESS)
2678 		goto out;
2679 
2680 	res = tee_obj_get(utc, tee_svc_uref_to_vaddr(derived_key), &so);
2681 	if (res != TEE_SUCCESS)
2682 		goto out;
2683 
2684 	/* Find information needed about the object to initialize */
2685 	sk = so->attr;
2686 
2687 	/* Find description of object */
2688 	type_props = tee_svc_find_type_props(so->info.objectType);
2689 	if (!type_props) {
2690 		res = TEE_ERROR_NOT_SUPPORTED;
2691 		goto out;
2692 	}
2693 
2694 	if (cs->algo == TEE_ALG_DH_DERIVE_SHARED_SECRET) {
2695 		size_t alloc_size;
2696 		struct bignum *pub;
2697 		struct bignum *ss;
2698 
2699 		if (!crypto_ops.bignum.allocate ||
2700 		    !crypto_ops.bignum.free ||
2701 		    !crypto_ops.bignum.bin2bn ||
2702 		    !crypto_ops.bignum.bn2bin ||
2703 		    !crypto_ops.bignum.num_bytes ||
2704 		    !crypto_ops.acipher.dh_shared_secret) {
2705 			res = TEE_ERROR_NOT_IMPLEMENTED;
2706 			goto out;
2707 		}
2708 		if (param_count != 1 ||
2709 		    params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE) {
2710 			res = TEE_ERROR_BAD_PARAMETERS;
2711 			goto out;
2712 		}
2713 
2714 		alloc_size = params[0].content.ref.length * 8;
2715 		pub = crypto_ops.bignum.allocate(alloc_size);
2716 		ss = crypto_ops.bignum.allocate(alloc_size);
2717 		if (pub && ss) {
2718 			crypto_ops.bignum.bin2bn(params[0].content.ref.buffer,
2719 					params[0].content.ref.length, pub);
2720 			res = crypto_ops.acipher.dh_shared_secret(ko->attr,
2721 								  pub, ss);
2722 			if (res == TEE_SUCCESS) {
2723 				sk->key_size = crypto_ops.bignum.num_bytes(ss);
2724 				crypto_ops.bignum.bn2bin(ss,
2725 							 (uint8_t *)(sk + 1));
2726 				so->info.handleFlags |=
2727 						TEE_HANDLE_FLAG_INITIALIZED;
2728 				set_attribute(so, type_props,
2729 					      TEE_ATTR_SECRET_VALUE);
2730 			}
2731 		} else {
2732 			res = TEE_ERROR_OUT_OF_MEMORY;
2733 		}
2734 		crypto_ops.bignum.free(pub);
2735 		crypto_ops.bignum.free(ss);
2736 	} else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_ECDH) {
2737 		size_t alloc_size;
2738 		struct ecc_public_key key_public;
2739 		uint8_t *pt_secret;
2740 		unsigned long pt_secret_len;
2741 
2742 		if (!crypto_ops.bignum.bin2bn ||
2743 		    !crypto_ops.acipher.alloc_ecc_public_key ||
2744 		    !crypto_ops.acipher.free_ecc_public_key ||
2745 		    !crypto_ops.acipher.ecc_shared_secret) {
2746 			res = TEE_ERROR_NOT_IMPLEMENTED;
2747 			goto out;
2748 		}
2749 		if (param_count != 2 ||
2750 		    params[0].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_X ||
2751 		    params[1].attributeID != TEE_ATTR_ECC_PUBLIC_VALUE_Y) {
2752 			res = TEE_ERROR_BAD_PARAMETERS;
2753 			goto out;
2754 		}
2755 
2756 		switch (cs->algo) {
2757 		case TEE_ALG_ECDH_P192:
2758 			alloc_size = 192;
2759 			break;
2760 		case TEE_ALG_ECDH_P224:
2761 			alloc_size = 224;
2762 			break;
2763 		case TEE_ALG_ECDH_P256:
2764 			alloc_size = 256;
2765 			break;
2766 		case TEE_ALG_ECDH_P384:
2767 			alloc_size = 384;
2768 			break;
2769 		case TEE_ALG_ECDH_P521:
2770 			alloc_size = 521;
2771 			break;
2772 		default:
2773 			res = TEE_ERROR_NOT_IMPLEMENTED;
2774 			goto out;
2775 		}
2776 
2777 		/* Create the public key */
2778 		res = crypto_ops.acipher.alloc_ecc_public_key(&key_public,
2779 							      alloc_size);
2780 		if (res != TEE_SUCCESS)
2781 			goto out;
2782 		key_public.curve = ((struct ecc_keypair *)ko->attr)->curve;
2783 		crypto_ops.bignum.bin2bn(params[0].content.ref.buffer,
2784 					 params[0].content.ref.length,
2785 					 key_public.x);
2786 		crypto_ops.bignum.bin2bn(params[1].content.ref.buffer,
2787 					 params[1].content.ref.length,
2788 					 key_public.y);
2789 
2790 		pt_secret = (uint8_t *)(sk + 1);
2791 		pt_secret_len = sk->alloc_size;
2792 		res = crypto_ops.acipher.ecc_shared_secret(ko->attr,
2793 				&key_public, pt_secret, &pt_secret_len);
2794 
2795 		if (res == TEE_SUCCESS) {
2796 			sk->key_size = pt_secret_len;
2797 			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2798 			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
2799 		}
2800 
2801 		/* free the public key */
2802 		crypto_ops.acipher.free_ecc_public_key(&key_public);
2803 	}
2804 #if defined(CFG_CRYPTO_HKDF)
2805 	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_HKDF) {
2806 		void *salt, *info;
2807 		size_t salt_len, info_len, okm_len;
2808 		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
2809 		struct tee_cryp_obj_secret *ik = ko->attr;
2810 		const uint8_t *ikm = (const uint8_t *)(ik + 1);
2811 
2812 		res = get_hkdf_params(params, param_count, &salt, &salt_len,
2813 				      &info, &info_len, &okm_len);
2814 		if (res != TEE_SUCCESS)
2815 			goto out;
2816 
2817 		/* Requested size must fit into the output object's buffer */
2818 		if (okm_len > ik->alloc_size) {
2819 			res = TEE_ERROR_BAD_PARAMETERS;
2820 			goto out;
2821 		}
2822 
2823 		res = tee_cryp_hkdf(hash_id, ikm, ik->key_size, salt, salt_len,
2824 				    info, info_len, (uint8_t *)(sk + 1),
2825 				    okm_len);
2826 		if (res == TEE_SUCCESS) {
2827 			sk->key_size = okm_len;
2828 			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2829 			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
2830 		}
2831 	}
2832 #endif
2833 #if defined(CFG_CRYPTO_CONCAT_KDF)
2834 	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_CONCAT_KDF) {
2835 		void *info;
2836 		size_t info_len, derived_key_len;
2837 		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
2838 		struct tee_cryp_obj_secret *ss = ko->attr;
2839 		const uint8_t *shared_secret = (const uint8_t *)(ss + 1);
2840 
2841 		res = get_concat_kdf_params(params, param_count, &info,
2842 					    &info_len, &derived_key_len);
2843 		if (res != TEE_SUCCESS)
2844 			goto out;
2845 
2846 		/* Requested size must fit into the output object's buffer */
2847 		if (derived_key_len > ss->alloc_size) {
2848 			res = TEE_ERROR_BAD_PARAMETERS;
2849 			goto out;
2850 		}
2851 
2852 		res = tee_cryp_concat_kdf(hash_id, shared_secret, ss->key_size,
2853 					  info, info_len, (uint8_t *)(sk + 1),
2854 					  derived_key_len);
2855 		if (res == TEE_SUCCESS) {
2856 			sk->key_size = derived_key_len;
2857 			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2858 			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
2859 		}
2860 	}
2861 #endif
2862 #if defined(CFG_CRYPTO_PBKDF2)
2863 	else if (TEE_ALG_GET_MAIN_ALG(cs->algo) == TEE_MAIN_ALGO_PBKDF2) {
2864 		void *salt;
2865 		size_t salt_len, iteration_count, derived_key_len;
2866 		uint32_t hash_id = TEE_ALG_GET_DIGEST_HASH(cs->algo);
2867 		struct tee_cryp_obj_secret *ss = ko->attr;
2868 		const uint8_t *password = (const uint8_t *)(ss + 1);
2869 
2870 		res = get_pbkdf2_params(params, param_count, &salt, &salt_len,
2871 					&derived_key_len, &iteration_count);
2872 		if (res != TEE_SUCCESS)
2873 			goto out;
2874 
2875 		/* Requested size must fit into the output object's buffer */
2876 		if (derived_key_len > ss->alloc_size) {
2877 			res = TEE_ERROR_BAD_PARAMETERS;
2878 			goto out;
2879 		}
2880 
2881 		res = tee_cryp_pbkdf2(hash_id, password, ss->key_size, salt,
2882 				      salt_len, iteration_count,
2883 				      (uint8_t *)(sk + 1), derived_key_len);
2884 		if (res == TEE_SUCCESS) {
2885 			sk->key_size = derived_key_len;
2886 			so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2887 			set_attribute(so, type_props, TEE_ATTR_SECRET_VALUE);
2888 		}
2889 	}
2890 #endif
2891 	else
2892 		res = TEE_ERROR_NOT_SUPPORTED;
2893 
2894 out:
2895 	free(params);
2896 	return res;
2897 }
2898 
2899 TEE_Result syscall_cryp_random_number_generate(void *buf, size_t blen)
2900 {
2901 	TEE_Result res;
2902 	struct tee_ta_session *sess;
2903 
2904 	res = tee_ta_get_current_session(&sess);
2905 	if (res != TEE_SUCCESS)
2906 		return res;
2907 
2908 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2909 					  TEE_MEMORY_ACCESS_WRITE |
2910 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2911 					  (uaddr_t)buf, blen);
2912 	if (res != TEE_SUCCESS)
2913 		return res;
2914 
2915 	res = crypto_rng_read(buf, blen);
2916 	if (res != TEE_SUCCESS)
2917 		return res;
2918 
2919 	return res;
2920 }
2921 
2922 TEE_Result syscall_authenc_init(unsigned long state, const void *nonce,
2923 			size_t nonce_len, size_t tag_len,
2924 			size_t aad_len, size_t payload_len)
2925 {
2926 	TEE_Result res;
2927 	struct tee_cryp_state *cs;
2928 	struct tee_ta_session *sess;
2929 	struct tee_obj *o;
2930 	struct tee_cryp_obj_secret *key;
2931 
2932 	res = tee_ta_get_current_session(&sess);
2933 	if (res != TEE_SUCCESS)
2934 		return res;
2935 
2936 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2937 	if (res != TEE_SUCCESS)
2938 		return res;
2939 
2940 	res = tee_obj_get(to_user_ta_ctx(sess->ctx), cs->key1, &o);
2941 	if (res != TEE_SUCCESS)
2942 		return res;
2943 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2944 		return TEE_ERROR_BAD_PARAMETERS;
2945 
2946 	if (!crypto_ops.authenc.init)
2947 		return TEE_ERROR_NOT_IMPLEMENTED;
2948 	key = o->attr;
2949 	res = crypto_ops.authenc.init(cs->ctx, cs->algo, cs->mode,
2950 				      (uint8_t *)(key + 1), key->key_size,
2951 				      nonce, nonce_len, tag_len, aad_len,
2952 				      payload_len);
2953 	if (res != TEE_SUCCESS)
2954 		return res;
2955 
2956 	cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t)
2957 				crypto_ops.authenc.final;
2958 	return TEE_SUCCESS;
2959 }
2960 
2961 TEE_Result syscall_authenc_update_aad(unsigned long state,
2962 			const void *aad_data, size_t aad_data_len)
2963 {
2964 	TEE_Result res;
2965 	struct tee_cryp_state *cs;
2966 	struct tee_ta_session *sess;
2967 
2968 	res = tee_ta_get_current_session(&sess);
2969 	if (res != TEE_SUCCESS)
2970 		return res;
2971 
2972 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
2973 					  TEE_MEMORY_ACCESS_READ |
2974 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2975 					  (uaddr_t) aad_data,
2976 					  aad_data_len);
2977 	if (res != TEE_SUCCESS)
2978 		return res;
2979 
2980 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
2981 	if (res != TEE_SUCCESS)
2982 		return res;
2983 
2984 	if (!crypto_ops.authenc.update_aad)
2985 		return TEE_ERROR_NOT_IMPLEMENTED;
2986 	res = crypto_ops.authenc.update_aad(cs->ctx, cs->algo, cs->mode,
2987 					    aad_data, aad_data_len);
2988 	if (res != TEE_SUCCESS)
2989 		return res;
2990 
2991 	return TEE_SUCCESS;
2992 }
2993 
2994 TEE_Result syscall_authenc_update_payload(unsigned long state,
2995 			const void *src_data, size_t src_len, void *dst_data,
2996 			uint64_t *dst_len)
2997 {
2998 	TEE_Result res;
2999 	struct tee_cryp_state *cs;
3000 	struct tee_ta_session *sess;
3001 	uint64_t dlen;
3002 	size_t tmp_dlen;
3003 
3004 	res = tee_ta_get_current_session(&sess);
3005 	if (res != TEE_SUCCESS)
3006 		return res;
3007 
3008 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
3009 	if (res != TEE_SUCCESS)
3010 		return res;
3011 
3012 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3013 					  TEE_MEMORY_ACCESS_READ |
3014 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3015 					  (uaddr_t) src_data, src_len);
3016 	if (res != TEE_SUCCESS)
3017 		return res;
3018 
3019 	res = tee_svc_copy_from_user(&dlen, dst_len, sizeof(dlen));
3020 	if (res != TEE_SUCCESS)
3021 		return res;
3022 
3023 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3024 					  TEE_MEMORY_ACCESS_READ |
3025 					  TEE_MEMORY_ACCESS_WRITE |
3026 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3027 					  (uaddr_t)dst_data, dlen);
3028 	if (res != TEE_SUCCESS)
3029 		return res;
3030 
3031 	if (dlen < src_len) {
3032 		res = TEE_ERROR_SHORT_BUFFER;
3033 		goto out;
3034 	}
3035 
3036 	if (!crypto_ops.authenc.update_payload)
3037 		return TEE_ERROR_NOT_IMPLEMENTED;
3038 	tmp_dlen = dlen;
3039 	res = crypto_ops.authenc.update_payload(cs->ctx, cs->algo, cs->mode,
3040 						src_data, src_len, dst_data,
3041 						&tmp_dlen);
3042 	dlen = tmp_dlen;
3043 
3044 out:
3045 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
3046 		TEE_Result res2 = tee_svc_copy_to_user(dst_len, &dlen,
3047 						       sizeof(*dst_len));
3048 		if (res2 != TEE_SUCCESS)
3049 			res = res2;
3050 	}
3051 
3052 	return res;
3053 }
3054 
3055 TEE_Result syscall_authenc_enc_final(unsigned long state,
3056 			const void *src_data, size_t src_len, void *dst_data,
3057 			uint64_t *dst_len, void *tag, uint64_t *tag_len)
3058 {
3059 	TEE_Result res;
3060 	struct tee_cryp_state *cs;
3061 	struct tee_ta_session *sess;
3062 	uint64_t dlen;
3063 	uint64_t tlen;
3064 	size_t tmp_dlen;
3065 	size_t tmp_tlen;
3066 
3067 	res = tee_ta_get_current_session(&sess);
3068 	if (res != TEE_SUCCESS)
3069 		return res;
3070 
3071 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
3072 	if (res != TEE_SUCCESS)
3073 		return res;
3074 
3075 	if (cs->mode != TEE_MODE_ENCRYPT)
3076 		return TEE_ERROR_BAD_PARAMETERS;
3077 
3078 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3079 					  TEE_MEMORY_ACCESS_READ |
3080 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3081 					  (uaddr_t)src_data, src_len);
3082 	if (res != TEE_SUCCESS)
3083 		return res;
3084 
3085 	if (!dst_len) {
3086 		dlen = 0;
3087 	} else {
3088 		res = tee_svc_copy_from_user(&dlen, dst_len, sizeof(dlen));
3089 		if (res != TEE_SUCCESS)
3090 			return res;
3091 
3092 		res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3093 						  TEE_MEMORY_ACCESS_READ |
3094 						  TEE_MEMORY_ACCESS_WRITE |
3095 						  TEE_MEMORY_ACCESS_ANY_OWNER,
3096 						  (uaddr_t)dst_data, dlen);
3097 		if (res != TEE_SUCCESS)
3098 			return res;
3099 	}
3100 
3101 	if (dlen < src_len) {
3102 		res = TEE_ERROR_SHORT_BUFFER;
3103 		goto out;
3104 	}
3105 
3106 	res = tee_svc_copy_from_user(&tlen, tag_len, sizeof(tlen));
3107 	if (res != TEE_SUCCESS)
3108 		return res;
3109 
3110 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3111 					  TEE_MEMORY_ACCESS_READ |
3112 					  TEE_MEMORY_ACCESS_WRITE |
3113 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3114 					  (uaddr_t)tag, tlen);
3115 	if (res != TEE_SUCCESS)
3116 		return res;
3117 
3118 	if (!crypto_ops.authenc.enc_final)
3119 		return TEE_ERROR_NOT_IMPLEMENTED;
3120 	tmp_dlen = dlen;
3121 	tmp_tlen = tlen;
3122 	res = crypto_ops.authenc.enc_final(cs->ctx, cs->algo, src_data,
3123 					   src_len, dst_data, &tmp_dlen, tag,
3124 					   &tmp_tlen);
3125 	dlen = tmp_dlen;
3126 	tlen = tmp_tlen;
3127 
3128 out:
3129 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
3130 		TEE_Result res2;
3131 
3132 		if (dst_len != NULL) {
3133 			res2 = tee_svc_copy_to_user(dst_len, &dlen,
3134 						    sizeof(*dst_len));
3135 			if (res2 != TEE_SUCCESS)
3136 				return res2;
3137 		}
3138 
3139 		res2 = tee_svc_copy_to_user(tag_len, &tlen, sizeof(*tag_len));
3140 		if (res2 != TEE_SUCCESS)
3141 			return res2;
3142 	}
3143 
3144 	return res;
3145 }
3146 
3147 TEE_Result syscall_authenc_dec_final(unsigned long state,
3148 			const void *src_data, size_t src_len, void *dst_data,
3149 			uint64_t *dst_len, const void *tag, size_t tag_len)
3150 {
3151 	TEE_Result res;
3152 	struct tee_cryp_state *cs;
3153 	struct tee_ta_session *sess;
3154 	uint64_t dlen;
3155 	size_t tmp_dlen;
3156 
3157 	res = tee_ta_get_current_session(&sess);
3158 	if (res != TEE_SUCCESS)
3159 		return res;
3160 
3161 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
3162 	if (res != TEE_SUCCESS)
3163 		return res;
3164 
3165 	if (cs->mode != TEE_MODE_DECRYPT)
3166 		return TEE_ERROR_BAD_PARAMETERS;
3167 
3168 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3169 					  TEE_MEMORY_ACCESS_READ |
3170 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3171 					  (uaddr_t)src_data, src_len);
3172 	if (res != TEE_SUCCESS)
3173 		return res;
3174 
3175 	if (!dst_len) {
3176 		dlen = 0;
3177 	} else {
3178 		res = tee_svc_copy_from_user(&dlen, dst_len, sizeof(dlen));
3179 		if (res != TEE_SUCCESS)
3180 			return res;
3181 
3182 		res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3183 						  TEE_MEMORY_ACCESS_READ |
3184 						  TEE_MEMORY_ACCESS_WRITE |
3185 						  TEE_MEMORY_ACCESS_ANY_OWNER,
3186 						  (uaddr_t)dst_data, dlen);
3187 		if (res != TEE_SUCCESS)
3188 			return res;
3189 	}
3190 
3191 	if (dlen < src_len) {
3192 		res = TEE_ERROR_SHORT_BUFFER;
3193 		goto out;
3194 	}
3195 
3196 	res = tee_mmu_check_access_rights(to_user_ta_ctx(sess->ctx),
3197 					  TEE_MEMORY_ACCESS_READ |
3198 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3199 					  (uaddr_t)tag, tag_len);
3200 	if (res != TEE_SUCCESS)
3201 		return res;
3202 
3203 	if (!crypto_ops.authenc.dec_final)
3204 		return TEE_ERROR_NOT_IMPLEMENTED;
3205 	tmp_dlen = dlen;
3206 	res = crypto_ops.authenc.dec_final(cs->ctx, cs->algo, src_data,
3207 					   src_len, dst_data, &tmp_dlen, tag,
3208 					   tag_len);
3209 	dlen = tmp_dlen;
3210 
3211 out:
3212 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
3213 	    dst_len != NULL) {
3214 		TEE_Result res2;
3215 
3216 		res2 = tee_svc_copy_to_user(dst_len, &dlen, sizeof(*dst_len));
3217 		if (res2 != TEE_SUCCESS)
3218 			return res2;
3219 	}
3220 
3221 	return res;
3222 }
3223 
3224 static int pkcs1_get_salt_len(const TEE_Attribute *params, uint32_t num_params,
3225 			      size_t default_len)
3226 {
3227 	size_t n;
3228 
3229 	assert(default_len < INT_MAX);
3230 
3231 	for (n = 0; n < num_params; n++) {
3232 		if (params[n].attributeID == TEE_ATTR_RSA_PSS_SALT_LENGTH) {
3233 			if (params[n].content.value.a < INT_MAX)
3234 				return params[n].content.value.a;
3235 			break;
3236 		}
3237 	}
3238 	/*
3239 	 * If salt length isn't provided use the default value which is
3240 	 * the length of the digest.
3241 	 */
3242 	return default_len;
3243 }
3244 
3245 TEE_Result syscall_asymm_operate(unsigned long state,
3246 			const struct utee_attribute *usr_params,
3247 			size_t num_params, const void *src_data, size_t src_len,
3248 			void *dst_data, uint64_t *dst_len)
3249 {
3250 	TEE_Result res;
3251 	struct tee_cryp_state *cs;
3252 	struct tee_ta_session *sess;
3253 	uint64_t dlen64;
3254 	size_t dlen;
3255 	struct tee_obj *o;
3256 	void *label = NULL;
3257 	size_t label_len = 0;
3258 	size_t n;
3259 	int salt_len;
3260 	TEE_Attribute *params = NULL;
3261 	struct user_ta_ctx *utc;
3262 
3263 	res = tee_ta_get_current_session(&sess);
3264 	if (res != TEE_SUCCESS)
3265 		return res;
3266 	utc = to_user_ta_ctx(sess->ctx);
3267 
3268 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
3269 	if (res != TEE_SUCCESS)
3270 		return res;
3271 
3272 	res = tee_mmu_check_access_rights(
3273 		utc,
3274 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER,
3275 		(uaddr_t) src_data, src_len);
3276 	if (res != TEE_SUCCESS)
3277 		return res;
3278 
3279 	res = tee_svc_copy_from_user(&dlen64, dst_len, sizeof(dlen64));
3280 	if (res != TEE_SUCCESS)
3281 		return res;
3282 	dlen = dlen64;
3283 
3284 	res = tee_mmu_check_access_rights(
3285 		utc,
3286 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
3287 			TEE_MEMORY_ACCESS_ANY_OWNER,
3288 		(uaddr_t) dst_data, dlen);
3289 	if (res != TEE_SUCCESS)
3290 		return res;
3291 
3292 	params = malloc(sizeof(TEE_Attribute) * num_params);
3293 	if (!params)
3294 		return TEE_ERROR_OUT_OF_MEMORY;
3295 	res = copy_in_attrs(utc, usr_params, num_params, params);
3296 	if (res != TEE_SUCCESS)
3297 		goto out;
3298 
3299 	res = tee_obj_get(utc, cs->key1, &o);
3300 	if (res != TEE_SUCCESS)
3301 		goto out;
3302 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
3303 		res = TEE_ERROR_GENERIC;
3304 		goto out;
3305 	}
3306 
3307 	switch (cs->algo) {
3308 	case TEE_ALG_RSA_NOPAD:
3309 		if (cs->mode == TEE_MODE_ENCRYPT) {
3310 			if (crypto_ops.acipher.rsanopad_encrypt)
3311 				res = crypto_ops.acipher.rsanopad_encrypt(
3312 					o->attr, src_data, src_len,
3313 					dst_data, &dlen);
3314 			else
3315 				res = TEE_ERROR_NOT_IMPLEMENTED;
3316 		} else if (cs->mode == TEE_MODE_DECRYPT) {
3317 			if (crypto_ops.acipher.rsanopad_decrypt)
3318 				res = crypto_ops.acipher.rsanopad_decrypt(
3319 					o->attr, src_data, src_len, dst_data,
3320 					&dlen);
3321 			else
3322 				res = TEE_ERROR_NOT_IMPLEMENTED;
3323 		} else {
3324 			/*
3325 			 * We will panic because "the mode is not compatible
3326 			 * with the function"
3327 			 */
3328 			res = TEE_ERROR_GENERIC;
3329 		}
3330 		break;
3331 
3332 	case TEE_ALG_RSAES_PKCS1_V1_5:
3333 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
3334 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
3335 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
3336 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
3337 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
3338 		for (n = 0; n < num_params; n++) {
3339 			if (params[n].attributeID == TEE_ATTR_RSA_OAEP_LABEL) {
3340 				label = params[n].content.ref.buffer;
3341 				label_len = params[n].content.ref.length;
3342 				break;
3343 			}
3344 		}
3345 
3346 		if (cs->mode == TEE_MODE_ENCRYPT) {
3347 			if (crypto_ops.acipher.rsaes_encrypt)
3348 				res = crypto_ops.acipher.rsaes_encrypt(
3349 					cs->algo, o->attr, label, label_len,
3350 					src_data, src_len, dst_data, &dlen);
3351 			else
3352 				res = TEE_ERROR_NOT_IMPLEMENTED;
3353 		} else if (cs->mode == TEE_MODE_DECRYPT) {
3354 			if (crypto_ops.acipher.rsaes_decrypt)
3355 				res = crypto_ops.acipher.rsaes_decrypt(
3356 					cs->algo, o->attr,
3357 					label, label_len,
3358 					src_data, src_len, dst_data, &dlen);
3359 			else
3360 				res = TEE_ERROR_NOT_IMPLEMENTED;
3361 		} else {
3362 			res = TEE_ERROR_BAD_PARAMETERS;
3363 		}
3364 		break;
3365 
3366 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
3367 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
3368 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
3369 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
3370 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
3371 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
3372 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
3373 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
3374 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
3375 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
3376 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
3377 		if (cs->mode != TEE_MODE_SIGN) {
3378 			res = TEE_ERROR_BAD_PARAMETERS;
3379 			break;
3380 		}
3381 		salt_len = pkcs1_get_salt_len(params, num_params, src_len);
3382 		if (!crypto_ops.acipher.rsassa_sign) {
3383 			res = TEE_ERROR_NOT_IMPLEMENTED;
3384 			break;
3385 		}
3386 		res = crypto_ops.acipher.rsassa_sign(cs->algo, o->attr,
3387 						     salt_len, src_data,
3388 						     src_len, dst_data, &dlen);
3389 		break;
3390 
3391 	case TEE_ALG_DSA_SHA1:
3392 	case TEE_ALG_DSA_SHA224:
3393 	case TEE_ALG_DSA_SHA256:
3394 		if (!crypto_ops.acipher.dsa_sign) {
3395 			res = TEE_ERROR_NOT_IMPLEMENTED;
3396 			break;
3397 		}
3398 		res = crypto_ops.acipher.dsa_sign(cs->algo, o->attr, src_data,
3399 						  src_len, dst_data, &dlen);
3400 		break;
3401 	case TEE_ALG_ECDSA_P192:
3402 	case TEE_ALG_ECDSA_P224:
3403 	case TEE_ALG_ECDSA_P256:
3404 	case TEE_ALG_ECDSA_P384:
3405 	case TEE_ALG_ECDSA_P521:
3406 		if (!crypto_ops.acipher.ecc_sign) {
3407 			res = TEE_ERROR_NOT_IMPLEMENTED;
3408 			break;
3409 		}
3410 		res = crypto_ops.acipher.ecc_sign(cs->algo, o->attr, src_data,
3411 						  src_len, dst_data, &dlen);
3412 		break;
3413 
3414 	default:
3415 		res = TEE_ERROR_BAD_PARAMETERS;
3416 		break;
3417 	}
3418 
3419 out:
3420 	free(params);
3421 
3422 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
3423 		TEE_Result res2;
3424 
3425 		dlen64 = dlen;
3426 		res2 = tee_svc_copy_to_user(dst_len, &dlen64, sizeof(*dst_len));
3427 		if (res2 != TEE_SUCCESS)
3428 			return res2;
3429 	}
3430 
3431 	return res;
3432 }
3433 
3434 TEE_Result syscall_asymm_verify(unsigned long state,
3435 			const struct utee_attribute *usr_params,
3436 			size_t num_params, const void *data, size_t data_len,
3437 			const void *sig, size_t sig_len)
3438 {
3439 	TEE_Result res;
3440 	struct tee_cryp_state *cs;
3441 	struct tee_ta_session *sess;
3442 	struct tee_obj *o;
3443 	size_t hash_size;
3444 	int salt_len;
3445 	TEE_Attribute *params = NULL;
3446 	uint32_t hash_algo;
3447 	struct user_ta_ctx *utc;
3448 
3449 	res = tee_ta_get_current_session(&sess);
3450 	if (res != TEE_SUCCESS)
3451 		return res;
3452 	utc = to_user_ta_ctx(sess->ctx);
3453 
3454 	res = tee_svc_cryp_get_state(sess, tee_svc_uref_to_vaddr(state), &cs);
3455 	if (res != TEE_SUCCESS)
3456 		return res;
3457 
3458 	if (cs->mode != TEE_MODE_VERIFY)
3459 		return TEE_ERROR_BAD_PARAMETERS;
3460 
3461 	res = tee_mmu_check_access_rights(utc,
3462 					  TEE_MEMORY_ACCESS_READ |
3463 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3464 					  (uaddr_t)data, data_len);
3465 	if (res != TEE_SUCCESS)
3466 		return res;
3467 
3468 	res = tee_mmu_check_access_rights(utc,
3469 					  TEE_MEMORY_ACCESS_READ |
3470 					  TEE_MEMORY_ACCESS_ANY_OWNER,
3471 					  (uaddr_t)sig, sig_len);
3472 	if (res != TEE_SUCCESS)
3473 		return res;
3474 
3475 	params = malloc(sizeof(TEE_Attribute) * num_params);
3476 	if (!params)
3477 		return TEE_ERROR_OUT_OF_MEMORY;
3478 	res = copy_in_attrs(utc, usr_params, num_params, params);
3479 	if (res != TEE_SUCCESS)
3480 		goto out;
3481 
3482 	res = tee_obj_get(utc, cs->key1, &o);
3483 	if (res != TEE_SUCCESS)
3484 		goto out;
3485 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
3486 		res = TEE_ERROR_BAD_PARAMETERS;
3487 		goto out;
3488 	}
3489 
3490 	switch (TEE_ALG_GET_MAIN_ALG(cs->algo)) {
3491 	case TEE_MAIN_ALGO_RSA:
3492 		hash_algo = TEE_DIGEST_HASH_TO_ALGO(cs->algo);
3493 		res = tee_hash_get_digest_size(hash_algo, &hash_size);
3494 		if (res != TEE_SUCCESS)
3495 			break;
3496 		if (data_len != hash_size) {
3497 			res = TEE_ERROR_BAD_PARAMETERS;
3498 			break;
3499 		}
3500 		salt_len = pkcs1_get_salt_len(params, num_params, hash_size);
3501 		if (!crypto_ops.acipher.rsassa_verify) {
3502 			res = TEE_ERROR_NOT_IMPLEMENTED;
3503 			break;
3504 		}
3505 		res = crypto_ops.acipher.rsassa_verify(cs->algo, o->attr,
3506 						       salt_len, data,
3507 						       data_len, sig, sig_len);
3508 		break;
3509 
3510 	case TEE_MAIN_ALGO_DSA:
3511 		hash_algo = TEE_DIGEST_HASH_TO_ALGO(cs->algo);
3512 		res = tee_hash_get_digest_size(hash_algo, &hash_size);
3513 		if (res != TEE_SUCCESS)
3514 			break;
3515 		/*
3516 		 * Depending on the DSA algorithm (NIST), the digital signature
3517 		 * output size may be truncated to the size of a key pair
3518 		 * (Q prime size). Q prime size must be less or equal than the
3519 		 * hash output length of the hash algorithm involved.
3520 		 */
3521 		if (data_len > hash_size) {
3522 			res = TEE_ERROR_BAD_PARAMETERS;
3523 			break;
3524 		}
3525 		if (!crypto_ops.acipher.dsa_verify) {
3526 			res = TEE_ERROR_NOT_IMPLEMENTED;
3527 			break;
3528 		}
3529 		res = crypto_ops.acipher.dsa_verify(cs->algo, o->attr, data,
3530 						    data_len, sig, sig_len);
3531 		break;
3532 
3533 	case TEE_MAIN_ALGO_ECDSA:
3534 		if (!crypto_ops.acipher.ecc_verify) {
3535 			res = TEE_ERROR_NOT_IMPLEMENTED;
3536 			break;
3537 		}
3538 		res = crypto_ops.acipher.ecc_verify(cs->algo, o->attr, data,
3539 						    data_len, sig, sig_len);
3540 		break;
3541 
3542 	default:
3543 		res = TEE_ERROR_NOT_SUPPORTED;
3544 	}
3545 
3546 out:
3547 	free(params);
3548 	return res;
3549 }
3550