1 // SPDX-License-Identifier: BSD-2-Clause
2 /* Copyright (c) 2018, Linaro Limited */
3 
4 #include <arith_taf.h>
5 #include <inttypes.h>
6 #include <ta_crypt.h>
7 #include <tee_internal_api.h>
8 #include <util.h>
9 
10 #include "handle.h"
11 
12 #define HT_BIGINT	BIT(31)
13 #define HT_FMMCTX	BIT(30)
14 #define HT_FMMVAR	BIT(29)
15 #define HT_MASK		(HT_BIGINT | HT_FMMCTX | HT_FMMVAR)
16 
17 #define CHECK_PT(t0, t1, t2, t3) do { \
18 		const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_##t0, \
19 							TEE_PARAM_TYPE_##t1, \
20 							TEE_PARAM_TYPE_##t2, \
21 							TEE_PARAM_TYPE_##t3); \
22 		\
23 		if ((param_types) != exp_pt) { \
24 			EMSG("Unpexteded param_types 0x%" PRIx32 ", exptected 0x%" PRIx32, (param_types), exp_pt); \
25 			return TEE_ERROR_BAD_PARAMETERS; \
26 		} \
27 	} while (0)
28 
29 static struct handle_db hdb = HANDLE_DB_INITIALIZER;
30 
lookup_handle(uint32_t type,uint32_t handle)31 static void *lookup_handle(uint32_t type, uint32_t handle)
32 {
33 	void *ptr = NULL;
34 
35 	if ((handle & HT_MASK) == type)
36 		ptr = handle_lookup(&hdb, handle & ~HT_MASK);
37 
38 	if (!ptr)
39 		EMSG("Invalid handle 0x%" PRIx32, handle);
40 
41 	return ptr;
42 }
43 
get_handle(uint32_t type,void * ptr,uint32_t * handle)44 static bool get_handle(uint32_t type, void *ptr, uint32_t *handle)
45 {
46 	switch (type) {
47 	case HT_BIGINT:
48 	case HT_FMMCTX:
49 	case HT_FMMVAR:
50 		break;
51 	default:
52 		EMSG("Invalid type 0x%" PRIx32, type);
53 		return false;
54 	}
55 
56 	int h = handle_get(&hdb, ptr);
57 
58 	if (h < 0) {
59 		EMSG("Failed to allocate handle");
60 		return false;
61 	}
62 
63 	*handle = (uint32_t)h | type;
64 	return true;
65 }
66 
put_handle(uint32_t handle)67 static void *put_handle(uint32_t handle)
68 {
69 	void *ptr = handle_put(&hdb, handle & ~HT_MASK);
70 
71 	if (!ptr)
72 		EMSG("Invalid handle 0x%" PRIx32, handle);
73 
74 	return ptr;
75 }
76 
ta_entry_arith_new_var(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])77 TEE_Result ta_entry_arith_new_var(uint32_t param_types,
78 				  TEE_Param params[TEE_NUM_PARAMS])
79 {
80 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
81 
82 	size_t len = TEE_BigIntSizeInU32(params[0].value.a);
83 	TEE_BigInt *big_int = TEE_Malloc(len * sizeof(TEE_BigInt), 0);
84 
85 	if (!big_int)
86 		return TEE_ERROR_OUT_OF_MEMORY;
87 
88 	if (!get_handle(HT_BIGINT, big_int, &params[1].value.a)) {
89 		TEE_Free(big_int);
90 		return TEE_ERROR_OUT_OF_MEMORY;
91 	}
92 
93 	TEE_BigIntInit(big_int, len);
94 
95 	return TEE_SUCCESS;
96 }
97 
ta_entry_arith_new_fmm_ctx(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])98 TEE_Result ta_entry_arith_new_fmm_ctx(uint32_t param_types,
99 				      TEE_Param params[TEE_NUM_PARAMS])
100 {
101 	TEE_BigInt *modulus = NULL;
102 	uint32_t len = 0;
103 	TEE_BigIntFMMContext *ctx = NULL;
104 
105 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
106 
107 	modulus = lookup_handle(HT_BIGINT, params[0].value.b);
108 	if (!modulus)
109 		return TEE_ERROR_BAD_PARAMETERS;
110 
111 	len = TEE_BigIntFMMContextSizeInU32(params[0].value.a);
112 	ctx = TEE_Malloc(len * sizeof(*ctx), 0);
113 
114 	if (!get_handle(HT_FMMCTX, ctx, &params[1].value.a)) {
115 		TEE_Free(ctx);
116 		return TEE_ERROR_OUT_OF_MEMORY;
117 	}
118 
119 	TEE_BigIntInitFMMContext(ctx, len, modulus);
120 
121 	return TEE_SUCCESS;
122 }
123 
ta_entry_arith_new_fmm_var(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])124 TEE_Result ta_entry_arith_new_fmm_var(uint32_t param_types,
125 				      TEE_Param params[TEE_NUM_PARAMS])
126 {
127 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
128 
129 	size_t len = TEE_BigIntFMMSizeInU32(params[0].value.a);
130 	TEE_BigIntFMM *fmm = TEE_Malloc(len * sizeof(*fmm), 0);
131 
132 	if (!fmm)
133 		return TEE_ERROR_OUT_OF_MEMORY;
134 
135 	if (!get_handle(HT_FMMVAR, fmm, &params[1].value.a)) {
136 		TEE_Free(fmm);
137 		return TEE_ERROR_OUT_OF_MEMORY;
138 	}
139 
140 	TEE_BigIntInitFMM(fmm, len);
141 
142 	return TEE_SUCCESS;
143 }
144 
ta_entry_arith_free_handle(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])145 TEE_Result ta_entry_arith_free_handle(uint32_t param_types,
146 				      TEE_Param params[TEE_NUM_PARAMS])
147 {
148 	CHECK_PT(VALUE_INPUT, NONE, NONE, NONE);
149 
150 	void *ptr = put_handle(params[0].value.a & ~HT_MASK);
151 
152 	if (!ptr)
153 		return TEE_ERROR_BAD_PARAMETERS;
154 
155 	TEE_Free(ptr);
156 
157 	return TEE_SUCCESS;
158 }
159 
ta_entry_arith_from_octet_string(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])160 TEE_Result ta_entry_arith_from_octet_string(uint32_t param_types,
161 					    TEE_Param params[TEE_NUM_PARAMS])
162 {
163 	CHECK_PT(VALUE_INPUT, MEMREF_INPUT, NONE, NONE);
164 
165 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
166 
167 	if (!big_int)
168 		return TEE_ERROR_BAD_PARAMETERS;
169 
170 	return TEE_BigIntConvertFromOctetString(big_int,
171 						params[1].memref.buffer,
172 						params[1].memref.size,
173 						params[0].value.b);
174 }
175 
ta_entry_arith_from_s32(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])176 TEE_Result ta_entry_arith_from_s32(uint32_t param_types,
177 				   TEE_Param params[TEE_NUM_PARAMS])
178 {
179 	CHECK_PT(VALUE_INPUT, NONE, NONE, NONE);
180 
181 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
182 
183 	if (!big_int)
184 		return TEE_ERROR_BAD_PARAMETERS;
185 
186 	TEE_BigIntConvertFromS32(big_int, params[0].value.b);
187 
188 	return TEE_SUCCESS;
189 }
190 
ta_entry_arith_get_value(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])191 TEE_Result ta_entry_arith_get_value(uint32_t param_types,
192 				    TEE_Param params[TEE_NUM_PARAMS])
193 {
194 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, MEMREF_OUTPUT, NONE);
195 
196 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
197 
198 	if (!big_int)
199 		return TEE_ERROR_BAD_PARAMETERS;
200 
201 	if (TEE_BigIntCmpS32(big_int, 0) < 0)
202 		params[1].value.a = -1;
203 	else
204 		params[1].value.a = 1;
205 
206 	return TEE_BigIntConvertToOctetString(params[2].memref.buffer,
207 					      &params[2].memref.size, big_int);
208 }
209 
ta_entry_arith_get_value_s32(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])210 TEE_Result ta_entry_arith_get_value_s32(uint32_t param_types,
211 					TEE_Param params[TEE_NUM_PARAMS])
212 {
213 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
214 
215 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
216 
217 	if (!big_int)
218 		return TEE_ERROR_BAD_PARAMETERS;
219 
220 	int32_t v = 0;
221 	TEE_Result res = TEE_BigIntConvertToS32(&v, big_int);
222 
223 	if (!res)
224 		params[1].value.a = v;
225 
226 	return res;
227 }
228 
ta_entry_arith_get_bit(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])229 TEE_Result ta_entry_arith_get_bit(uint32_t param_types,
230 				  TEE_Param params[TEE_NUM_PARAMS])
231 {
232 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
233 
234 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
235 
236 	if (!big_int)
237 		return TEE_ERROR_BAD_PARAMETERS;
238 
239 	params[1].value.a = TEE_BigIntGetBit(big_int, params[0].value.b);
240 
241 	return TEE_SUCCESS;
242 }
243 
ta_entry_arith_get_bit_count(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])244 TEE_Result ta_entry_arith_get_bit_count(uint32_t param_types,
245 					TEE_Param params[TEE_NUM_PARAMS])
246 {
247 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
248 
249 	TEE_BigInt *big_int = lookup_handle(HT_BIGINT, params[0].value.a);
250 
251 	if (!big_int)
252 		return TEE_ERROR_BAD_PARAMETERS;
253 
254 	params[1].value.a = TEE_BigIntGetBitCount(big_int);
255 
256 	return TEE_SUCCESS;
257 }
258 
ta_entry_arith_shift_right(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])259 TEE_Result ta_entry_arith_shift_right(uint32_t param_types,
260 				      TEE_Param params[TEE_NUM_PARAMS])
261 {
262 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
263 
264 	TEE_BigInt *op = lookup_handle(HT_BIGINT, params[0].value.a);
265 	TEE_BigInt *dest = lookup_handle(HT_BIGINT, params[1].value.a);
266 
267 	if (!op || !dest)
268 		return TEE_ERROR_BAD_PARAMETERS;
269 
270 	TEE_BigIntShiftRight(dest, op, params[0].value.b);
271 
272 	return TEE_SUCCESS;
273 }
274 
ta_entry_arith_cmp(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])275 TEE_Result ta_entry_arith_cmp(uint32_t param_types,
276 			      TEE_Param params[TEE_NUM_PARAMS])
277 {
278 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
279 
280 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
281 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
282 
283 	if (!op1 || !op2)
284 		return TEE_ERROR_BAD_PARAMETERS;
285 
286 	params[1].value.a = TEE_BigIntCmp(op1, op2);
287 
288 	return TEE_SUCCESS;
289 }
290 
ta_entry_arith_cmp_s32(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])291 TEE_Result ta_entry_arith_cmp_s32(uint32_t param_types,
292 				  TEE_Param params[TEE_NUM_PARAMS])
293 {
294 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
295 
296 	TEE_BigInt *op = lookup_handle(HT_BIGINT, params[0].value.a);
297 
298 	if (!op)
299 		return TEE_ERROR_BAD_PARAMETERS;
300 
301 	params[1].value.a = TEE_BigIntCmpS32(op, params[0].value.b);
302 
303 	return TEE_SUCCESS;
304 }
305 
ternary_func(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS],void (* func)(TEE_BigInt * dest,const TEE_BigInt * op1,const TEE_BigInt * op2,const TEE_BigInt * n))306 static TEE_Result ternary_func(uint32_t param_types,
307 			       TEE_Param params[TEE_NUM_PARAMS],
308 			       void (*func)(TEE_BigInt *dest,
309 					    const TEE_BigInt *op1,
310 					    const TEE_BigInt *op2,
311 					    const TEE_BigInt *n))
312 {
313 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
314 
315 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
316 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
317 	TEE_BigInt *n = lookup_handle(HT_BIGINT, params[1].value.a);
318 	TEE_BigInt *dest = lookup_handle(HT_BIGINT, params[1].value.b);
319 
320 	if (!op1 || !op2 || !n || !dest)
321 		return TEE_ERROR_BAD_PARAMETERS;
322 
323 	func(dest, op1, op2, n);
324 
325 	return TEE_SUCCESS;
326 }
327 
binary_func(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS],void (* func)(TEE_BigInt * dest,const TEE_BigInt * op1,const TEE_BigInt * op2))328 static TEE_Result binary_func(uint32_t param_types,
329 			      TEE_Param params[TEE_NUM_PARAMS],
330 			      void (*func)(TEE_BigInt *dest,
331 					   const TEE_BigInt *op1,
332 					   const TEE_BigInt *op2))
333 {
334 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
335 
336 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
337 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
338 	TEE_BigInt *dest = lookup_handle(HT_BIGINT, params[1].value.a);
339 
340 	if (!op1 || !op2 || !dest)
341 		return TEE_ERROR_BAD_PARAMETERS;
342 
343 	func(dest, op1, op2);
344 
345 	return TEE_SUCCESS;
346 }
347 
unary_func(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS],void (* func)(TEE_BigInt * dest,const TEE_BigInt * op))348 static TEE_Result unary_func(uint32_t param_types,
349 			     TEE_Param params[TEE_NUM_PARAMS],
350 			     void (*func)(TEE_BigInt *dest,
351 					  const TEE_BigInt *op))
352 {
353 	CHECK_PT(VALUE_INPUT, NONE, NONE, NONE);
354 
355 	TEE_BigInt *op = lookup_handle(HT_BIGINT, params[0].value.a);
356 	TEE_BigInt *dest = lookup_handle(HT_BIGINT, params[0].value.b);
357 
358 	if (!op || !dest)
359 		return TEE_ERROR_BAD_PARAMETERS;
360 
361 	func(dest, op);
362 
363 	return TEE_SUCCESS;
364 }
365 
ta_entry_arith_add(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])366 TEE_Result ta_entry_arith_add(uint32_t param_types,
367 			      TEE_Param params[TEE_NUM_PARAMS])
368 {
369 	return binary_func(param_types, params,  TEE_BigIntAdd);
370 }
371 
ta_entry_arith_sub(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])372 TEE_Result ta_entry_arith_sub(uint32_t param_types,
373 			      TEE_Param params[TEE_NUM_PARAMS])
374 {
375 	return binary_func(param_types, params,  TEE_BigIntSub);
376 }
377 
ta_entry_arith_mul(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])378 TEE_Result ta_entry_arith_mul(uint32_t param_types,
379 			      TEE_Param params[TEE_NUM_PARAMS])
380 {
381 	return binary_func(param_types, params,  TEE_BigIntMul);
382 }
383 
ta_entry_arith_neg(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])384 TEE_Result ta_entry_arith_neg(uint32_t param_types,
385 			      TEE_Param params[TEE_NUM_PARAMS])
386 {
387 	return unary_func(param_types, params, TEE_BigIntNeg);
388 }
389 
ta_entry_arith_sqr(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])390 TEE_Result ta_entry_arith_sqr(uint32_t param_types,
391 			      TEE_Param params[TEE_NUM_PARAMS])
392 {
393 	return unary_func(param_types, params, TEE_BigIntSquare);
394 }
395 
ta_entry_arith_div(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])396 TEE_Result ta_entry_arith_div(uint32_t param_types,
397 			      TEE_Param params[TEE_NUM_PARAMS])
398 {
399 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
400 
401 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
402 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
403 	TEE_BigInt *dest_q = lookup_handle(HT_BIGINT, params[1].value.a);
404 	TEE_BigInt *dest_r = lookup_handle(HT_BIGINT, params[1].value.b);
405 
406 	if (!op1 || !op2 || !dest_q || !dest_r)
407 		return TEE_ERROR_BAD_PARAMETERS;
408 
409 	TEE_BigIntDiv(dest_q, dest_r, op1, op2);
410 
411 	return TEE_SUCCESS;
412 }
413 
ta_entry_arith_mod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])414 TEE_Result ta_entry_arith_mod(uint32_t param_types,
415 			      TEE_Param params[TEE_NUM_PARAMS])
416 {
417 	return binary_func(param_types, params, TEE_BigIntMod);
418 }
419 
ta_entry_arith_addmod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])420 TEE_Result ta_entry_arith_addmod(uint32_t param_types,
421 				 TEE_Param params[TEE_NUM_PARAMS])
422 {
423 	return ternary_func(param_types, params, TEE_BigIntAddMod);
424 }
425 
ta_entry_arith_submod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])426 TEE_Result ta_entry_arith_submod(uint32_t param_types,
427 				 TEE_Param params[TEE_NUM_PARAMS])
428 {
429 	return ternary_func(param_types, params, TEE_BigIntSubMod);
430 }
431 
ta_entry_arith_mulmod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])432 TEE_Result ta_entry_arith_mulmod(uint32_t param_types,
433 				 TEE_Param params[TEE_NUM_PARAMS])
434 {
435 	return ternary_func(param_types, params, TEE_BigIntMulMod);
436 }
437 
ta_entry_arith_sqrmod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])438 TEE_Result ta_entry_arith_sqrmod(uint32_t param_types,
439 				 TEE_Param params[TEE_NUM_PARAMS])
440 {
441 	return binary_func(param_types, params, TEE_BigIntSquareMod);
442 }
443 
ta_entry_arith_invmod(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])444 TEE_Result ta_entry_arith_invmod(uint32_t param_types,
445 				 TEE_Param params[TEE_NUM_PARAMS])
446 {
447 	return binary_func(param_types, params, TEE_BigIntInvMod);
448 }
449 
ta_entry_arith_is_rel_prime(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])450 TEE_Result ta_entry_arith_is_rel_prime(uint32_t param_types,
451 				       TEE_Param params[TEE_NUM_PARAMS])
452 {
453 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
454 
455 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
456 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
457 
458 	if (!op1 || !op2)
459 		return TEE_ERROR_BAD_PARAMETERS;
460 
461 	params[1].value.a = TEE_BigIntRelativePrime(op1, op2);
462 
463 	return TEE_SUCCESS;
464 }
465 
ta_entry_arith_compute_egcd(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])466 TEE_Result ta_entry_arith_compute_egcd(uint32_t param_types,
467 				       TEE_Param params[TEE_NUM_PARAMS])
468 {
469 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, VALUE_INPUT, NONE);
470 
471 	TEE_BigInt *op1 = lookup_handle(HT_BIGINT, params[0].value.a);
472 	TEE_BigInt *op2 = lookup_handle(HT_BIGINT, params[0].value.b);
473 	TEE_BigInt *dest_gcd = lookup_handle(HT_BIGINT, params[2].value.a);
474 	TEE_BigInt *dest_u = NULL;
475 	TEE_BigInt *dest_v = NULL;
476 
477 	if (!op1 || !op2 || !dest_gcd)
478 		return TEE_ERROR_BAD_PARAMETERS;
479 
480 	if (params[1].value.a != TA_CRYPT_ARITH_INVALID_HANDLE) {
481 		dest_u = lookup_handle(HT_BIGINT, params[1].value.a);
482 		if (!dest_u)
483 			return TEE_ERROR_BAD_PARAMETERS;
484 	}
485 	if (params[1].value.b != TA_CRYPT_ARITH_INVALID_HANDLE) {
486 		dest_v = lookup_handle(HT_BIGINT, params[1].value.b);
487 		if (!dest_v)
488 			return TEE_ERROR_BAD_PARAMETERS;
489 	}
490 
491 	TEE_BigIntComputeExtendedGcd(dest_gcd, dest_u, dest_v, op1, op2);
492 
493 	return TEE_SUCCESS;
494 }
495 
ta_entry_arith_is_prime(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])496 TEE_Result ta_entry_arith_is_prime(uint32_t param_types,
497 				   TEE_Param params[TEE_NUM_PARAMS])
498 {
499 	CHECK_PT(VALUE_INPUT, VALUE_OUTPUT, NONE, NONE);
500 
501 	TEE_BigInt *op = lookup_handle(HT_BIGINT, params[0].value.a);
502 
503 	if (!op)
504 		return TEE_ERROR_BAD_PARAMETERS;
505 
506 	params[1].value.a = TEE_BigIntIsProbablePrime(op, params[0].value.b);
507 
508 	return TEE_SUCCESS;
509 }
510 
ta_entry_arith_to_fmm(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])511 TEE_Result ta_entry_arith_to_fmm(uint32_t param_types,
512 				 TEE_Param params[TEE_NUM_PARAMS])
513 {
514 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
515 
516 	TEE_BigInt *src = lookup_handle(HT_BIGINT, params[0].value.a);
517 	TEE_BigInt *n = lookup_handle(HT_BIGINT, params[0].value.b);
518 	TEE_BigIntFMMContext *ctx = lookup_handle(HT_FMMCTX, params[1].value.a);
519 	TEE_BigIntFMM *dest = lookup_handle(HT_FMMVAR, params[1].value.b);
520 
521 	if (!src || !n | !ctx || !dest)
522 		return TEE_ERROR_BAD_PARAMETERS;
523 
524 	TEE_BigIntConvertToFMM(dest, src, n, ctx);
525 
526 	return TEE_SUCCESS;
527 }
528 
ta_entry_arith_from_fmm(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])529 TEE_Result ta_entry_arith_from_fmm(uint32_t param_types,
530 				   TEE_Param params[TEE_NUM_PARAMS])
531 {
532 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, NONE, NONE);
533 
534 	TEE_BigIntFMM *src = lookup_handle(HT_FMMVAR, params[0].value.a);
535 	TEE_BigInt *n = lookup_handle(HT_BIGINT, params[0].value.b);
536 	TEE_BigIntFMMContext *ctx = lookup_handle(HT_FMMCTX, params[1].value.a);
537 	TEE_BigInt *dest = lookup_handle(HT_BIGINT, params[1].value.b);
538 
539 	if (!src || !n | !ctx || !dest)
540 		return TEE_ERROR_BAD_PARAMETERS;
541 
542 	TEE_BigIntConvertFromFMM(dest, src, n, ctx);
543 
544 	return TEE_SUCCESS;
545 }
546 
ta_entry_arith_compute_fmm(uint32_t param_types,TEE_Param params[TEE_NUM_PARAMS])547 TEE_Result ta_entry_arith_compute_fmm(uint32_t param_types,
548 				      TEE_Param params[TEE_NUM_PARAMS])
549 {
550 	CHECK_PT(VALUE_INPUT, VALUE_INPUT, VALUE_INPUT, NONE);
551 
552 	TEE_BigIntFMM *op1 = lookup_handle(HT_FMMVAR, params[0].value.a);
553 	TEE_BigIntFMM *op2 = lookup_handle(HT_FMMVAR, params[0].value.b);
554 	TEE_BigInt *n = lookup_handle(HT_BIGINT, params[1].value.a);
555 	TEE_BigIntFMMContext *ctx = lookup_handle(HT_FMMCTX, params[1].value.b);
556 	TEE_BigIntFMM *dest = lookup_handle(HT_FMMVAR, params[2].value.a);
557 
558 	if (!op1 || !op2 || !n | !ctx || !dest)
559 		return TEE_ERROR_BAD_PARAMETERS;
560 
561 	TEE_BigIntComputeFMM(dest, op1, op2, n, ctx);
562 
563 	return TEE_SUCCESS;
564 }
565