xref: /optee_os/core/tee/tee_svc_cryp.c (revision 2c276d687367efa8cf5d60cba165ad4493a72739)
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 <tomcrypt.h>
28 #include <mpalib.h>
29 #include <tee_api_types.h>
30 #include <kernel/tee_ta_manager.h>
31 #include <utee_defines.h>
32 #include <mm/tee_mmu.h>
33 #include <tee/tee_svc.h>
34 #include <tee/tee_svc_cryp.h>
35 #include <sys/queue.h>
36 #include <tee/tee_hash.h>
37 #include <tee/tee_mac.h>
38 #include <tee/tee_cipher.h>
39 #include <tee/tee_authenc.h>
40 #include <tee/tee_obj.h>
41 #include <tee/tee_acipher.h>
42 #include <kernel/tee_core_trace.h>
43 #include <tee_ltc_wrapper.h>
44 #include <rng_support.h>
45 
46 /*
47  * Big Numbers, used by LTC, allocation size
48  */
49 #define LTC_BIGNUMBERS_ALLOC_SIZE \
50 	((mpa_StaticVarSizeInU32(LTC_MAX_BITS_PER_VARIABLE)) * sizeof(uint32_t))
51 
52 /*
53  * Set the allocation bytes used for a big number. This is the first uint32_t
54  * member of the array representing the big number
55  * Equals the total allocation size
56  *   minus 4 for the 'alloc' member
57  *   minus 4 for the 'size' member
58  */
59 #define SET_MPA_ALLOCSIZE(_x) \
60 	((uint32_t *)(_x))[0] = (LTC_BIGNUMBERS_ALLOC_SIZE - 8)
61 
62 /* Set an attribute on an object */
63 #define SET_ATTRIBUTE(_object, _props, _attr)	\
64 	(_object)->have_attrs |= \
65 		(1 << (tee_svc_cryp_obj_find_type_attr_idx((_attr), (_props))))
66 
67 /* Get an attribute on an object */
68 #define GET_ATTRIBUTE(_object, _props, _attr)	\
69 	((_object)->have_attrs & \
70 		(1 << (tee_svc_cryp_obj_find_type_attr_idx((_attr), (_props)))))
71 
72 #define TEE_USAGE_DEFAULT   0xffffffff
73 #define TEE_ATTR_BIT_PROTECTED              (1 << 28)
74 
75 typedef void (*tee_cryp_ctx_finalize_func_t) (void *ctx, uint32_t algo);
76 struct tee_cryp_state {
77 	TAILQ_ENTRY(tee_cryp_state) link;
78 	uint32_t algo;
79 	uint32_t mode;
80 	uint32_t key1;
81 	uint32_t key2;
82 	size_t ctx_size;
83 	void *ctx;
84 	tee_cryp_ctx_finalize_func_t ctx_finalize;
85 };
86 
87 struct tee_cryp_obj_secret {
88 	uint32_t key_size;
89 
90 	/*
91 	 * Pseudo code visualize layout of structure
92 	 * Next follows data, such as:
93 	 *	uint8_t data[key_size]
94 	 * key_size must never exceed
95 	 * (obj->data_size - sizeof(struct tee_cryp_obj_secret)).
96 	 */
97 };
98 
99 /*
100  * Following set of structures contains the "plain" data used by LibTomCrypt
101  * Translation to the real LTC types (that is only a collection of pointers)
102  * is then straightforward
103  */
104 
105 struct ltc_bignumbers {
106 	uint8_t b[LTC_BIGNUMBERS_ALLOC_SIZE];
107 };
108 
109 /*
110  * RSA key pair. Contains the public and private keys.
111  * rsa_key is the original type from LTC
112  */
113 struct tee_ltc_rsa_key_pair {
114 	struct ltc_bignumbers e;	/* the public exponent */
115 	struct ltc_bignumbers d;	/* The private exponent */
116 	struct ltc_bignumbers N;	/* The modulus */
117 
118 	/* Next are the CRT parameters, that are optional */
119 	struct ltc_bignumbers p;	/* The p factor of N */
120 	struct ltc_bignumbers q;	/* The q factor of N */
121 	struct ltc_bignumbers qP;	/* The 1/q mod p */
122 	struct ltc_bignumbers dP;	/* The d mod (p - 1) */
123 	struct ltc_bignumbers dQ;	/* The d mod (q - 1) */
124 };
125 
126 /*
127  * RSA public key. rsa_key is the original type from LTC, with type PK_PUBLIC
128  */
129 struct tee_ltc_rsa_public_key {
130 	struct ltc_bignumbers e;	/* the public exponent */
131 	struct ltc_bignumbers N;	/* The modulus */
132 };
133 
134 /*
135  * DSA key pair. dsa_key is the original type from LTC, with type PK_PRIVATE
136  */
137 struct tee_ltc_dsa_key_pair {
138 	struct ltc_bignumbers g;	/* Base generator */
139 	struct ltc_bignumbers p;	/* Prime modulus */
140 	struct ltc_bignumbers q;	/* Order of subgroup */
141 	struct ltc_bignumbers y;	/* Public key */
142 	struct ltc_bignumbers x;	/* Private key */
143 };
144 
145 /*
146  * DSA public key. dsa_key is the original type from LTC, with type PK_PUBLIC
147  */
148 struct tee_ltc_dsa_public_key {
149 	struct ltc_bignumbers g;	/* Base generator */
150 	struct ltc_bignumbers p;	/* Prime modulus */
151 	struct ltc_bignumbers q;	/* Order of subgroup */
152 	struct ltc_bignumbers y;	/* Public key */
153 };
154 
155 /*
156  * DH key pair. dsa_key is the original type from LTC, with type PK_PRIVATE
157  */
158 struct tee_ltc_dh_key_pair {
159 	struct ltc_bignumbers g;	/* Base generator */
160 	struct ltc_bignumbers p;	/* Prime modulus */
161 	struct ltc_bignumbers x;	/* Private key */
162 	struct ltc_bignumbers y;	/* Public key */
163 
164 	/* other parameters */
165 	struct ltc_bignumbers q;	/* Sub Prime */
166 	uint32_t xbits;
167 };
168 
169 #define TEE_TYPE_ATTR_OPTIONAL       0x0
170 #define TEE_TYPE_ATTR_REQUIRED       0x1
171 #define TEE_TYPE_ATTR_OPTIONAL_GROUP 0x2
172 #define TEE_TYPE_ATTR_SIZE_INDICATOR 0x4
173 #define TEE_TYPE_ATTR_GEN_KEY_OPT    0x8
174 #define TEE_TYPE_ATTR_GEN_KEY_REQ    0x10
175 
176 #define TEE_TYPE_CONV_FUNC_NONE       0
177     /* Handle storing of generic secret keys of varying lengths */
178 #define TEE_TYPE_CONV_FUNC_SECRET     1
179     /* Convert Array of bytes to/from Big Number from mpa (used by LTC). */
180 #define TEE_TYPE_CONV_FUNC_BIGINT     2
181     /* Convert to/from value attribute depending on direction */
182 #define TEE_TYPE_CONV_FUNC_VALUE      4
183 
184 struct tee_cryp_obj_type_attrs {
185 	uint32_t attr_id;
186 	uint16_t flags;
187 	uint16_t conv_func;
188 	uint16_t raw_offs;
189 	uint16_t raw_size;
190 };
191 
192 #define RAW_DATA(_x, _y)	\
193 	.raw_offs = offsetof(_x, _y), .raw_size = TEE_MEMBER_SIZE(_x, _y)
194 
195 static const struct tee_cryp_obj_type_attrs
196 	tee_cryp_obj_secret_value_attrs[] = {
197 	{
198 	.attr_id = TEE_ATTR_SECRET_VALUE,
199 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
200 	.conv_func = TEE_TYPE_CONV_FUNC_SECRET,
201 	.raw_offs = 0,
202 	.raw_size = 0
203 	},
204 };
205 
206 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_pub_key_attrs[] = {
207 	{
208 	.attr_id = TEE_ATTR_RSA_MODULUS,
209 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
210 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
211 	RAW_DATA(struct tee_ltc_rsa_public_key, N)
212 	},
213 
214 	{
215 	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
216 	.flags = TEE_TYPE_ATTR_REQUIRED,
217 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
218 	RAW_DATA(struct tee_ltc_rsa_public_key, e)
219 	},
220 };
221 
222 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_rsa_keypair_attrs[] = {
223 	{
224 	.attr_id = TEE_ATTR_RSA_MODULUS,
225 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
226 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
227 	RAW_DATA(struct tee_ltc_rsa_key_pair, N)
228 	},
229 
230 	{
231 	.attr_id = TEE_ATTR_RSA_PUBLIC_EXPONENT,
232 	.flags = TEE_TYPE_ATTR_REQUIRED,
233 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
234 	RAW_DATA(struct tee_ltc_rsa_key_pair, e)
235 	},
236 
237 	{
238 	.attr_id = TEE_ATTR_RSA_PRIVATE_EXPONENT,
239 	.flags = TEE_TYPE_ATTR_REQUIRED,
240 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
241 	RAW_DATA(struct tee_ltc_rsa_key_pair, d)
242 	},
243 
244 	{
245 	.attr_id = TEE_ATTR_RSA_PRIME1,
246 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
247 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
248 	RAW_DATA(struct tee_ltc_rsa_key_pair, p)
249 	},
250 
251 	{
252 	.attr_id = TEE_ATTR_RSA_PRIME2,
253 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
254 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
255 	RAW_DATA(struct tee_ltc_rsa_key_pair, q)
256 	},
257 
258 	{
259 	.attr_id = TEE_ATTR_RSA_EXPONENT1,
260 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
261 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
262 	RAW_DATA(struct tee_ltc_rsa_key_pair, dP)
263 	},
264 
265 	{
266 	.attr_id = TEE_ATTR_RSA_EXPONENT2,
267 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
268 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
269 	RAW_DATA(struct tee_ltc_rsa_key_pair, dQ)
270 	},
271 
272 	{
273 	.attr_id = TEE_ATTR_RSA_COEFFICIENT,
274 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP,
275 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
276 	RAW_DATA(struct tee_ltc_rsa_key_pair, qP)
277 	},
278 };
279 
280 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_pub_key_attrs[] = {
281 	{
282 	.attr_id = TEE_ATTR_DSA_PRIME,
283 	.flags = TEE_TYPE_ATTR_REQUIRED,
284 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
285 	RAW_DATA(struct tee_ltc_dsa_public_key, p)
286 	},
287 
288 	{
289 	.attr_id = TEE_ATTR_DSA_SUBPRIME,
290 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR,
291 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
292 	RAW_DATA(struct tee_ltc_dsa_public_key, q)
293 	},
294 
295 	{
296 	.attr_id = TEE_ATTR_DSA_BASE,
297 	.flags = TEE_TYPE_ATTR_REQUIRED,
298 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
299 	RAW_DATA(struct tee_ltc_dsa_public_key, g)
300 	},
301 
302 	{
303 	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
304 	.flags = TEE_TYPE_ATTR_REQUIRED,
305 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
306 	RAW_DATA(struct tee_ltc_dsa_public_key, y)
307 	},
308 };
309 
310 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dsa_keypair_attrs[] = {
311 	{
312 	.attr_id = TEE_ATTR_DSA_PRIME,
313 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
314 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
315 	RAW_DATA(struct tee_ltc_dsa_key_pair, p)
316 	},
317 
318 	{
319 	.attr_id = TEE_ATTR_DSA_SUBPRIME,
320 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
321 		 TEE_TYPE_ATTR_GEN_KEY_REQ,
322 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
323 	RAW_DATA(struct tee_ltc_dsa_key_pair, q)
324 	},
325 
326 	{
327 	.attr_id = TEE_ATTR_DSA_BASE,
328 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
329 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
330 	RAW_DATA(struct tee_ltc_dsa_key_pair, g)
331 	},
332 
333 	{
334 	.attr_id = TEE_ATTR_DSA_PRIVATE_VALUE,
335 	.flags = TEE_TYPE_ATTR_REQUIRED,
336 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
337 	RAW_DATA(struct tee_ltc_dsa_key_pair, x)
338 	},
339 
340 	{
341 	.attr_id = TEE_ATTR_DSA_PUBLIC_VALUE,
342 	.flags = TEE_TYPE_ATTR_REQUIRED,
343 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
344 	RAW_DATA(struct tee_ltc_dsa_key_pair, y)
345 	},
346 };
347 
348 static const struct tee_cryp_obj_type_attrs tee_cryp_obj_dh_keypair_attrs[] = {
349 	{
350 	.attr_id = TEE_ATTR_DH_PRIME,
351 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_SIZE_INDICATOR |
352 		 TEE_TYPE_ATTR_GEN_KEY_REQ,
353 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
354 	RAW_DATA(struct tee_ltc_dh_key_pair, p)
355 	},
356 
357 	{
358 	.attr_id = TEE_ATTR_DH_BASE,
359 	.flags = TEE_TYPE_ATTR_REQUIRED | TEE_TYPE_ATTR_GEN_KEY_REQ,
360 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
361 	RAW_DATA(struct tee_ltc_dh_key_pair, g)
362 	},
363 
364 	{
365 	.attr_id = TEE_ATTR_DH_PUBLIC_VALUE,
366 	.flags = TEE_TYPE_ATTR_REQUIRED,
367 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
368 	RAW_DATA(struct tee_ltc_dh_key_pair, y)
369 	},
370 
371 	{
372 	.attr_id = TEE_ATTR_DH_PRIVATE_VALUE,
373 	.flags = TEE_TYPE_ATTR_REQUIRED,
374 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
375 	RAW_DATA(struct tee_ltc_dh_key_pair, x)
376 	},
377 
378 	{
379 	.attr_id = TEE_ATTR_DH_SUBPRIME,
380 	.flags = TEE_TYPE_ATTR_OPTIONAL_GROUP |	 TEE_TYPE_ATTR_GEN_KEY_OPT,
381 	.conv_func = TEE_TYPE_CONV_FUNC_BIGINT,
382 	RAW_DATA(struct tee_ltc_dh_key_pair, q)
383 	},
384 
385 	{
386 	.attr_id = TEE_ATTR_DH_X_BITS,
387 	.flags = TEE_TYPE_ATTR_GEN_KEY_OPT,
388 	.conv_func = TEE_TYPE_CONV_FUNC_VALUE,
389 	RAW_DATA(struct tee_ltc_dh_key_pair, xbits)
390 	},
391 };
392 
393 struct tee_cryp_obj_type_props {
394 	TEE_ObjectType obj_type;
395 	uint16_t min_size;	/* may not be smaller than this */
396 	uint16_t max_size;	/* may not be larger than this */
397 	uint16_t alloc_size;	/* this many bytes are allocated to hold data */
398 	uint8_t quanta;		/* may only be an multiple of this */
399 
400 	uint8_t num_type_attrs;
401 	const struct tee_cryp_obj_type_attrs *type_attrs;
402 };
403 
404 #define PROP(obj_type, quanta, min_size, max_size, alloc_size, type_attrs) \
405 		{ (obj_type), (min_size), (max_size), (alloc_size), (quanta), \
406 		  TEE_ARRAY_SIZE(type_attrs), (type_attrs) }
407 
408 static const struct tee_cryp_obj_type_props tee_cryp_obj_props[] = {
409 	PROP(TEE_TYPE_AES, 64, 128, 256,	/* valid sizes 128, 192, 256 */
410 		256 / 8 + sizeof(struct tee_cryp_obj_secret),
411 		tee_cryp_obj_secret_value_attrs),
412 	PROP(TEE_TYPE_DES, 56, 56, 56,
413 		/*
414 		* Valid size 56 without parity, note that we still allocate
415 		* for 64 bits since the key is supplied with parity.
416 		*/
417 		64 / 8 + sizeof(struct tee_cryp_obj_secret),
418 		tee_cryp_obj_secret_value_attrs),
419 	PROP(TEE_TYPE_DES3, 56, 112, 168,
420 		/*
421 		* Valid sizes 112, 168 without parity, note that we still
422 		* allocate for with space for the parity since the key is
423 		* supplied with parity.
424 		*/
425 		192 / 8 + sizeof(struct tee_cryp_obj_secret),
426 		tee_cryp_obj_secret_value_attrs),
427 	PROP(TEE_TYPE_HMAC_MD5, 8, 64, 512,
428 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
429 		tee_cryp_obj_secret_value_attrs),
430 	PROP(TEE_TYPE_HMAC_SHA1, 8, 80, 512,
431 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
432 		tee_cryp_obj_secret_value_attrs),
433 	PROP(TEE_TYPE_HMAC_SHA224, 8, 112, 512,
434 		512 / 8 + sizeof(struct tee_cryp_obj_secret),
435 		tee_cryp_obj_secret_value_attrs),
436 	PROP(TEE_TYPE_HMAC_SHA256, 8, 192, 1024,
437 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
438 		tee_cryp_obj_secret_value_attrs),
439 	PROP(TEE_TYPE_HMAC_SHA384, 8, 256, 1024,
440 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
441 		tee_cryp_obj_secret_value_attrs),
442 	PROP(TEE_TYPE_HMAC_SHA512, 8, 256, 1024,
443 		1024 / 8 + sizeof(struct tee_cryp_obj_secret),
444 		tee_cryp_obj_secret_value_attrs),
445 	PROP(TEE_TYPE_GENERIC_SECRET, 8, 0, 4096,
446 		4096 / 8 + sizeof(struct tee_cryp_obj_secret),
447 		tee_cryp_obj_secret_value_attrs),
448 
449 	PROP(TEE_TYPE_RSA_PUBLIC_KEY, 1, 256, 2048,
450 		sizeof(struct tee_ltc_rsa_public_key),
451 		tee_cryp_obj_rsa_pub_key_attrs),
452 
453 	PROP(TEE_TYPE_RSA_KEYPAIR, 1, 256, 2048,
454 		sizeof(struct tee_ltc_rsa_key_pair),
455 		tee_cryp_obj_rsa_keypair_attrs),
456 
457 	PROP(TEE_TYPE_DSA_PUBLIC_KEY, 64, 512, 1024,
458 		sizeof(struct tee_ltc_dsa_public_key),
459 		tee_cryp_obj_dsa_pub_key_attrs),
460 
461 	PROP(TEE_TYPE_DSA_KEYPAIR, 64, 512, 1024,
462 		sizeof(struct tee_ltc_dsa_key_pair),
463 		tee_cryp_obj_dsa_keypair_attrs),
464 
465 	PROP(TEE_TYPE_DH_KEYPAIR, 1, 256, 2048,
466 		sizeof(struct tee_ltc_dh_key_pair),
467 		tee_cryp_obj_dh_keypair_attrs),
468 };
469 
470 /*
471  * Populate the pointers in ltc_key, given struct tee_ltc_rsa_key_pair
472  */
473 static void tee_populate_rsa_key_pair(
474 	rsa_key *ltc_key,
475 	struct tee_ltc_rsa_key_pair *tee_key,
476 	bool crt)
477 {
478 	ltc_key->type = PK_PRIVATE;
479 	ltc_key->e = (char *)&tee_key->e;
480 	ltc_key->d = (char *)&tee_key->d;
481 	ltc_key->N = (char *)&tee_key->N;
482 
483 	if (crt) {
484 		ltc_key->p = (char *)&tee_key->p;
485 		ltc_key->q = (char *)&tee_key->q;
486 		ltc_key->qP = (char *)&tee_key->qP;
487 		ltc_key->dP = (char *)&tee_key->dP;
488 		ltc_key->dQ = (char *)&tee_key->dQ;
489 	} else {
490 		ltc_key->p = 0;
491 		ltc_key->q = 0;
492 		ltc_key->qP = 0;
493 		ltc_key->dP = 0;
494 		ltc_key->dQ = 0;
495 	}
496 
497 	SET_MPA_ALLOCSIZE(&tee_key->e);
498 	SET_MPA_ALLOCSIZE(&tee_key->d);
499 	SET_MPA_ALLOCSIZE(&tee_key->N);
500 	SET_MPA_ALLOCSIZE(&tee_key->p);
501 	SET_MPA_ALLOCSIZE(&tee_key->q);
502 	SET_MPA_ALLOCSIZE(&tee_key->qP);
503 	SET_MPA_ALLOCSIZE(&tee_key->dP);
504 	SET_MPA_ALLOCSIZE(&tee_key->dQ);
505 }
506 
507 static void tee_populate_rsa_public_key(
508 	rsa_key *ltc_key,
509 	struct tee_ltc_rsa_public_key *tee_key)
510 {
511 	ltc_key->type = PK_PUBLIC;
512 	ltc_key->e = (char *)&tee_key->e;
513 	ltc_key->N = (char *)&tee_key->N;
514 	SET_MPA_ALLOCSIZE(&tee_key->e);
515 	SET_MPA_ALLOCSIZE(&tee_key->N);
516 }
517 
518 static void tee_populate_dsa_key_pair(
519 	dsa_key *ltc_key,
520 	struct tee_ltc_dsa_key_pair *tee_key)
521 {
522 	ltc_key->type = PK_PRIVATE;
523 	ltc_key->g = (char *)&tee_key->g;
524 	ltc_key->p = (char *)&tee_key->p;
525 	ltc_key->q = (char *)&tee_key->q;
526 	ltc_key->y = (char *)&tee_key->y;
527 	ltc_key->x = (char *)&tee_key->x;
528 
529 	SET_MPA_ALLOCSIZE(&tee_key->g);
530 	SET_MPA_ALLOCSIZE(&tee_key->p);
531 	SET_MPA_ALLOCSIZE(&tee_key->q);
532 	SET_MPA_ALLOCSIZE(&tee_key->y);
533 	SET_MPA_ALLOCSIZE(&tee_key->x);
534 
535 	ltc_key->qord = mp_unsigned_bin_size(&tee_key->g);
536 }
537 
538 static void tee_populate_dsa_public_key(
539 	dsa_key *ltc_key,
540 	struct tee_ltc_dsa_public_key *tee_key)
541 {
542 	ltc_key->type = PK_PUBLIC;
543 	ltc_key->g = (char *)&tee_key->g;
544 	ltc_key->p = (char *)&tee_key->p;
545 	ltc_key->q = (char *)&tee_key->q;
546 	ltc_key->y = (char *)&tee_key->y;
547 
548 	SET_MPA_ALLOCSIZE(&tee_key->g);
549 	SET_MPA_ALLOCSIZE(&tee_key->p);
550 	SET_MPA_ALLOCSIZE(&tee_key->q);
551 	SET_MPA_ALLOCSIZE(&tee_key->y);
552 
553 	ltc_key->qord = mp_unsigned_bin_size(&tee_key->g);
554 }
555 
556 static void tee_populate_dh_key_pair(
557 	dh_key *ltc_key,
558 	struct tee_ltc_dh_key_pair *tee_key)
559 {
560 	ltc_key->type = PK_PRIVATE;
561 	ltc_key->g = (char *)&tee_key->g;
562 	ltc_key->p = (char *)&tee_key->p;
563 	ltc_key->x = (char *)&tee_key->x;
564 	ltc_key->y = (char *)&tee_key->y;
565 
566 	SET_MPA_ALLOCSIZE(&tee_key->g);
567 	SET_MPA_ALLOCSIZE(&tee_key->p);
568 	SET_MPA_ALLOCSIZE(&tee_key->x);
569 	SET_MPA_ALLOCSIZE(&tee_key->y);
570 
571 	/*
572 	 * q and xbits are not part of the dh key. They are only used to
573 	 * generate a key pair
574 	 * Alloc size must be set on 'q' anyway
575 	 */
576 	SET_MPA_ALLOCSIZE(&tee_key->q);
577 }
578 
579 TEE_Result tee_svc_cryp_obj_get_info(uint32_t obj, TEE_ObjectInfo *info)
580 {
581 	TEE_Result res;
582 	struct tee_ta_session *sess;
583 	struct tee_obj *o;
584 
585 	res = tee_ta_get_current_session(&sess);
586 	if (res != TEE_SUCCESS)
587 		return res;
588 
589 	res = tee_obj_get(sess->ctx, obj, &o);
590 	if (res != TEE_SUCCESS)
591 		return res;
592 
593 	return tee_svc_copy_to_user(sess, info, &o->info, sizeof(o->info));
594 }
595 
596 TEE_Result tee_svc_cryp_obj_restrict_usage(uint32_t obj, uint32_t usage)
597 {
598 	TEE_Result res;
599 	struct tee_ta_session *sess;
600 	struct tee_obj *o;
601 
602 	res = tee_ta_get_current_session(&sess);
603 	if (res != TEE_SUCCESS)
604 		return res;
605 
606 	res = tee_obj_get(sess->ctx, obj, &o);
607 	if (res != TEE_SUCCESS)
608 		return res;
609 
610 	o->info.objectUsage &= usage;
611 
612 	return TEE_SUCCESS;
613 }
614 
615 static TEE_Result tee_svc_cryp_obj_get_raw_data(
616 		struct tee_obj *o,
617 		const struct tee_cryp_obj_type_props *type_props,
618 		size_t idx, void **data, size_t *size)
619 {
620 	const struct tee_cryp_obj_type_attrs *type_attr =
621 	    type_props->type_attrs + idx;
622 	if (type_attr->raw_size == 0) {
623 		struct tee_cryp_obj_secret *key =
624 		    (struct tee_cryp_obj_secret *)o->data;
625 
626 		/* Handle generic secret */
627 		if (type_attr->raw_offs != 0)
628 			return TEE_ERROR_BAD_STATE;
629 		*size = key->key_size;
630 	} else {
631 		*size = type_attr->raw_size;
632 	}
633 	*data = (uint8_t *)o->data + type_attr->raw_offs;
634 	return TEE_SUCCESS;
635 }
636 
637 static int tee_svc_cryp_obj_find_type_attr_idx(
638 		uint32_t attr_id,
639 		const struct tee_cryp_obj_type_props *type_props)
640 {
641 	size_t n;
642 
643 	for (n = 0; n < type_props->num_type_attrs; n++) {
644 		if (attr_id == type_props->type_attrs[n].attr_id)
645 			return n;
646 	}
647 	return -1;
648 }
649 
650 static const struct tee_cryp_obj_type_props *tee_svc_find_type_props(
651 		TEE_ObjectType obj_type)
652 {
653 	size_t n;
654 
655 	for (n = 0; n < TEE_ARRAY_SIZE(tee_cryp_obj_props); n++) {
656 		if (tee_cryp_obj_props[n].obj_type == obj_type)
657 			return tee_cryp_obj_props + n;
658 	}
659 
660 	return NULL;
661 }
662 
663 static TEE_Result tee_svc_cryp_obj_copy_out(struct tee_ta_session *sess,
664 					    void *buffer, size_t *size,
665 					    uint16_t conv_func,
666 					    void *raw_data,
667 					    size_t raw_data_size)
668 {
669 	TEE_Result res;
670 	size_t s;
671 
672 	res = tee_svc_copy_from_user(sess, &s, size, sizeof(size_t));
673 	if (res != TEE_SUCCESS)
674 		return res;
675 
676 	switch (conv_func) {
677 	case TEE_TYPE_CONV_FUNC_NONE:
678 		res =
679 		    tee_svc_copy_to_user(sess, size, &raw_data_size,
680 					 sizeof(size_t));
681 		if (res != TEE_SUCCESS)
682 			return res;
683 
684 		if (s < raw_data_size)
685 			return TEE_ERROR_SHORT_BUFFER;
686 
687 		return tee_svc_copy_to_user(sess, buffer, raw_data,
688 					    raw_data_size);
689 	case TEE_TYPE_CONV_FUNC_SECRET:
690 		{
691 			struct tee_cryp_obj_secret *obj;
692 			size_t key_size;
693 
694 			if (!TEE_ALIGNMENT_IS_OK
695 			    (raw_data, struct tee_cryp_obj_secret))
696 				 return TEE_ERROR_BAD_STATE;
697 			obj = (struct tee_cryp_obj_secret *)(void *)raw_data;
698 			key_size = obj->key_size;
699 
700 			res =
701 			    tee_svc_copy_to_user(sess, size, &key_size,
702 						 sizeof(size_t));
703 			if (res != TEE_SUCCESS)
704 				return res;
705 
706 			if (s < key_size)
707 				return TEE_ERROR_SHORT_BUFFER;
708 
709 			return tee_svc_copy_to_user(sess, buffer, obj + 1,
710 						    key_size);
711 		}
712 
713 	case TEE_TYPE_CONV_FUNC_BIGINT:
714 	{
715 		size_t req_size;
716 
717 		SET_MPA_ALLOCSIZE(raw_data);
718 		req_size = mp_unsigned_bin_size(raw_data);
719 		if (req_size == 0)
720 			return TEE_SUCCESS;
721 		res = tee_svc_copy_to_user(
722 			sess, size, &req_size, sizeof(size_t));
723 		if (res != TEE_SUCCESS)
724 			return res;
725 
726 		/* Check that the converted result fits the user buffer. */
727 		if (s < req_size)
728 			return TEE_ERROR_SHORT_BUFFER;
729 
730 		/* Check we can access data using supplied user mode pointer */
731 		res = tee_mmu_check_access_rights(sess->ctx,
732 						  TEE_MEMORY_ACCESS_READ |
733 						  TEE_MEMORY_ACCESS_WRITE |
734 						  TEE_MEMORY_ACCESS_ANY_OWNER,
735 						  (tee_uaddr_t)buffer,
736 						  req_size);
737 		if (res != TEE_SUCCESS)
738 			return res;
739 
740 		/*
741 		 * write the mpa number (stored in raw data) into an array of
742 		 * bytes (stored in buffer)
743 		 */
744 		mp_to_unsigned_bin(raw_data, buffer);
745 		return TEE_SUCCESS;
746 	}
747 
748 	case TEE_TYPE_CONV_FUNC_VALUE:
749 		{
750 			uint32_t value[2] = { 0, 0 };
751 			size_t n = sizeof(value);
752 
753 			/*
754 			 * a value attribute consists of two uint32 but have not
755 			 * seen anything that actaully would need that so this
756 			 * fills in one with data and the other with zero
757 			 */
758 			TEE_ASSERT(raw_data_size == sizeof(uint32_t));
759 			value[0] = *(uint32_t *)raw_data;
760 
761 			res =
762 			    tee_svc_copy_to_user(sess, size, &n,
763 						 sizeof(size_t));
764 			if (res != TEE_SUCCESS)
765 				return res;
766 
767 			/* Check that the converted result fits the user buf */
768 			if (s < n)
769 				return TEE_ERROR_SHORT_BUFFER;
770 
771 			return tee_svc_copy_to_user(sess, buffer, &value, n);
772 		}
773 	default:
774 		return TEE_ERROR_BAD_STATE;
775 	}
776 
777 }
778 
779 TEE_Result tee_svc_cryp_obj_get_attr(uint32_t obj, uint32_t attr_id,
780 				     void *buffer, size_t *size)
781 {
782 	TEE_Result res;
783 	struct tee_ta_session *sess;
784 	struct tee_obj *o;
785 	const struct tee_cryp_obj_type_props *type_props;
786 	int idx;
787 	size_t raw_size;
788 	void *raw_data;
789 
790 	res = tee_ta_get_current_session(&sess);
791 	if (res != TEE_SUCCESS)
792 		return res;
793 
794 	res = tee_obj_get(sess->ctx, obj, &o);
795 	if (res != TEE_SUCCESS)
796 		return TEE_ERROR_ITEM_NOT_FOUND;
797 
798 	/* Check that the object is initialized */
799 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
800 		return TEE_ERROR_ITEM_NOT_FOUND;
801 
802 	/* Check that getting the attribute is allowed */
803 	if ((attr_id & TEE_ATTR_BIT_PROTECTED) == 0 &&
804 	    (o->info.objectUsage & TEE_USAGE_EXTRACTABLE) == 0)
805 		return TEE_ERROR_ACCESS_DENIED;
806 
807 	type_props = tee_svc_find_type_props(o->info.objectType);
808 	if (type_props == NULL) {
809 		/* Unknown object type, "can't happen" */
810 		return TEE_ERROR_BAD_STATE;
811 	}
812 
813 	idx = tee_svc_cryp_obj_find_type_attr_idx(attr_id, type_props);
814 	if ((idx < 0) || ((o->have_attrs & (1 << idx)) == 0))
815 		return TEE_ERROR_ITEM_NOT_FOUND;
816 
817 	res = tee_svc_cryp_obj_get_raw_data(o, type_props, idx,
818 					    &raw_data, &raw_size);
819 	if (res != TEE_SUCCESS)
820 		return res;
821 
822 	return tee_svc_cryp_obj_copy_out(sess, buffer, size,
823 					 type_props->type_attrs[idx].conv_func,
824 					 raw_data, raw_size);
825 }
826 
827 TEE_Result tee_svc_cryp_obj_alloc(TEE_ObjectType obj_type,
828 				  uint32_t max_obj_size, uint32_t *obj)
829 {
830 	TEE_Result res;
831 	struct tee_ta_session *sess;
832 	const struct tee_cryp_obj_type_props *type_props;
833 	struct tee_obj *o;
834 
835 	res = tee_ta_get_current_session(&sess);
836 	if (res != TEE_SUCCESS)
837 		return res;
838 
839 	/*
840 	 * Verify that maxObjectSize is supported and find out how
841 	 * much should be allocated.
842 	 */
843 
844 	/* Find description of object */
845 	type_props = tee_svc_find_type_props(obj_type);
846 	if (type_props == NULL)
847 		return TEE_ERROR_NOT_SUPPORTED;
848 
849 	/* Check that maxObjectSize follows restrictions */
850 	if (max_obj_size % type_props->quanta != 0)
851 		return TEE_ERROR_NOT_SUPPORTED;
852 	if (max_obj_size < type_props->min_size)
853 		return TEE_ERROR_NOT_SUPPORTED;
854 	if (max_obj_size > type_props->max_size)
855 		return TEE_ERROR_NOT_SUPPORTED;
856 
857 	o = calloc(1, sizeof(*o));
858 	if (o == NULL)
859 		return TEE_ERROR_OUT_OF_MEMORY;
860 	o->data = calloc(1, type_props->alloc_size);
861 	if (o->data == NULL) {
862 		free(o);
863 		return TEE_ERROR_OUT_OF_MEMORY;
864 	}
865 	o->data_size = type_props->alloc_size;
866 
867 	o->info.objectType = obj_type;
868 	o->info.maxObjectSize = max_obj_size;
869 	o->info.objectUsage = TEE_USAGE_DEFAULT;
870 	o->info.handleFlags = 0;
871 
872 	o->fd = -1;
873 
874 	tee_obj_add(sess->ctx, o);
875 
876 	res = tee_svc_copy_to_user(sess, obj, &o, sizeof(o));
877 	if (res != TEE_SUCCESS)
878 		tee_obj_close(sess->ctx, o);
879 	return res;
880 }
881 
882 TEE_Result tee_svc_cryp_obj_close(uint32_t obj)
883 {
884 	TEE_Result res;
885 	struct tee_ta_session *sess;
886 	struct tee_obj *o;
887 
888 	res = tee_ta_get_current_session(&sess);
889 	if (res != TEE_SUCCESS)
890 		return res;
891 
892 	res = tee_obj_get(sess->ctx, obj, &o);
893 	if (res != TEE_SUCCESS)
894 		return res;
895 
896 	/*
897 	 * If it's busy it's used by an operation, a client should never have
898 	 * this handle.
899 	 */
900 	if (o->busy)
901 		return TEE_ERROR_ITEM_NOT_FOUND;
902 
903 	tee_obj_close(sess->ctx, o);
904 	return TEE_SUCCESS;
905 }
906 
907 TEE_Result tee_svc_cryp_obj_reset(uint32_t obj)
908 {
909 	TEE_Result res;
910 	struct tee_ta_session *sess;
911 	struct tee_obj *o;
912 
913 	res = tee_ta_get_current_session(&sess);
914 	if (res != TEE_SUCCESS)
915 		return res;
916 
917 	res = tee_obj_get(sess->ctx, obj, &o);
918 	if (res != TEE_SUCCESS)
919 		return res;
920 
921 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) == 0) {
922 		memset(o->data, 0, o->data_size);
923 		o->info.objectSize = 0;
924 		o->info.objectUsage = TEE_USAGE_DEFAULT;
925 	} else {
926 		return TEE_ERROR_BAD_PARAMETERS;
927 	}
928 
929 	return TEE_SUCCESS;
930 }
931 
932 static TEE_Result tee_svc_cryp_obj_store_attr_raw(struct tee_ta_session *sess,
933 						  uint16_t conv_func,
934 						  const TEE_Attribute *attr,
935 						  void *data, size_t data_size)
936 {
937 	TEE_Result res;
938 
939 	if (attr == NULL)
940 		return TEE_ERROR_BAD_STATE;
941 
942 	if (conv_func != TEE_TYPE_CONV_FUNC_VALUE &&
943 	    attr->content.ref.buffer == NULL)
944 		return TEE_ERROR_BAD_PARAMETERS;
945 
946 	switch (conv_func) {
947 	case TEE_TYPE_CONV_FUNC_NONE:
948 		/* No conversion data size has to match exactly */
949 		if (attr->content.ref.length != data_size)
950 			return TEE_ERROR_BAD_PARAMETERS;
951 		return tee_svc_copy_from_user(sess, data,
952 					      attr->content.ref.buffer,
953 					      data_size);
954 	case TEE_TYPE_CONV_FUNC_SECRET:
955 		{
956 			struct tee_cryp_obj_secret *obj;
957 
958 			if (!TEE_ALIGNMENT_IS_OK
959 			    (data, struct tee_cryp_obj_secret))
960 				 return TEE_ERROR_BAD_STATE;
961 			obj = (struct tee_cryp_obj_secret *)(void *)data;
962 
963 			/* Data size has to fit in allocated buffer */
964 			if (attr->content.ref.length >
965 			    (data_size - sizeof(struct tee_cryp_obj_secret)))
966 				return TEE_ERROR_BAD_PARAMETERS;
967 
968 			res = tee_svc_copy_from_user(sess, obj + 1,
969 						     attr->content.ref.buffer,
970 						     attr->content.ref.length);
971 			if (res == TEE_SUCCESS)
972 				obj->key_size = attr->content.ref.length;
973 			return res;
974 		}
975 
976 	case TEE_TYPE_CONV_FUNC_BIGINT:
977 		/*
978 		 * Check that the converted result fits in the
979 		 * allocated buffer
980 		 */
981 		if (attr->content.ref.length >
982 		    (data_size +
983 		     sizeof(uint32_t) * MPA_NUMBASE_METADATA_SIZE_IN_U32))
984 			return TEE_ERROR_BAD_PARAMETERS;
985 
986 		/* Check data can be accessed */
987 		res = tee_mmu_check_access_rights(
988 			sess->ctx,
989 			TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER,
990 			(tee_uaddr_t)attr->content.ref.buffer,
991 			attr->content.ref.length);
992 		if (res != TEE_SUCCESS)
993 			return res;
994 
995 		/*
996 		 * read the array of bytes (stored in attr->content.ref.buffer)
997 		 * and save it as a mpa number (stored in data)
998 		 */
999 		SET_MPA_ALLOCSIZE(data);
1000 		mp_read_unsigned_bin(
1001 			data,
1002 			attr->content.ref.buffer,
1003 			attr->content.ref.length);
1004 		return TEE_SUCCESS;
1005 
1006 	case TEE_TYPE_CONV_FUNC_VALUE:
1007 		/*
1008 		 * a value attribute consists of two uint32 but have not
1009 		 * seen anything that actaully would need that so this fills
1010 		 * the data from the first value and discards the second value
1011 		 */
1012 		*(uint32_t *)data = attr->content.value.a;
1013 
1014 		return TEE_SUCCESS;
1015 
1016 	default:
1017 		return TEE_ERROR_BAD_STATE;
1018 	}
1019 }
1020 
1021 enum attr_usage {
1022 	ATTR_USAGE_POPULATE,
1023 	ATTR_USAGE_GENERATE_KEY
1024 };
1025 
1026 static TEE_Result tee_svc_cryp_check_attr(
1027 		enum attr_usage usage,
1028 		const struct tee_cryp_obj_type_props *type_props,
1029 		TEE_Attribute *attrs,
1030 		uint32_t attr_count)
1031 {
1032 	uint32_t required_flag;
1033 	uint32_t opt_flag;
1034 	bool all_opt_needed;
1035 	uint32_t req_attrs = 0;
1036 	uint32_t opt_grp_attrs = 0;
1037 	uint32_t attrs_found = 0;
1038 	size_t n;
1039 
1040 	if (usage == ATTR_USAGE_POPULATE) {
1041 		required_flag = TEE_TYPE_ATTR_REQUIRED;
1042 		opt_flag = TEE_TYPE_ATTR_OPTIONAL_GROUP;
1043 		all_opt_needed = true;
1044 	} else {
1045 		required_flag = TEE_TYPE_ATTR_GEN_KEY_REQ;
1046 		opt_flag = TEE_TYPE_ATTR_GEN_KEY_OPT;
1047 		all_opt_needed = false;
1048 	}
1049 
1050 	/*
1051 	 * First find out which attributes are required and which belong to
1052 	 * the optional group
1053 	 */
1054 	for (n = 0; n < type_props->num_type_attrs; n++) {
1055 		uint32_t bit = 1 << n;
1056 		uint32_t flags = type_props->type_attrs[n].flags;
1057 
1058 		if (flags & required_flag)
1059 			req_attrs |= bit;
1060 		else if (flags & opt_flag)
1061 			opt_grp_attrs |= bit;
1062 	}
1063 
1064 	/*
1065 	 * Verify that all required attributes are in place and
1066 	 * that the same attribute isn't repeated.
1067 	 */
1068 	for (n = 0; n < attr_count; n++) {
1069 		int idx =
1070 		    tee_svc_cryp_obj_find_type_attr_idx(attrs[n].attributeID,
1071 							type_props);
1072 		if (idx >= 0) {
1073 			uint32_t bit = 1 << idx;
1074 
1075 			if ((attrs_found & bit) != 0)
1076 				return TEE_ERROR_ITEM_NOT_FOUND;
1077 
1078 			attrs_found |= bit;
1079 		}
1080 	}
1081 	/* Required attribute missing */
1082 	if ((attrs_found & req_attrs) != req_attrs)
1083 		return TEE_ERROR_ITEM_NOT_FOUND;
1084 
1085 	/*
1086 	 * If the flag says that "if one of the optional attributes are included
1087 	 * all of them has to be included" this must be checked.
1088 	 */
1089 	if (all_opt_needed && (attrs_found & opt_grp_attrs) != 0 &&
1090 	    (attrs_found & opt_grp_attrs) != opt_grp_attrs)
1091 		return TEE_ERROR_ITEM_NOT_FOUND;
1092 
1093 	return TEE_SUCCESS;
1094 }
1095 
1096 static TEE_Result tee_svc_cryp_obj_populate_type(
1097 		struct tee_ta_session *sess,
1098 		struct tee_obj *o,
1099 		const struct tee_cryp_obj_type_props *type_props,
1100 		const TEE_Attribute *attrs,
1101 		uint32_t attr_count)
1102 {
1103 	TEE_Result res;
1104 	uint32_t have_attrs = 0;
1105 	size_t obj_size = 0;
1106 	size_t n;
1107 
1108 	for (n = 0; n < attr_count; n++) {
1109 		size_t raw_size;
1110 		void *raw_data;
1111 		int idx =
1112 		    tee_svc_cryp_obj_find_type_attr_idx(attrs[n].attributeID,
1113 							type_props);
1114 		if (idx < 0)
1115 			continue;
1116 
1117 		have_attrs |= 1 << idx;
1118 
1119 		res = tee_svc_cryp_obj_get_raw_data(o, type_props, idx,
1120 						    &raw_data, &raw_size);
1121 		if (res != TEE_SUCCESS)
1122 			return res;
1123 
1124 		res =
1125 		    tee_svc_cryp_obj_store_attr_raw(
1126 			    sess, type_props->type_attrs[idx].conv_func,
1127 			    attrs + n, raw_data, raw_size);
1128 		if (res != TEE_SUCCESS)
1129 			return res;
1130 
1131 		/*
1132 		 * First attr_idx signifies the attribute that gives the size
1133 		 * of the object
1134 		 */
1135 		if (type_props->type_attrs[idx].flags &
1136 		    TEE_TYPE_ATTR_SIZE_INDICATOR) {
1137 			obj_size += attrs[n].content.ref.length * 8;
1138 		}
1139 	}
1140 
1141 	/*
1142 	 * We have to do it like this because the parity bits aren't counted
1143 	 * when telling the size of the key in bits.
1144 	 */
1145 	if (o->info.objectType == TEE_TYPE_DES ||
1146 	    o->info.objectType == TEE_TYPE_DES3)
1147 		obj_size -= obj_size / 8; /* Exclude parity in size of key */
1148 
1149 	o->have_attrs = have_attrs;
1150 	o->info.objectSize = obj_size;
1151 	return TEE_SUCCESS;
1152 }
1153 
1154 TEE_Result tee_svc_cryp_obj_populate(uint32_t obj, TEE_Attribute *attrs,
1155 				     uint32_t attr_count)
1156 {
1157 	TEE_Result res;
1158 	struct tee_ta_session *sess;
1159 	struct tee_obj *o;
1160 	const struct tee_cryp_obj_type_props *type_props;
1161 
1162 	res = tee_ta_get_current_session(&sess);
1163 	if (res != TEE_SUCCESS)
1164 		return res;
1165 
1166 	res = tee_obj_get(sess->ctx, obj, &o);
1167 	if (res != TEE_SUCCESS)
1168 		return res;
1169 
1170 	/* Must be a transient object */
1171 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1172 		return TEE_ERROR_BAD_PARAMETERS;
1173 
1174 	/* Must not be initialized already */
1175 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1176 		return TEE_ERROR_BAD_PARAMETERS;
1177 
1178 	type_props = tee_svc_find_type_props(o->info.objectType);
1179 	if (type_props == NULL)
1180 		return TEE_ERROR_NOT_IMPLEMENTED;
1181 
1182 	res = tee_svc_cryp_check_attr(ATTR_USAGE_POPULATE, type_props, attrs,
1183 				      attr_count);
1184 	if (res != TEE_SUCCESS)
1185 		return res;
1186 
1187 	res = tee_svc_cryp_obj_populate_type(sess, o, type_props, attrs,
1188 					     attr_count);
1189 	if (res == TEE_SUCCESS)
1190 		o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1191 
1192 	return res;
1193 }
1194 
1195 TEE_Result tee_svc_cryp_obj_copy(uint32_t dst, uint32_t src)
1196 {
1197 	TEE_Result res;
1198 	struct tee_ta_session *sess;
1199 	struct tee_obj *dst_o;
1200 	struct tee_obj *src_o;
1201 
1202 	res = tee_ta_get_current_session(&sess);
1203 	if (res != TEE_SUCCESS)
1204 		return res;
1205 
1206 	res = tee_obj_get(sess->ctx, dst, &dst_o);
1207 	if (res != TEE_SUCCESS)
1208 		return res;
1209 
1210 	res = tee_obj_get(sess->ctx, src, &src_o);
1211 	if (res != TEE_SUCCESS)
1212 		return res;
1213 
1214 	if ((src_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1215 		return TEE_ERROR_BAD_PARAMETERS;
1216 	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1217 		return TEE_ERROR_BAD_PARAMETERS;
1218 	if ((dst_o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1219 		return TEE_ERROR_BAD_PARAMETERS;
1220 
1221 	if (dst_o->info.objectType == src_o->info.objectType) {
1222 		/* Generic case */
1223 		if (dst_o->data_size != src_o->data_size)
1224 			return TEE_ERROR_BAD_STATE;
1225 		dst_o->have_attrs = src_o->have_attrs;
1226 		memcpy(dst_o->data, src_o->data, src_o->data_size);
1227 
1228 	} else if (dst_o->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY &&
1229 		   src_o->info.objectType == TEE_TYPE_RSA_KEYPAIR) {
1230 		/* Extract public key from RSA key pair */
1231 		struct tee_ltc_rsa_key_pair *key_pair = src_o->data;
1232 		struct tee_ltc_rsa_public_key *pub_key = dst_o->data;
1233 		size_t n;
1234 
1235 		memcpy(&pub_key->e, &key_pair->e, sizeof(pub_key->e));
1236 		memcpy(&pub_key->N, &key_pair->N, sizeof(pub_key->N));
1237 
1238 		/* Set the attributes */
1239 		dst_o->have_attrs = 0;
1240 		for (n = 0; n < TEE_ARRAY_SIZE(tee_cryp_obj_rsa_pub_key_attrs);
1241 		     n++)
1242 			dst_o->have_attrs |= 1 << n;
1243 
1244 	} else if (dst_o->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY &&
1245 		   src_o->info.objectType == TEE_TYPE_DSA_KEYPAIR) {
1246 		/* Extract public key from DSA key pair */
1247 		struct tee_ltc_dsa_key_pair *key_pair = src_o->data;
1248 		struct tee_ltc_dsa_public_key *pub_key = dst_o->data;
1249 		size_t n;
1250 
1251 		memcpy(&pub_key->g, &key_pair->g, sizeof(pub_key->g));
1252 		memcpy(&pub_key->p, &key_pair->p, sizeof(pub_key->p));
1253 		memcpy(&pub_key->q, &key_pair->q, sizeof(pub_key->q));
1254 		memcpy(&pub_key->y, &key_pair->y, sizeof(pub_key->y));
1255 
1256 		/* Set the attributes */
1257 		dst_o->have_attrs = 0;
1258 		for (n = 0; n < TEE_ARRAY_SIZE(tee_cryp_obj_dsa_pub_key_attrs);
1259 		     n++)
1260 			dst_o->have_attrs |= 1 << n;
1261 
1262 	} else
1263 		return TEE_ERROR_BAD_PARAMETERS;
1264 
1265 	dst_o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1266 	dst_o->info.objectSize = src_o->info.objectSize;
1267 	dst_o->info.objectUsage = src_o->info.objectUsage;
1268 	return TEE_SUCCESS;
1269 }
1270 
1271 static TEE_Result tee_svc_obj_generate_key_rsa(
1272 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1273 	uint32_t key_size)
1274 {
1275 	TEE_Result res;
1276 	struct tee_ltc_rsa_key_pair *tee_rsa_key;
1277 	rsa_key ltc_rsa_key;
1278 
1279 	TEE_ASSERT(sizeof(struct tee_ltc_rsa_key_pair) == o->data_size);
1280 	tee_rsa_key = (struct tee_ltc_rsa_key_pair *)o->data;
1281 	tee_populate_rsa_key_pair(&ltc_rsa_key, tee_rsa_key, true);
1282 	res = tee_acipher_gen_rsa_keys(&ltc_rsa_key, key_size);
1283 	if (res != TEE_SUCCESS)
1284 		return res;
1285 
1286 	/* Set bits for all known attributes for this object type */
1287 	o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1288 	return TEE_SUCCESS;
1289 }
1290 
1291 static TEE_Result tee_svc_obj_generate_key_dsa(
1292 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1293 	uint32_t key_size)
1294 {
1295 	TEE_Result res;
1296 	struct tee_ltc_dsa_key_pair *tee_dsa_key;
1297 	dsa_key ltc_dsa_key;
1298 
1299 	TEE_ASSERT(sizeof(struct tee_ltc_dsa_key_pair) == o->data_size);
1300 	tee_dsa_key = (struct tee_ltc_dsa_key_pair *)o->data;
1301 	tee_populate_dsa_key_pair(&ltc_dsa_key, tee_dsa_key);
1302 	res = tee_acipher_gen_dsa_keys(&ltc_dsa_key, key_size);
1303 	if (res != TEE_SUCCESS)
1304 		return res;
1305 
1306 	/* Set bits for all known attributes for this object type */
1307 	o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1308 	return TEE_SUCCESS;
1309 }
1310 
1311 static TEE_Result tee_svc_obj_generate_key_dh(
1312 	struct tee_ta_session *sess,
1313 	struct tee_obj *o, const struct tee_cryp_obj_type_props *type_props,
1314 	uint32_t key_size, const TEE_Attribute *params, uint32_t param_count)
1315 {
1316 	TEE_Result res;
1317 	struct tee_ltc_dh_key_pair *tee_dh_key;
1318 	dh_key ltc_dh_key;
1319 	struct ltc_bignumbers *dh_q = NULL;
1320 	uint32_t dh_xbits = 0;
1321 
1322 	TEE_ASSERT(sizeof(struct tee_ltc_dh_key_pair) == o->data_size);
1323 
1324 	/* Copy the present attributes into the obj before starting */
1325 	res = tee_svc_cryp_obj_populate_type(
1326 			sess, o, type_props, params, param_count);
1327 	if (res != TEE_SUCCESS)
1328 		return res;
1329 
1330 	tee_dh_key = (struct tee_ltc_dh_key_pair *)o->data;
1331 	tee_populate_dh_key_pair(&ltc_dh_key, tee_dh_key);
1332 
1333 	if (GET_ATTRIBUTE(o, type_props, TEE_ATTR_DH_SUBPRIME))
1334 		dh_q = &tee_dh_key->q;
1335 	if (GET_ATTRIBUTE(o, type_props, TEE_ATTR_DH_X_BITS))
1336 		dh_xbits = tee_dh_key->xbits;
1337 	res = tee_acipher_gen_dh_keys(&ltc_dh_key, dh_q, dh_xbits);
1338 	if (res != TEE_SUCCESS)
1339 		return res;
1340 
1341 	/* Set bits for the generated public and private key */
1342 	SET_ATTRIBUTE(o, type_props, TEE_ATTR_DH_PUBLIC_VALUE);
1343 	SET_ATTRIBUTE(o, type_props, TEE_ATTR_DH_PRIVATE_VALUE);
1344 	SET_ATTRIBUTE(o, type_props, TEE_ATTR_DH_X_BITS);
1345 	return TEE_SUCCESS;
1346 }
1347 
1348 TEE_Result tee_svc_obj_generate_key(
1349 	uint32_t obj, uint32_t key_size,
1350 	const TEE_Attribute *params, uint32_t param_count)
1351 {
1352 	TEE_Result res;
1353 	struct tee_ta_session *sess;
1354 	const struct tee_cryp_obj_type_props *type_props;
1355 	struct tee_obj *o;
1356 	struct tee_cryp_obj_secret *key;
1357 	size_t byte_size;
1358 
1359 	res = tee_ta_get_current_session(&sess);
1360 	if (res != TEE_SUCCESS)
1361 		return res;
1362 
1363 	res = tee_obj_get(sess->ctx, obj, &o);
1364 	if (res != TEE_SUCCESS)
1365 		return res;
1366 
1367 	/* Must be a transient object */
1368 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
1369 		return TEE_ERROR_BAD_STATE;
1370 
1371 	/* Must not be initialized already */
1372 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
1373 		return TEE_ERROR_BAD_STATE;
1374 
1375 	/* Find description of object */
1376 	type_props = tee_svc_find_type_props(o->info.objectType);
1377 	if (type_props == NULL)
1378 		return TEE_ERROR_NOT_SUPPORTED;
1379 
1380 	/* Check that maxObjectSize follows restrictions */
1381 	if (key_size % type_props->quanta != 0)
1382 		return TEE_ERROR_NOT_SUPPORTED;
1383 	if (key_size < type_props->min_size)
1384 		return TEE_ERROR_NOT_SUPPORTED;
1385 	if (key_size > type_props->max_size)
1386 		return TEE_ERROR_NOT_SUPPORTED;
1387 
1388 	res = tee_svc_cryp_check_attr(ATTR_USAGE_GENERATE_KEY, type_props,
1389 				      (TEE_Attribute *)params, param_count);
1390 	if (res != TEE_SUCCESS)
1391 		return res;
1392 
1393 	switch (o->info.objectType) {
1394 	case TEE_TYPE_AES:
1395 	case TEE_TYPE_DES:
1396 	case TEE_TYPE_DES3:
1397 	case TEE_TYPE_HMAC_MD5:
1398 	case TEE_TYPE_HMAC_SHA1:
1399 	case TEE_TYPE_HMAC_SHA224:
1400 	case TEE_TYPE_HMAC_SHA256:
1401 	case TEE_TYPE_HMAC_SHA384:
1402 	case TEE_TYPE_HMAC_SHA512:
1403 	case TEE_TYPE_GENERIC_SECRET:
1404 		byte_size = key_size / 8;
1405 
1406 		/*
1407 		 * We have to do it like this because the parity bits aren't
1408 		 * counted when telling the size of the key in bits.
1409 		 */
1410 		if (o->info.objectType == TEE_TYPE_DES ||
1411 		    o->info.objectType == TEE_TYPE_DES3) {
1412 			byte_size = (key_size + key_size / 7) / 8;
1413 		}
1414 
1415 		key = (struct tee_cryp_obj_secret *)o->data;
1416 		if (byte_size > (o->data_size - sizeof(*key)))
1417 			return TEE_ERROR_EXCESS_DATA;
1418 
1419 		res = get_rng_array((void *)(key + 1), byte_size);
1420 		if (res != TEE_SUCCESS)
1421 			return res;
1422 
1423 		/* Force the last bit to have exactly a value on byte_size */
1424 		((char *)key)[sizeof(key->key_size) + byte_size - 1] |= 0x80;
1425 		key->key_size = byte_size;
1426 
1427 		/* Set bits for all known attributes for this object type */
1428 		o->have_attrs = (1 << type_props->num_type_attrs) - 1;
1429 
1430 		break;
1431 
1432 	case TEE_TYPE_RSA_KEYPAIR:
1433 		res = tee_svc_obj_generate_key_rsa(o, type_props, key_size);
1434 		if (res != TEE_SUCCESS)
1435 			return res;
1436 		break;
1437 
1438 	case TEE_TYPE_DSA_KEYPAIR:
1439 		res = tee_svc_obj_generate_key_dsa(o, type_props, key_size);
1440 		if (res != TEE_SUCCESS)
1441 			return res;
1442 		break;
1443 
1444 	case TEE_TYPE_DH_KEYPAIR:
1445 		res = tee_svc_obj_generate_key_dh(
1446 			sess, o, type_props, key_size, params, param_count);
1447 		if (res != TEE_SUCCESS)
1448 			return res;
1449 		break;
1450 
1451 	default:
1452 		return TEE_ERROR_BAD_FORMAT;
1453 	}
1454 
1455 	o->info.objectSize = key_size;
1456 	o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
1457 	return TEE_SUCCESS;
1458 }
1459 
1460 static TEE_Result tee_svc_cryp_get_state(struct tee_ta_session *sess,
1461 					 uint32_t state_id,
1462 					 struct tee_cryp_state **state)
1463 {
1464 	struct tee_cryp_state *s;
1465 
1466 	TAILQ_FOREACH(s, &sess->ctx->cryp_states, link) {
1467 		if (state_id == (uint32_t) s) {
1468 			*state = s;
1469 			return TEE_SUCCESS;
1470 		}
1471 	}
1472 	return TEE_ERROR_BAD_PARAMETERS;
1473 }
1474 
1475 static void cryp_state_free(struct tee_ta_ctx *ctx, struct tee_cryp_state *cs)
1476 {
1477 	struct tee_obj *o;
1478 
1479 	if (tee_obj_get(ctx, cs->key1, &o) == TEE_SUCCESS)
1480 		tee_obj_close(ctx, o);
1481 	if (tee_obj_get(ctx, cs->key2, &o) == TEE_SUCCESS)
1482 		tee_obj_close(ctx, o);
1483 
1484 	TAILQ_REMOVE(&ctx->cryp_states, cs, link);
1485 	if (cs->ctx_finalize != NULL)
1486 		cs->ctx_finalize(cs->ctx, cs->algo);
1487 	free(cs->ctx);
1488 	free(cs);
1489 }
1490 
1491 static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o,
1492 					      uint32_t algo,
1493 					      TEE_OperationMode mode)
1494 {
1495 	uint32_t req_key_type;
1496 
1497 	switch (TEE_ALG_GET_MAIN_ALG(algo)) {
1498 	case TEE_MAIN_ALGO_MD5:
1499 		req_key_type = TEE_TYPE_HMAC_MD5;
1500 		break;
1501 	case TEE_MAIN_ALGO_SHA1:
1502 		req_key_type = TEE_TYPE_HMAC_SHA1;
1503 		break;
1504 	case TEE_MAIN_ALGO_SHA224:
1505 		req_key_type = TEE_TYPE_HMAC_SHA224;
1506 		break;
1507 	case TEE_MAIN_ALGO_SHA256:
1508 		req_key_type = TEE_TYPE_HMAC_SHA256;
1509 		break;
1510 	case TEE_MAIN_ALGO_SHA384:
1511 		req_key_type = TEE_TYPE_HMAC_SHA384;
1512 		break;
1513 	case TEE_MAIN_ALGO_SHA512:
1514 		req_key_type = TEE_TYPE_HMAC_SHA512;
1515 		break;
1516 	case TEE_MAIN_ALGO_AES:
1517 		req_key_type = TEE_TYPE_AES;
1518 		break;
1519 	case TEE_MAIN_ALGO_DES:
1520 		req_key_type = TEE_TYPE_DES;
1521 		break;
1522 	case TEE_MAIN_ALGO_DES3:
1523 		req_key_type = TEE_TYPE_DES3;
1524 		break;
1525 	case TEE_MAIN_ALGO_RSA:
1526 		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
1527 			req_key_type = TEE_TYPE_RSA_PUBLIC_KEY;
1528 		else
1529 			req_key_type = TEE_TYPE_RSA_KEYPAIR;
1530 		break;
1531 	case TEE_MAIN_ALGO_DSA:
1532 		if (mode == TEE_MODE_ENCRYPT || mode == TEE_MODE_VERIFY)
1533 			req_key_type = TEE_TYPE_DSA_PUBLIC_KEY;
1534 		else
1535 			req_key_type = TEE_TYPE_DSA_KEYPAIR;
1536 		break;
1537 	case TEE_MAIN_ALGO_DH:
1538 		req_key_type = TEE_TYPE_DH_KEYPAIR;
1539 		break;
1540 	default:
1541 		return TEE_ERROR_BAD_PARAMETERS;
1542 	}
1543 
1544 	if (req_key_type != o->info.objectType)
1545 		return TEE_ERROR_BAD_PARAMETERS;
1546 	return TEE_SUCCESS;
1547 }
1548 
1549 TEE_Result tee_svc_cryp_state_alloc(uint32_t algo, uint32_t mode,
1550 				    uint32_t key1, uint32_t key2,
1551 				    uint32_t *state)
1552 {
1553 	TEE_Result res;
1554 	struct tee_cryp_state *cs;
1555 	struct tee_ta_session *sess;
1556 	struct tee_obj *o1 = NULL;
1557 	struct tee_obj *o2 = NULL;
1558 
1559 	res = tee_ta_get_current_session(&sess);
1560 	if (res != TEE_SUCCESS)
1561 		return res;
1562 
1563 	if (key1 != 0) {
1564 		res = tee_obj_get(sess->ctx, key1, &o1);
1565 		if (res != TEE_SUCCESS)
1566 			return res;
1567 		if (o1->busy)
1568 			return TEE_ERROR_BAD_PARAMETERS;
1569 		res = tee_svc_cryp_check_key_type(o1, algo, mode);
1570 		if (res != TEE_SUCCESS)
1571 			return res;
1572 	}
1573 	if (key2 != 0) {
1574 		res = tee_obj_get(sess->ctx, key2, &o2);
1575 		if (res != TEE_SUCCESS)
1576 			return res;
1577 		if (o2->busy)
1578 			return TEE_ERROR_BAD_PARAMETERS;
1579 		res = tee_svc_cryp_check_key_type(o2, algo, mode);
1580 		if (res != TEE_SUCCESS)
1581 			return res;
1582 	}
1583 
1584 	cs = calloc(1, sizeof(struct tee_cryp_state));
1585 	if (cs == NULL)
1586 		return TEE_ERROR_OUT_OF_MEMORY;
1587 	TAILQ_INSERT_TAIL(&sess->ctx->cryp_states, cs, link);
1588 	cs->algo = algo;
1589 	cs->mode = mode;
1590 
1591 	switch (TEE_ALG_GET_CLASS(algo)) {
1592 	case TEE_OPERATION_CIPHER:
1593 		if ((algo == TEE_ALG_AES_XTS && (key1 == 0 || key2 == 0)) ||
1594 		    (algo != TEE_ALG_AES_XTS && (key1 == 0 || key2 != 0))) {
1595 			res = TEE_ERROR_BAD_PARAMETERS;
1596 		} else {
1597 			res = tee_cipher_get_ctx_size(algo, &cs->ctx_size);
1598 			if (res != TEE_SUCCESS)
1599 				break;
1600 			cs->ctx = calloc(1, cs->ctx_size);
1601 			if (cs->ctx == NULL)
1602 				res = TEE_ERROR_OUT_OF_MEMORY;
1603 		}
1604 		break;
1605 	case TEE_OPERATION_AE:
1606 		if (key1 == 0 || key2 != 0) {
1607 			res = TEE_ERROR_BAD_PARAMETERS;
1608 		} else {
1609 			res = tee_authenc_get_ctx_size(algo, &cs->ctx_size);
1610 			if (res != TEE_SUCCESS)
1611 				break;
1612 			cs->ctx = calloc(1, cs->ctx_size);
1613 			if (cs->ctx == NULL)
1614 				res = TEE_ERROR_OUT_OF_MEMORY;
1615 		}
1616 		break;
1617 	case TEE_OPERATION_MAC:
1618 		if (key1 == 0 || key2 != 0) {
1619 			res = TEE_ERROR_BAD_PARAMETERS;
1620 		} else {
1621 			res = tee_mac_get_ctx_size(algo, &cs->ctx_size);
1622 			if (res != TEE_SUCCESS)
1623 				break;
1624 			cs->ctx = calloc(1, cs->ctx_size);
1625 			if (cs->ctx == NULL)
1626 				res = TEE_ERROR_OUT_OF_MEMORY;
1627 		}
1628 		break;
1629 	case TEE_OPERATION_DIGEST:
1630 		if (key1 != 0 || key2 != 0) {
1631 			res = TEE_ERROR_BAD_PARAMETERS;
1632 		} else {
1633 			res = tee_hash_get_ctx_size(algo, &cs->ctx_size);
1634 			if (res != TEE_SUCCESS)
1635 				break;
1636 			cs->ctx = calloc(1, cs->ctx_size);
1637 			if (cs->ctx == NULL)
1638 				res = TEE_ERROR_OUT_OF_MEMORY;
1639 		}
1640 		break;
1641 	case TEE_OPERATION_ASYMMETRIC_CIPHER:
1642 	case TEE_OPERATION_ASYMMETRIC_SIGNATURE:
1643 		if (key1 == 0 || key2 != 0)
1644 			res = TEE_ERROR_BAD_PARAMETERS;
1645 		break;
1646 	case TEE_OPERATION_KEY_DERIVATION:
1647 		if (key1 == 0 || key2 != 0)
1648 			res = TEE_ERROR_BAD_PARAMETERS;
1649 		break;
1650 	default:
1651 		res = TEE_ERROR_NOT_SUPPORTED;
1652 		break;
1653 	}
1654 	if (res != TEE_SUCCESS)
1655 		goto out;
1656 
1657 	res = tee_svc_copy_to_user(sess, state, &cs, sizeof(uint32_t));
1658 	if (res != TEE_SUCCESS)
1659 		goto out;
1660 
1661 	/* Register keys */
1662 	if (o1 != NULL) {
1663 		o1->busy = true;
1664 		cs->key1 = key1;
1665 	}
1666 	if (o2 != NULL) {
1667 		o2->busy = true;
1668 		cs->key2 = key2;
1669 	}
1670 
1671 out:
1672 	if (res != TEE_SUCCESS)
1673 		cryp_state_free(sess->ctx, cs);
1674 	return res;
1675 }
1676 
1677 TEE_Result tee_svc_cryp_state_copy(uint32_t dst, uint32_t src)
1678 {
1679 	TEE_Result res;
1680 	struct tee_cryp_state *cs_dst;
1681 	struct tee_cryp_state *cs_src;
1682 	struct tee_ta_session *sess;
1683 
1684 	res = tee_ta_get_current_session(&sess);
1685 	if (res != TEE_SUCCESS)
1686 		return res;
1687 
1688 	res = tee_svc_cryp_get_state(sess, dst, &cs_dst);
1689 	if (res != TEE_SUCCESS)
1690 		return res;
1691 	res = tee_svc_cryp_get_state(sess, src, &cs_src);
1692 	if (res != TEE_SUCCESS)
1693 		return res;
1694 	if (cs_dst->algo != cs_src->algo || cs_dst->mode != cs_src->mode)
1695 		return TEE_ERROR_BAD_PARAMETERS;
1696 	/* "Can't happen" */
1697 	if (cs_dst->ctx_size != cs_src->ctx_size)
1698 		return TEE_ERROR_BAD_STATE;
1699 
1700 	memcpy(cs_dst->ctx, cs_src->ctx, cs_src->ctx_size);
1701 	return TEE_SUCCESS;
1702 }
1703 
1704 void tee_svc_cryp_free_states(struct tee_ta_ctx *ctx)
1705 {
1706 	struct tee_cryp_state_head *states = &ctx->cryp_states;
1707 
1708 	while (!TAILQ_EMPTY(states))
1709 		cryp_state_free(ctx, TAILQ_FIRST(states));
1710 }
1711 
1712 TEE_Result tee_svc_cryp_state_free(uint32_t state)
1713 {
1714 	TEE_Result res;
1715 	struct tee_cryp_state *cs;
1716 	struct tee_ta_session *sess;
1717 
1718 	res = tee_ta_get_current_session(&sess);
1719 	if (res != TEE_SUCCESS)
1720 		return res;
1721 
1722 	res = tee_svc_cryp_get_state(sess, state, &cs);
1723 	if (res != TEE_SUCCESS)
1724 		return res;
1725 	cryp_state_free(sess->ctx, cs);
1726 	return TEE_SUCCESS;
1727 }
1728 
1729 /* iv and iv_len are ignored for some algorithms */
1730 TEE_Result tee_svc_hash_init(uint32_t state, const void *iv, size_t iv_len)
1731 {
1732 	TEE_Result res;
1733 	struct tee_cryp_state *cs;
1734 	struct tee_ta_session *sess;
1735 
1736 	res = tee_ta_get_current_session(&sess);
1737 	if (res != TEE_SUCCESS)
1738 		return res;
1739 
1740 	res = tee_svc_cryp_get_state(sess, state, &cs);
1741 	if (res != TEE_SUCCESS)
1742 		return res;
1743 
1744 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
1745 	case TEE_OPERATION_DIGEST:
1746 		res = tee_hash_init(cs->ctx, cs->algo);
1747 		if (res != TEE_SUCCESS)
1748 			return res;
1749 		break;
1750 	case TEE_OPERATION_MAC:
1751 		{
1752 			struct tee_obj *o;
1753 			struct tee_cryp_obj_secret *key;
1754 
1755 			res = tee_obj_get(sess->ctx, cs->key1, &o);
1756 			if (res != TEE_SUCCESS)
1757 				return res;
1758 			if ((o->info.handleFlags &
1759 			     TEE_HANDLE_FLAG_INITIALIZED) == 0)
1760 				return TEE_ERROR_BAD_PARAMETERS;
1761 
1762 			key = (struct tee_cryp_obj_secret *)o->data;
1763 			res = tee_mac_init(cs->ctx, cs->algo, (void *)(key + 1),
1764 					   key->key_size);
1765 			if (res != TEE_SUCCESS)
1766 				return res;
1767 			break;
1768 		}
1769 	default:
1770 		return TEE_ERROR_BAD_PARAMETERS;
1771 	}
1772 
1773 	return TEE_SUCCESS;
1774 }
1775 
1776 TEE_Result tee_svc_hash_update(uint32_t state, const void *chunk,
1777 			       size_t chunk_size)
1778 {
1779 	TEE_Result res;
1780 	struct tee_cryp_state *cs;
1781 	struct tee_ta_session *sess;
1782 
1783 	res = tee_ta_get_current_session(&sess);
1784 	if (res != TEE_SUCCESS)
1785 		return res;
1786 
1787 	res = tee_mmu_check_access_rights(sess->ctx,
1788 					  TEE_MEMORY_ACCESS_READ |
1789 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1790 					  (tee_uaddr_t)chunk, chunk_size);
1791 	if (res != TEE_SUCCESS)
1792 		return res;
1793 
1794 	res = tee_svc_cryp_get_state(sess, state, &cs);
1795 	if (res != TEE_SUCCESS)
1796 		return res;
1797 
1798 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
1799 	case TEE_OPERATION_DIGEST:
1800 		res = tee_hash_update(cs->ctx, cs->algo, chunk, chunk_size);
1801 		if (res != TEE_SUCCESS)
1802 			return res;
1803 		break;
1804 	case TEE_OPERATION_MAC:
1805 		res = tee_mac_update(cs->ctx, cs->algo, chunk, chunk_size);
1806 		if (res != TEE_SUCCESS)
1807 			return res;
1808 		break;
1809 	default:
1810 		return TEE_ERROR_BAD_PARAMETERS;
1811 	}
1812 
1813 	return TEE_SUCCESS;
1814 }
1815 
1816 TEE_Result tee_svc_hash_final(uint32_t state, const void *chunk,
1817 			      size_t chunk_size, void *hash, size_t *hash_len)
1818 {
1819 	TEE_Result res, res2;
1820 	size_t hash_size;
1821 	size_t hlen;
1822 	struct tee_cryp_state *cs;
1823 	struct tee_ta_session *sess;
1824 
1825 	res = tee_ta_get_current_session(&sess);
1826 	if (res != TEE_SUCCESS)
1827 		return res;
1828 
1829 	res = tee_mmu_check_access_rights(sess->ctx,
1830 					  TEE_MEMORY_ACCESS_READ |
1831 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1832 					  (tee_uaddr_t)chunk, chunk_size);
1833 	if (res != TEE_SUCCESS)
1834 		return res;
1835 
1836 	res = tee_svc_copy_from_user(sess, &hlen, hash_len, sizeof(size_t));
1837 	if (res != TEE_SUCCESS)
1838 		return res;
1839 
1840 	res = tee_mmu_check_access_rights(sess->ctx,
1841 					  TEE_MEMORY_ACCESS_READ |
1842 					  TEE_MEMORY_ACCESS_WRITE |
1843 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1844 					  (tee_uaddr_t)hash, hlen);
1845 	if (res != TEE_SUCCESS)
1846 		return res;
1847 
1848 	res = tee_svc_cryp_get_state(sess, state, &cs);
1849 	if (res != TEE_SUCCESS)
1850 		return res;
1851 
1852 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
1853 	case TEE_OPERATION_DIGEST:
1854 		res = tee_hash_get_digest_size(cs->algo, &hash_size);
1855 		if (res != TEE_SUCCESS)
1856 			return res;
1857 		if (*hash_len < hash_size) {
1858 			res = TEE_ERROR_SHORT_BUFFER;
1859 			goto out;
1860 		}
1861 
1862 		res = tee_hash_update(cs->ctx, cs->algo, chunk, chunk_size);
1863 		if (res != TEE_SUCCESS)
1864 			return res;
1865 		res = tee_hash_final(cs->ctx, cs->algo, hash, hash_size);
1866 		if (res != TEE_SUCCESS)
1867 			return res;
1868 		break;
1869 	case TEE_OPERATION_MAC:
1870 		res = tee_mac_get_digest_size(cs->algo, &hash_size);
1871 		if (res != TEE_SUCCESS)
1872 			return res;
1873 		if (*hash_len < hash_size) {
1874 			res = TEE_ERROR_SHORT_BUFFER;
1875 			goto out;
1876 		}
1877 
1878 		res = tee_mac_final(cs->ctx, cs->algo, chunk, chunk_size, hash,
1879 				    hash_size);
1880 		if (res != TEE_SUCCESS)
1881 			return res;
1882 		break;
1883 	default:
1884 		return TEE_ERROR_BAD_PARAMETERS;
1885 	}
1886 out:
1887 	res2 =
1888 	    tee_svc_copy_to_user(sess, hash_len, &hash_size, sizeof(*hash_len));
1889 	if (res2 != TEE_SUCCESS)
1890 		return res2;
1891 	return res;
1892 }
1893 
1894 TEE_Result tee_svc_cipher_init(uint32_t state, const void *iv, size_t iv_len)
1895 {
1896 	TEE_Result res;
1897 	struct tee_cryp_state *cs;
1898 	struct tee_ta_session *sess;
1899 	struct tee_obj *o;
1900 	struct tee_cryp_obj_secret *key1;
1901 
1902 	res = tee_ta_get_current_session(&sess);
1903 	if (res != TEE_SUCCESS)
1904 		return res;
1905 
1906 	res = tee_svc_cryp_get_state(sess, state, &cs);
1907 	if (res != TEE_SUCCESS)
1908 		return res;
1909 
1910 	res = tee_mmu_check_access_rights(sess->ctx,
1911 					  TEE_MEMORY_ACCESS_READ |
1912 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1913 					  (tee_uaddr_t) iv, iv_len);
1914 	if (res != TEE_SUCCESS)
1915 		return res;
1916 
1917 	res = tee_obj_get(sess->ctx, cs->key1, &o);
1918 	if (res != TEE_SUCCESS)
1919 		return res;
1920 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1921 		return TEE_ERROR_BAD_PARAMETERS;
1922 
1923 	key1 = (struct tee_cryp_obj_secret *)o->data;
1924 
1925 	if (tee_obj_get(sess->ctx, cs->key2, &o) == TEE_SUCCESS) {
1926 		struct tee_cryp_obj_secret *key2 =
1927 		    (struct tee_cryp_obj_secret *)o->data;
1928 
1929 		if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1930 			return TEE_ERROR_BAD_PARAMETERS;
1931 
1932 		res = tee_cipher_init3(cs->ctx, cs->algo, cs->mode,
1933 				       (uint8_t *)(key1 + 1), key1->key_size,
1934 				       (uint8_t *)(key2 + 1), key2->key_size,
1935 				       iv, iv_len);
1936 	} else {
1937 		res = tee_cipher_init2(cs->ctx, cs->algo, cs->mode,
1938 			       (uint8_t *)(key1 + 1), key1->key_size,
1939 				       iv, iv_len);
1940 	}
1941 	if (res != TEE_SUCCESS)
1942 		return res;
1943 
1944 	cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t) tee_cipher_final;
1945 	return TEE_SUCCESS;
1946 }
1947 
1948 static TEE_Result tee_svc_cipher_update_helper(uint32_t state, bool last_block,
1949 					       const void *src, size_t src_len,
1950 					       void *dst, size_t *dst_len)
1951 {
1952 	TEE_Result res;
1953 	struct tee_cryp_state *cs;
1954 	struct tee_ta_session *sess;
1955 	size_t dlen;
1956 
1957 	res = tee_ta_get_current_session(&sess);
1958 	if (res != TEE_SUCCESS)
1959 		return res;
1960 
1961 	res = tee_svc_cryp_get_state(sess, state, &cs);
1962 	if (res != TEE_SUCCESS)
1963 		return res;
1964 
1965 	res = tee_mmu_check_access_rights(sess->ctx,
1966 					  TEE_MEMORY_ACCESS_READ |
1967 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1968 					  (tee_uaddr_t)src, src_len);
1969 	if (res != TEE_SUCCESS)
1970 		return res;
1971 
1972 	if (dst_len == NULL) {
1973 		dlen = 0;
1974 	} else {
1975 		res =
1976 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
1977 					   sizeof(size_t));
1978 		if (res != TEE_SUCCESS)
1979 			return res;
1980 
1981 		res = tee_mmu_check_access_rights(sess->ctx,
1982 						  TEE_MEMORY_ACCESS_READ |
1983 						  TEE_MEMORY_ACCESS_WRITE |
1984 						  TEE_MEMORY_ACCESS_ANY_OWNER,
1985 						  (tee_uaddr_t)dst, dlen);
1986 		if (res != TEE_SUCCESS)
1987 			return res;
1988 	}
1989 
1990 	if (dlen < src_len) {
1991 		res = TEE_ERROR_SHORT_BUFFER;
1992 		goto out;
1993 	}
1994 
1995 	if (src_len > 0) {
1996 		/* Permit src_len == 0 to finalize the operation */
1997 		res = tee_cipher_update(cs->ctx, cs->algo, cs->mode, last_block,
1998 					src, src_len, dst);
1999 	}
2000 
2001 	if (last_block && cs->ctx_finalize != NULL) {
2002 		cs->ctx_finalize(cs->ctx, cs->mode);
2003 		cs->ctx_finalize = NULL;
2004 	}
2005 
2006 out:
2007 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
2008 	    dst_len != NULL) {
2009 		TEE_Result res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2010 						       sizeof(size_t));
2011 		if (res2 != TEE_SUCCESS)
2012 			res = res2;
2013 	}
2014 
2015 	return res;
2016 }
2017 
2018 TEE_Result tee_svc_cipher_update(uint32_t state, const void *src,
2019 				 size_t src_len, void *dst, size_t *dst_len)
2020 {
2021 	return tee_svc_cipher_update_helper(state, false /* last_block */,
2022 					    src, src_len, dst, dst_len);
2023 }
2024 
2025 TEE_Result tee_svc_cipher_final(uint32_t state, const void *src,
2026 				size_t src_len, void *dst, size_t *dst_len)
2027 {
2028 	return tee_svc_cipher_update_helper(state, true /* last_block */,
2029 					    src, src_len, dst, dst_len);
2030 }
2031 
2032 TEE_Result tee_svc_cryp_derive_key(uint32_t state, const TEE_Attribute *params,
2033 				   uint32_t param_count, uint32_t derived_key)
2034 {
2035 	TEE_Result res;
2036 	struct tee_ta_session *sess;
2037 	struct tee_obj *ko;
2038 	struct tee_obj *so;
2039 	struct tee_cryp_state *cs;
2040 	struct tee_cryp_obj_secret *sk;
2041 	const struct tee_cryp_obj_type_props *type_props;
2042 	struct ltc_bignumbers publicvalue;
2043 	struct ltc_bignumbers sharedsecret;
2044 	struct tee_ltc_dh_key_pair *tee_dh_key;
2045 	dh_key ltc_dh_key;
2046 
2047 	res = tee_ta_get_current_session(&sess);
2048 	if (res != TEE_SUCCESS)
2049 		return res;
2050 
2051 	res = tee_svc_cryp_get_state(sess, state, &cs);
2052 	if (res != TEE_SUCCESS)
2053 		return res;
2054 
2055 	if ((param_count != 1) ||
2056 	    (params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE))
2057 		return TEE_ERROR_BAD_PARAMETERS;
2058 
2059 	/* get key set in operation */
2060 	res = tee_obj_get(sess->ctx, cs->key1, &ko);
2061 	if (res != TEE_SUCCESS)
2062 		return res;
2063 
2064 	tee_dh_key = (struct tee_ltc_dh_key_pair *)ko->data;
2065 	tee_populate_dh_key_pair(&ltc_dh_key, tee_dh_key);
2066 
2067 	res = tee_obj_get(sess->ctx, derived_key, &so);
2068 	if (res != TEE_SUCCESS)
2069 		return res;
2070 
2071 	/* find information needed about the object to initialize */
2072 	sk = (struct tee_cryp_obj_secret *)so->data;
2073 
2074 	/* Find description of object */
2075 	type_props = tee_svc_find_type_props(so->info.objectType);
2076 	if (type_props == NULL)
2077 		return TEE_ERROR_NOT_SUPPORTED;
2078 
2079 	SET_MPA_ALLOCSIZE(&publicvalue);
2080 	SET_MPA_ALLOCSIZE(&sharedsecret);
2081 
2082 	/* extract information from the attributes passed to the function */
2083 	mp_read_unsigned_bin(
2084 		&publicvalue,
2085 		params[0].content.ref.buffer,
2086 		params[0].content.ref.length);
2087 	res = tee_derive_dh_shared_secret(
2088 		&ltc_dh_key, &publicvalue, &sharedsecret);
2089 
2090 	if (res == TEE_SUCCESS) {
2091 		sk->key_size = mp_unsigned_bin_size(&sharedsecret);
2092 		mp_to_unsigned_bin(&sharedsecret, (uint8_t *)(sk + 1));
2093 		so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2094 		SET_ATTRIBUTE(so, type_props, TEE_ATTR_SECRET_VALUE);
2095 	}
2096 	return res;
2097 }
2098 
2099 TEE_Result get_rng_array(void *buffer, int len)
2100 {
2101 	char *buf_char = buffer;
2102 	int i;
2103 
2104 
2105 	if (buf_char == NULL)
2106 		return TEE_ERROR_BAD_PARAMETERS;
2107 
2108 	for (i = 0; i < len; i++)
2109 		buf_char[i] = hw_get_random_byte();
2110 
2111 	return TEE_SUCCESS;
2112 }
2113 
2114 TEE_Result tee_svc_cryp_random_number_generate(void *buf, size_t blen)
2115 {
2116 	TEE_Result res;
2117 	struct tee_ta_session *sess;
2118 
2119 	res = tee_ta_get_current_session(&sess);
2120 	if (res != TEE_SUCCESS)
2121 		return res;
2122 
2123 	res = tee_mmu_check_access_rights(sess->ctx,
2124 					  TEE_MEMORY_ACCESS_WRITE |
2125 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2126 					  (tee_uaddr_t)buf, blen);
2127 	if (res != TEE_SUCCESS)
2128 		return res;
2129 
2130 	res = get_rng_array(buf, blen);
2131 	if (res != TEE_SUCCESS)
2132 		return res;
2133 
2134 	return res;
2135 }
2136 
2137 TEE_Result tee_svc_authenc_init(uint32_t state, const void *nonce,
2138 				size_t nonce_len, size_t tag_len,
2139 				size_t aad_len, size_t payload_len)
2140 {
2141 	TEE_Result res;
2142 	struct tee_cryp_state *cs;
2143 	struct tee_ta_session *sess;
2144 	struct tee_obj *o;
2145 	struct tee_cryp_obj_secret *key;
2146 
2147 	res = tee_ta_get_current_session(&sess);
2148 	if (res != TEE_SUCCESS)
2149 		return res;
2150 
2151 	res = tee_svc_cryp_get_state(sess, state, &cs);
2152 	if (res != TEE_SUCCESS)
2153 		return res;
2154 
2155 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2156 	if (res != TEE_SUCCESS)
2157 		return res;
2158 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2159 		return TEE_ERROR_BAD_PARAMETERS;
2160 
2161 	key = (struct tee_cryp_obj_secret *)o->data;
2162 	res = tee_authenc_init(cs->ctx, cs->algo, cs->mode,
2163 			       (uint8_t *)(key + 1), key->key_size,
2164 			       nonce, nonce_len, tag_len, aad_len, payload_len);
2165 	if (res != TEE_SUCCESS)
2166 		return res;
2167 
2168 	cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t)tee_authenc_final;
2169 	return TEE_SUCCESS;
2170 }
2171 
2172 TEE_Result tee_svc_authenc_update_aad(uint32_t state, const void *aad_data,
2173 				      size_t aad_data_len)
2174 {
2175 	TEE_Result res;
2176 	struct tee_cryp_state *cs;
2177 	struct tee_ta_session *sess;
2178 
2179 	res = tee_ta_get_current_session(&sess);
2180 	if (res != TEE_SUCCESS)
2181 		return res;
2182 
2183 	res = tee_mmu_check_access_rights(sess->ctx,
2184 					  TEE_MEMORY_ACCESS_READ |
2185 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2186 					  (tee_uaddr_t) aad_data, aad_data_len);
2187 	if (res != TEE_SUCCESS)
2188 		return res;
2189 
2190 	res = tee_svc_cryp_get_state(sess, state, &cs);
2191 	if (res != TEE_SUCCESS)
2192 		return res;
2193 
2194 	res = tee_authenc_update_aad(cs->ctx, cs->algo, cs->mode, aad_data,
2195 				     aad_data_len);
2196 	if (res != TEE_SUCCESS)
2197 		return res;
2198 
2199 	return TEE_SUCCESS;
2200 }
2201 
2202 TEE_Result tee_svc_authenc_update_payload(uint32_t state, const void *src_data,
2203 					  size_t src_len, void *dst_data,
2204 					  size_t *dst_len)
2205 {
2206 	TEE_Result res;
2207 	struct tee_cryp_state *cs;
2208 	struct tee_ta_session *sess;
2209 	size_t dlen;
2210 
2211 	res = tee_ta_get_current_session(&sess);
2212 	if (res != TEE_SUCCESS)
2213 		return res;
2214 
2215 	res = tee_svc_cryp_get_state(sess, state, &cs);
2216 	if (res != TEE_SUCCESS)
2217 		return res;
2218 
2219 	res = tee_mmu_check_access_rights(sess->ctx,
2220 					  TEE_MEMORY_ACCESS_READ |
2221 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2222 					  (tee_uaddr_t) src_data, src_len);
2223 	if (res != TEE_SUCCESS)
2224 		return res;
2225 
2226 	res = tee_svc_copy_from_user(sess, &dlen, dst_len, sizeof(size_t));
2227 	if (res != TEE_SUCCESS)
2228 		return res;
2229 
2230 	res = tee_mmu_check_access_rights(sess->ctx,
2231 					  TEE_MEMORY_ACCESS_READ |
2232 					  TEE_MEMORY_ACCESS_WRITE |
2233 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2234 					  (tee_uaddr_t)dst_data, dlen);
2235 	if (res != TEE_SUCCESS)
2236 		return res;
2237 
2238 	if (dlen < src_len) {
2239 		res = TEE_ERROR_SHORT_BUFFER;
2240 		goto out;
2241 	}
2242 
2243 	res = tee_authenc_update_payload(cs->ctx, cs->algo, cs->mode, src_data,
2244 					 src_len, dst_data);
2245 
2246 out:
2247 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2248 		TEE_Result res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2249 						       sizeof(size_t));
2250 		if (res2 != TEE_SUCCESS)
2251 			res = res2;
2252 	}
2253 
2254 	return res;
2255 }
2256 
2257 TEE_Result tee_svc_authenc_enc_final(uint32_t state, const void *src_data,
2258 				     size_t src_len, void *dst_data,
2259 				     size_t *dst_len, void *tag,
2260 				     size_t *tag_len)
2261 {
2262 	TEE_Result res;
2263 	struct tee_cryp_state *cs;
2264 	struct tee_ta_session *sess;
2265 	size_t dlen;
2266 	size_t tlen;
2267 
2268 	res = tee_ta_get_current_session(&sess);
2269 	if (res != TEE_SUCCESS)
2270 		return res;
2271 
2272 	res = tee_svc_cryp_get_state(sess, state, &cs);
2273 	if (res != TEE_SUCCESS)
2274 		return res;
2275 
2276 	if (cs->mode != TEE_MODE_ENCRYPT)
2277 		return TEE_ERROR_BAD_PARAMETERS;
2278 
2279 	res = tee_mmu_check_access_rights(sess->ctx,
2280 					  TEE_MEMORY_ACCESS_READ |
2281 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2282 					  (tee_uaddr_t)src_data, src_len);
2283 	if (res != TEE_SUCCESS)
2284 		return res;
2285 
2286 	if (dst_len == NULL) {
2287 		dlen = 0;
2288 	} else {
2289 		res =
2290 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
2291 					   sizeof(size_t));
2292 		if (res != TEE_SUCCESS)
2293 			return res;
2294 
2295 		res = tee_mmu_check_access_rights(sess->ctx,
2296 						  TEE_MEMORY_ACCESS_READ |
2297 						  TEE_MEMORY_ACCESS_WRITE |
2298 						  TEE_MEMORY_ACCESS_ANY_OWNER,
2299 						  (tee_uaddr_t)dst_data, dlen);
2300 		if (res != TEE_SUCCESS)
2301 			return res;
2302 	}
2303 
2304 	if (dlen < src_len) {
2305 		res = TEE_ERROR_SHORT_BUFFER;
2306 		goto out;
2307 	}
2308 
2309 	res = tee_svc_copy_from_user(sess, &tlen, tag_len, sizeof(size_t));
2310 	if (res != TEE_SUCCESS)
2311 		return res;
2312 
2313 	res = tee_mmu_check_access_rights(sess->ctx,
2314 					  TEE_MEMORY_ACCESS_READ |
2315 					  TEE_MEMORY_ACCESS_WRITE |
2316 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2317 					  (tee_uaddr_t)tag, tlen);
2318 	if (res != TEE_SUCCESS)
2319 		return res;
2320 
2321 	res = tee_authenc_enc_final(cs->ctx, cs->algo, src_data, src_len,
2322 				    dst_data, tag, &tlen);
2323 
2324 out:
2325 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2326 		TEE_Result res2;
2327 
2328 		if (dst_len != NULL) {
2329 			res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2330 						    sizeof(size_t));
2331 			if (res2 != TEE_SUCCESS)
2332 				return res2;
2333 		}
2334 
2335 		res2 =
2336 		    tee_svc_copy_to_user(sess, tag_len, &tlen, sizeof(size_t));
2337 		if (res2 != TEE_SUCCESS)
2338 			return res2;
2339 	}
2340 
2341 	return res;
2342 }
2343 
2344 TEE_Result tee_svc_authenc_dec_final(uint32_t state, const void *src_data,
2345 				     size_t src_len, void *dst_data,
2346 				     size_t *dst_len, const void *tag,
2347 				     size_t tag_len)
2348 {
2349 	TEE_Result res;
2350 	struct tee_cryp_state *cs;
2351 	struct tee_ta_session *sess;
2352 	size_t dlen;
2353 
2354 	res = tee_ta_get_current_session(&sess);
2355 	if (res != TEE_SUCCESS)
2356 		return res;
2357 
2358 	res = tee_svc_cryp_get_state(sess, state, &cs);
2359 	if (res != TEE_SUCCESS)
2360 		return res;
2361 
2362 	if (cs->mode != TEE_MODE_DECRYPT)
2363 		return TEE_ERROR_BAD_PARAMETERS;
2364 
2365 	res = tee_mmu_check_access_rights(sess->ctx,
2366 					  TEE_MEMORY_ACCESS_READ |
2367 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2368 					  (tee_uaddr_t)src_data, src_len);
2369 	if (res != TEE_SUCCESS)
2370 		return res;
2371 
2372 	if (dst_len == NULL) {
2373 		dlen = 0;
2374 	} else {
2375 		res =
2376 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
2377 					   sizeof(size_t));
2378 		if (res != TEE_SUCCESS)
2379 			return res;
2380 
2381 		res = tee_mmu_check_access_rights(sess->ctx,
2382 						  TEE_MEMORY_ACCESS_READ |
2383 						  TEE_MEMORY_ACCESS_WRITE |
2384 						  TEE_MEMORY_ACCESS_ANY_OWNER,
2385 						  (tee_uaddr_t)dst_data, dlen);
2386 		if (res != TEE_SUCCESS)
2387 			return res;
2388 	}
2389 
2390 	if (dlen < src_len) {
2391 		res = TEE_ERROR_SHORT_BUFFER;
2392 		goto out;
2393 	}
2394 
2395 	res = tee_mmu_check_access_rights(sess->ctx,
2396 					  TEE_MEMORY_ACCESS_READ |
2397 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2398 					  (tee_uaddr_t)tag, tag_len);
2399 	if (res != TEE_SUCCESS)
2400 		return res;
2401 
2402 	res = tee_authenc_dec_final(cs->ctx, cs->algo, src_data, src_len,
2403 				    dst_data, tag, tag_len);
2404 
2405 out:
2406 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
2407 	    dst_len != NULL) {
2408 		TEE_Result res2;
2409 
2410 		res2 =
2411 		    tee_svc_copy_to_user(sess, dst_len, &src_len,
2412 					 sizeof(size_t));
2413 		if (res2 != TEE_SUCCESS)
2414 			return res2;
2415 	}
2416 
2417 	return res;
2418 }
2419 
2420 static void tee_svc_asymm_pkcs1_get_salt_len(const TEE_Attribute *params,
2421 					     uint32_t num_params, int *salt_len)
2422 {
2423 	size_t n;
2424 
2425 	for (n = 0; n < num_params; n++) {
2426 		if (params[n].attributeID == TEE_ATTR_RSA_PSS_SALT_LENGTH) {
2427 			*salt_len = params[n].content.value.a;
2428 			return;
2429 		}
2430 	}
2431 	*salt_len = -1;
2432 }
2433 
2434 static TEE_Result tee_svc_asymm_rsa_check_crt_exist(struct tee_obj *o,
2435 						    bool *crt_exist)
2436 {
2437 	const struct tee_cryp_obj_type_props *type_props;
2438 	int i;
2439 
2440 	type_props = tee_svc_find_type_props(o->info.objectType);
2441 	if (type_props == NULL)
2442 		return TEE_ERROR_BAD_PARAMETERS;
2443 
2444 	/*
2445 	 * if one crt attribute exits all must exists and this is
2446 	 * checked when populating it
2447 	 */
2448 	i = tee_svc_cryp_obj_find_type_attr_idx(TEE_ATTR_RSA_PRIME1,
2449 		type_props);
2450 
2451 	if ((o->have_attrs & (1 << i)) != 0)
2452 		*crt_exist = true;
2453 	else
2454 		*crt_exist = false;
2455 
2456 	return TEE_SUCCESS;
2457 }
2458 
2459 TEE_Result tee_svc_asymm_operate(uint32_t state, const TEE_Attribute *params,
2460 				 uint32_t num_params, const void *src_data,
2461 				 size_t src_len, void *dst_data,
2462 				 size_t *dst_len)
2463 {
2464 	TEE_Result res;
2465 	struct tee_cryp_state *cs;
2466 	struct tee_ta_session *sess;
2467 	size_t dlen;
2468 	struct tee_obj *o;
2469 	struct tee_ltc_rsa_public_key *tee_rsa_public_key;
2470 	struct tee_ltc_rsa_key_pair *tee_rsa_key_pair;
2471 	struct tee_ltc_dsa_key_pair *tee_dsa_key;
2472 	union {
2473 		rsa_key ltc_rsa_key;
2474 		dsa_key ltc_dsa_key;
2475 	} key_type;
2476 	void *label = NULL;
2477 	size_t label_len = 0;
2478 	size_t n;
2479 	bool crt_exist;
2480 	int salt_len;
2481 
2482 	res = tee_ta_get_current_session(&sess);
2483 	if (res != TEE_SUCCESS)
2484 		return res;
2485 
2486 	res = tee_svc_cryp_get_state(sess, state, &cs);
2487 	if (res != TEE_SUCCESS)
2488 		return res;
2489 
2490 	res = tee_mmu_check_access_rights(
2491 		sess->ctx,
2492 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER,
2493 		(tee_uaddr_t) src_data, src_len);
2494 	if (res != TEE_SUCCESS)
2495 		return res;
2496 
2497 	res = tee_svc_copy_from_user(sess, &dlen, dst_len, sizeof(size_t));
2498 	if (res != TEE_SUCCESS)
2499 		return res;
2500 
2501 	res = tee_mmu_check_access_rights(
2502 		sess->ctx,
2503 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
2504 			TEE_MEMORY_ACCESS_ANY_OWNER,
2505 		(tee_uaddr_t) dst_data, dlen);
2506 	if (res != TEE_SUCCESS)
2507 		return res;
2508 
2509 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2510 	if (res != TEE_SUCCESS)
2511 		return res;
2512 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2513 		return TEE_ERROR_GENERIC;
2514 
2515 	switch (cs->algo) {
2516 	case TEE_ALG_RSA_NOPAD:
2517 		if (cs->mode == TEE_MODE_ENCRYPT) {
2518 			tee_rsa_public_key = o->data;
2519 			tee_populate_rsa_public_key(
2520 				&key_type.ltc_rsa_key, tee_rsa_public_key);
2521 		} else if (cs->mode == TEE_MODE_DECRYPT) {
2522 			tee_rsa_key_pair = o->data;
2523 			res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2524 			if (res != TEE_SUCCESS)
2525 				return res;
2526 			tee_populate_rsa_key_pair(
2527 				&key_type.ltc_rsa_key, tee_rsa_key_pair,
2528 				crt_exist);
2529 
2530 		} else {
2531 			/*
2532 			 * We will panic because "the mode is not compatible
2533 			 * with the function"
2534 			 */
2535 			return TEE_ERROR_GENERIC;
2536 		}
2537 
2538 		res = tee_acipher_rsadorep(
2539 			&key_type.ltc_rsa_key,
2540 			src_data, src_len, dst_data, &dlen);
2541 		break;
2542 
2543 	case TEE_ALG_RSAES_PKCS1_V1_5:
2544 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
2545 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
2546 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
2547 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
2548 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
2549 		for (n = 0; n < num_params; n++) {
2550 			if (params[n].attributeID == TEE_ATTR_RSA_OAEP_LABEL) {
2551 				label = params[n].content.ref.buffer;
2552 				label_len = params[n].content.ref.length;
2553 				break;
2554 			}
2555 		}
2556 
2557 		if (cs->mode == TEE_MODE_ENCRYPT) {
2558 			tee_rsa_public_key = o->data;
2559 			tee_populate_rsa_public_key(
2560 				&key_type.ltc_rsa_key, tee_rsa_public_key);
2561 			res = tee_acipher_rsaes_encrypt(
2562 				cs->algo, &key_type.ltc_rsa_key,
2563 				label, label_len,
2564 				src_data, src_len, dst_data, &dlen);
2565 		} else if (cs->mode == TEE_MODE_DECRYPT) {
2566 			tee_rsa_key_pair = o->data;
2567 			res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2568 			if (res != TEE_SUCCESS)
2569 				return res;
2570 
2571 			tee_populate_rsa_key_pair(
2572 				&key_type.ltc_rsa_key,
2573 				tee_rsa_key_pair, crt_exist);
2574 			res = tee_acipher_rsaes_decrypt(
2575 				cs->algo, &key_type.ltc_rsa_key,
2576 				label, label_len,
2577 				src_data, src_len, dst_data, &dlen);
2578 		} else {
2579 			res = TEE_ERROR_BAD_PARAMETERS;
2580 		}
2581 		break;
2582 
2583 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
2584 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
2585 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
2586 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
2587 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
2588 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
2589 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
2590 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
2591 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
2592 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
2593 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
2594 		if (cs->mode != TEE_MODE_SIGN) {
2595 			res = TEE_ERROR_BAD_PARAMETERS;
2596 			break;
2597 		}
2598 		tee_rsa_key_pair = o->data;
2599 		res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2600 		if (res != TEE_SUCCESS)
2601 			return res;
2602 		tee_populate_rsa_key_pair(
2603 			&key_type.ltc_rsa_key, tee_rsa_key_pair, crt_exist);
2604 
2605 		tee_svc_asymm_pkcs1_get_salt_len(params, num_params, &salt_len);
2606 
2607 		res = tee_acipher_rsassa_sign(
2608 			cs->algo, &key_type.ltc_rsa_key, salt_len,
2609 			src_data, src_len, dst_data, &dlen);
2610 		break;
2611 
2612 	case TEE_ALG_DSA_SHA1:
2613 		tee_dsa_key = o->data;
2614 		tee_populate_dsa_key_pair(&key_type.ltc_dsa_key, tee_dsa_key);
2615 		res = tee_acipher_dsa_sign(
2616 			cs->algo, &key_type.ltc_dsa_key,
2617 			src_data, src_len, dst_data, &dlen);
2618 		break;
2619 
2620 	default:
2621 		res = TEE_ERROR_BAD_PARAMETERS;
2622 		break;
2623 	}
2624 
2625 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2626 		TEE_Result res2;
2627 
2628 		res2 =
2629 		    tee_svc_copy_to_user(sess, dst_len, &dlen, sizeof(size_t));
2630 		if (res2 != TEE_SUCCESS)
2631 			return res2;
2632 	}
2633 
2634 	return res;
2635 }
2636 
2637 TEE_Result tee_svc_asymm_verify(uint32_t state, const TEE_Attribute *params,
2638 				uint32_t num_params, const void *data,
2639 				size_t data_len, const void *sig,
2640 				size_t sig_len)
2641 {
2642 	TEE_Result res;
2643 	struct tee_cryp_state *cs;
2644 	struct tee_ta_session *sess;
2645 	struct tee_obj *o;
2646 	size_t hash_size;
2647 	struct tee_ltc_rsa_public_key *tee_rsa_key;
2648 	int salt_len;
2649 	struct tee_ltc_dsa_public_key *tee_dsa_key;
2650 	union {
2651 		rsa_key ltc_rsa_key;
2652 		dsa_key ltc_dsa_key;
2653 	} key_type;
2654 
2655 	res = tee_ta_get_current_session(&sess);
2656 	if (res != TEE_SUCCESS)
2657 		return res;
2658 
2659 	res = tee_svc_cryp_get_state(sess, state, &cs);
2660 	if (res != TEE_SUCCESS)
2661 		return res;
2662 
2663 	if (cs->mode != TEE_MODE_VERIFY)
2664 		return TEE_ERROR_BAD_PARAMETERS;
2665 
2666 	res = tee_mmu_check_access_rights(sess->ctx,
2667 					  TEE_MEMORY_ACCESS_READ |
2668 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2669 					  (tee_uaddr_t)data, data_len);
2670 	if (res != TEE_SUCCESS)
2671 		return res;
2672 
2673 	res = tee_mmu_check_access_rights(sess->ctx,
2674 					  TEE_MEMORY_ACCESS_READ |
2675 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2676 					  (tee_uaddr_t)sig, sig_len);
2677 	if (res != TEE_SUCCESS)
2678 		return res;
2679 
2680 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2681 	if (res != TEE_SUCCESS)
2682 		return res;
2683 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2684 		return TEE_ERROR_BAD_PARAMETERS;
2685 
2686 	res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(cs->algo),
2687 				       &hash_size);
2688 	if (res != TEE_SUCCESS)
2689 		return res;
2690 
2691 	if (data_len != hash_size)
2692 		return TEE_ERROR_BAD_PARAMETERS;
2693 
2694 	switch (TEE_ALG_GET_MAIN_ALG(cs->algo)) {
2695 	case TEE_MAIN_ALGO_RSA:
2696 		tee_rsa_key = o->data;
2697 		tee_svc_asymm_pkcs1_get_salt_len(params, num_params, &salt_len);
2698 		tee_populate_rsa_public_key(&key_type.ltc_rsa_key, tee_rsa_key);
2699 		res = tee_acipher_rsassa_verify(
2700 			cs->algo, &key_type.ltc_rsa_key, salt_len,
2701 			data, data_len, sig, sig_len);
2702 		break;
2703 
2704 	case TEE_MAIN_ALGO_DSA:
2705 		tee_dsa_key = o->data;
2706 		tee_populate_dsa_public_key(&key_type.ltc_dsa_key, tee_dsa_key);
2707 		res = tee_acipher_dsa_verify(
2708 			cs->algo, &key_type.ltc_dsa_key,
2709 			data, data_len, sig, sig_len);
2710 		break;
2711 
2712 	default:
2713 		res = TEE_ERROR_NOT_SUPPORTED;
2714 	}
2715 
2716 	return res;
2717 }
2718