diff options
Diffstat (limited to '3rd_party/libsrp6a-sha512/t_math.c')
-rw-r--r-- | 3rd_party/libsrp6a-sha512/t_math.c | 968 |
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" | ||
38 | typedef BIGNUM * BigInteger; | ||
39 | typedef BN_CTX * BigIntegerCtx; | ||
40 | typedef 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" | ||
46 | static ENGINE * default_engine = NULL; | ||
47 | # endif /* OPENSSL_ENGINE */ | ||
48 | #endif | ||
49 | typedef int (*modexp_meth)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, | ||
50 | const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *mctx); | ||
51 | static modexp_meth default_modexp = NULL; | ||
52 | #elif defined(CRYPTOLIB) | ||
53 | # include "libcrypt.h" | ||
54 | typedef BigInt BigInteger; | ||
55 | typedef void * BigIntegerCtx; | ||
56 | typedef void * BigIntegerModAccel; | ||
57 | #elif defined(GNU_MP) | ||
58 | # include "gmp.h" | ||
59 | typedef MP_INT * BigInteger; | ||
60 | typedef void * BigIntegerCtx; | ||
61 | typedef 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 | ||
73 | typedef mp_int * BigInteger; | ||
74 | typedef void * BigIntegerCtx; | ||
75 | typedef void * BigIntegerModAccel; | ||
76 | #elif defined(GCRYPT) | ||
77 | # include "gcrypt.h" | ||
78 | typedef gcry_mpi_t BigInteger; | ||
79 | typedef void * BigIntegerCtx; | ||
80 | typedef void * BigIntegerModAccel; | ||
81 | #elif defined(MPI) | ||
82 | # include "mpi.h" | ||
83 | typedef mp_int * BigInteger; | ||
84 | typedef void * BigIntegerCtx; | ||
85 | typedef void * BigIntegerModAccel; | ||
86 | #elif defined(MBEDTLS) | ||
87 | #include <mbedtls/bignum.h> | ||
88 | #include <mbedtls/error.h> | ||
89 | typedef mbedtls_mpi* BigInteger; | ||
90 | typedef void * BigIntegerCtx; | ||
91 | typedef 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 | |||
103 | BigInteger | ||
104 | BigIntegerFromInt(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 | |||
139 | BigInteger | ||
140 | BigIntegerFromBytes(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 | |||
207 | int | ||
208 | BigIntegerToBytes(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 | |||
258 | BigIntegerResult | ||
259 | BigIntegerToCstr(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 | |||
269 | BigIntegerResult | ||
270 | BigIntegerToCstrEx(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 | |||
288 | BigIntegerResult | ||
289 | BigIntegerToHex(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 | |||
309 | static char b64table[] = | ||
310 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; | ||
311 | |||
312 | BigIntegerResult | ||
313 | BigIntegerToString(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 | |||
336 | int | ||
337 | BigIntegerBitLen(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 | |||
354 | int | ||
355 | BigIntegerCmp(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 | |||
372 | int | ||
373 | BigIntegerCmpInt(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 | |||
401 | BigIntegerResult | ||
402 | BigIntegerLShift(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 | |||
421 | BigIntegerResult | ||
422 | BigIntegerAdd(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 | |||
440 | BigIntegerResult | ||
441 | BigIntegerAddInt(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 | |||
465 | BigIntegerResult | ||
466 | BigIntegerSub(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 | |||
484 | BigIntegerResult | ||
485 | BigIntegerSubInt(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 | |||
509 | BigIntegerResult | ||
510 | BigIntegerMul(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 | |||
533 | BigIntegerResult | ||
534 | BigIntegerMulInt(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 | |||
558 | BigIntegerResult | ||
559 | BigIntegerDivInt(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 | |||
595 | BigIntegerResult | ||
596 | BigIntegerMod(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 | |||
619 | unsigned int | ||
620 | BigIntegerModInt(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 | |||
677 | BigIntegerResult | ||
678 | BigIntegerModMul(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 | |||
707 | BigIntegerResult | ||
708 | BigIntegerModExp(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) | ||
751 | int _mbedtls_f_rng(void* unused, unsigned char *buf, size_t size) | ||
752 | { | ||
753 | t_random(buf, size); | ||
754 | return 0; | ||
755 | } | ||
756 | #endif | ||
757 | |||
758 | int | ||
759 | BigIntegerCheckPrime(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 | |||
813 | BigIntegerResult | ||
814 | BigIntegerFree(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 | |||
835 | BigIntegerResult | ||
836 | BigIntegerClearFree(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 | |||
861 | BigIntegerCtx | ||
862 | BigIntegerCtxNew() | ||
863 | { | ||
864 | #ifdef OPENSSL | ||
865 | return BN_CTX_new(); | ||
866 | #else | ||
867 | return NULL; | ||
868 | #endif | ||
869 | } | ||
870 | |||
871 | BigIntegerResult | ||
872 | BigIntegerCtxFree(BigIntegerCtx ctx) | ||
873 | { | ||
874 | #ifdef OPENSSL | ||
875 | if(ctx) | ||
876 | BN_CTX_free(ctx); | ||
877 | #endif | ||
878 | return BIG_INTEGER_SUCCESS; | ||
879 | } | ||
880 | |||
881 | BigIntegerModAccel | ||
882 | BigIntegerModAccelNew(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 | |||
901 | BigIntegerResult | ||
902 | BigIntegerModAccelFree(BigIntegerModAccel accel) | ||
903 | { | ||
904 | #ifdef OPENSSL | ||
905 | if(accel) | ||
906 | BN_MONT_CTX_free(accel); | ||
907 | #endif | ||
908 | return BIG_INTEGER_SUCCESS; | ||
909 | } | ||
910 | |||
911 | BigIntegerResult | ||
912 | BigIntegerInitialize() | ||
913 | { | ||
914 | #if OPENSSL_VERSION_NUMBER >= 0x00907000 && defined(OPENSSL_ENGINE) | ||
915 | ENGINE_load_builtin_engines(); | ||
916 | #endif | ||
917 | return BIG_INTEGER_SUCCESS; | ||
918 | } | ||
919 | |||
920 | BigIntegerResult | ||
921 | BigIntegerFinalize() | ||
922 | { | ||
923 | return BigIntegerReleaseEngine(); | ||
924 | } | ||
925 | |||
926 | BigIntegerResult | ||
927 | BigIntegerUseEngine(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 | |||
956 | BigIntegerResult | ||
957 | BigIntegerReleaseEngine() | ||
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 | } | ||