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