xref: /optee_os/core/tee/tee_svc_cryp.c (revision af0c87eccf97c3dc97cfb68f2dffb487343388bc)
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 	/* No data, but size provided isn't valid parameters. */
1787 	if (!chunk && chunk_size)
1788 		return TEE_ERROR_BAD_PARAMETERS;
1789 
1790 	/* Zero length hash is valid, but nothing we need to do. */
1791 	if (!chunk_size)
1792 		return TEE_SUCCESS;
1793 
1794 	res = tee_ta_get_current_session(&sess);
1795 	if (res != TEE_SUCCESS)
1796 		return res;
1797 
1798 	res = tee_mmu_check_access_rights(sess->ctx,
1799 					  TEE_MEMORY_ACCESS_READ |
1800 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1801 					  (tee_uaddr_t)chunk, chunk_size);
1802 	if (res != TEE_SUCCESS)
1803 		return res;
1804 
1805 	res = tee_svc_cryp_get_state(sess, state, &cs);
1806 	if (res != TEE_SUCCESS)
1807 		return res;
1808 
1809 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
1810 	case TEE_OPERATION_DIGEST:
1811 		res = tee_hash_update(cs->ctx, cs->algo, chunk, chunk_size);
1812 		if (res != TEE_SUCCESS)
1813 			return res;
1814 		break;
1815 	case TEE_OPERATION_MAC:
1816 		res = tee_mac_update(cs->ctx, cs->algo, chunk, chunk_size);
1817 		if (res != TEE_SUCCESS)
1818 			return res;
1819 		break;
1820 	default:
1821 		return TEE_ERROR_BAD_PARAMETERS;
1822 	}
1823 
1824 	return TEE_SUCCESS;
1825 }
1826 
1827 TEE_Result tee_svc_hash_final(uint32_t state, const void *chunk,
1828 			      size_t chunk_size, void *hash, size_t *hash_len)
1829 {
1830 	TEE_Result res, res2;
1831 	size_t hash_size;
1832 	size_t hlen;
1833 	struct tee_cryp_state *cs;
1834 	struct tee_ta_session *sess;
1835 
1836 	/* No data, but size provided isn't valid parameters. */
1837 	if (!chunk && chunk_size)
1838 		return TEE_ERROR_BAD_PARAMETERS;
1839 
1840 	res = tee_ta_get_current_session(&sess);
1841 	if (res != TEE_SUCCESS)
1842 		return res;
1843 
1844 	res = tee_mmu_check_access_rights(sess->ctx,
1845 					  TEE_MEMORY_ACCESS_READ |
1846 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1847 					  (tee_uaddr_t)chunk, chunk_size);
1848 	if (res != TEE_SUCCESS)
1849 		return res;
1850 
1851 	res = tee_svc_copy_from_user(sess, &hlen, hash_len, sizeof(size_t));
1852 	if (res != TEE_SUCCESS)
1853 		return res;
1854 
1855 	res = tee_mmu_check_access_rights(sess->ctx,
1856 					  TEE_MEMORY_ACCESS_READ |
1857 					  TEE_MEMORY_ACCESS_WRITE |
1858 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1859 					  (tee_uaddr_t)hash, hlen);
1860 	if (res != TEE_SUCCESS)
1861 		return res;
1862 
1863 	res = tee_svc_cryp_get_state(sess, state, &cs);
1864 	if (res != TEE_SUCCESS)
1865 		return res;
1866 
1867 	switch (TEE_ALG_GET_CLASS(cs->algo)) {
1868 	case TEE_OPERATION_DIGEST:
1869 		res = tee_hash_get_digest_size(cs->algo, &hash_size);
1870 		if (res != TEE_SUCCESS)
1871 			return res;
1872 		if (*hash_len < hash_size) {
1873 			res = TEE_ERROR_SHORT_BUFFER;
1874 			goto out;
1875 		}
1876 
1877 		if (chunk_size) {
1878 			res = tee_hash_update(cs->ctx, cs->algo, chunk,
1879 					      chunk_size);
1880 			if (res != TEE_SUCCESS)
1881 				return res;
1882 		}
1883 
1884 		res = tee_hash_final(cs->ctx, cs->algo, hash, hash_size);
1885 		if (res != TEE_SUCCESS)
1886 			return res;
1887 		break;
1888 
1889 	case TEE_OPERATION_MAC:
1890 		res = tee_mac_get_digest_size(cs->algo, &hash_size);
1891 		if (res != TEE_SUCCESS)
1892 			return res;
1893 		if (*hash_len < hash_size) {
1894 			res = TEE_ERROR_SHORT_BUFFER;
1895 			goto out;
1896 		}
1897 
1898 		res = tee_mac_final(cs->ctx, cs->algo, chunk, chunk_size, hash,
1899 				    hash_size);
1900 		if (res != TEE_SUCCESS)
1901 			return res;
1902 		break;
1903 
1904 	default:
1905 		return TEE_ERROR_BAD_PARAMETERS;
1906 	}
1907 out:
1908 	res2 =
1909 	    tee_svc_copy_to_user(sess, hash_len, &hash_size, sizeof(*hash_len));
1910 	if (res2 != TEE_SUCCESS)
1911 		return res2;
1912 	return res;
1913 }
1914 
1915 TEE_Result tee_svc_cipher_init(uint32_t state, const void *iv, size_t iv_len)
1916 {
1917 	TEE_Result res;
1918 	struct tee_cryp_state *cs;
1919 	struct tee_ta_session *sess;
1920 	struct tee_obj *o;
1921 	struct tee_cryp_obj_secret *key1;
1922 
1923 	res = tee_ta_get_current_session(&sess);
1924 	if (res != TEE_SUCCESS)
1925 		return res;
1926 
1927 	res = tee_svc_cryp_get_state(sess, state, &cs);
1928 	if (res != TEE_SUCCESS)
1929 		return res;
1930 
1931 	res = tee_mmu_check_access_rights(sess->ctx,
1932 					  TEE_MEMORY_ACCESS_READ |
1933 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1934 					  (tee_uaddr_t) iv, iv_len);
1935 	if (res != TEE_SUCCESS)
1936 		return res;
1937 
1938 	res = tee_obj_get(sess->ctx, cs->key1, &o);
1939 	if (res != TEE_SUCCESS)
1940 		return res;
1941 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1942 		return TEE_ERROR_BAD_PARAMETERS;
1943 
1944 	key1 = (struct tee_cryp_obj_secret *)o->data;
1945 
1946 	if (tee_obj_get(sess->ctx, cs->key2, &o) == TEE_SUCCESS) {
1947 		struct tee_cryp_obj_secret *key2 =
1948 		    (struct tee_cryp_obj_secret *)o->data;
1949 
1950 		if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1951 			return TEE_ERROR_BAD_PARAMETERS;
1952 
1953 		res = tee_cipher_init3(cs->ctx, cs->algo, cs->mode,
1954 				       (uint8_t *)(key1 + 1), key1->key_size,
1955 				       (uint8_t *)(key2 + 1), key2->key_size,
1956 				       iv, iv_len);
1957 	} else {
1958 		res = tee_cipher_init2(cs->ctx, cs->algo, cs->mode,
1959 			       (uint8_t *)(key1 + 1), key1->key_size,
1960 				       iv, iv_len);
1961 	}
1962 	if (res != TEE_SUCCESS)
1963 		return res;
1964 
1965 	cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t) tee_cipher_final;
1966 	return TEE_SUCCESS;
1967 }
1968 
1969 static TEE_Result tee_svc_cipher_update_helper(uint32_t state, bool last_block,
1970 					       const void *src, size_t src_len,
1971 					       void *dst, size_t *dst_len)
1972 {
1973 	TEE_Result res;
1974 	struct tee_cryp_state *cs;
1975 	struct tee_ta_session *sess;
1976 	size_t dlen;
1977 
1978 	res = tee_ta_get_current_session(&sess);
1979 	if (res != TEE_SUCCESS)
1980 		return res;
1981 
1982 	res = tee_svc_cryp_get_state(sess, state, &cs);
1983 	if (res != TEE_SUCCESS)
1984 		return res;
1985 
1986 	res = tee_mmu_check_access_rights(sess->ctx,
1987 					  TEE_MEMORY_ACCESS_READ |
1988 					  TEE_MEMORY_ACCESS_ANY_OWNER,
1989 					  (tee_uaddr_t)src, src_len);
1990 	if (res != TEE_SUCCESS)
1991 		return res;
1992 
1993 	if (dst_len == NULL) {
1994 		dlen = 0;
1995 	} else {
1996 		res =
1997 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
1998 					   sizeof(size_t));
1999 		if (res != TEE_SUCCESS)
2000 			return res;
2001 
2002 		res = tee_mmu_check_access_rights(sess->ctx,
2003 						  TEE_MEMORY_ACCESS_READ |
2004 						  TEE_MEMORY_ACCESS_WRITE |
2005 						  TEE_MEMORY_ACCESS_ANY_OWNER,
2006 						  (tee_uaddr_t)dst, dlen);
2007 		if (res != TEE_SUCCESS)
2008 			return res;
2009 	}
2010 
2011 	if (dlen < src_len) {
2012 		res = TEE_ERROR_SHORT_BUFFER;
2013 		goto out;
2014 	}
2015 
2016 	if (src_len > 0) {
2017 		/* Permit src_len == 0 to finalize the operation */
2018 		res = tee_cipher_update(cs->ctx, cs->algo, cs->mode, last_block,
2019 					src, src_len, dst);
2020 	}
2021 
2022 	if (last_block && cs->ctx_finalize != NULL) {
2023 		cs->ctx_finalize(cs->ctx, cs->mode);
2024 		cs->ctx_finalize = NULL;
2025 	}
2026 
2027 out:
2028 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
2029 	    dst_len != NULL) {
2030 		TEE_Result res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2031 						       sizeof(size_t));
2032 		if (res2 != TEE_SUCCESS)
2033 			res = res2;
2034 	}
2035 
2036 	return res;
2037 }
2038 
2039 TEE_Result tee_svc_cipher_update(uint32_t state, const void *src,
2040 				 size_t src_len, void *dst, size_t *dst_len)
2041 {
2042 	return tee_svc_cipher_update_helper(state, false /* last_block */,
2043 					    src, src_len, dst, dst_len);
2044 }
2045 
2046 TEE_Result tee_svc_cipher_final(uint32_t state, const void *src,
2047 				size_t src_len, void *dst, size_t *dst_len)
2048 {
2049 	return tee_svc_cipher_update_helper(state, true /* last_block */,
2050 					    src, src_len, dst, dst_len);
2051 }
2052 
2053 TEE_Result tee_svc_cryp_derive_key(uint32_t state, const TEE_Attribute *params,
2054 				   uint32_t param_count, uint32_t derived_key)
2055 {
2056 	TEE_Result res;
2057 	struct tee_ta_session *sess;
2058 	struct tee_obj *ko;
2059 	struct tee_obj *so;
2060 	struct tee_cryp_state *cs;
2061 	struct tee_cryp_obj_secret *sk;
2062 	const struct tee_cryp_obj_type_props *type_props;
2063 	struct ltc_bignumbers publicvalue;
2064 	struct ltc_bignumbers sharedsecret;
2065 	struct tee_ltc_dh_key_pair *tee_dh_key;
2066 	dh_key ltc_dh_key;
2067 
2068 	res = tee_ta_get_current_session(&sess);
2069 	if (res != TEE_SUCCESS)
2070 		return res;
2071 
2072 	res = tee_svc_cryp_get_state(sess, state, &cs);
2073 	if (res != TEE_SUCCESS)
2074 		return res;
2075 
2076 	if ((param_count != 1) ||
2077 	    (params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE))
2078 		return TEE_ERROR_BAD_PARAMETERS;
2079 
2080 	/* get key set in operation */
2081 	res = tee_obj_get(sess->ctx, cs->key1, &ko);
2082 	if (res != TEE_SUCCESS)
2083 		return res;
2084 
2085 	tee_dh_key = (struct tee_ltc_dh_key_pair *)ko->data;
2086 	tee_populate_dh_key_pair(&ltc_dh_key, tee_dh_key);
2087 
2088 	res = tee_obj_get(sess->ctx, derived_key, &so);
2089 	if (res != TEE_SUCCESS)
2090 		return res;
2091 
2092 	/* find information needed about the object to initialize */
2093 	sk = (struct tee_cryp_obj_secret *)so->data;
2094 
2095 	/* Find description of object */
2096 	type_props = tee_svc_find_type_props(so->info.objectType);
2097 	if (type_props == NULL)
2098 		return TEE_ERROR_NOT_SUPPORTED;
2099 
2100 	SET_MPA_ALLOCSIZE(&publicvalue);
2101 	SET_MPA_ALLOCSIZE(&sharedsecret);
2102 
2103 	/* extract information from the attributes passed to the function */
2104 	mp_read_unsigned_bin(
2105 		&publicvalue,
2106 		params[0].content.ref.buffer,
2107 		params[0].content.ref.length);
2108 	res = tee_derive_dh_shared_secret(
2109 		&ltc_dh_key, &publicvalue, &sharedsecret);
2110 
2111 	if (res == TEE_SUCCESS) {
2112 		sk->key_size = mp_unsigned_bin_size(&sharedsecret);
2113 		mp_to_unsigned_bin(&sharedsecret, (uint8_t *)(sk + 1));
2114 		so->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
2115 		SET_ATTRIBUTE(so, type_props, TEE_ATTR_SECRET_VALUE);
2116 	}
2117 	return res;
2118 }
2119 
2120 TEE_Result get_rng_array(void *buffer, int len)
2121 {
2122 	char *buf_char = buffer;
2123 	int i;
2124 
2125 
2126 	if (buf_char == NULL)
2127 		return TEE_ERROR_BAD_PARAMETERS;
2128 
2129 	for (i = 0; i < len; i++)
2130 		buf_char[i] = hw_get_random_byte();
2131 
2132 	return TEE_SUCCESS;
2133 }
2134 
2135 TEE_Result tee_svc_cryp_random_number_generate(void *buf, size_t blen)
2136 {
2137 	TEE_Result res;
2138 	struct tee_ta_session *sess;
2139 
2140 	res = tee_ta_get_current_session(&sess);
2141 	if (res != TEE_SUCCESS)
2142 		return res;
2143 
2144 	res = tee_mmu_check_access_rights(sess->ctx,
2145 					  TEE_MEMORY_ACCESS_WRITE |
2146 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2147 					  (tee_uaddr_t)buf, blen);
2148 	if (res != TEE_SUCCESS)
2149 		return res;
2150 
2151 	res = get_rng_array(buf, blen);
2152 	if (res != TEE_SUCCESS)
2153 		return res;
2154 
2155 	return res;
2156 }
2157 
2158 TEE_Result tee_svc_authenc_init(uint32_t state, const void *nonce,
2159 				size_t nonce_len, size_t tag_len,
2160 				size_t aad_len, size_t payload_len)
2161 {
2162 	TEE_Result res;
2163 	struct tee_cryp_state *cs;
2164 	struct tee_ta_session *sess;
2165 	struct tee_obj *o;
2166 	struct tee_cryp_obj_secret *key;
2167 
2168 	res = tee_ta_get_current_session(&sess);
2169 	if (res != TEE_SUCCESS)
2170 		return res;
2171 
2172 	res = tee_svc_cryp_get_state(sess, state, &cs);
2173 	if (res != TEE_SUCCESS)
2174 		return res;
2175 
2176 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2177 	if (res != TEE_SUCCESS)
2178 		return res;
2179 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2180 		return TEE_ERROR_BAD_PARAMETERS;
2181 
2182 	key = (struct tee_cryp_obj_secret *)o->data;
2183 	res = tee_authenc_init(cs->ctx, cs->algo, cs->mode,
2184 			       (uint8_t *)(key + 1), key->key_size,
2185 			       nonce, nonce_len, tag_len, aad_len, payload_len);
2186 	if (res != TEE_SUCCESS)
2187 		return res;
2188 
2189 	cs->ctx_finalize = (tee_cryp_ctx_finalize_func_t)tee_authenc_final;
2190 	return TEE_SUCCESS;
2191 }
2192 
2193 TEE_Result tee_svc_authenc_update_aad(uint32_t state, const void *aad_data,
2194 				      size_t aad_data_len)
2195 {
2196 	TEE_Result res;
2197 	struct tee_cryp_state *cs;
2198 	struct tee_ta_session *sess;
2199 
2200 	res = tee_ta_get_current_session(&sess);
2201 	if (res != TEE_SUCCESS)
2202 		return res;
2203 
2204 	res = tee_mmu_check_access_rights(sess->ctx,
2205 					  TEE_MEMORY_ACCESS_READ |
2206 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2207 					  (tee_uaddr_t) aad_data, aad_data_len);
2208 	if (res != TEE_SUCCESS)
2209 		return res;
2210 
2211 	res = tee_svc_cryp_get_state(sess, state, &cs);
2212 	if (res != TEE_SUCCESS)
2213 		return res;
2214 
2215 	res = tee_authenc_update_aad(cs->ctx, cs->algo, cs->mode, aad_data,
2216 				     aad_data_len);
2217 	if (res != TEE_SUCCESS)
2218 		return res;
2219 
2220 	return TEE_SUCCESS;
2221 }
2222 
2223 TEE_Result tee_svc_authenc_update_payload(uint32_t state, const void *src_data,
2224 					  size_t src_len, void *dst_data,
2225 					  size_t *dst_len)
2226 {
2227 	TEE_Result res;
2228 	struct tee_cryp_state *cs;
2229 	struct tee_ta_session *sess;
2230 	size_t dlen;
2231 
2232 	res = tee_ta_get_current_session(&sess);
2233 	if (res != TEE_SUCCESS)
2234 		return res;
2235 
2236 	res = tee_svc_cryp_get_state(sess, state, &cs);
2237 	if (res != TEE_SUCCESS)
2238 		return res;
2239 
2240 	res = tee_mmu_check_access_rights(sess->ctx,
2241 					  TEE_MEMORY_ACCESS_READ |
2242 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2243 					  (tee_uaddr_t) src_data, src_len);
2244 	if (res != TEE_SUCCESS)
2245 		return res;
2246 
2247 	res = tee_svc_copy_from_user(sess, &dlen, dst_len, sizeof(size_t));
2248 	if (res != TEE_SUCCESS)
2249 		return res;
2250 
2251 	res = tee_mmu_check_access_rights(sess->ctx,
2252 					  TEE_MEMORY_ACCESS_READ |
2253 					  TEE_MEMORY_ACCESS_WRITE |
2254 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2255 					  (tee_uaddr_t)dst_data, dlen);
2256 	if (res != TEE_SUCCESS)
2257 		return res;
2258 
2259 	if (dlen < src_len) {
2260 		res = TEE_ERROR_SHORT_BUFFER;
2261 		goto out;
2262 	}
2263 
2264 	res = tee_authenc_update_payload(cs->ctx, cs->algo, cs->mode, src_data,
2265 					 src_len, dst_data);
2266 
2267 out:
2268 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2269 		TEE_Result res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2270 						       sizeof(size_t));
2271 		if (res2 != TEE_SUCCESS)
2272 			res = res2;
2273 	}
2274 
2275 	return res;
2276 }
2277 
2278 TEE_Result tee_svc_authenc_enc_final(uint32_t state, const void *src_data,
2279 				     size_t src_len, void *dst_data,
2280 				     size_t *dst_len, void *tag,
2281 				     size_t *tag_len)
2282 {
2283 	TEE_Result res;
2284 	struct tee_cryp_state *cs;
2285 	struct tee_ta_session *sess;
2286 	size_t dlen;
2287 	size_t tlen;
2288 
2289 	res = tee_ta_get_current_session(&sess);
2290 	if (res != TEE_SUCCESS)
2291 		return res;
2292 
2293 	res = tee_svc_cryp_get_state(sess, state, &cs);
2294 	if (res != TEE_SUCCESS)
2295 		return res;
2296 
2297 	if (cs->mode != TEE_MODE_ENCRYPT)
2298 		return TEE_ERROR_BAD_PARAMETERS;
2299 
2300 	res = tee_mmu_check_access_rights(sess->ctx,
2301 					  TEE_MEMORY_ACCESS_READ |
2302 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2303 					  (tee_uaddr_t)src_data, src_len);
2304 	if (res != TEE_SUCCESS)
2305 		return res;
2306 
2307 	if (dst_len == NULL) {
2308 		dlen = 0;
2309 	} else {
2310 		res =
2311 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
2312 					   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)dst_data, dlen);
2321 		if (res != TEE_SUCCESS)
2322 			return res;
2323 	}
2324 
2325 	if (dlen < src_len) {
2326 		res = TEE_ERROR_SHORT_BUFFER;
2327 		goto out;
2328 	}
2329 
2330 	res = tee_svc_copy_from_user(sess, &tlen, tag_len, sizeof(size_t));
2331 	if (res != TEE_SUCCESS)
2332 		return res;
2333 
2334 	res = tee_mmu_check_access_rights(sess->ctx,
2335 					  TEE_MEMORY_ACCESS_READ |
2336 					  TEE_MEMORY_ACCESS_WRITE |
2337 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2338 					  (tee_uaddr_t)tag, tlen);
2339 	if (res != TEE_SUCCESS)
2340 		return res;
2341 
2342 	res = tee_authenc_enc_final(cs->ctx, cs->algo, src_data, src_len,
2343 				    dst_data, tag, &tlen);
2344 
2345 out:
2346 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2347 		TEE_Result res2;
2348 
2349 		if (dst_len != NULL) {
2350 			res2 = tee_svc_copy_to_user(sess, dst_len, &src_len,
2351 						    sizeof(size_t));
2352 			if (res2 != TEE_SUCCESS)
2353 				return res2;
2354 		}
2355 
2356 		res2 =
2357 		    tee_svc_copy_to_user(sess, tag_len, &tlen, sizeof(size_t));
2358 		if (res2 != TEE_SUCCESS)
2359 			return res2;
2360 	}
2361 
2362 	return res;
2363 }
2364 
2365 TEE_Result tee_svc_authenc_dec_final(uint32_t state, const void *src_data,
2366 				     size_t src_len, void *dst_data,
2367 				     size_t *dst_len, const void *tag,
2368 				     size_t tag_len)
2369 {
2370 	TEE_Result res;
2371 	struct tee_cryp_state *cs;
2372 	struct tee_ta_session *sess;
2373 	size_t dlen;
2374 
2375 	res = tee_ta_get_current_session(&sess);
2376 	if (res != TEE_SUCCESS)
2377 		return res;
2378 
2379 	res = tee_svc_cryp_get_state(sess, state, &cs);
2380 	if (res != TEE_SUCCESS)
2381 		return res;
2382 
2383 	if (cs->mode != TEE_MODE_DECRYPT)
2384 		return TEE_ERROR_BAD_PARAMETERS;
2385 
2386 	res = tee_mmu_check_access_rights(sess->ctx,
2387 					  TEE_MEMORY_ACCESS_READ |
2388 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2389 					  (tee_uaddr_t)src_data, src_len);
2390 	if (res != TEE_SUCCESS)
2391 		return res;
2392 
2393 	if (dst_len == NULL) {
2394 		dlen = 0;
2395 	} else {
2396 		res =
2397 		    tee_svc_copy_from_user(sess, &dlen, dst_len,
2398 					   sizeof(size_t));
2399 		if (res != TEE_SUCCESS)
2400 			return res;
2401 
2402 		res = tee_mmu_check_access_rights(sess->ctx,
2403 						  TEE_MEMORY_ACCESS_READ |
2404 						  TEE_MEMORY_ACCESS_WRITE |
2405 						  TEE_MEMORY_ACCESS_ANY_OWNER,
2406 						  (tee_uaddr_t)dst_data, dlen);
2407 		if (res != TEE_SUCCESS)
2408 			return res;
2409 	}
2410 
2411 	if (dlen < src_len) {
2412 		res = TEE_ERROR_SHORT_BUFFER;
2413 		goto out;
2414 	}
2415 
2416 	res = tee_mmu_check_access_rights(sess->ctx,
2417 					  TEE_MEMORY_ACCESS_READ |
2418 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2419 					  (tee_uaddr_t)tag, tag_len);
2420 	if (res != TEE_SUCCESS)
2421 		return res;
2422 
2423 	res = tee_authenc_dec_final(cs->ctx, cs->algo, src_data, src_len,
2424 				    dst_data, tag, tag_len);
2425 
2426 out:
2427 	if ((res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) &&
2428 	    dst_len != NULL) {
2429 		TEE_Result res2;
2430 
2431 		res2 =
2432 		    tee_svc_copy_to_user(sess, dst_len, &src_len,
2433 					 sizeof(size_t));
2434 		if (res2 != TEE_SUCCESS)
2435 			return res2;
2436 	}
2437 
2438 	return res;
2439 }
2440 
2441 static void tee_svc_asymm_pkcs1_get_salt_len(const TEE_Attribute *params,
2442 					     uint32_t num_params, int *salt_len)
2443 {
2444 	size_t n;
2445 
2446 	for (n = 0; n < num_params; n++) {
2447 		if (params[n].attributeID == TEE_ATTR_RSA_PSS_SALT_LENGTH) {
2448 			*salt_len = params[n].content.value.a;
2449 			return;
2450 		}
2451 	}
2452 	*salt_len = -1;
2453 }
2454 
2455 static TEE_Result tee_svc_asymm_rsa_check_crt_exist(struct tee_obj *o,
2456 						    bool *crt_exist)
2457 {
2458 	const struct tee_cryp_obj_type_props *type_props;
2459 	int i;
2460 
2461 	type_props = tee_svc_find_type_props(o->info.objectType);
2462 	if (type_props == NULL)
2463 		return TEE_ERROR_BAD_PARAMETERS;
2464 
2465 	/*
2466 	 * if one crt attribute exits all must exists and this is
2467 	 * checked when populating it
2468 	 */
2469 	i = tee_svc_cryp_obj_find_type_attr_idx(TEE_ATTR_RSA_PRIME1,
2470 		type_props);
2471 
2472 	if ((o->have_attrs & (1 << i)) != 0)
2473 		*crt_exist = true;
2474 	else
2475 		*crt_exist = false;
2476 
2477 	return TEE_SUCCESS;
2478 }
2479 
2480 TEE_Result tee_svc_asymm_operate(uint32_t state, const TEE_Attribute *params,
2481 				 uint32_t num_params, const void *src_data,
2482 				 size_t src_len, void *dst_data,
2483 				 size_t *dst_len)
2484 {
2485 	TEE_Result res;
2486 	struct tee_cryp_state *cs;
2487 	struct tee_ta_session *sess;
2488 	size_t dlen;
2489 	struct tee_obj *o;
2490 	struct tee_ltc_rsa_public_key *tee_rsa_public_key;
2491 	struct tee_ltc_rsa_key_pair *tee_rsa_key_pair;
2492 	struct tee_ltc_dsa_key_pair *tee_dsa_key;
2493 	union {
2494 		rsa_key ltc_rsa_key;
2495 		dsa_key ltc_dsa_key;
2496 	} key_type;
2497 	void *label = NULL;
2498 	size_t label_len = 0;
2499 	size_t n;
2500 	bool crt_exist;
2501 	int salt_len;
2502 
2503 	res = tee_ta_get_current_session(&sess);
2504 	if (res != TEE_SUCCESS)
2505 		return res;
2506 
2507 	res = tee_svc_cryp_get_state(sess, state, &cs);
2508 	if (res != TEE_SUCCESS)
2509 		return res;
2510 
2511 	res = tee_mmu_check_access_rights(
2512 		sess->ctx,
2513 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_ANY_OWNER,
2514 		(tee_uaddr_t) src_data, src_len);
2515 	if (res != TEE_SUCCESS)
2516 		return res;
2517 
2518 	res = tee_svc_copy_from_user(sess, &dlen, dst_len, sizeof(size_t));
2519 	if (res != TEE_SUCCESS)
2520 		return res;
2521 
2522 	res = tee_mmu_check_access_rights(
2523 		sess->ctx,
2524 		TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE |
2525 			TEE_MEMORY_ACCESS_ANY_OWNER,
2526 		(tee_uaddr_t) dst_data, dlen);
2527 	if (res != TEE_SUCCESS)
2528 		return res;
2529 
2530 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2531 	if (res != TEE_SUCCESS)
2532 		return res;
2533 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2534 		return TEE_ERROR_GENERIC;
2535 
2536 	switch (cs->algo) {
2537 	case TEE_ALG_RSA_NOPAD:
2538 		if (cs->mode == TEE_MODE_ENCRYPT) {
2539 			tee_rsa_public_key = o->data;
2540 			tee_populate_rsa_public_key(
2541 				&key_type.ltc_rsa_key, tee_rsa_public_key);
2542 		} else if (cs->mode == TEE_MODE_DECRYPT) {
2543 			tee_rsa_key_pair = o->data;
2544 			res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2545 			if (res != TEE_SUCCESS)
2546 				return res;
2547 			tee_populate_rsa_key_pair(
2548 				&key_type.ltc_rsa_key, tee_rsa_key_pair,
2549 				crt_exist);
2550 
2551 		} else {
2552 			/*
2553 			 * We will panic because "the mode is not compatible
2554 			 * with the function"
2555 			 */
2556 			return TEE_ERROR_GENERIC;
2557 		}
2558 
2559 		res = tee_acipher_rsadorep(
2560 			&key_type.ltc_rsa_key,
2561 			src_data, src_len, dst_data, &dlen);
2562 		break;
2563 
2564 	case TEE_ALG_RSAES_PKCS1_V1_5:
2565 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
2566 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
2567 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
2568 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
2569 	case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
2570 		for (n = 0; n < num_params; n++) {
2571 			if (params[n].attributeID == TEE_ATTR_RSA_OAEP_LABEL) {
2572 				label = params[n].content.ref.buffer;
2573 				label_len = params[n].content.ref.length;
2574 				break;
2575 			}
2576 		}
2577 
2578 		if (cs->mode == TEE_MODE_ENCRYPT) {
2579 			tee_rsa_public_key = o->data;
2580 			tee_populate_rsa_public_key(
2581 				&key_type.ltc_rsa_key, tee_rsa_public_key);
2582 			res = tee_acipher_rsaes_encrypt(
2583 				cs->algo, &key_type.ltc_rsa_key,
2584 				label, label_len,
2585 				src_data, src_len, dst_data, &dlen);
2586 		} else if (cs->mode == TEE_MODE_DECRYPT) {
2587 			tee_rsa_key_pair = o->data;
2588 			res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2589 			if (res != TEE_SUCCESS)
2590 				return res;
2591 
2592 			tee_populate_rsa_key_pair(
2593 				&key_type.ltc_rsa_key,
2594 				tee_rsa_key_pair, crt_exist);
2595 			res = tee_acipher_rsaes_decrypt(
2596 				cs->algo, &key_type.ltc_rsa_key,
2597 				label, label_len,
2598 				src_data, src_len, dst_data, &dlen);
2599 		} else {
2600 			res = TEE_ERROR_BAD_PARAMETERS;
2601 		}
2602 		break;
2603 
2604 	case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
2605 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
2606 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
2607 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
2608 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
2609 	case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
2610 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
2611 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
2612 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
2613 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
2614 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
2615 		if (cs->mode != TEE_MODE_SIGN) {
2616 			res = TEE_ERROR_BAD_PARAMETERS;
2617 			break;
2618 		}
2619 		tee_rsa_key_pair = o->data;
2620 		res = tee_svc_asymm_rsa_check_crt_exist(o, &crt_exist);
2621 		if (res != TEE_SUCCESS)
2622 			return res;
2623 		tee_populate_rsa_key_pair(
2624 			&key_type.ltc_rsa_key, tee_rsa_key_pair, crt_exist);
2625 
2626 		tee_svc_asymm_pkcs1_get_salt_len(params, num_params, &salt_len);
2627 
2628 		res = tee_acipher_rsassa_sign(
2629 			cs->algo, &key_type.ltc_rsa_key, salt_len,
2630 			src_data, src_len, dst_data, &dlen);
2631 		break;
2632 
2633 	case TEE_ALG_DSA_SHA1:
2634 		tee_dsa_key = o->data;
2635 		tee_populate_dsa_key_pair(&key_type.ltc_dsa_key, tee_dsa_key);
2636 		res = tee_acipher_dsa_sign(
2637 			cs->algo, &key_type.ltc_dsa_key,
2638 			src_data, src_len, dst_data, &dlen);
2639 		break;
2640 
2641 	default:
2642 		res = TEE_ERROR_BAD_PARAMETERS;
2643 		break;
2644 	}
2645 
2646 	if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
2647 		TEE_Result res2;
2648 
2649 		res2 =
2650 		    tee_svc_copy_to_user(sess, dst_len, &dlen, sizeof(size_t));
2651 		if (res2 != TEE_SUCCESS)
2652 			return res2;
2653 	}
2654 
2655 	return res;
2656 }
2657 
2658 TEE_Result tee_svc_asymm_verify(uint32_t state, const TEE_Attribute *params,
2659 				uint32_t num_params, const void *data,
2660 				size_t data_len, const void *sig,
2661 				size_t sig_len)
2662 {
2663 	TEE_Result res;
2664 	struct tee_cryp_state *cs;
2665 	struct tee_ta_session *sess;
2666 	struct tee_obj *o;
2667 	size_t hash_size;
2668 	struct tee_ltc_rsa_public_key *tee_rsa_key;
2669 	int salt_len;
2670 	struct tee_ltc_dsa_public_key *tee_dsa_key;
2671 	union {
2672 		rsa_key ltc_rsa_key;
2673 		dsa_key ltc_dsa_key;
2674 	} key_type;
2675 
2676 	res = tee_ta_get_current_session(&sess);
2677 	if (res != TEE_SUCCESS)
2678 		return res;
2679 
2680 	res = tee_svc_cryp_get_state(sess, state, &cs);
2681 	if (res != TEE_SUCCESS)
2682 		return res;
2683 
2684 	if (cs->mode != TEE_MODE_VERIFY)
2685 		return TEE_ERROR_BAD_PARAMETERS;
2686 
2687 	res = tee_mmu_check_access_rights(sess->ctx,
2688 					  TEE_MEMORY_ACCESS_READ |
2689 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2690 					  (tee_uaddr_t)data, data_len);
2691 	if (res != TEE_SUCCESS)
2692 		return res;
2693 
2694 	res = tee_mmu_check_access_rights(sess->ctx,
2695 					  TEE_MEMORY_ACCESS_READ |
2696 					  TEE_MEMORY_ACCESS_ANY_OWNER,
2697 					  (tee_uaddr_t)sig, sig_len);
2698 	if (res != TEE_SUCCESS)
2699 		return res;
2700 
2701 	res = tee_obj_get(sess->ctx, cs->key1, &o);
2702 	if (res != TEE_SUCCESS)
2703 		return res;
2704 	if ((o->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) == 0)
2705 		return TEE_ERROR_BAD_PARAMETERS;
2706 
2707 	res = tee_hash_get_digest_size(TEE_DIGEST_HASH_TO_ALGO(cs->algo),
2708 				       &hash_size);
2709 	if (res != TEE_SUCCESS)
2710 		return res;
2711 
2712 	if (data_len != hash_size)
2713 		return TEE_ERROR_BAD_PARAMETERS;
2714 
2715 	switch (TEE_ALG_GET_MAIN_ALG(cs->algo)) {
2716 	case TEE_MAIN_ALGO_RSA:
2717 		tee_rsa_key = o->data;
2718 		tee_svc_asymm_pkcs1_get_salt_len(params, num_params, &salt_len);
2719 		tee_populate_rsa_public_key(&key_type.ltc_rsa_key, tee_rsa_key);
2720 		res = tee_acipher_rsassa_verify(
2721 			cs->algo, &key_type.ltc_rsa_key, salt_len,
2722 			data, data_len, sig, sig_len);
2723 		break;
2724 
2725 	case TEE_MAIN_ALGO_DSA:
2726 		tee_dsa_key = o->data;
2727 		tee_populate_dsa_public_key(&key_type.ltc_dsa_key, tee_dsa_key);
2728 		res = tee_acipher_dsa_verify(
2729 			cs->algo, &key_type.ltc_dsa_key,
2730 			data, data_len, sig, sig_len);
2731 		break;
2732 
2733 	default:
2734 		res = TEE_ERROR_NOT_SUPPORTED;
2735 	}
2736 
2737 	return res;
2738 }
2739