• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 
13 #ifndef TEE_ARITH_API_H
14 #define TEE_ARITH_API_H
15 
16 #include <tee_defines.h>
17 
18 /*
19  * below definitions are defined by Global Platform
20  * for compatibility:
21  * don't make any change to the content below
22  */
23 typedef uint32_t TEE_BigInt;
24 typedef uint32_t TEE_BigIntFMM;
25 typedef uint32_t TEE_BigIntFMMContext;
26 
27 #define TEE_BigIntSizeInU32(n) ((((n) + 31) / 32) + 2)
28 
29 /*
30  * returns the size of the array of uint32_t values
31  *
32  * @param modulusSizeInBits [IN]  Size of modulus in bits
33  *
34  * @return Number of bytes needed to store a TEE_BigIntFMM given a modulus of length modulusSizeInBits
35  */
36 size_t TEE_BigIntFMMSizeInU32(size_t modulusSizeInBits);
37 
38 /*
39  * returns the size of the array of uint32_t values needed to represent a fast modular context
40  *
41  * @param modulusSizeInBits [IN]  Size of modulus in bits
42  *
43  * @return Number of bytes needed to store a TEE_BigIntFMMContext given a modulus of length modulusSizeInBits
44  */
45 size_t TEE_BigIntFMMContextSizeInU32(size_t modulusSizeInBits);
46 
47 /*
48  * initializes bigInt
49  *
50  * @param bigInt[OUT] A pointer to the TEE_BigInt to be initialized
51  * @param len[IN] The size in uint32_t of the memory pointed to by bigInt
52  *
53  * @return void
54  */
55 void TEE_BigIntInit(TEE_BigInt *bigInt, size_t len);
56 
57 /*
58  * calculates the necessary prerequisites for the fast modular multiplication and stores them in a context.
59  *
60  * @param context[OUT]  A pointer to the TEE_BigIntFMMContext to be initialized
61  * @param len[IN] The size in uint32_t of the memory pointed to by context
62  * @param modulus[IN] The modulus
63  *
64  * @return void
65  */
66 void TEE_BigIntInitFMMContext(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus);
67 
68 #if defined(API_LEVEL) && defined(API_LEVEL1_1_1) && (API_LEVEL >= API_LEVEL1_1_1)
69 
70 /*
71  * calculates the necessary prerequisites for the fast modular multiplication and stores them in a context.
72  *
73  * @param context[OUT]  A pointer to the TEE_BigIntFMMContext to be initialized
74  * @param len[IN] The size in uint32_t of the memory pointed to by context
75  * @param modulus[IN] The modulus
76  *
77  * @return #TEE_SUCCESS success
78  * @return other failed
79  */
80 TEE_Result TEE_BigIntInitFMMContext1(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus);
81 #endif /* API_LEVEL */
82 
83 /*
84  * initializes bigIntFMM and sets its represented value to zero.
85  *
86  * @param context[IN]  A pointer to the TEE_BigIntFMM to be initialized
87  * @param len[IN] The size in uint32_t of the memory pointed to by bigIntFMM
88  *
89  * @return void
90  */
91 void TEE_BigIntInitFMM(TEE_BigIntFMM *bigIntFMM, size_t len);
92 
93 /*
94  * converts a bufferLen byte octet string buffer into a TEE_BigInt format.
95  *
96  * @param dest [OUT] Pointer to a TEE_BigInt to hold the result
97  * @param buffer [IN] Pointer to the buffer containing the octet string representation of the integer
98  * @param bufferLen [IN] The length of *buffer in bytes
99  * @param sign [IN] The sign of dest is set to the sign of sign
100  *
101  * @return #TEE_SUCCESS support
102  * @return #TEE_ERROR_OVERFLOW If memory allocation for the dest is too small
103  */
104 TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt *dest, const uint8_t *buffer, size_t bufferLen, int32_t sign);
105 
106 /*
107  * converts the absolute value of an integer in TEE_BigInt format into an octet string
108  *
109  * @param buffer [OUT]  Output buffer where converted octet string representation of the integer is written
110  * @param bufferLen [IN]  The length of *buffer in bytes
111  * @param bigInt [IN]  Pointer to the integer that will be converted to an octet string
112  *
113  * @return #TEE_SUCCESS support
114  * @return #TEE_ERROR_SHORT_BUFFER If the output buffer is too small to contain the octet string
115  */
116 TEE_Result TEE_BigIntConvertToOctetString(void *buffer, size_t *bufferLen, const TEE_BigInt *bigInt);
117 
118 /*
119  * sets *dest to the value shortVal
120  *
121  * @param dest [OUT] Pointer to a TEE_BigInt to store the result
122  * @param shortVal [IN] Input value
123  *
124  * @return void
125  */
126 void TEE_BigIntConvertFromS32(TEE_BigInt *dest, int32_t shortVal);
127 
128 /*
129  * sets *dest to the value of src, including the sign of src.
130  *
131  * @param dest [OUT] Pointer to an int32_t to store the result
132  * @param src [IN] Pointer to the input value
133  *
134  * @return #TEE_SUCCESS support
135  * @return #TEE_ERROR_OVERFLOW If src does not fit within an int32_t
136  */
137 TEE_Result TEE_BigIntConvertToS32(int32_t *dest, const TEE_BigInt *src);
138 
139 /*
140  * checks whether op1>op2, op1==op2, or op1<op2
141  *
142  * @param op1 [IN] Pointer to the first operand
143  * @param op2 [IN] Pointer to the second operand
144  *
145  * @return 0 if op1==op2
146  * @return a positive number if op1>op2
147  */
148 int32_t TEE_BigIntCmp(const TEE_BigInt *op1, const TEE_BigInt *op2);
149 
150 /*
151  * checks whether op>shortVal, op==shortVal, or op<shortVal
152  *
153  * @param op [IN] Pointer to the first operand
154  * @param shortVal [IN] Pointer to the second operand
155  *
156  * @return 0 if op1==shortVal
157  * @return a positive number if op1>shortVal
158  */
159 int32_t TEE_BigIntCmpS32(const TEE_BigInt *op, int32_t shortVal);
160 
161 /*
162  * computes |dest| = |op| >> bits
163  *
164  * @param dest [OUT] Pointer to TEE_BigInt to hold the shifted result
165  * @param op [IN] Pointer to the operand to be shifted
166  * @param bits [IN] Number of bits to shift
167  *
168  * @return void
169  */
170 void TEE_BigIntShiftRight(TEE_BigInt *dest, const TEE_BigInt *op, size_t bits);
171 
172 /*
173  * returns the bitIndexth bit of the natural binary representation of |src|
174  *
175  * @param src [IN] Pointer to the integer
176  * @param bitIndex[IN] The offset of the bit to be read, starting at offset 0 for the least significant bit
177  *
178  * @return true The Boolean value of the bitIndexth bit in |src| is '1'
179  * @return false The Boolean value of the bitIndexth bit in |src| is '0'
180  */
181 bool TEE_BigIntGetBit(const TEE_BigInt *src, uint32_t bitIndex);
182 
183 /*
184  * returns the number of bits in the natural binary representation of |src|; that is, the magnitude of src
185  *
186  * @param src [IN] Pointer to the integer
187  *
188  * @return 0 src equals zero
189  * @return others The number of bits in the natural binary representation of |src|.
190  */
191 uint32_t TEE_BigIntGetBitCount(const TEE_BigInt *src);
192 
193 #if defined(API_LEVEL) && (API_LEVEL >= API_LEVEL1_2)
194 /*
195  * sets the bitIndexth bit of the natural binary representation of |op| to 1 or 0
196  *
197  * @param op [IN/OUT] Pointer to the integer
198  * @param bitIndex [IN] The offset of the bit to be set, starting at offset 0 for the least significant bit
199  * @param value [IN] The bit value to set where true represents a '1' and false represents a '0'
200  *
201  * @return #TEE_SUCCESS support
202  * @return #TEE_ERROR_OVERFLOW If the bitIndexth bit is larger than allocated bit length of op
203  */
204 TEE_Result TEE_BigIntSetBit(TEE_BigInt *op, uint32_t bitIndex, bool value);
205 
206 /*
207  * assigns the value of src to dest
208  *
209  * @param dest [OUT] Pointer to TEE_BigInt to be assigned
210  * @param src [IN] Pointer to the source operand
211  *
212  * @return #TEE_SUCCESS support
213  * @return #TEE_ERROR_OVERFLOW In case the dest operand cannot hold the value of src
214  */
215 TEE_Result TEE_BigIntAssign(TEE_BigInt *dest, const TEE_BigInt *src);
216 
217 /*
218  * assigns the value of |src| to dest
219  *
220  * @param dest [OUT] Pointer to TEE_BigInt to be assigned
221  * @param src [IN] Pointer to the source operand
222  *
223  * @return #TEE_SUCCESS support
224  * @return #TEE_ERROR_OVERFLOW In case the dest operand cannot hold the value of |src|
225  */
226 TEE_Result TEE_BigIntAbs(TEE_BigInt *dest, const TEE_BigInt *src);
227 #endif /* API_LEVEL */
228 
229 /*
230  * computes dest = op1 + op2
231  *
232  * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 + op2
233  * @param op1 [IN] Pointer to the first operand
234  * @param op2 [IN] Pointer to the second operand
235  *
236  * @return void
237  */
238 void TEE_BigIntAdd(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2);
239 
240 /*
241  * computes dest = op1 - op2
242  *
243  * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 - op2
244  * @param op1 [IN] Pointer to the first operand
245  * @param op2 [IN] Pointer to the second operand
246  *
247  * @return void
248  */
249 void TEE_BigIntSub(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2);
250 
251 /*
252  * negates an operand: dest = -op
253  *
254  * @param dest [OUT] PPointer to TEE_BigInt to store the result -op
255  * @param op [IN] Pointer to the operand to be negated
256  *
257  * @return void
258  */
259 void TEE_BigIntNeg(TEE_BigInt *dest, const TEE_BigInt *op);
260 
261 /*
262  * computes dest = op1 * op2
263  *
264  * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 * op2
265  * @param op1 [IN] Pointer to the first operand
266  * @param op2 [IN] Pointer to the second operand
267  *
268  * @return void
269  */
270 void TEE_BigIntMul(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2);
271 
272 /*
273  * computes dest = op * op
274  *
275  * @param dest [OUT] Pointer to TEE_BigInt to store the result op * op
276  * @param op [IN] Pointer to the operand to be squared
277  *
278  * @return void
279  */
280 void TEE_BigIntSquare(TEE_BigInt *dest, const TEE_BigInt *op);
281 
282 /*
283  * computes dest_r and dest_q such that op1 = dest_q * op2 + dest_r
284  *
285  * @param dest_q [OUT] Pointer to a TEE_BigInt to store the quotient
286  * @param dest_r [IN] Pointer to a TEE_BigInt to store the remainder
287  * @param op1 [OUT] Pointer to the first operand, the dividend
288  * @param op2 [IN] Pointer to the second operand, the divisor
289  *
290  * @return #TEE_SUCCESS operation success
291  * @return #TEE_ERROR_BAD_PARAMETERS If any of the parameters is NULL
292  */
293 void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r, const TEE_BigInt *op1, const TEE_BigInt *op2);
294 
295 /*
296  * computes dest = op (mod n) such that 0 <= dest < n.
297  *
298  * @param dest [OUT] Pointer to TEE_BigInt to hold the result op (mod n)
299  * @param op [IN] Pointer to the operand to be reduced mod n
300  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1.
301  *
302  * @return void
303  */
304 void TEE_BigIntMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n);
305 
306 /*
307  * computes dest = (op1 + op2) (mod n).
308  *
309  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 + op2)(mod n)
310  * @param op1 [IN] Pointer to the first operand
311  * @param op2 [IN] Pointer to the second operand
312  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1
313  *
314  * @return void
315  */
316 void TEE_BigIntAddMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n);
317 
318 /*
319  * computes dest = (op1 - op2) (mod n).
320  *
321  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 - op2)(mod n)
322  * @param op1 [IN] Pointer to the first operand
323  * @param op2 [IN] Pointer to the second operand
324  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1
325  *
326  * @return void
327  */
328 void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n);
329 
330 /*
331  * computes dest = (op1 * op2) (mod n).
332  *
333  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 * op2)(mod n)
334  * @param op1 [IN] Pointer to the first operand
335  * @param op2 [IN] Pointer to the second operand
336  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1
337  *
338  * @return void
339  */
340 void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n);
341 
342 /*
343  * computes dest = (op * op) (mod n).
344  *
345  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op * op)(mod n)
346  * @param op1 [IN] Pointer to the operand
347  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1
348  *
349  * @return void
350  */
351 void TEE_BigIntSquareMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n);
352 
353 /*
354  * computes dest such that dest * op = 1 (mod n).
355  *
356  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op^-1)(mod n)
357  * @param op1 [IN] Pointer to the operand
358  * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1
359  *
360  * @return void
361  */
362 void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n);
363 
364 /*
365  * determines whether gcd(op1, op2) == 1.
366  *
367  * @param op1 [IN] Pointer to the first operand
368  * @param op2 [IN] Pointer to the second operand
369  *
370  * @return true if gcd(op1, op2) == 1
371  * @return fast otherwise
372  */
373 bool TEE_BigIntRelativePrime(const TEE_BigInt *op1, const TEE_BigInt *op2);
374 
375 /*
376  * computes the greatest common divisor of the input parameters op1 and op2.
377  *
378  * @param gcd [OUT] Pointer to TEE_BigInt to hold the greatest common divisor of op1 and op2
379  * @param u [OUT] Pointer to TEE_BigInt to hold the first coefficient
380  * @param v [OUT] Pointer to TEE_BigInt to hold the second coefficient
381  * @param op1 [IN] Pointer to the first operand
382  * @param op2 [IN] Pointer to the second operand
383  *
384  * @return void
385  */
386 void TEE_BigIntComputeExtendedGcd(TEE_BigInt *gcd, TEE_BigInt *u, TEE_BigInt *v, const TEE_BigInt *op1,
387                                   const TEE_BigInt *op2);
388 /*
389  * performs a probabilistic primality test on op
390  *
391  * @param op [IN] Candidate number that is tested for primality
392  * @param confidenceLevel [IN]  The desired confidence level for a non-conclusive test
393  *
394  * @return 0 If op is a composite number
395  * @return 1 If op is guaranteed to be prime
396  * @return -1 If the test is non-conclusive but the probability that op is composite is less than 2^(-confidenceLevel)
397  */
398 int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt *op, uint32_t confidenceLevel);
399 
400 /*
401  * converts src into a representation suitable for doing fast modular multiplicatio
402  *
403  * @param dest [OUT] Pointer to an initialized TEE_BigIntFMM memory area
404  * @param src [IN] Pointer to the TEE_BigInt to convert
405  * @param n [IN] Pointer to the modulus
406  * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1
407  *
408  * @return void
409  */
410 void TEE_BigIntConvertToFMM(TEE_BigIntFMM *dest, const TEE_BigInt *src, const TEE_BigInt *n,
411                             const TEE_BigIntFMMContext *context);
412 
413 /*
414  * converts src in the fast modular multiplication representation back to a TEE_BigInt representation
415  *
416  * @param dest [OUT] Pointer to an initialized TEE_BigIntFMM memory area to hold the converted result
417  * @param src [IN] Pointer to a TEE_BigIntFMM holding the value in the fast modular multiplication representation
418  * @param n [IN] Pointer to the modulus
419  * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1
420  *
421  * @return void
422  */
423 void TEE_BigIntConvertFromFMM(TEE_BigInt *dest, const TEE_BigIntFMM *src, const TEE_BigInt *n,
424                               const TEE_BigIntFMMContext *context);
425 
426 /*
427  * calculates dest = op1 * op2 in the fast modular multiplication representation
428  *
429  * @param dest [OUT] Pointer to TEE_BigIntFMM to hold the result op1 * op2
430  * @param op1 [IN] Pointer to the first operand
431  * @param op2 [IN] Pointer to the second operand
432  * @param n [IN] Pointer to the modulus
433  * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1
434  *
435  * @return void
436  */
437 void TEE_BigIntComputeFMM(TEE_BigIntFMM *dest, const TEE_BigIntFMM *op1, const TEE_BigIntFMM *op2, const TEE_BigInt *n,
438                           const TEE_BigIntFMMContext *context);
439 
440 #if defined(API_LEVEL) && defined(API_LEVEL1_1_1) && (API_LEVEL >= API_LEVEL1_1_1)
441 /*
442  * computes dest = (op1 ^ op2) (mod n).
443  *
444  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 ^ op2)(mod n)
445  * @param op1 [IN] Pointer to the first operand
446  * @param op2 [IN] Pointer to the second operand
447  * @param n [IN] Pointer to the modulus
448  * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 or NULL
449  *
450  * @return #TEE_SUCCESS success
451  * @return #TEE_ERROR_NOT_SUPPORTED If the value of n is not supported
452  */
453 TEE_Result TEE_BigIntExpMod(TEE_BigInt *des, TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n,
454                             TEE_BigIntFMMContext *context);
455 #endif /* API_LEVEL */
456 
457 /*
458  * check whether n exists to make dest = (op1 ^ op2) (mod n).
459  *
460  * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 ^ op2)(mod n)
461  * @param op1 [IN] Pointer to the first operand
462  * @param op2 [IN] Pointer to the second operand
463  * @param n [IN] Pointer to the modulus
464  * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 or NULL
465  *
466  * @return true If the value of n is supported
467  * @return false If the value of n is not supported
468  */
469 bool EXT_TEE_BigIntExpMod(TEE_BigInt *out, TEE_BigInt *in, const TEE_BigInt *exp, const TEE_BigInt *n);
470 #endif
471