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 ©,
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 ÷,
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 <c_ecc_fp_mulmod,
527 #else
528 <c_ecc_mulmod,
529 #endif
530 <c_ecc_projective_add_point,
531 <c_ecc_projective_dbl_point,
532 <c_ecc_map,
533 #ifdef LTC_ECC_SHAMIR
534 #ifdef LTC_MECC_FP
535 <c_ecc_fp_mul2add,
536 #else
537 <c_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