1 // SPDX-License-Identifier: BSD-2-Clause
2 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3  *
4  * LibTomCrypt is a library that provides various cryptographic
5  * algorithms in a highly modular and flexible manner.
6  *
7  * The library is free for all purposes without any express
8  * guarantee it works.
9  */
10 
11 #define DESC_DEF_ONLY
12 #include "tomcrypt_private.h"
13 
14 #ifdef LTM_DESC
15 
16 #include <tommath.h>
17 
18 static const struct {
19     int mpi_code, ltc_code;
20 } mpi_to_ltc_codes[] = {
21    { MP_OKAY ,  CRYPT_OK},
22    { MP_MEM  ,  CRYPT_MEM},
23    { MP_VAL  ,  CRYPT_INVALID_ARG},
24 };
25 
26 /**
27    Convert a MPI error to a LTC error (Possibly the most powerful function ever!  Oh wait... no)
28    @param err    The error to convert
29    @return The equivalent LTC error code or CRYPT_ERROR if none found
30 */
mpi_to_ltc_error(int err)31 static int mpi_to_ltc_error(int err)
32 {
33    int x;
34 
35    for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
36        if (err == mpi_to_ltc_codes[x].mpi_code) {
37           return mpi_to_ltc_codes[x].ltc_code;
38        }
39    }
40    return CRYPT_ERROR;
41 }
42 
init(void ** a)43 static int init(void **a)
44 {
45    int err;
46 
47    LTC_ARGCHK(a != NULL);
48 
49    *a = XCALLOC(1, sizeof(mp_int));
50    if (*a == NULL) {
51       return CRYPT_MEM;
52    }
53 
54    if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
55       XFREE(*a);
56    }
57    return err;
58 }
59 
deinit(void * a)60 static void deinit(void *a)
61 {
62    LTC_ARGCHKVD(a != NULL);
63    mp_clear(a);
64    XFREE(a);
65 }
66 
neg(void * a,void * b)67 static int neg(void *a, void *b)
68 {
69    LTC_ARGCHK(a != NULL);
70    LTC_ARGCHK(b != NULL);
71    return mpi_to_ltc_error(mp_neg(a, b));
72 }
73 
copy(void * a,void * b)74 static int copy(void *a, void *b)
75 {
76    LTC_ARGCHK(a != NULL);
77    LTC_ARGCHK(b != NULL);
78    return mpi_to_ltc_error(mp_copy(a, b));
79 }
80 
init_copy(void ** a,void * b)81 static int init_copy(void **a, void *b)
82 {
83    if (init(a) != CRYPT_OK) {
84       return CRYPT_MEM;
85    }
86    return copy(b, *a);
87 }
88 
89 /* ---- trivial ---- */
set_int(void * a,ltc_mp_digit b)90 static int set_int(void *a, ltc_mp_digit b)
91 {
92    LTC_ARGCHK(a != NULL);
93 #ifdef BN_MP_SET_INT_C
94    return mpi_to_ltc_error(mp_set_int(a, b));
95 #else
96    mp_set_u32(a, b);
97    return CRYPT_OK;
98 #endif
99 }
100 
get_int(void * a)101 static unsigned long get_int(void *a)
102 {
103    LTC_ARGCHK(a != NULL);
104 #ifdef BN_MP_GET_INT_C
105    return mp_get_int(a);
106 #else
107    return mp_get_ul(a);
108 #endif
109 }
110 
get_digit(void * a,int n)111 static ltc_mp_digit get_digit(void *a, int n)
112 {
113    mp_int *A;
114    LTC_ARGCHK(a != NULL);
115    A = a;
116    return (n >= A->used || n < 0) ? 0 : A->dp[n];
117 }
118 
get_digit_count(void * a)119 static int get_digit_count(void *a)
120 {
121    mp_int *A;
122    LTC_ARGCHK(a != NULL);
123    A = a;
124    return A->used;
125 }
126 
compare(void * a,void * b)127 static int compare(void *a, void *b)
128 {
129    int ret;
130    LTC_ARGCHK(a != NULL);
131    LTC_ARGCHK(b != NULL);
132    ret = mp_cmp(a, b);
133    switch (ret) {
134       case MP_LT: return LTC_MP_LT;
135       case MP_EQ: return LTC_MP_EQ;
136       case MP_GT: return LTC_MP_GT;
137       default:    return 0;
138    }
139 }
140 
compare_d(void * a,ltc_mp_digit b)141 static int compare_d(void *a, ltc_mp_digit b)
142 {
143    int ret;
144    LTC_ARGCHK(a != NULL);
145    ret = mp_cmp_d(a, b);
146    switch (ret) {
147       case MP_LT: return LTC_MP_LT;
148       case MP_EQ: return LTC_MP_EQ;
149       case MP_GT: return LTC_MP_GT;
150       default:    return 0;
151    }
152 }
153 
count_bits(void * a)154 static int count_bits(void *a)
155 {
156    LTC_ARGCHK(a != NULL);
157    return mp_count_bits(a);
158 }
159 
count_lsb_bits(void * a)160 static int count_lsb_bits(void *a)
161 {
162    LTC_ARGCHK(a != NULL);
163    return mp_cnt_lsb(a);
164 }
165 
166 
twoexpt(void * a,int n)167 static int twoexpt(void *a, int n)
168 {
169    LTC_ARGCHK(a != NULL);
170    return mpi_to_ltc_error(mp_2expt(a, n));
171 }
172 
173 /* ---- conversions ---- */
174 
175 /* read ascii string */
read_radix(void * a,const char * b,int radix)176 static int read_radix(void *a, const char *b, int radix)
177 {
178    LTC_ARGCHK(a != NULL);
179    LTC_ARGCHK(b != NULL);
180    return mpi_to_ltc_error(mp_read_radix(a, b, radix));
181 }
182 
183 /* write one */
write_radix(void * a,char * b,int radix)184 static int write_radix(void *a, char *b, int radix)
185 {
186    LTC_ARGCHK(a != NULL);
187    LTC_ARGCHK(b != NULL);
188    return mpi_to_ltc_error(mp_toradix(a, b, radix));
189 }
190 
191 /* get size as unsigned char string */
unsigned_size(void * a)192 static unsigned long unsigned_size(void *a)
193 {
194    LTC_ARGCHK(a != NULL);
195    return mp_unsigned_bin_size(a);
196 }
197 
198 /* store */
unsigned_write(void * a,unsigned char * b)199 static int unsigned_write(void *a, unsigned char *b)
200 {
201    LTC_ARGCHK(a != NULL);
202    LTC_ARGCHK(b != NULL);
203    return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
204 }
205 
206 /* read */
unsigned_read(void * a,unsigned char * b,unsigned long len)207 static int unsigned_read(void *a, unsigned char *b, unsigned long len)
208 {
209    LTC_ARGCHK(a != NULL);
210    LTC_ARGCHK(b != NULL);
211    return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
212 }
213 
214 /* add */
add(void * a,void * b,void * c)215 static int add(void *a, void *b, void *c)
216 {
217    LTC_ARGCHK(a != NULL);
218    LTC_ARGCHK(b != NULL);
219    LTC_ARGCHK(c != NULL);
220    return mpi_to_ltc_error(mp_add(a, b, c));
221 }
222 
addi(void * a,ltc_mp_digit b,void * c)223 static int addi(void *a, ltc_mp_digit b, void *c)
224 {
225    LTC_ARGCHK(a != NULL);
226    LTC_ARGCHK(c != NULL);
227    return mpi_to_ltc_error(mp_add_d(a, b, c));
228 }
229 
230 /* sub */
sub(void * a,void * b,void * c)231 static int sub(void *a, void *b, void *c)
232 {
233    LTC_ARGCHK(a != NULL);
234    LTC_ARGCHK(b != NULL);
235    LTC_ARGCHK(c != NULL);
236    return mpi_to_ltc_error(mp_sub(a, b, c));
237 }
238 
subi(void * a,ltc_mp_digit b,void * c)239 static int subi(void *a, ltc_mp_digit b, void *c)
240 {
241    LTC_ARGCHK(a != NULL);
242    LTC_ARGCHK(c != NULL);
243    return mpi_to_ltc_error(mp_sub_d(a, b, c));
244 }
245 
246 /* mul */
mul(void * a,void * b,void * c)247 static int mul(void *a, void *b, void *c)
248 {
249    LTC_ARGCHK(a != NULL);
250    LTC_ARGCHK(b != NULL);
251    LTC_ARGCHK(c != NULL);
252    return mpi_to_ltc_error(mp_mul(a, b, c));
253 }
254 
muli(void * a,ltc_mp_digit b,void * c)255 static int muli(void *a, ltc_mp_digit b, void *c)
256 {
257    LTC_ARGCHK(a != NULL);
258    LTC_ARGCHK(c != NULL);
259    return mpi_to_ltc_error(mp_mul_d(a, b, c));
260 }
261 
262 /* sqr */
sqr(void * a,void * b)263 static int sqr(void *a, void *b)
264 {
265    LTC_ARGCHK(a != NULL);
266    LTC_ARGCHK(b != NULL);
267    return mpi_to_ltc_error(mp_sqr(a, b));
268 }
269 
270 /* sqrtmod_prime */
sqrtmod_prime(void * a,void * b,void * c)271 static int sqrtmod_prime(void *a, void *b, void *c)
272 {
273    LTC_ARGCHK(a != NULL);
274    LTC_ARGCHK(b != NULL);
275    LTC_ARGCHK(c != NULL);
276    return mpi_to_ltc_error(mp_sqrtmod_prime(a, b, c));
277 }
278 
279 /* div */
divide(void * a,void * b,void * c,void * d)280 static int divide(void *a, void *b, void *c, void *d)
281 {
282    LTC_ARGCHK(a != NULL);
283    LTC_ARGCHK(b != NULL);
284    return mpi_to_ltc_error(mp_div(a, b, c, d));
285 }
286 
div_2(void * a,void * b)287 static int div_2(void *a, void *b)
288 {
289    LTC_ARGCHK(a != NULL);
290    LTC_ARGCHK(b != NULL);
291    return mpi_to_ltc_error(mp_div_2(a, b));
292 }
293 
294 /* modi */
modi(void * a,ltc_mp_digit b,ltc_mp_digit * c)295 static int modi(void *a, ltc_mp_digit b, ltc_mp_digit *c)
296 {
297    mp_digit tmp;
298    int      err;
299 
300    LTC_ARGCHK(a != NULL);
301    LTC_ARGCHK(c != NULL);
302 
303    if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) {
304       return err;
305    }
306    *c = tmp;
307    return CRYPT_OK;
308 }
309 
310 /* gcd */
gcd(void * a,void * b,void * c)311 static int gcd(void *a, void *b, void *c)
312 {
313    LTC_ARGCHK(a != NULL);
314    LTC_ARGCHK(b != NULL);
315    LTC_ARGCHK(c != NULL);
316    return mpi_to_ltc_error(mp_gcd(a, b, c));
317 }
318 
319 /* lcm */
lcm(void * a,void * b,void * c)320 static int lcm(void *a, void *b, void *c)
321 {
322    LTC_ARGCHK(a != NULL);
323    LTC_ARGCHK(b != NULL);
324    LTC_ARGCHK(c != NULL);
325    return mpi_to_ltc_error(mp_lcm(a, b, c));
326 }
327 
addmod(void * a,void * b,void * c,void * d)328 static int addmod(void *a, void *b, void *c, void *d)
329 {
330    LTC_ARGCHK(a != NULL);
331    LTC_ARGCHK(b != NULL);
332    LTC_ARGCHK(c != NULL);
333    LTC_ARGCHK(d != NULL);
334    return mpi_to_ltc_error(mp_addmod(a,b,c,d));
335 }
336 
submod(void * a,void * b,void * c,void * d)337 static int submod(void *a, void *b, void *c, void *d)
338 {
339    LTC_ARGCHK(a != NULL);
340    LTC_ARGCHK(b != NULL);
341    LTC_ARGCHK(c != NULL);
342    LTC_ARGCHK(d != NULL);
343    return mpi_to_ltc_error(mp_submod(a,b,c,d));
344 }
345 
mulmod(void * a,void * b,void * c,void * d)346 static int mulmod(void *a, void *b, void *c, void *d)
347 {
348    LTC_ARGCHK(a != NULL);
349    LTC_ARGCHK(b != NULL);
350    LTC_ARGCHK(c != NULL);
351    LTC_ARGCHK(d != NULL);
352    return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
353 }
354 
sqrmod(void * a,void * b,void * c)355 static int sqrmod(void *a, void *b, void *c)
356 {
357    LTC_ARGCHK(a != NULL);
358    LTC_ARGCHK(b != NULL);
359    LTC_ARGCHK(c != NULL);
360    return mpi_to_ltc_error(mp_sqrmod(a,b,c));
361 }
362 
363 /* invmod */
invmod(void * a,void * b,void * c)364 static int invmod(void *a, void *b, void *c)
365 {
366    LTC_ARGCHK(a != NULL);
367    LTC_ARGCHK(b != NULL);
368    LTC_ARGCHK(c != NULL);
369    return mpi_to_ltc_error(mp_invmod(a, b, c));
370 }
371 
372 /* setup */
montgomery_setup(void * a,void ** b)373 static int montgomery_setup(void *a, void **b)
374 {
375    int err;
376    LTC_ARGCHK(a != NULL);
377    LTC_ARGCHK(b != NULL);
378    *b = XCALLOC(1, sizeof(mp_digit));
379    if (*b == NULL) {
380       return CRYPT_MEM;
381    }
382    if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
383       XFREE(*b);
384    }
385    return err;
386 }
387 
388 /* get normalization value */
montgomery_normalization(void * a,void * b)389 static int montgomery_normalization(void *a, void *b)
390 {
391    LTC_ARGCHK(a != NULL);
392    LTC_ARGCHK(b != NULL);
393    return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b));
394 }
395 
396 /* reduce */
montgomery_reduce(void * a,void * b,void * c)397 static int montgomery_reduce(void *a, void *b, void *c)
398 {
399    LTC_ARGCHK(a != NULL);
400    LTC_ARGCHK(b != NULL);
401    LTC_ARGCHK(c != NULL);
402    return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c)));
403 }
404 
405 /* clean up */
montgomery_deinit(void * a)406 static void montgomery_deinit(void *a)
407 {
408    XFREE(a);
409 }
410 
exptmod(void * a,void * b,void * c,void * d)411 static int exptmod(void *a, void *b, void *c, void *d)
412 {
413    LTC_ARGCHK(a != NULL);
414    LTC_ARGCHK(b != NULL);
415    LTC_ARGCHK(c != NULL);
416    LTC_ARGCHK(d != NULL);
417    return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
418 }
419 
isprime(void * a,int b,int * c)420 static int isprime(void *a, int b, int *c)
421 {
422    int err;
423    LTC_ARGCHK(a != NULL);
424    LTC_ARGCHK(c != NULL);
425    b = mp_prime_rabin_miller_trials(mp_count_bits(a));
426    err = mpi_to_ltc_error(mp_prime_is_prime(a, b, c));
427    *c = (*c == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
428    return err;
429 }
430 
set_rand(void * a,int size)431 static int set_rand(void *a, int size)
432 {
433    LTC_ARGCHK(a != NULL);
434    return mpi_to_ltc_error(mp_rand(a, size));
435 }
436 
437 #ifndef MP_DIGIT_BIT
438 #define MP_DIGIT_BIT DIGIT_BIT
439 #endif
440 
441 const ltc_math_descriptor ltm_desc = {
442 
443    "LibTomMath",
444    (int)MP_DIGIT_BIT,
445 
446    &init,
447    &init_copy,
448    &deinit,
449 
450    &neg,
451    &copy,
452 
453    &set_int,
454    &get_int,
455    &get_digit,
456    &get_digit_count,
457    &compare,
458    &compare_d,
459    &count_bits,
460    &count_lsb_bits,
461    &twoexpt,
462 
463    &read_radix,
464    &write_radix,
465    &unsigned_size,
466    &unsigned_write,
467    &unsigned_read,
468 
469    &add,
470    &addi,
471    &sub,
472    &subi,
473    &mul,
474    &muli,
475    &sqr,
476    &sqrtmod_prime,
477    &divide,
478    &div_2,
479    &modi,
480    &gcd,
481    &lcm,
482 
483    &mulmod,
484    &sqrmod,
485    &invmod,
486 
487    &montgomery_setup,
488    &montgomery_normalization,
489    &montgomery_reduce,
490    &montgomery_deinit,
491 
492    &exptmod,
493    &isprime,
494 
495 #ifdef LTC_MECC
496 #ifdef LTC_MECC_FP
497    &ltc_ecc_fp_mulmod,
498 #else
499    &ltc_ecc_mulmod,
500 #endif
501    &ltc_ecc_projective_add_point,
502    &ltc_ecc_projective_dbl_point,
503    &ltc_ecc_map,
504 #ifdef LTC_ECC_SHAMIR
505 #ifdef LTC_MECC_FP
506    &ltc_ecc_fp_mul2add,
507 #else
508    &ltc_ecc_mul2add,
509 #endif /* LTC_MECC_FP */
510 #else
511    NULL,
512 #endif /* LTC_ECC_SHAMIR */
513 #else
514    NULL, NULL, NULL, NULL, NULL,
515 #endif /* LTC_MECC */
516 
517 #ifdef LTC_MRSA
518    &rsa_make_key,
519    &rsa_exptmod,
520 #else
521    NULL, NULL,
522 #endif
523    &addmod,
524    &submod,
525 
526    &set_rand,
527 
528 };
529 
530 
531 #endif
532 
533 /* ref:         $Format:%D$ */
534 /* git commit:  $Format:%H$ */
535 /* commit time: $Format:%ai$ */
536