summaryrefslogtreecommitdiffstats
path: root/3rd_party/libsrp6a-sha512/t_math.c
diff options
context:
space:
mode:
Diffstat (limited to '3rd_party/libsrp6a-sha512/t_math.c')
-rw-r--r--3rd_party/libsrp6a-sha512/t_math.c968
1 files changed, 968 insertions, 0 deletions
diff --git a/3rd_party/libsrp6a-sha512/t_math.c b/3rd_party/libsrp6a-sha512/t_math.c
new file mode 100644
index 0000000..dac19ec
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_math.c
@@ -0,0 +1,968 @@
1/*
2 * Copyright (c) 1997-2007 The Stanford SRP Authentication Project
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 *
20 * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
21 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
22 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
23 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
24 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * Redistributions in source or binary form must retain an intact copy
27 * of this copyright notice.
28 */
29
30#include <stdio.h>
31#include <sys/types.h>
32
33#include "config.h"
34
35#ifdef OPENSSL
36# include "openssl/opensslv.h"
37# include "openssl/bn.h"
38typedef BIGNUM * BigInteger;
39typedef BN_CTX * BigIntegerCtx;
40typedef BN_MONT_CTX * BigIntegerModAccel;
41#include <limits.h>
42#if OPENSSL_VERSION_NUMBER < 0x30000000L
43# ifndef OPENSSL_NO_ENGINE
44# define OPENSSL_ENGINE
45# include "openssl/engine.h"
46static ENGINE * default_engine = NULL;
47# endif /* OPENSSL_ENGINE */
48#endif
49typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
50 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx);
51static modexp_meth default_modexp = NULL;
52#elif defined(CRYPTOLIB)
53# include "libcrypt.h"
54typedef BigInt BigInteger;
55typedef void * BigIntegerCtx;
56typedef void * BigIntegerModAccel;
57#elif defined(GNU_MP)
58# include "gmp.h"
59typedef MP_INT * BigInteger;
60typedef void * BigIntegerCtx;
61typedef void * BigIntegerModAccel;
62# if __GNU_MP_VERSION >= 4 || (__GNU_MP_VERSION == 4 && __GNU_MP_VERSION_MINOR >= 1)
63/* GMP 4.1 and up has fast import/export routines for integer conversion */
64# define GMP_IMPEXP 1
65# endif
66#elif defined(TOMMATH)
67# ifdef TOMCRYPT
68 /* as of v0.96 */
69# include "ltc_tommath.h"
70# else
71# include "tommath.h"
72# endif
73typedef mp_int * BigInteger;
74typedef void * BigIntegerCtx;
75typedef void * BigIntegerModAccel;
76#elif defined(GCRYPT)
77# include "gcrypt.h"
78typedef gcry_mpi_t BigInteger;
79typedef void * BigIntegerCtx;
80typedef void * BigIntegerModAccel;
81#elif defined(MPI)
82# include "mpi.h"
83typedef mp_int * BigInteger;
84typedef void * BigIntegerCtx;
85typedef void * BigIntegerModAccel;
86#elif defined(MBEDTLS)
87#include <mbedtls/bignum.h>
88#include <mbedtls/error.h>
89typedef mbedtls_mpi* BigInteger;
90typedef void * BigIntegerCtx;
91typedef void * BigIntegerModAccel;
92#else
93# error "no math library specified"
94#endif
95#define MATH_PRIV
96
97#include "t_defines.h"
98#include "t_pwd.h"
99#include "srp_aux.h"
100
101/* Math library interface stubs */
102
103BigInteger
104BigIntegerFromInt(unsigned int n)
105{
106#ifdef OPENSSL
107 BIGNUM * a = BN_new();
108 if(a)
109 BN_set_word(a, n);
110 return a;
111#elif defined(CRYPTOLIB)
112 return bigInit(n);
113#elif defined(GNU_MP)
114 BigInteger rv = (BigInteger) malloc(sizeof(MP_INT));
115 if(rv)
116 mpz_init_set_ui(rv, n);
117 return rv;
118#elif defined(GCRYPT)
119 BigInteger rv = gcry_mpi_new(32);
120 gcry_mpi_set_ui(rv, n);
121 return rv;
122#elif defined(MPI) || defined(TOMMATH)
123 BigInteger rv = (BigInteger) malloc(sizeof(mp_int));
124 if(rv) {
125 mp_init(rv);
126 mp_set_int(rv, n);
127 }
128 return rv;
129#elif defined(MBEDTLS)
130 mbedtls_mpi* a = (mbedtls_mpi*)malloc(sizeof(mbedtls_mpi));
131 if (a) {
132 mbedtls_mpi_init(a);
133 mbedtls_mpi_lset(a, n);
134 }
135 return a;
136#endif
137}
138
139BigInteger
140BigIntegerFromBytes(const unsigned char *bytes, int length)
141{
142#ifdef OPENSSL
143 BIGNUM * a = BN_new();
144 BN_bin2bn(bytes, length, a);
145 return a;
146#elif defined(CRYPTOLIB)
147 BigInteger rv, t;
148 int i, n;
149
150 rv = bigInit(0);
151 if(rv == NULL)
152 return rv;
153 if(length % 4 == 0)
154 RSA_bufToBig(bytes, length, rv);
155 else { /* Wouldn't need this if cryptolib behaved better */
156 i = length & 0x3;
157 if(length > i)
158 RSA_bufToBig(bytes + i, length - i, rv);
159 for(n = 0; i > 0; --i)
160 n = (n << 8) | *bytes++;
161 t = bigInit(n);
162 bigLeftShift(t, (length & ~0x3) << 3, t);
163 bigAdd(rv, t, rv);
164 freeBignum(t);
165 }
166 return rv;
167#elif defined(GNU_MP)
168 BigInteger rv = (BigInteger) malloc(sizeof(MP_INT));
169
170# ifdef GMP_IMPEXP
171 if(rv) {
172 mpz_init(rv);
173 mpz_import(rv, length, 1, 1, 1, 0, bytes);
174 }
175# else
176 cstr * hexbuf = cstr_new();
177
178 if(hexbuf) {
179 if(rv)
180 mpz_init_set_str(rv, t_tohexcstr(hexbuf, bytes, length), 16);
181 cstr_clear_free(hexbuf);
182 }
183# endif /* GMP_IMPEXP */
184
185 return rv;
186#elif defined(GCRYPT)
187 BigInteger rv;
188 gcry_mpi_scan(&rv, GCRYMPI_FMT_USG, bytes, length, NULL);
189 return rv;
190#elif defined(MPI) || defined(TOMMATH)
191 BigInteger rv = (BigInteger) malloc(sizeof(mp_int));
192 if(rv) {
193 mp_init(rv);
194 mp_read_unsigned_bin(rv, (unsigned char *)bytes, length);
195 }
196 return rv;
197#elif defined(MBEDTLS)
198 mbedtls_mpi* a = (mbedtls_mpi*)malloc(sizeof(mbedtls_mpi));
199 if (a) {
200 mbedtls_mpi_init(a);
201 mbedtls_mpi_read_binary(a, bytes, length);
202 }
203 return a;
204#endif
205}
206
207int
208BigIntegerToBytes(BigInteger src, unsigned char *dest, int destlen)
209{
210#ifdef OPENSSL
211 return BN_bn2bin(src, dest);
212#elif defined(CRYPTOLIB)
213 int i, j;
214 cstr * rawbuf;
215
216 trim(src);
217 i = bigBytes(src);
218 j = (bigBits(src) + 7) / 8;
219 if(i == j)
220 RSA_bigToBuf(src, i, dest);
221 else { /* Wouldn't need this if cryptolib behaved better */
222 rawbuf = cstr_new();
223 cstr_set_length(rawbuf, i);
224 RSA_bigToBuf(src, i, rawbuf->data);
225 memcpy(dest, rawbuf->data + (i-j), j);
226 cstr_clear_free(rawbuf);
227 }
228 return j;
229#elif defined(GNU_MP)
230 size_t r = 0;
231# ifdef GMP_IMPEXP
232 mpz_export(dest, &r, 1, 1, 1, 0, src);
233# else
234 cstr * hexbuf = cstr_new();
235
236 if(hexbuf) {
237 cstr_set_length(hexbuf, mpz_sizeinbase(src, 16) + 1);
238 mpz_get_str(hexbuf->data, 16, src);
239 r = t_fromhex(dest, hexbuf->data);
240 cstr_clear_free(hexbuf);
241 }
242# endif
243 return r;
244#elif defined(GCRYPT)
245 size_t r = 0;
246 gcry_mpi_print(GCRYMPI_FMT_USG, dest, destlen, &r, src);
247 return r;
248#elif defined(MPI) || defined(TOMMATH)
249 mp_to_unsigned_bin(src, dest);
250 return mp_unsigned_bin_size(src);
251#elif defined(MBEDTLS)
252 size_t r = mbedtls_mpi_size(src);
253 mbedtls_mpi_write_binary(src, dest, r);
254 return r;
255#endif
256}
257
258BigIntegerResult
259BigIntegerToCstr(BigInteger x, cstr * out)
260{
261 int n = BigIntegerByteLen(x);
262 if(cstr_set_length(out, n) < 0)
263 return BIG_INTEGER_ERROR;
264 if(cstr_set_length(out, BigIntegerToBytes(x, (unsigned char*)out->data, n)) < 0)
265 return BIG_INTEGER_ERROR;
266 return BIG_INTEGER_SUCCESS;
267}
268
269BigIntegerResult
270BigIntegerToCstrEx(BigInteger x, cstr * out, int len)
271{
272 int n;
273 if(cstr_set_length(out, len) < 0)
274 return BIG_INTEGER_ERROR;
275#if defined(MBEDTLS)
276 /* mbedtls will prefix the output with zeros if the buffer is larger */
277 mbedtls_mpi_write_binary(x, (unsigned char*)out->data, len);
278#else
279 n = BigIntegerToBytes(x, (unsigned char*)out->data, len);
280 if(n < len) {
281 memmove(out->data + (len - n), out->data, n);
282 memset(out->data, 0, len - n);
283 }
284#endif
285 return BIG_INTEGER_SUCCESS;
286}
287
288BigIntegerResult
289BigIntegerToHex(BigInteger src, char *dest, int destlen)
290{
291#ifdef OPENSSL
292 strncpy(dest, BN_bn2hex(src), destlen);
293#elif defined(CRYPTOLIB)
294 trim(src);
295 bigsprint(src, dest);
296#elif defined(GNU_MP)
297 mpz_get_str(dest, 16, src);
298#elif defined(GCRYPT)
299 gcry_mpi_print(GCRYMPI_FMT_HEX, dest, destlen, NULL, src);
300#elif defined(MPI) || defined(TOMMATH)
301 mp_toradix(src, dest, 16);
302#elif defined(MBEDTLS)
303 size_t olen = 0;
304 mbedtls_mpi_write_string(src, 16, dest, destlen, &olen);
305#endif
306 return BIG_INTEGER_SUCCESS;
307}
308
309static char b64table[] =
310 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
311
312BigIntegerResult
313BigIntegerToString(BigInteger src, char *dest, int destlen, unsigned int radix)
314{
315 BigInteger t = BigIntegerFromInt(0);
316 char * p = dest;
317 char c;
318
319 *p++ = b64table[BigIntegerModInt(src, radix, NULL)];
320 BigIntegerDivInt(t, src, radix, NULL);
321 while(BigIntegerCmpInt(t, 0) > 0) {
322 *p++ = b64table[BigIntegerModInt(t, radix, NULL)];
323 BigIntegerDivInt(t, t, radix, NULL);
324 }
325 BigIntegerFree(t);
326 *p-- = '\0';
327 /* reverse the string */
328 while(p > dest) {
329 c = *p;
330 *p-- = *dest;
331 *dest++ = c;
332 }
333 return BIG_INTEGER_SUCCESS;
334}
335
336int
337BigIntegerBitLen(BigInteger b)
338{
339#ifdef OPENSSL
340 return BN_num_bits(b);
341#elif defined(CRYPTOLIB)
342 return bigBits(b);
343#elif defined(GNU_MP)
344 return mpz_sizeinbase(b, 2);
345#elif defined(GCRYPT)
346 return gcry_mpi_get_nbits(b);
347#elif defined(MPI) || defined(TOMMATH)
348 return mp_count_bits(b);
349#elif defined(MBEDTLS)
350 return (int)mbedtls_mpi_bitlen(b);
351#endif
352}
353
354int
355BigIntegerCmp(BigInteger c1, BigInteger c2)
356{
357#ifdef OPENSSL
358 return BN_cmp(c1, c2);
359#elif defined(CRYPTOLIB)
360 return bigCompare(c1, c2);
361#elif defined(GNU_MP)
362 return mpz_cmp(c1, c2);
363#elif defined(GCRYPT)
364 return gcry_mpi_cmp(c1, c2);
365#elif defined(MPI) || defined(TOMMATH)
366 return mp_cmp(c1, c2);
367#elif defined(MBEDTLS)
368 return mbedtls_mpi_cmp_mpi(c1, c2);
369#endif
370}
371
372int
373BigIntegerCmpInt(BigInteger c1, unsigned int c2)
374{
375#ifdef OPENSSL
376 BigInteger bc2 = BigIntegerFromInt(c2);
377 int rv = BigIntegerCmp(c1, bc2);
378 BigIntegerFree(bc2);
379 return rv;
380#elif defined(CRYPTOLIB)
381 BigInteger t;
382 int rv;
383
384 t = bigInit(c2);
385 rv = bigCompare(c1, t);
386 freeBignum(t);
387 return rv;
388#elif defined(GNU_MP)
389 return mpz_cmp_ui(c1, c2);
390#elif defined(TOMMATH)
391 return mp_cmp_d(c1, c2);
392#elif defined(GCRYPT)
393 return gcry_mpi_cmp_ui(c1, c2);
394#elif defined(MPI)
395 return mp_cmp_int(c1, c2);
396#elif defined(MBEDTLS)
397 return mbedtls_mpi_cmp_int(c1, c2);
398#endif
399}
400
401BigIntegerResult
402BigIntegerLShift(BigInteger result, BigInteger x, unsigned int bits)
403{
404#ifdef OPENSSL
405 BN_lshift(result, x, bits);
406#elif defined(CRYPTOLIB)
407 bigLeftShift(x, bits, result);
408#elif defined(GNU_MP)
409 mpz_mul_2exp(result, x, bits);
410#elif defined(GCRYPT)
411 gcry_mpi_mul_2exp(result, x, bits);
412#elif defined(MPI) || defined(TOMMATH)
413 mp_mul_2d(x, bits, result);
414#elif defined(MBEDTLS)
415 mbedtls_mpi_copy(result, x);
416 mbedtls_mpi_shift_l(result, bits);
417#endif
418 return BIG_INTEGER_SUCCESS;
419}
420
421BigIntegerResult
422BigIntegerAdd(BigInteger result, BigInteger a1, BigInteger a2)
423{
424#ifdef OPENSSL
425 BN_add(result, a1, a2);
426#elif defined(CRYPTOLIB)
427 bigAdd(a1, a2, result);
428#elif defined(GNU_MP)
429 mpz_add(result, a1, a2);
430#elif defined(GCRYPT)
431 gcry_mpi_add(result, a1, a2);
432#elif defined(MPI) || defined(TOMMATH)
433 mp_add(a1, a2, result);
434#elif defined(MBEDTLS)
435 mbedtls_mpi_add_mpi(result, a1, a2);
436#endif
437 return BIG_INTEGER_SUCCESS;
438}
439
440BigIntegerResult
441BigIntegerAddInt(BigInteger result, BigInteger a1, unsigned int a2)
442{
443#ifdef OPENSSL
444 if(result != a1)
445 BN_copy(result, a1);
446 BN_add_word(result, a2);
447#elif defined(CRYPTOLIB)
448 BigInteger t;
449
450 t = bigInit(a2);
451 bigAdd(a1, t, result);
452 freeBignum(t);
453#elif defined(GNU_MP)
454 mpz_add_ui(result, a1, a2);
455#elif defined(GCRYPT)
456 gcry_mpi_add_ui(result, a1, a2);
457#elif defined(MPI) || defined(TOMMATH)
458 mp_add_d(a1, a2, result);
459#elif defined(MBEDTLS)
460 mbedtls_mpi_add_int(result, a1, a2);
461#endif
462 return BIG_INTEGER_SUCCESS;
463}
464
465BigIntegerResult
466BigIntegerSub(BigInteger result, BigInteger s1, BigInteger s2)
467{
468#ifdef OPENSSL
469 BN_sub(result, s1, s2);
470#elif defined(CRYPTOLIB)
471 bigSubtract(s1, s2, result);
472#elif defined(GNU_MP)
473 mpz_sub(result, s1, s2);
474#elif defined(GCRYPT)
475 gcry_mpi_sub(result, s1, s2);
476#elif defined(MPI) || defined(TOMMATH)
477 mp_sub(s1, s2, result);
478#elif defined(MBEDTLS)
479 mbedtls_mpi_sub_mpi(result, s1, s2);
480#endif
481 return BIG_INTEGER_SUCCESS;
482}
483
484BigIntegerResult
485BigIntegerSubInt(BigInteger result, BigInteger s1, unsigned int s2)
486{
487#ifdef OPENSSL
488 if(result != s1)
489 BN_copy(result, s1);
490 BN_sub_word(result, s2);
491#elif defined(CRYPTOLIB)
492 BigInteger t;
493
494 t = bigInit(s2);
495 bigSubtract(s1, t, result);
496 freeBignum(t);
497#elif defined(GNU_MP)
498 mpz_sub_ui(result, s1, s2);
499#elif defined(GCRYPT)
500 gcry_mpi_sub_ui(result, s1, s2);
501#elif defined(MPI) || defined(TOMMATH)
502 mp_sub_d(s1, s2, result);
503#elif defined(MBEDTLS)
504 mbedtls_mpi_sub_int(result, s1, s2);
505#endif
506 return BIG_INTEGER_SUCCESS;
507}
508
509BigIntegerResult
510BigIntegerMul(BigInteger result, BigInteger m1, BigInteger m2, BigIntegerCtx c)
511{
512#ifdef OPENSSL
513 BN_CTX * ctx = NULL;
514 if(c == NULL)
515 c = ctx = BN_CTX_new();
516 BN_mul(result, m1, m2, c);
517 if(ctx)
518 BN_CTX_free(ctx);
519#elif defined(CRYPTOLIB)
520 bigMultiply(m1, m2, result);
521#elif defined(GNU_MP)
522 mpz_mul(result, m1, m2);
523#elif defined(GCRYPT)
524 gcry_mpi_mul(result, m1, m2);
525#elif defined(MPI) || defined(TOMMATH)
526 mp_mul(m1, m2, result);
527#elif defined(MBEDTLS)
528 mbedtls_mpi_mul_mpi(result, m1, m2);
529#endif
530 return BIG_INTEGER_SUCCESS;
531}
532
533BigIntegerResult
534BigIntegerMulInt(BigInteger result, BigInteger m1, unsigned int m2, BigIntegerCtx c)
535{
536#ifdef OPENSSL
537 if(result != m1)
538 BN_copy(result, m1);
539 BN_mul_word(result, m2);
540#elif defined(CRYPTOLIB)
541 BigInteger t;
542
543 t = bigInit(m2);
544 bigMultiply(m1, t, result);
545 freeBignum(t);
546#elif defined(GNU_MP)
547 mpz_mul_ui(result, m1, m2);
548#elif defined(GCRYPT)
549 gcry_mpi_mul_ui(result, m1, m2);
550#elif defined(MPI) || defined(TOMMATH)
551 mp_mul_d(m1, m2, result);
552#elif defined(MBEDTLS)
553 mbedtls_mpi_mul_int(result, m1, m2);
554#endif
555 return BIG_INTEGER_SUCCESS;
556}
557
558BigIntegerResult
559BigIntegerDivInt(BigInteger result, BigInteger d, unsigned int m, BigIntegerCtx c)
560{
561#ifdef OPENSSL
562 if(result != d)
563 BN_copy(result, d);
564 BN_div_word(result, m);
565#elif defined(CRYPTOLIB)
566 BigInteger t, u, q;
567
568 t = bigInit(m);
569 u = bigInit(0);
570 /* We use a separate variable q because cryptolib breaks if result == d */
571 q = bigInit(0);
572 bigDivide(d, t, q, u);
573 freeBignum(t);
574 freeBignum(u);
575 bigCopy(q, result);
576 freeBignum(q);
577#elif defined(GNU_MP)
578# ifdef GMP2
579 mpz_fdiv_q_ui(result, d, m);
580# else
581 mpz_div_ui(result, d, m);
582# endif
583#elif defined(GCRYPT)
584 BigInteger t = BigIntegerFromInt(m);
585 gcry_mpi_div(result, NULL, d, t, -1);
586 BigIntegerFree(t);
587#elif defined(MPI) || defined(TOMMATH)
588 mp_div_d(d, m, result, NULL);
589#elif defined(MBEDTLS)
590 mbedtls_mpi_div_int(result, NULL, d, m);
591#endif
592 return BIG_INTEGER_SUCCESS;
593}
594
595BigIntegerResult
596BigIntegerMod(BigInteger result, BigInteger d, BigInteger m, BigIntegerCtx c)
597{
598#ifdef OPENSSL
599 BN_CTX * ctx = NULL;
600 if(c == NULL)
601 c = ctx = BN_CTX_new();
602 BN_mod(result, d, m, c);
603 if(ctx)
604 BN_CTX_free(ctx);
605#elif defined(CRYPTOLIB)
606 bigMod(d, m, result);
607#elif defined(GNU_MP)
608 mpz_mod(result, d, m);
609#elif defined(GCRYPT)
610 gcry_mpi_mod(result, d, m);
611#elif defined(MPI) || defined(TOMMATH)
612 mp_mod(d, m, result);
613#elif defined(MBEDTLS)
614 mbedtls_mpi_mod_mpi(result, d, m);
615#endif
616 return BIG_INTEGER_SUCCESS;
617}
618
619unsigned int
620BigIntegerModInt(BigInteger d, unsigned int m, BigIntegerCtx c)
621{
622#ifdef OPENSSL
623 return BN_mod_word(d, m);
624#elif defined(CRYPTOLIB)
625 BigInteger t, u;
626 unsigned char r[4];
627
628 t = bigInit(m);
629 u = bigInit(0);
630 bigMod(d, t, u);
631 bigToBuf(u, sizeof(r), r);
632 freeBignum(t);
633 freeBignum(u);
634 return r[0] | (r[1] << 8) | (r[2] << 16) | (r[3] << 24);
635#elif defined(GNU_MP)
636 MP_INT result;
637 unsigned int i;
638
639 mpz_init(&result);
640
641/* Define GMP2 if you're using an old gmp.h but want to link against a
642 * newer libgmp.a (e.g. 2.0 or later). */
643
644# ifdef GMP2
645 mpz_fdiv_r_ui(&result, d, m);
646# else
647 mpz_mod_ui(&result, d, m);
648# endif
649 i = mpz_get_ui(&result);
650 mpz_clear(&result);
651 return i;
652#elif defined(GCRYPT)
653 /* TODO: any way to clean this up??? */
654 unsigned char r[4];
655 size_t len, i;
656 unsigned int ret = 0;
657 BigInteger t = BigIntegerFromInt(m);
658 BigInteger a = BigIntegerFromInt(0);
659 gcry_mpi_mod(a, d, t);
660 gcry_mpi_print(GCRYMPI_FMT_USG, r, 4, &len, a);
661 for(i = 0; i < len; ++i)
662 ret = (ret << 8) | r[i];
663 BigIntegerFree(t);
664 BigIntegerFree(a);
665 return ret;
666#elif defined(MPI) || defined(TOMMATH)
667 mp_digit r;
668 mp_mod_d(d, m, &r);
669 return r;
670#elif defined(MBEDTLS)
671 mbedtls_mpi_uint r = 0;
672 mbedtls_mpi_mod_int(&r, d, m);
673 return r;
674#endif
675}
676
677BigIntegerResult
678BigIntegerModMul(BigInteger r, BigInteger m1, BigInteger m2, BigInteger modulus, BigIntegerCtx c)
679{
680#ifdef OPENSSL
681 BN_CTX * ctx = NULL;
682 if(c == NULL)
683 c = ctx = BN_CTX_new();
684 BN_mod_mul(r, m1, m2, modulus, c);
685 if(ctx)
686 BN_CTX_free(ctx);
687#elif defined(CRYPTOLIB)
688 bigMultiply(m1, m2, r);
689 bigMod(r, modulus, r);
690#elif defined(GNU_MP)
691 mpz_mul(r, m1, m2);
692 mpz_mod(r, r, modulus);
693#elif defined(GCRYPT)
694 gcry_mpi_mulm(r, m1, m2, modulus);
695#elif defined(MPI) || defined(TOMMATH)
696 mp_mulmod(m1, m2, modulus, r);
697#elif defined(MBEDTLS)
698 mbedtls_mpi d;
699 mbedtls_mpi_init(&d);
700 mbedtls_mpi_mul_mpi(&d, m1, m2);
701 mbedtls_mpi_mod_mpi(r, &d, modulus);
702 mbedtls_mpi_free(&d);
703#endif
704 return BIG_INTEGER_SUCCESS;
705}
706
707BigIntegerResult
708BigIntegerModExp(BigInteger r, BigInteger b, BigInteger e, BigInteger m, BigIntegerCtx c, BigIntegerModAccel a)
709{
710#ifdef OPENSSL
711#if OPENSSL_VERSION_NUMBER >= 0x00906000
712 BN_ULONG B = BN_get_word(b);
713#endif
714 BN_CTX * ctx = NULL;
715 if(c == NULL)
716 c = ctx = BN_CTX_new();
717 if(default_modexp) {
718 (*default_modexp)(r, b, e, m, c, a);
719 }
720 else if(a == NULL) {
721 BN_mod_exp(r, b, e, m, c);
722 }
723/*
724 * In LibreSSL BN_mod_exp_mont_word() is not a public symbol where BN_mod_exp()
725 * and BN_mod_exp_mont() will use the word optimization when appropriate.
726 */
727#if OPENSSL_VERSION_NUMBER >= 0x00906000 && !defined(LIBRESSL_VERSION_NUMBER)
728 else if(B > 0 && B < ULONG_MAX) { /* 0.9.6 and above has mont_word optimization */
729 BN_mod_exp_mont_word(r, B, e, m, c, a);
730 }
731#endif
732 else
733 BN_mod_exp_mont(r, b, e, m, c, a);
734 if(ctx)
735 BN_CTX_free(ctx);
736#elif defined(CRYPTOLIB)
737 bigPow(b, e, m, r);
738#elif defined(GNU_MP)
739 mpz_powm(r, b, e, m);
740#elif defined(GCRYPT)
741 gcry_mpi_powm(r, b, e, m);
742#elif defined(MPI) || defined(TOMMATH)
743 mp_exptmod(b, e, m, r);
744#elif defined(MBEDTLS)
745 mbedtls_mpi_exp_mod(r, b, e, m, NULL);
746#endif
747 return BIG_INTEGER_SUCCESS;
748}
749
750#if defined(MBEDTLS)
751int _mbedtls_f_rng(void* unused, unsigned char *buf, size_t size)
752{
753 t_random(buf, size);
754 return 0;
755}
756#endif
757
758int
759BigIntegerCheckPrime(BigInteger n, BigIntegerCtx c)
760{
761#ifdef OPENSSL
762 int rv;
763 BN_CTX * ctx = NULL;
764 if(c == NULL)
765 c = ctx = BN_CTX_new();
766#if OPENSSL_VERSION_NUMBER >= 0x00908000
767 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
768 rv = BN_check_prime(n, c, NULL);
769 #else
770 rv = BN_is_prime_ex(n, 25, c, NULL);
771 #endif
772#else
773 rv = BN_is_prime(n, 25, NULL, c, NULL);
774#endif
775 if(ctx)
776 BN_CTX_free(ctx);
777 return rv;
778#elif defined(CRYPTOLIB)
779#if 0
780 /*
781 * Ugh. Not only is cryptolib's bigDivide sensitive to inputs
782 * and outputs being the same, but now the primeTest needs random
783 * numbers, which it gets by calling cryptolib's broken truerand
784 * implementation(!) We have to fake it out by doing our own
785 * seeding explicitly.
786 */
787 static int seeded = 0;
788 static unsigned char seedbuf[64];
789 if(!seeded) {
790 t_random(seedbuf, sizeof(seedbuf));
791 seedDesRandom(seedbuf, sizeof(seedbuf));
792 memset(seedbuf, 0, sizeof(seedbuf));
793 seeded = 1;
794 }
795#endif /* 0 */
796 t_random(NULL, 0);
797 return primeTest(n);
798#elif defined(GNU_MP)
799 return mpz_probab_prime_p(n, 25);
800#elif defined(GCRYPT)
801 return (gcry_prime_check(n, 0) == GPG_ERR_NO_ERROR);
802#elif defined(TOMMATH)
803 int rv;
804 mp_prime_is_prime(n, 25, &rv);
805 return rv;
806#elif defined(MPI)
807 return (mpp_pprime(n, 25) == MP_YES);
808#elif defined(MBEDTLS)
809 return mbedtls_mpi_is_prime_ext(n, 25, _mbedtls_f_rng, NULL);
810#endif
811}
812
813BigIntegerResult
814BigIntegerFree(BigInteger b)
815{
816#ifdef OPENSSL
817 BN_free(b);
818#elif defined(CRYPTOLIB)
819 freeBignum(b);
820#elif defined(GNU_MP)
821 mpz_clear(b);
822 free(b);
823#elif defined(GCRYPT)
824 gcry_mpi_release(b);
825#elif defined(MPI) || defined(TOMMATH)
826 mp_clear(b);
827 free(b);
828#elif defined(MBEDTLS)
829 mbedtls_mpi_free(b);
830 free(b);
831#endif
832 return BIG_INTEGER_SUCCESS;
833}
834
835BigIntegerResult
836BigIntegerClearFree(BigInteger b)
837{
838#ifdef OPENSSL
839 BN_clear_free(b);
840#elif defined(CRYPTOLIB)
841 /* TODO */
842 freeBignum(b);
843#elif defined(GNU_MP)
844 /* TODO */
845 mpz_clear(b);
846 free(b);
847#elif defined(GCRYPT)
848 /* TODO */
849 gcry_mpi_release(b);
850#elif defined(MPI) || defined(TOMMATH)
851 /* TODO */
852 mp_clear(b);
853 free(b);
854#elif defined(MBEDTLS)
855 mbedtls_mpi_free(b);
856 free(b);
857#endif
858 return BIG_INTEGER_SUCCESS;
859}
860
861BigIntegerCtx
862BigIntegerCtxNew()
863{
864#ifdef OPENSSL
865 return BN_CTX_new();
866#else
867 return NULL;
868#endif
869}
870
871BigIntegerResult
872BigIntegerCtxFree(BigIntegerCtx ctx)
873{
874#ifdef OPENSSL
875 if(ctx)
876 BN_CTX_free(ctx);
877#endif
878 return BIG_INTEGER_SUCCESS;
879}
880
881BigIntegerModAccel
882BigIntegerModAccelNew(BigInteger m, BigIntegerCtx c)
883{
884#ifdef OPENSSL
885 BN_CTX * ctx = NULL;
886 BN_MONT_CTX * mctx;
887 if(default_modexp)
888 return NULL;
889 if(c == NULL)
890 c = ctx = BN_CTX_new();
891 mctx = BN_MONT_CTX_new();
892 BN_MONT_CTX_set(mctx, m, c);
893 if(ctx)
894 BN_CTX_free(ctx);
895 return mctx;
896#else
897 return NULL;
898#endif
899}
900
901BigIntegerResult
902BigIntegerModAccelFree(BigIntegerModAccel accel)
903{
904#ifdef OPENSSL
905 if(accel)
906 BN_MONT_CTX_free(accel);
907#endif
908 return BIG_INTEGER_SUCCESS;
909}
910
911BigIntegerResult
912BigIntegerInitialize()
913{
914#if OPENSSL_VERSION_NUMBER >= 0x00907000 && defined(OPENSSL_ENGINE)
915 ENGINE_load_builtin_engines();
916#endif
917 return BIG_INTEGER_SUCCESS;
918}
919
920BigIntegerResult
921BigIntegerFinalize()
922{
923 return BigIntegerReleaseEngine();
924}
925
926BigIntegerResult
927BigIntegerUseEngine(const char * engine)
928{
929#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
930 ENGINE * e = ENGINE_by_id(engine);
931 if(e) {
932 if(ENGINE_init(e) > 0) {
933#if OPENSSL_VERSION_NUMBER >= 0x00907000
934 /* 0.9.7 loses the BN_mod_exp method. Pity. */
935 const RSA_METHOD * rsa = ENGINE_get_RSA(e);
936 if(rsa)
937#if (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3000000fL) || (!defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100005L)
938 default_modexp = (modexp_meth)RSA_meth_get_bn_mod_exp(rsa);
939#else
940 default_modexp = (modexp_meth)rsa->bn_mod_exp;
941#endif
942#else
943 default_modexp = (modexp_meth)ENGINE_get_BN_mod_exp(e);
944#endif
945 BigIntegerReleaseEngine();
946 default_engine = e;
947 return BIG_INTEGER_SUCCESS;
948 }
949 else
950 ENGINE_free(e);
951 }
952#endif
953 return BIG_INTEGER_ERROR;
954}
955
956BigIntegerResult
957BigIntegerReleaseEngine()
958{
959#if defined(OPENSSL) && defined(OPENSSL_ENGINE)
960 if(default_engine) {
961 ENGINE_finish(default_engine);
962 ENGINE_free(default_engine);
963 default_engine = NULL;
964 default_modexp = NULL;
965 }
966#endif
967 return BIG_INTEGER_SUCCESS;
968}