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