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