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