summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c')
-rw-r--r--FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c1464
1 files changed, 1131 insertions, 333 deletions
diff --git a/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c b/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c
index b3ce4203e..56d684b46 100644
--- a/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c
+++ b/FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/integer.c
@@ -1,8 +1,8 @@
/* integer.c
*
- * Copyright (C) 2006-2015 wolfSSL Inc.
+ * Copyright (C) 2006-2020 wolfSSL Inc.
*
- * This file is part of wolfSSL. (formerly known as CyaSSL)
+ * This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,10 +16,11 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
+
/*
* Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
* http://math.libtomcrypt.com
@@ -33,19 +34,70 @@
/* in case user set USE_FAST_MATH there */
#include <wolfssl/wolfcrypt/settings.h>
+#ifdef NO_INLINE
+ #include <wolfssl/wolfcrypt/misc.h>
+#else
+ #define WOLFSSL_MISC_INCLUDED
+ #include <wolfcrypt/src/misc.c>
+#endif
+
#ifndef NO_BIG_INT
#ifndef USE_FAST_MATH
+#ifndef WOLFSSL_SP_MATH
+
#include <wolfssl/wolfcrypt/integer.h>
-#ifndef NO_WOLFSSL_SMALL_STACK
- #ifndef WOLFSSL_SMALL_STACK
- #define WOLFSSL_SMALL_STACK
+#if defined(FREESCALE_LTC_TFM)
+ #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
+#endif
+#ifdef WOLFSSL_DEBUG_MATH
+ #include <stdio.h>
+#endif
+
+#ifdef SHOW_GEN
+ #ifndef NO_STDIO_FILESYSTEM
+ #include <stdio.h>
#endif
#endif
-static void bn_reverse (unsigned char *s, int len);
+#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
+#ifdef __cplusplus
+ extern "C" {
+#endif
+WOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod,
+ mp_int* res);
+WOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod,
+ mp_int* res);
+WOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod,
+ mp_int* res);
+WOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod,
+ mp_int* res);
+WOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod,
+ mp_int* res);
+#ifdef __cplusplus
+ } /* extern "C" */
+#endif
+#endif
+
+/* reverse an array, used for radix code */
+static void
+bn_reverse (unsigned char *s, int len)
+{
+ int ix, iy;
+ unsigned char t;
+
+ ix = 0;
+ iy = len - 1;
+ while (ix < iy) {
+ t = s[ix];
+ s[ix] = s[iy];
+ s[iy] = t;
+ ++ix;
+ --iy;
+ }
+}
/* math settings check */
word32 CheckRunTimeSettings(void)
@@ -60,6 +112,13 @@ int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
{
int res = MP_OKAY;
+ if (a) XMEMSET(a, 0, sizeof(mp_int));
+ if (b) XMEMSET(b, 0, sizeof(mp_int));
+ if (c) XMEMSET(c, 0, sizeof(mp_int));
+ if (d) XMEMSET(d, 0, sizeof(mp_int));
+ if (e) XMEMSET(e, 0, sizeof(mp_int));
+ if (f) XMEMSET(f, 0, sizeof(mp_int));
+
if (a && ((res = mp_init(a)) != MP_OKAY))
return res;
@@ -95,33 +154,28 @@ int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
/* init a new mp_int */
int mp_init (mp_int * a)
{
- int i;
+ /* Safeguard against passing in a null pointer */
+ if (a == NULL)
+ return MP_VAL;
- /* allocate memory required and clear it */
- a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC, 0,
- DYNAMIC_TYPE_BIGINT);
- if (a->dp == NULL) {
- return MP_MEM;
- }
-
- /* set the digits to zero */
- for (i = 0; i < MP_PREC; i++) {
- a->dp[i] = 0;
- }
+ /* defer allocation until mp_grow */
+ a->dp = NULL;
/* set the used to zero, allocated digits to the default precision
* and sign to positive */
a->used = 0;
- a->alloc = MP_PREC;
+ a->alloc = 0;
a->sign = MP_ZPOS;
+#ifdef HAVE_WOLF_BIGINT
+ wc_bigint_init(&a->raw);
+#endif
return MP_OKAY;
}
/* clear one (frees) */
-void
-mp_clear (mp_int * a)
+void mp_clear (mp_int * a)
{
int i;
@@ -136,15 +190,52 @@ mp_clear (mp_int * a)
}
/* free ram */
- XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT);
+ mp_free(a);
/* reset members to make debugging easier */
- a->dp = NULL;
a->alloc = a->used = 0;
a->sign = MP_ZPOS;
}
}
+void mp_free (mp_int * a)
+{
+ /* only do anything if a hasn't been freed previously */
+ if (a->dp != NULL) {
+ /* free ram */
+ XFREE(a->dp, 0, DYNAMIC_TYPE_BIGINT);
+ a->dp = NULL;
+ }
+
+#ifdef HAVE_WOLF_BIGINT
+ wc_bigint_free(&a->raw);
+#endif
+}
+
+void mp_forcezero(mp_int * a)
+{
+ if (a == NULL)
+ return;
+
+ /* only do anything if a hasn't been freed previously */
+ if (a->dp != NULL) {
+ /* force zero the used digits */
+ ForceZero(a->dp, a->used * sizeof(mp_digit));
+#ifdef HAVE_WOLF_BIGINT
+ wc_bigint_zero(&a->raw);
+#endif
+ /* free ram */
+ mp_free(a);
+
+ /* reset members to make debugging easier */
+ a->alloc = a->used = 0;
+ a->sign = MP_ZPOS;
+ }
+
+ a->sign = MP_ZPOS;
+ a->used = 0;
+}
+
/* get the size for an unsigned equivalent */
int mp_unsigned_bin_size (mp_int * a)
@@ -155,8 +246,7 @@ int mp_unsigned_bin_size (mp_int * a)
/* returns the number of bits in an int */
-int
-mp_count_bits (mp_int * a)
+int mp_count_bits (mp_int * a)
{
int r;
mp_digit q;
@@ -187,11 +277,11 @@ int mp_leading_bit (mp_int * a)
if (mp_init_copy(&t, a) != MP_OKAY)
return 0;
- while (mp_iszero(&t) == 0) {
+ while (mp_iszero(&t) == MP_NO) {
#ifndef MP_8BIT
bit = (t.dp[0] & 0x80) != 0;
#else
- bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;
+ bit = ((t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80) != 0;
#endif
if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
break;
@@ -200,6 +290,22 @@ int mp_leading_bit (mp_int * a)
return bit;
}
+int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b)
+{
+ int res = 0;
+ while (mp_iszero(t) == MP_NO) {
+#ifndef MP_8BIT
+ b[x++] = (unsigned char) (t->dp[0] & 255);
+#else
+ b[x++] = (unsigned char) (t->dp[0] | ((t->dp[1] & 0x01) << 7));
+#endif
+ if ((res = mp_div_2d (t, 8, t, NULL)) != MP_OKAY) {
+ return res;
+ }
+ res = x;
+ }
+ return res;
+}
/* store in unsigned [big endian] format */
int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
@@ -211,49 +317,62 @@ int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
return res;
}
- x = 0;
- while (mp_iszero (&t) == 0) {
-#ifndef MP_8BIT
- b[x++] = (unsigned char) (t.dp[0] & 255);
-#else
- b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
-#endif
- if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
- mp_clear (&t);
- return res;
- }
+ x = mp_to_unsigned_bin_at_pos(0, &t, b);
+ if (x < 0) {
+ mp_clear(&t);
+ return x;
}
+
bn_reverse (b, x);
mp_clear (&t);
- return MP_OKAY;
+ return res;
}
+int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)
+{
+ int i, len;
+
+ len = mp_unsigned_bin_size(a);
+
+ /* pad front w/ zeros to match length */
+ for (i = 0; i < c - len; i++)
+ b[i] = 0x00;
+ return mp_to_unsigned_bin(a, b + i);
+}
/* creates "a" then copies b into it */
int mp_init_copy (mp_int * a, mp_int * b)
{
int res;
- if ((res = mp_init (a)) != MP_OKAY) {
+ if ((res = mp_init_size (a, b->used)) != MP_OKAY) {
return res;
}
- return mp_copy (b, a);
+
+ if((res = mp_copy (b, a)) != MP_OKAY) {
+ mp_clear(a);
+ }
+
+ return res;
}
/* copy, b = a */
-int
-mp_copy (mp_int * a, mp_int * b)
+int mp_copy (mp_int * a, mp_int * b)
{
int res, n;
+ /* Safeguard against passing in a null pointer */
+ if (a == NULL || b == NULL)
+ return MP_VAL;
+
/* if dst == src do nothing */
if (a == b) {
return MP_OKAY;
}
/* grow dest */
- if (b->alloc < a->used) {
+ if (b->alloc < a->used || b->alloc == 0) {
if ((res = mp_grow (b, a->used)) != MP_OKAY) {
return res;
}
@@ -261,7 +380,7 @@ mp_copy (mp_int * a, mp_int * b)
/* zero b and copy the parameters over */
{
- register mp_digit *tmpa, *tmpb;
+ mp_digit *tmpa, *tmpb;
/* pointer aliases */
@@ -277,7 +396,7 @@ mp_copy (mp_int * a, mp_int * b)
}
/* clear high digits */
- for (; n < b->used; n++) {
+ for (; n < b->used && b->dp; n++) {
*tmpb++ = 0;
}
}
@@ -296,7 +415,7 @@ int mp_grow (mp_int * a, int size)
mp_digit *tmp;
/* if the alloc size is smaller alloc more ram */
- if (a->alloc < size) {
+ if (a->alloc < size || size == 0) {
/* ensure there are always at least MP_PREC digits extra on top */
size += (MP_PREC * 2) - (size % MP_PREC);
@@ -306,8 +425,8 @@ int mp_grow (mp_int * a, int size)
* in case the operation failed we don't want
* to overwrite the dp member of a.
*/
- tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, 0,
- DYNAMIC_TYPE_BIGINT);
+ tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size, NULL,
+ DYNAMIC_TYPE_BIGINT);
if (tmp == NULL) {
/* reallocation failed but "a" is still valid [can be freed] */
return MP_MEM;
@@ -327,25 +446,6 @@ int mp_grow (mp_int * a, int size)
}
-/* reverse an array, used for radix code */
-void
-bn_reverse (unsigned char *s, int len)
-{
- int ix, iy;
- unsigned char t;
-
- ix = 0;
- iy = len - 1;
- while (ix < iy) {
- t = s[ix];
- s[ix] = s[iy];
- s[iy] = t;
- ++ix;
- --iy;
- }
-}
-
-
/* shift right by a certain bit count (store quotient in c, optional
remainder in d) */
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
@@ -406,6 +506,9 @@ void mp_zero (mp_int * a)
int n;
mp_digit *tmp;
+ if (a == NULL)
+ return;
+
a->sign = MP_ZPOS;
a->used = 0;
@@ -419,12 +522,11 @@ void mp_zero (mp_int * a)
/* trim unused digits
*
* This is used to ensure that leading zero digits are
- * trimed and the leading "used" digit will be non-zero
+ * trimmed and the leading "used" digit will be non-zero
* Typically very fast. Also fixes the sign if there
* are no more leading digits
*/
-void
-mp_clamp (mp_int * a)
+void mp_clamp (mp_int * a)
{
/* decrease used while the most significant digit is
* zero.
@@ -443,8 +545,7 @@ mp_clamp (mp_int * a)
/* swap the elements of two integers, for cases where you can't simply swap the
* mp_int pointers around
*/
-void
-mp_exch (mp_int * a, mp_int * b)
+void mp_exch (mp_int * a, mp_int * b)
{
mp_int t;
@@ -457,10 +558,12 @@ mp_exch (mp_int * a, mp_int * b)
/* shift right a certain number of bits */
void mp_rshb (mp_int *c, int x)
{
- register mp_digit *tmpc, mask, shift;
+ mp_digit *tmpc, mask, shift;
mp_digit r, rr;
mp_digit D = x;
+ if (mp_iszero(c)) return;
+
/* mask */
mask = (((mp_digit)1) << D) - 1;
@@ -483,6 +586,7 @@ void mp_rshb (mp_int *c, int x)
/* set the carry to the carry bits of the current word found above */
r = rr;
}
+ mp_clamp(c);
}
@@ -503,7 +607,7 @@ void mp_rshd (mp_int * a, int b)
}
{
- register mp_digit *bottom, *top;
+ mp_digit *bottom, *top;
/* shift the digits down */
@@ -539,8 +643,7 @@ void mp_rshd (mp_int * a, int b)
/* calc a value mod 2**b */
-int
-mp_mod_2d (mp_int * a, int b, mp_int * c)
+int mp_mod_2d (mp_int * a, int b, mp_int * c)
{
int x, res;
@@ -637,8 +740,8 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c)
/* shift any bit count < DIGIT_BIT */
d = (mp_digit) (b % DIGIT_BIT);
if (d != 0) {
- register mp_digit *tmpc, shift, mask, r, rr;
- register int x;
+ mp_digit *tmpc, shift, mask, r, rr;
+ int x;
/* bitmask for carries */
mask = (((mp_digit)1) << d) - 1;
@@ -656,7 +759,7 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c)
rr = (*tmpc >> shift) & mask;
/* shift the current word and OR in the carry */
- *tmpc = ((*tmpc << d) | r) & MP_MASK;
+ *tmpc = (mp_digit)(((*tmpc << d) | r) & MP_MASK);
++tmpc;
/* set the carry to the carry bits of the current word */
@@ -691,7 +794,7 @@ int mp_lshd (mp_int * a, int b)
}
{
- register mp_digit *top, *bottom;
+ mp_digit *top, *bottom;
/* increment the used by the shift amount then copy upwards */
a->used += b;
@@ -703,7 +806,7 @@ int mp_lshd (mp_int * a, int b)
bottom = a->dp + a->used - 1 - b;
/* much like mp_rshd this is implemented using a sliding window
- * except the window goes the otherway around. Copying from
+ * except the window goes the other way around. Copying from
* the bottom to the top. see bn_mp_rshd.c for more info.
*/
for (x = a->used - 1; x >= b; x--) {
@@ -722,17 +825,33 @@ int mp_lshd (mp_int * a, int b)
/* this is a shell function that calls either the normal or Montgomery
* exptmod functions. Originally the call to the montgomery code was
- * embedded in the normal function but that wasted alot of stack space
+ * embedded in the normal function but that wasted a lot of stack space
* for nothing (since 99% of the time the Montgomery code would be called)
*/
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+#else
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+#endif
{
int dr;
/* modulus P must be positive */
- if (P->sign == MP_NEG) {
+ if (mp_iszero(P) || P->sign == MP_NEG) {
return MP_VAL;
}
+ if (mp_isone(P)) {
+ mp_set(Y, 0);
+ return MP_OKAY;
+ }
+ if (mp_iszero(X)) {
+ mp_set(Y, 1);
+ return MP_OKAY;
+ }
+ if (mp_iszero(G)) {
+ mp_set(Y, 0);
+ return MP_OKAY;
+ }
/* if exponent X is negative we have to recurse */
if (X->sign == MP_NEG) {
@@ -771,6 +890,12 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
#endif
}
+#ifdef BN_MP_EXPTMOD_BASE_2
+ if (G->used == 1 && G->dp[0] == 2) {
+ return mp_exptmod_base_2(X, P, Y);
+ }
+#endif
+
/* modified diminished radix reduction */
#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && \
defined(BN_S_MP_EXPTMOD_C)
@@ -787,6 +912,8 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
dr = 0;
#endif
+ (void)dr;
+
#ifdef BN_MP_REDUCE_IS_2K_C
/* if not, is it a unrestricted DR modulus? */
if (dr == 0) {
@@ -796,7 +923,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
/* if the modulus is odd or dr != 0 use the montgomery method */
#ifdef BN_MP_EXPTMOD_FAST_C
- if (mp_isodd (P) == 1 || dr != 0) {
+ if (mp_isodd (P) == MP_YES || dr != 0) {
return mp_exptmod_fast (G, X, P, Y, dr);
} else {
#endif
@@ -812,13 +939,17 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
#endif
}
+int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y)
+{
+ (void)digits;
+ return mp_exptmod(G, X, P, Y);
+}
/* b = |a|
*
* Simple function copies the input and fixes the sign to positive
*/
-int
-mp_abs (mp_int * a, mp_int * b)
+int mp_abs (mp_int * a, mp_int * b)
{
int res;
@@ -837,22 +968,28 @@ mp_abs (mp_int * a, mp_int * b)
/* hac 14.61, pp608 */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_mp_invmod(mp_int * a, mp_int * b, mp_int * c)
+#else
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+#endif
{
- /* b cannot be negative */
- if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ /* b cannot be negative or zero, and can not divide by 0 (1/a mod b) */
+ if (b->sign == MP_NEG || mp_iszero(b) == MP_YES || mp_iszero(a) == MP_YES) {
return MP_VAL;
}
#ifdef BN_FAST_MP_INVMOD_C
/* if the modulus is odd we can use a faster routine instead */
- if (mp_isodd (b) == 1) {
+ if ((mp_isodd(b) == MP_YES) && (mp_cmp_d(b, 1) != MP_EQ)) {
return fast_mp_invmod (a, b, c);
}
#endif
#ifdef BN_MP_INVMOD_SLOW_C
return mp_invmod_slow(a, b, c);
+#else
+ return MP_VAL;
#endif
}
@@ -869,7 +1006,7 @@ int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
int res, neg, loop_check = 0;
/* 2. [modified] b must be odd */
- if (mp_iseven (b) == 1) {
+ if (mp_iseven (b) == MP_YES) {
return MP_VAL;
}
@@ -895,17 +1032,19 @@ int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
- mp_set (&D, 1);
+ if ((res = mp_set (&D, 1)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
top:
/* 4. while u is even do */
- while (mp_iseven (&u) == 1) {
+ while (mp_iseven (&u) == MP_YES) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if B is odd then */
- if (mp_isodd (&B) == 1) {
+ if (mp_isodd (&B) == MP_YES) {
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
@@ -917,13 +1056,13 @@ top:
}
/* 5. while v is even do */
- while (mp_iseven (&v) == 1) {
+ while (mp_iseven (&v) == MP_YES) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if D is odd then */
- if (mp_isodd (&D) == 1) {
+ if (mp_isodd (&D) == MP_YES) {
/* D = (D-x)/2 */
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
@@ -957,8 +1096,8 @@ top:
}
/* if not zero goto step 4 */
- if (mp_iszero (&u) == 0) {
- if (++loop_check > 1024) {
+ if (mp_iszero (&u) == MP_NO) {
+ if (++loop_check > MAX_INVMOD_SZ) {
res = MP_VAL;
goto LBL_ERR;
}
@@ -980,6 +1119,12 @@ top:
goto LBL_ERR;
}
}
+ /* too big */
+ while (mp_cmp_mag(&D, b) != MP_LT) {
+ if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ }
mp_exch (&D, c);
c->sign = neg;
res = MP_OKAY;
@@ -1001,31 +1146,42 @@ int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
int res;
/* b cannot be negative */
- if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+ if (b->sign == MP_NEG || mp_iszero(b) == MP_YES) {
return MP_VAL;
}
/* init temps */
if ((res = mp_init_multi(&x, &y, &u, &v,
&A, &B)) != MP_OKAY) {
- return res;
+ return res;
}
/* init rest of tmps temps */
if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {
- return res;
+ mp_clear(&x);
+ mp_clear(&y);
+ mp_clear(&u);
+ mp_clear(&v);
+ mp_clear(&A);
+ mp_clear(&B);
+ return res;
}
/* x = a, y = b */
if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
- goto LBL_ERR;
+ goto LBL_ERR;
+ }
+ if (mp_isone(&x)) {
+ mp_set(c, 1);
+ res = MP_OKAY;
+ goto LBL_ERR;
}
if ((res = mp_copy (b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
/* 2. [modified] if x,y are both even then return an error! */
- if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+ if (mp_iseven (&x) == MP_YES && mp_iseven (&y) == MP_YES) {
res = MP_VAL;
goto LBL_ERR;
}
@@ -1037,24 +1193,28 @@ int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
- mp_set (&A, 1);
- mp_set (&D, 1);
+ if ((res = mp_set (&A, 1)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
+ if ((res = mp_set (&D, 1)) != MP_OKAY) {
+ goto LBL_ERR;
+ }
top:
/* 4. while u is even do */
- while (mp_iseven (&u) == 1) {
+ while (mp_iseven (&u) == MP_YES) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if A or B is odd then */
- if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+ if (mp_isodd (&A) == MP_YES || mp_isodd (&B) == MP_YES) {
/* A = (A+y)/2, B = (B-x)/2 */
if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
- goto LBL_ERR;
+ goto LBL_ERR;
}
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
- goto LBL_ERR;
+ goto LBL_ERR;
}
}
/* A = A/2, B = B/2 */
@@ -1067,19 +1227,19 @@ top:
}
/* 5. while v is even do */
- while (mp_iseven (&v) == 1) {
+ while (mp_iseven (&v) == MP_YES) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if C or D is odd then */
- if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+ if (mp_isodd (&C) == MP_YES || mp_isodd (&D) == MP_YES) {
/* C = (C+y)/2, D = (D-x)/2 */
if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
- goto LBL_ERR;
+ goto LBL_ERR;
}
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
- goto LBL_ERR;
+ goto LBL_ERR;
}
}
/* C = C/2, D = D/2 */
@@ -1121,7 +1281,7 @@ top:
}
/* if not zero goto step 4 */
- if (mp_iszero (&u) == 0)
+ if (mp_iszero (&u) == MP_NO)
goto top;
/* now a = C, b = D, gcd == g*v */
@@ -1161,7 +1321,7 @@ LBL_ERR:mp_clear(&x);
}
-/* compare maginitude of two ints (unsigned) */
+/* compare magnitude of two ints (unsigned) */
int mp_cmp_mag (mp_int * a, mp_int * b)
{
int n;
@@ -1197,8 +1357,7 @@ int mp_cmp_mag (mp_int * a, mp_int * b)
/* compare two ints (signed)*/
-int
-mp_cmp (mp_int * a, mp_int * b)
+int mp_cmp (mp_int * a, mp_int * b)
{
/* compare based on sign */
if (a->sign != b->sign) {
@@ -1222,8 +1381,12 @@ mp_cmp (mp_int * a, mp_int * b)
/* compare a digit */
int mp_cmp_d(mp_int * a, mp_digit b)
{
+ /* special case for zero*/
+ if (a->used == 0 && b == 0)
+ return MP_EQ;
+
/* compare based on sign */
- if (a->sign == MP_NEG) {
+ if ((b && a->used == 0) || a->sign == MP_NEG) {
return MP_LT;
}
@@ -1244,22 +1407,38 @@ int mp_cmp_d(mp_int * a, mp_digit b)
/* set to a digit */
-void mp_set (mp_int * a, mp_digit b)
+int mp_set (mp_int * a, mp_digit b)
{
+ int res;
mp_zero (a);
- a->dp[0] = b & MP_MASK;
- a->used = (a->dp[0] != 0) ? 1 : 0;
+ res = mp_grow (a, 1);
+ if (res == MP_OKAY) {
+ a->dp[0] = (mp_digit)(b & MP_MASK);
+ a->used = (a->dp[0] != 0) ? 1 : 0;
+ }
+ return res;
}
+/* check if a bit is set */
+int mp_is_bit_set (mp_int *a, mp_digit b)
+{
+ if ((mp_digit)a->used < b/DIGIT_BIT)
+ return 0;
+
+ return (int)((a->dp[b/DIGIT_BIT] >> b%DIGIT_BIT) & (mp_digit)1);
+}
/* c = a mod b, 0 <= c < b */
-int
-mp_mod (mp_int * a, mp_int * b, mp_int * c)
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_mp_mod(mp_int * a, mp_int * b, mp_int * c)
+#else
+int mp_mod (mp_int * a, mp_int * b, mp_int * c)
+#endif
{
mp_int t;
int res;
- if ((res = mp_init (&t)) != MP_OKAY) {
+ if ((res = mp_init_size (&t, b->used)) != MP_OKAY) {
return res;
}
@@ -1268,11 +1447,11 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c)
return res;
}
- if (t.sign != b->sign) {
- res = mp_add (b, &t, c);
- } else {
+ if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) {
res = MP_OKAY;
mp_exch (&t, c);
+ } else {
+ res = mp_add (b, &t, c);
}
mp_clear (&t);
@@ -1287,7 +1466,7 @@ int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
int res, n, n2;
/* is divisor zero ? */
- if (mp_iszero (b) == 1) {
+ if (mp_iszero (b) == MP_YES) {
return MP_VAL;
}
@@ -1309,8 +1488,9 @@ int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
return res;
}
-
- mp_set(&tq, 1);
+ if ((res = mp_set(&tq, 1)) != MP_OKAY) {
+ return res;
+ }
n = mp_count_bits(a) - mp_count_bits(b);
if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
((res = mp_abs(b, &tb)) != MP_OKAY) ||
@@ -1367,7 +1547,7 @@ int mp_div_2(mp_int * a, mp_int * b)
oldused = b->used;
b->used = a->used;
{
- register mp_digit r, rr, *tmpa, *tmpb;
+ mp_digit r, rr, *tmpa, *tmpb;
/* source alias */
tmpa = a->dp + b->used - 1;
@@ -1403,7 +1583,7 @@ int mp_div_2(mp_int * a, mp_int * b)
/* high level addition (handles signs) */
int mp_add (mp_int * a, mp_int * b, mp_int * c)
{
- int sa, sb, res;
+ int sa, sb, res;
/* get sign of both inputs */
sa = a->sign;
@@ -1433,39 +1613,38 @@ int mp_add (mp_int * a, mp_int * b, mp_int * c)
/* low level addition, based on HAC pp.594, Algorithm 14.7 */
-int
-s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+int s_mp_add (mp_int * a, mp_int * b, mp_int * c)
{
mp_int *x;
- int olduse, res, min, max;
+ int olduse, res, min_ab, max_ab;
/* find sizes, we let |a| <= |b| which means we have to sort
* them. "x" will point to the input with the most digits
*/
if (a->used > b->used) {
- min = b->used;
- max = a->used;
+ min_ab = b->used;
+ max_ab = a->used;
x = a;
} else {
- min = a->used;
- max = b->used;
+ min_ab = a->used;
+ max_ab = b->used;
x = b;
}
/* init result */
- if (c->alloc < max + 1) {
- if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+ if (c->alloc < max_ab + 1) {
+ if ((res = mp_grow (c, max_ab + 1)) != MP_OKAY) {
return res;
}
}
/* get old used digit count and set new one */
olduse = c->used;
- c->used = max + 1;
+ c->used = max_ab + 1;
{
- register mp_digit u, *tmpa, *tmpb, *tmpc;
- register int i;
+ mp_digit u, *tmpa, *tmpb, *tmpc;
+ int i;
/* alias for digit pointers */
@@ -1480,7 +1659,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
/* zero the carry */
u = 0;
- for (i = 0; i < min; i++) {
+ for (i = 0; i < min_ab; i++) {
/* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
*tmpc = *tmpa++ + *tmpb++ + u;
@@ -1494,8 +1673,8 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
/* now copy higher words if any, that is in A+B
* if A or B has more digits add those in
*/
- if (min != max) {
- for (; i < max; i++) {
+ if (min_ab != max_ab) {
+ for (; i < max_ab; i++) {
/* T[i] = X[i] + U */
*tmpc = x->dp[i] + u;
@@ -1510,7 +1689,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
/* add carry */
*tmpc++ = u;
- /* clear digits above oldused */
+ /* clear digits above olduse */
for (i = c->used; i < olduse; i++) {
*tmpc++ = 0;
}
@@ -1522,27 +1701,31 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
-int
-s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+int s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
{
- int olduse, res, min, max;
+ int olduse, res, min_b, max_a;
/* find sizes */
- min = b->used;
- max = a->used;
+ min_b = b->used;
+ max_a = a->used;
/* init result */
- if (c->alloc < max) {
- if ((res = mp_grow (c, max)) != MP_OKAY) {
+ if (c->alloc < max_a) {
+ if ((res = mp_grow (c, max_a)) != MP_OKAY) {
return res;
}
}
+
+ /* sanity check on destination */
+ if (c->dp == NULL)
+ return MP_VAL;
+
olduse = c->used;
- c->used = max;
+ c->used = max_a;
{
- register mp_digit u, *tmpa, *tmpb, *tmpc;
- register int i;
+ mp_digit u, *tmpa, *tmpb, *tmpc;
+ int i;
/* alias for digit pointers */
tmpa = a->dp;
@@ -1551,7 +1734,7 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
/* set carry to zero */
u = 0;
- for (i = 0; i < min; i++) {
+ for (i = 0; i < min_b; i++) {
/* T[i] = A[i] - B[i] - U */
*tmpc = *tmpa++ - *tmpb++ - u;
@@ -1567,7 +1750,7 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
}
/* now copy higher words if any, e.g. if A has more digits than B */
- for (; i < max; i++) {
+ for (; i < max_a; i++) {
/* T[i] = A[i] - U */
*tmpc = *tmpa++ - u;
@@ -1590,8 +1773,7 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
/* high level subtraction (handles signs) */
-int
-mp_sub (mp_int * a, mp_int * b, mp_int * c)
+int mp_sub (mp_int * a, mp_int * b, mp_int * c)
{
int sa, sb, res;
@@ -1725,7 +1907,7 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
mp_digit buf, mp;
int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
#ifdef WOLFSSL_SMALL_STACK
- mp_int* M = NULL;
+ mp_int* M;
#else
mp_int M[TAB_SIZE];
#endif
@@ -1733,11 +1915,11 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
* one of many reduction algorithms without modding the guts of
* the code with if statements everywhere.
*/
- int (*redux)(mp_int*,mp_int*,mp_digit);
+ int (*redux)(mp_int*,mp_int*,mp_digit) = NULL;
#ifdef WOLFSSL_SMALL_STACK
M = (mp_int*) XMALLOC(sizeof(mp_int) * TAB_SIZE, NULL,
- DYNAMIC_TYPE_TMP_BUFFER);
+ DYNAMIC_TYPE_BIGINT);
if (M == NULL)
return MP_MEM;
#endif
@@ -1768,9 +1950,9 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
/* init M array */
/* init first cell */
- if ((err = mp_init(&M[1])) != MP_OKAY) {
+ if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
#ifdef WOLFSSL_SMALL_STACK
- XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
#endif
return err;
@@ -1778,14 +1960,14 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
/* now init the second half of the array */
for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- if ((err = mp_init(&M[x])) != MP_OKAY) {
+ if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
for (y = 1<<(winsize-1); y < x; y++) {
mp_clear (&M[y]);
}
mp_clear(&M[1]);
#ifdef WOLFSSL_SMALL_STACK
- XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
#endif
return err;
@@ -1807,7 +1989,7 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
/* automatically pick the comba one if available (saves quite a few
calls/ifs) */
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
- if (((P->used * 2 + 1) < MP_WARRAY) &&
+ if (((P->used * 2 + 1) < (int)MP_WARRAY) &&
P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
redux = fast_mp_montgomery_reduce;
} else
@@ -1816,9 +1998,6 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
#ifdef BN_MP_MONTGOMERY_REDUCE_C
/* use slower baseline Montgomery method */
redux = mp_montgomery_reduce;
-#else
- err = MP_VAL;
- goto LBL_M;
#endif
}
} else if (redmode == 1) {
@@ -1826,9 +2005,6 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
/* setup DR reduction for moduli of the form B**k - b */
mp_dr_setup(P, &mp);
redux = mp_dr_reduce;
-#else
- err = MP_VAL;
- goto LBL_M;
#endif
} else {
#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
@@ -1837,14 +2013,16 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
goto LBL_M;
}
redux = mp_reduce_2k;
-#else
+#endif
+ }
+
+ if (redux == NULL) {
err = MP_VAL;
goto LBL_M;
-#endif
}
/* setup result */
- if ((err = mp_init (&res)) != MP_OKAY) {
+ if ((err = mp_init_size (&res, P->alloc)) != MP_OKAY) {
goto LBL_M;
}
@@ -1861,17 +2039,19 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
goto LBL_RES;
}
-#else
- err = MP_VAL;
- goto LBL_RES;
-#endif
/* now set M[1] to G * R mod m */
if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
+#else
+ err = MP_VAL;
+ goto LBL_RES;
+#endif
} else {
- mp_set(&res, 1);
+ if ((err = mp_set(&res, 1)) != MP_OKAY) {
+ goto LBL_RES;
+ }
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
goto LBL_RES;
}
@@ -1883,7 +2063,8 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
}
for (x = 0; x < (winsize - 1); x++) {
- if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
+ if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))],
+ &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
goto LBL_RES;
}
if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) {
@@ -2024,16 +2205,179 @@ LBL_M:
}
#ifdef WOLFSSL_SMALL_STACK
- XFREE(M, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
+#endif
+
+ return err;
+}
+
+#ifdef BN_MP_EXPTMOD_BASE_2
+#if DIGIT_BIT < 16
+ #define WINSIZE 3
+#elif DIGIT_BIT < 32
+ #define WINSIZE 4
+#elif DIGIT_BIT < 64
+ #define WINSIZE 5
+#elif DIGIT_BIT < 128
+ #define WINSIZE 6
+#endif
+int mp_exptmod_base_2(mp_int * X, mp_int * P, mp_int * Y)
+{
+ mp_digit buf, mp;
+ int err = MP_OKAY, bitbuf, bitcpy, bitcnt, digidx, x, y;
+#ifdef WOLFSSL_SMALL_STACK
+ mp_int *res = NULL;
+#else
+ mp_int res[1];
+#endif
+ int (*redux)(mp_int*,mp_int*,mp_digit) = NULL;
+
+ /* automatically pick the comba one if available (saves quite a few
+ calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+ if (((P->used * 2 + 1) < (int)MP_WARRAY) &&
+ P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ redux = fast_mp_montgomery_reduce;
+ } else
#endif
+ {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+ /* use slower baseline Montgomery method */
+ redux = mp_montgomery_reduce;
+#else
+ return MP_VAL;
+#endif
+ }
+
+#ifdef WOLFSSL_SMALL_STACK
+ res = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (res == NULL) {
+ return MP_MEM;
+ }
+#endif
+
+ /* now setup montgomery */
+ if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ /* setup result */
+ if ((err = mp_init(res)) != MP_OKAY) {
+ goto LBL_M;
+ }
+
+ /* now we need R mod m */
+ if ((err = mp_montgomery_calc_normalization(res, P)) != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* Get the top bits left over after taking WINSIZE bits starting at the
+ * least-significant.
+ */
+ digidx = X->used - 1;
+ bitcpy = (X->used * DIGIT_BIT) % WINSIZE;
+ if (bitcpy > 0) {
+ bitcnt = (int)DIGIT_BIT - bitcpy;
+ buf = X->dp[digidx--];
+ bitbuf = (int)(buf >> bitcnt);
+ /* Multiply montgomery representation of 1 by 2 ^ top */
+ err = mp_mul_2d(res, bitbuf, res);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+ err = mp_mod(res, P, res);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+ /* Move out bits used */
+ buf <<= bitcpy;
+ bitcnt++;
+ }
+ else {
+ bitcnt = 1;
+ buf = 0;
+ }
+
+ /* empty window and reset */
+ bitbuf = 0;
+ bitcpy = 0;
+
+ for (;;) {
+ /* grab next digit as required */
+ if (--bitcnt == 0) {
+ /* if digidx == -1 we are out of digits so break */
+ if (digidx == -1) {
+ break;
+ }
+ /* read next digit and reset bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int)DIGIT_BIT;
+ }
+
+ /* grab the next msb from the exponent */
+ y = (int)(buf >> (DIGIT_BIT - 1)) & 1;
+ buf <<= (mp_digit)1;
+ /* add bit to the window */
+ bitbuf |= (y << (WINSIZE - ++bitcpy));
+
+ if (bitcpy == WINSIZE) {
+ /* ok window is filled so square as required and multiply */
+ /* square first */
+ for (x = 0; x < WINSIZE; x++) {
+ err = mp_sqr(res, res);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+ err = (*redux)(res, P, mp);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+ }
+
+ /* then multiply by 2^bitbuf */
+ err = mp_mul_2d(res, bitbuf, res);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+ err = mp_mod(res, P, res);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ }
+ }
+
+ /* fixup result if Montgomery reduction is used
+ * recall that any value in a Montgomery system is
+ * actually multiplied by R mod n. So we have
+ * to reduce one more time to cancel out the factor
+ * of R.
+ */
+ err = (*redux)(res, P, mp);
+ if (err != MP_OKAY) {
+ goto LBL_RES;
+ }
+
+ /* swap res with Y */
+ mp_copy(res, Y);
+LBL_RES:mp_clear (res);
+LBL_M:
+#ifdef WOLFSSL_SMALL_STACK
+ XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+#endif
return err;
}
+#undef WINSIZE
+#endif /* BN_MP_EXPTMOD_BASE_2 */
+
/* setups the montgomery reduction stuff */
-int
-mp_montgomery_setup (mp_int * n, mp_digit * rho)
+int mp_montgomery_setup (mp_int * n, mp_digit * rho)
{
mp_digit x, b;
@@ -2065,7 +2409,7 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho)
/* rho = -1/m mod b */
/* TAO, switched mp_word casts to mp_digit to shut up compiler */
- *rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK;
+ *rho = (mp_digit)((((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK);
return MP_OKAY;
}
@@ -2099,7 +2443,7 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
}
#ifdef WOLFSSL_SMALL_STACK
- W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+ W = (mp_word*)XMALLOC(sizeof(mp_word) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
if (W == NULL)
return MP_MEM;
#endif
@@ -2108,8 +2452,8 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* an array of double precision words W[...]
*/
{
- register mp_word *_W;
- register mp_digit *tmpx;
+ mp_word *_W;
+ mp_digit *tmpx;
/* alias for the W[] array */
_W = W;
@@ -2138,13 +2482,13 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* by casting the value down to a mp_digit. Note this requires
* that W[ix-1] have the carry cleared (see after the inner loop)
*/
- register mp_digit mu;
+ mp_digit mu;
mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
/* a = a + mu * m * b**i
*
* This is computed in place and on the fly. The multiplication
- * by b**i is handled by offseting which columns the results
+ * by b**i is handled by offsetting which columns the results
* are added to.
*
* Note the comba method normally doesn't handle carries in the
@@ -2156,9 +2500,9 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* first m->used words of W[] have the carries fixed
*/
{
- register int iy;
- register mp_digit *tmpn;
- register mp_word *_W;
+ int iy;
+ mp_digit *tmpn;
+ mp_word *_W;
/* alias for the digits of the modulus */
tmpn = n->dp;
@@ -2181,8 +2525,8 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* significant digits we zeroed].
*/
{
- register mp_digit *tmpx;
- register mp_word *_W, *_W1;
+ mp_digit *tmpx;
+ mp_word *_W, *_W1;
/* nox fix rest of carries */
@@ -2213,7 +2557,7 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
*tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
}
- /* zero oldused digits, if the input a was larger than
+ /* zero olduse digits, if the input a was larger than
* m->used+1 we'll have to clear the digits
*/
for (; ix < olduse; ix++) {
@@ -2226,7 +2570,7 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
mp_clamp (x);
#ifdef WOLFSSL_SMALL_STACK
- XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+ XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
#endif
/* if A >= m then A = A - m */
@@ -2238,8 +2582,7 @@ int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
/* computes xR**-1 == x (mod N) via Montgomery Reduction */
-int
-mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
{
int ix, res, digs;
mp_digit mu;
@@ -2251,7 +2594,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* are fixed up in the inner loop.
*/
digs = n->used * 2 + 1;
- if ((digs < MP_WARRAY) &&
+ if ((digs < (int)MP_WARRAY) &&
n->used <
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_mp_montgomery_reduce (x, n, rho);
@@ -2278,9 +2621,9 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
/* a = a + mu * m * b**i */
{
- register int iy;
- register mp_digit *tmpn, *tmpx, u;
- register mp_word r;
+ int iy;
+ mp_digit *tmpn, *tmpx, u;
+ mp_word r;
/* alias for digits of the modulus */
tmpn = n->dp;
@@ -2360,8 +2703,7 @@ void mp_dr_setup(mp_int *a, mp_digit *d)
*
* Input x must be in the range 0 <= x <= (n-1)**2
*/
-int
-mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
{
int err, i, m;
mp_word r;
@@ -2413,7 +2755,9 @@ top:
* Each successive "recursion" makes the input smaller and smaller.
*/
if (mp_cmp_mag (x, n) != MP_LT) {
- s_mp_sub(x, n, x);
+ if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
+ return err;
+ }
goto top;
}
return MP_OKAY;
@@ -2450,7 +2794,9 @@ top:
}
if (mp_cmp_mag(a, n) != MP_LT) {
- s_mp_sub(a, n, a);
+ if ((res = s_mp_sub(a, n, a)) != MP_OKAY) {
+ goto ERR;
+ }
goto top;
}
@@ -2487,37 +2833,49 @@ int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
}
-/* computes a = 2**b
- *
- * Simple algorithm which zeroes the int, grows it then just sets one bit
- * as required.
- */
-int
-mp_2expt (mp_int * a, int b)
+/* set the b bit of a */
+int mp_set_bit (mp_int * a, int b)
{
- int res;
+ int i = b / DIGIT_BIT, res;
- /* zero a as per default */
- mp_zero (a);
+ /*
+ * Require:
+ * bit index b >= 0
+ * a->alloc == a->used == 0 if a->dp == NULL
+ */
+ if (b < 0 || (a->dp == NULL && (a->alloc != 0 || a->used != 0)))
+ return MP_VAL;
- /* grow a to accomodate the single bit */
- if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
- return res;
- }
+ if (a->dp == NULL || a->used < (int)(i + 1)) {
+ /* grow a to accommodate the single bit */
+ if ((res = mp_grow (a, i + 1)) != MP_OKAY) {
+ return res;
+ }
- /* set the used count of where the bit will go */
- a->used = b / DIGIT_BIT + 1;
+ /* set the used count of where the bit will go */
+ a->used = (int)(i + 1);
+ }
- /* put the single bit in its place */
- a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+ /* put the single bit in its place */
+ a->dp[i] |= ((mp_digit)1) << (b % DIGIT_BIT);
- return MP_OKAY;
+ return MP_OKAY;
}
+/* computes a = 2**b
+ *
+ * Simple algorithm which zeros the int, set the required bit
+ */
+int mp_2expt (mp_int * a, int b)
+{
+ /* zero a as per default */
+ mp_zero (a);
+
+ return mp_set_bit(a, b);
+}
/* multiply by a digit */
-int
-mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+int mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
{
mp_digit u, *tmpa, *tmpc;
mp_word r;
@@ -2575,35 +2933,78 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
/* d = a * b (mod c) */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
+#else
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+#endif
{
int res;
mp_int t;
- if ((res = mp_init (&t)) != MP_OKAY) {
+ if ((res = mp_init_size (&t, c->used)) != MP_OKAY) {
return res;
}
- if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
- mp_clear (&t);
+ res = mp_mul (a, b, &t);
+ if (res == MP_OKAY) {
+ res = mp_mod (&t, c, d);
+ }
+
+ mp_clear (&t);
+ return res;
+}
+
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
- res = mp_mod (&t, c, d);
+
+ res = mp_sub (a, b, &t);
+ if (res == MP_OKAY) {
+ res = mp_mod (&t, c, d);
+ }
+
mp_clear (&t);
+
return res;
}
+/* d = a + b (mod c) */
+int mp_addmod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
+{
+ int res;
+ mp_int t;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ res = mp_add (a, b, &t);
+ if (res == MP_OKAY) {
+ res = mp_mod (&t, c, d);
+ }
+
+ mp_clear (&t);
+
+ return res;
+}
/* computes b = a*a */
-int
-mp_sqr (mp_int * a, mp_int * b)
+int mp_sqr (mp_int * a, mp_int * b)
{
int res;
{
#ifdef BN_FAST_S_MP_SQR_C
/* can we use the fast comba multiplier? */
- if ((a->used * 2 + 1) < MP_WARRAY &&
+ if ((a->used * 2 + 1) < (int)MP_WARRAY &&
a->used <
(1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
res = fast_s_mp_sqr (a, b);
@@ -2621,12 +3022,17 @@ mp_sqr (mp_int * a, mp_int * b)
/* high level multiplication (handles sign) */
+#if defined(FREESCALE_LTC_TFM)
+int wolfcrypt_mp_mul(mp_int *a, mp_int *b, mp_int *c)
+#else
int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+#endif
{
int res, neg;
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
{
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* can we use the fast multiplier?
*
* The fast multiplier can be used if the output will
@@ -2635,8 +3041,7 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
*/
int digs = a->used + b->used + 1;
-#ifdef BN_FAST_S_MP_MUL_DIGS_C
- if ((digs < MP_WARRAY) &&
+ if ((digs < (int)MP_WARRAY) &&
MIN(a->used, b->used) <=
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
res = fast_s_mp_mul_digs (a, b, c, digs);
@@ -2659,7 +3064,7 @@ int mp_mul_2(mp_int * a, mp_int * b)
{
int x, res, oldused;
- /* grow to accomodate result */
+ /* grow to accommodate result */
if (b->alloc < a->used + 1) {
if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
return res;
@@ -2670,7 +3075,7 @@ int mp_mul_2(mp_int * a, mp_int * b)
b->used = a->used;
{
- register mp_digit r, rr, *tmpa, *tmpb;
+ mp_digit r, rr, *tmpa, *tmpb;
/* alias for source */
tmpa = a->dp;
@@ -2688,7 +3093,7 @@ int mp_mul_2(mp_int * a, mp_int * b)
rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
/* now shift up this digit, add in the carry [from the previous] */
- *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+ *tmpb++ = (mp_digit)(((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK);
/* copy the carry that would be from the source
* digit into the next iteration
@@ -2717,8 +3122,7 @@ int mp_mul_2(mp_int * a, mp_int * b)
/* divide by three (based on routine from MPI and the GMP manual) */
-int
-mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
{
mp_int q;
mp_word w, t;
@@ -2783,7 +3187,7 @@ int mp_init_size (mp_int * a, int size)
size += (MP_PREC * 2) - (size % MP_PREC);
/* alloc mem */
- a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, 0,
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size, NULL,
DYNAMIC_TYPE_BIGINT);
if (a->dp == NULL) {
return MP_MEM;
@@ -2793,6 +3197,9 @@ int mp_init_size (mp_int * a, int size)
a->used = 0;
a->alloc = size;
a->sign = MP_ZPOS;
+#ifdef HAVE_WOLF_BIGINT
+ wc_bigint_init(&a->raw);
+#endif
/* zero the digits */
for (x = 0; x < size; x++) {
@@ -2832,11 +3239,11 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
}
}
- if (pa > MP_WARRAY)
+ if (pa > (int)MP_WARRAY)
return MP_RANGE; /* TAO range check */
#ifdef WOLFSSL_SMALL_STACK
- W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+ W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
if (W == NULL)
return MP_MEM;
#endif
@@ -2859,7 +3266,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
tmpx = a->dp + tx;
tmpy = a->dp + ty;
- /* this is the number of times the loop will iterrate, essentially
+ /* this is the number of times the loop will iterate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
@@ -2898,7 +3305,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
mp_digit *tmpb;
tmpb = b->dp;
for (ix = 0; ix < pa; ix++) {
- *tmpb++ = W[ix] & MP_MASK;
+ *tmpb++ = (mp_digit)(W[ix] & MP_MASK);
}
/* clear unused digits [that existed in the old copy of c] */
@@ -2909,7 +3316,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
mp_clamp (b);
#ifdef WOLFSSL_SMALL_STACK
- XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+ XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
#endif
return MP_OKAY;
@@ -2940,7 +3347,7 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
#else
mp_digit W[MP_WARRAY];
#endif
- register mp_word _W;
+ mp_word _W;
/* grow the destination as required */
if (c->alloc < digs) {
@@ -2951,11 +3358,11 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
/* number of output digits to produce */
pa = MIN(digs, a->used + b->used);
- if (pa > MP_WARRAY)
+ if (pa > (int)MP_WARRAY)
return MP_RANGE; /* TAO range check */
#ifdef WOLFSSL_SMALL_STACK
- W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+ W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
if (W == NULL)
return MP_MEM;
#endif
@@ -2975,7 +3382,7 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
tmpx = a->dp + tx;
tmpy = b->dp + ty;
- /* this is the number of times the loop will iterrate, essentially
+ /* this is the number of times the loop will iterate, essentially
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
@@ -2987,7 +3394,7 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
}
/* store term */
- W[ix] = ((mp_digit)_W) & MP_MASK;
+ W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
@@ -2998,9 +3405,9 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
c->used = pa;
{
- register mp_digit *tmpc;
+ mp_digit *tmpc;
tmpc = c->dp;
- for (ix = 0; ix < pa+1; ix++) {
+ for (ix = 0; ix < pa; ix++) { /* JRB, +1 could read uninitialized data */
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
@@ -3013,7 +3420,7 @@ int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
mp_clamp (c);
#ifdef WOLFSSL_SMALL_STACK
- XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+ XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
#endif
return MP_OKAY;
@@ -3084,7 +3491,7 @@ int s_mp_sqr (mp_int * a, mp_int * b)
}
-/* multiplies |a| * |b| and only computes upto digs digits of result
+/* multiplies |a| * |b| and only computes up to digs digits of result
* HAC pp. 595, Algorithm 14.12 Modified so you can control how
* many digits of output are created.
*/
@@ -3097,7 +3504,7 @@ int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
mp_digit tmpx, *tmpt, *tmpy;
/* can we use the fast multiplier? */
- if (((digs) < MP_WARRAY) &&
+ if ((digs < (int)MP_WARRAY) &&
MIN (a->used, b->used) <
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_s_mp_mul_digs (a, b, c, digs);
@@ -3157,8 +3564,8 @@ int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
/*
* shifts with subtractions when the result is greater than b.
*
- * The method is slightly modified to shift B unconditionally upto just under
- * the leading bit of b. This saves alot of multiple precision shifting.
+ * The method is slightly modified to shift B unconditionally up to just under
+ * the leading bit of b. This saves a lot of multiple precision shifting.
*/
int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
{
@@ -3168,15 +3575,17 @@ int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
bits = mp_count_bits (b) % DIGIT_BIT;
if (b->used > 1) {
- if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
+ if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1))
+ != MP_OKAY) {
return res;
}
} else {
- mp_set(a, 1);
+ if ((res = mp_set(a, 1)) != MP_OKAY) {
+ return res;
+ }
bits = 1;
}
-
/* now compute C = A * B mod b */
for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
@@ -3312,7 +3721,9 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
if ((err = mp_init (&res)) != MP_OKAY) {
goto LBL_MU;
}
- mp_set (&res, 1);
+ if ((err = mp_set (&res, 1)) != MP_OKAY) {
+ goto LBL_MU;
+ }
/* set initial mode and bit cnt */
mode = 0;
@@ -3427,7 +3838,7 @@ LBL_M:
/* pre-calculate the value required for Barrett reduction
- * For a given modulus "b" it calulates the value required in "a"
+ * For a given modulus "b" it calculates the value required in "a"
*/
int mp_reduce_setup (mp_int * a, mp_int * b)
{
@@ -3499,7 +3910,8 @@ int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
/* If x < 0, add b**(k+1) to it */
if (mp_cmp_d (x, 0) == MP_LT) {
- mp_set (&q, 1);
+ if ((res = mp_set (&q, 1)) != MP_OKAY)
+ goto CLEANUP;
if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
goto CLEANUP;
if ((res = mp_add (x, &q, x)) != MP_OKAY)
@@ -3551,7 +3963,9 @@ top:
}
if (mp_cmp_mag(a, n) != MP_LT) {
- s_mp_sub(a, n, a);
+ if ((res = s_mp_sub(a, n, a)) != MP_OKAY) {
+ goto ERR;
+ }
goto top;
}
@@ -3588,8 +4002,7 @@ ERR:
/* multiplies |a| * |b| and does not compute the lower digs digits
* [meant to get the higher part of the product]
*/
-int
-s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
{
mp_int t;
int res, pa, pb, ix, iy;
@@ -3599,8 +4012,9 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
/* can we use the fast multiplier? */
#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
- if (((a->used + b->used + 1) < MP_WARRAY)
- && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ if (((a->used + b->used + 1) < (int)MP_WARRAY)
+ && MIN (a->used, b->used) <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
return fast_s_mp_mul_high_digs (a, b, c, digs);
}
#endif
@@ -3612,7 +4026,7 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
pa = a->used;
pb = b->used;
- for (ix = 0; ix < pa; ix++) {
+ for (ix = 0; ix < pa && a->dp; ix++) {
/* clear the carry */
u = 0;
@@ -3665,6 +4079,10 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
#endif
mp_word _W;
+ if (a->dp == NULL) { /* JRB, avoid reading uninitialized values */
+ return MP_VAL;
+ }
+
/* grow the destination as required */
pa = a->used + b->used;
if (c->alloc < pa) {
@@ -3673,11 +4091,11 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
}
}
- if (pa > MP_WARRAY)
+ if (pa > (int)MP_WARRAY)
return MP_RANGE; /* TAO range check */
#ifdef WOLFSSL_SMALL_STACK
- W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, 0, DYNAMIC_TYPE_BIGINT);
+ W = (mp_digit*)XMALLOC(sizeof(mp_digit) * MP_WARRAY, NULL, DYNAMIC_TYPE_BIGINT);
if (W == NULL)
return MP_MEM;
#endif
@@ -3685,7 +4103,7 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
/* number of output digits to produce */
pa = a->used + b->used;
_W = 0;
- for (ix = digs; ix < pa; ix++) {
+ for (ix = digs; ix < pa; ix++) { /* JRB, have a->dp check at top of function*/
int tx, ty, iy;
mp_digit *tmpx, *tmpy;
@@ -3697,7 +4115,7 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
tmpx = a->dp + tx;
tmpy = b->dp + ty;
- /* this is the number of times the loop will iterrate, essentially its
+ /* this is the number of times the loop will iterate, essentially its
while (tx++ < a->used && ty-- >= 0) { ... }
*/
iy = MIN(a->used-tx, ty+1);
@@ -3708,7 +4126,7 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
}
/* store term */
- W[ix] = ((mp_digit)_W) & MP_MASK;
+ W[ix] = (mp_digit)(((mp_digit)_W) & MP_MASK);
/* make next carry */
_W = _W >> ((mp_word)DIGIT_BIT);
@@ -3719,10 +4137,10 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
c->used = pa;
{
- register mp_digit *tmpc;
+ mp_digit *tmpc;
tmpc = c->dp + digs;
- for (ix = digs; ix <= pa; ix++) {
+ for (ix = digs; ix < pa; ix++) { /* TAO, <= could potentially overwrite */
/* now extract the previous digit [below the carry] */
*tmpc++ = W[ix];
}
@@ -3735,32 +4153,40 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
mp_clamp (c);
#ifdef WOLFSSL_SMALL_STACK
- XFREE(W, 0, DYNAMIC_TYPE_BIGINT);
+ XFREE(W, NULL, DYNAMIC_TYPE_BIGINT);
#endif
return MP_OKAY;
}
-/* set a 32-bit const */
+#ifndef MP_SET_CHUNK_BITS
+ #define MP_SET_CHUNK_BITS 4
+#endif
int mp_set_int (mp_int * a, unsigned long b)
{
- int x, res;
+ int x, res;
+
+ /* use direct mp_set if b is less than mp_digit max */
+ if (b < MP_DIGIT_MAX) {
+ return mp_set (a, (mp_digit)b);
+ }
mp_zero (a);
- /* set four bits at a time */
- for (x = 0; x < 8; x++) {
- /* shift the number up four bits */
- if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+ /* set chunk bits at a time */
+ for (x = 0; x < (int)(sizeof(b) * 8) / MP_SET_CHUNK_BITS; x++) {
+ /* shift the number up chunk bits */
+ if ((res = mp_mul_2d (a, MP_SET_CHUNK_BITS, a)) != MP_OKAY) {
return res;
}
- /* OR in the top four bits of the source */
- a->dp[0] |= (b >> 28) & 15;
+ /* OR in the top bits of the source */
+ a->dp[0] |= (b >> ((sizeof(b) * 8) - MP_SET_CHUNK_BITS)) &
+ ((1 << MP_SET_CHUNK_BITS) - 1);
- /* shift the source up to the next four bits */
- b <<= 4;
+ /* shift the source up to the next chunk bits */
+ b <<= MP_SET_CHUNK_BITS;
/* ensure that digits are not clamped off */
a->used += 1;
@@ -3770,7 +4196,8 @@ int mp_set_int (mp_int * a, unsigned long b)
}
-#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC)
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) || !defined(NO_RSA) || \
+ !defined(NO_DSA) | !defined(NO_DH)
/* c = a * a (mod b) */
int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
@@ -3794,7 +4221,10 @@ int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
#endif
-#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN)
+#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(WOLFSSL_SNIFFER) || \
+ defined(WOLFSSL_HAVE_WOLFSCEP) || defined(WOLFSSL_KEY_GEN) || \
+ defined(OPENSSL_EXTRA) || defined(WC_RSA_BLINDING) || \
+ (!defined(NO_RSA) && !defined(NO_RSA_BOUNDS_CHECK))
/* single digit addition */
int mp_add_d (mp_int* a, mp_digit b, mp_int* c)
@@ -3854,7 +4284,7 @@ int mp_add_d (mp_int* a, mp_digit b, mp_int* c)
*tmpc++ &= MP_MASK;
}
/* set final carry */
- if (mu != 0 && ix < c->alloc) {
+ if (ix < c->alloc) {
ix++;
*tmpc++ = mu;
}
@@ -3961,7 +4391,9 @@ int mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
#endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */
-#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
+#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(HAVE_ECC) || \
+ defined(DEBUG_WOLFSSL) || !defined(NO_RSA) || !defined(NO_DSA) || \
+ !defined(NO_DH)
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
@@ -3971,16 +4403,17 @@ static const int lnz[16] = {
int mp_cnt_lsb(mp_int *a)
{
int x;
- mp_digit q, qq;
+ mp_digit q = 0, qq;
/* easy out */
- if (mp_iszero(a) == 1) {
+ if (mp_iszero(a) == MP_YES) {
return 0;
}
/* scan lower digits until non-zero */
- for (x = 0; x < a->used && a->dp[x] == 0; x++);
- q = a->dp[x];
+ for (x = 0; x < a->used && a->dp[x] == 0; x++) {}
+ if (a->dp)
+ q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
@@ -4021,7 +4454,7 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
mp_int q;
mp_word w;
mp_digit t;
- int res, ix;
+ int res = MP_OKAY, ix;
/* cannot divide by zero */
if (b == 0) {
@@ -4029,7 +4462,7 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
}
/* quick outs */
- if (b == 1 || mp_iszero(a) == 1) {
+ if (b == 1 || mp_iszero(a) == MP_YES) {
if (d != NULL) {
*d = 0;
}
@@ -4058,12 +4491,21 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
#endif
/* no easy answer [c'est la vie]. Just division */
- if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
- return res;
+ if (c != NULL) {
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ }
+ else {
+ if ((res = mp_init(&q)) != MP_OKAY) {
+ return res;
+ }
}
- q.used = a->used;
- q.sign = a->sign;
+
w = 0;
for (ix = a->used - 1; ix >= 0; ix--) {
w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
@@ -4074,7 +4516,8 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
} else {
t = 0;
}
- q.dp[ix] = (mp_digit)t;
+ if (c != NULL)
+ q.dp[ix] = (mp_digit)t;
}
if (d != NULL) {
@@ -4096,11 +4539,11 @@ int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
return mp_div_d(a, b, NULL, c);
}
-#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
+#endif /* WOLFSSL_KEY_GEN || HAVE_COMP_KEY || HAVE_ECC || DEBUG_WOLFSSL */
-#ifdef WOLFSSL_KEY_GEN
+#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA)
-const mp_digit ltm_prime_tab[] = {
+const mp_digit ltm_prime_tab[PRIME_SIZE] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
@@ -4189,9 +4632,30 @@ static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
if ((err = mp_init (&y)) != MP_OKAY) {
goto LBL_R;
}
- if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
- goto LBL_Y;
- }
+#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
+#ifndef WOLFSSL_SP_NO_2048
+ if (mp_count_bits(a) == 1024)
+ err = sp_ModExp_1024(b, &r, a, &y);
+ else if (mp_count_bits(a) == 2048)
+ err = sp_ModExp_2048(b, &r, a, &y);
+ else
+#endif
+#ifndef WOLFSSL_SP_NO_3072
+ if (mp_count_bits(a) == 1536)
+ err = sp_ModExp_1536(b, &r, a, &y);
+ else if (mp_count_bits(a) == 3072)
+ err = sp_ModExp_3072(b, &r, a, &y);
+ else
+#endif
+#ifdef WOLFSSL_SP_4096
+ if (mp_count_bits(a) == 4096)
+ err = sp_ModExp_4096(b, &r, a, &y);
+ else
+#endif
+#endif
+ err = mp_exptmod (b, &r, a, &y);
+ if (err != MP_OKAY)
+ goto LBL_Y;
/* if y != 1 and y != n1 do */
if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
@@ -4254,7 +4718,6 @@ static int mp_prime_is_divisible (mp_int * a, int *result)
return MP_OKAY;
}
-
/*
* Sets result to 1 if probably prime, 0 otherwise
*/
@@ -4271,10 +4734,15 @@ int mp_prime_is_prime (mp_int * a, int t, int *result)
return MP_VAL;
}
+ if (mp_isone(a)) {
+ *result = MP_NO;
+ return MP_OKAY;
+ }
+
/* is the input equal to one of the primes in the table? */
for (ix = 0; ix < PRIME_SIZE; ix++) {
if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
- *result = 1;
+ *result = MP_YES;
return MP_OKAY;
}
}
@@ -4296,7 +4764,9 @@ int mp_prime_is_prime (mp_int * a, int t, int *result)
for (ix = 0; ix < t; ix++) {
/* set the prime */
- mp_set (&b, ltm_prime_tab[ix]);
+ if ((err = mp_set (&b, ltm_prime_tab[ix])) != MP_OKAY) {
+ goto LBL_B;
+ }
if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
goto LBL_B;
@@ -4314,6 +4784,177 @@ LBL_B:mp_clear (&b);
}
+/*
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG *rng)
+{
+ mp_int b, c;
+ int ix, err, res;
+ byte* base = NULL;
+ word32 baseSz = 0;
+
+ /* default to no */
+ *result = MP_NO;
+
+ /* valid value of t? */
+ if (t <= 0 || t > PRIME_SIZE) {
+ return MP_VAL;
+ }
+
+ if (mp_isone(a)) {
+ *result = MP_NO;
+ return MP_OKAY;
+ }
+
+ /* is the input equal to one of the primes in the table? */
+ for (ix = 0; ix < PRIME_SIZE; ix++) {
+ if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+ *result = MP_YES;
+ return MP_OKAY;
+ }
+ }
+
+ /* first perform trial division */
+ if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+ return err;
+ }
+
+ /* return if it was trivially divisible */
+ if (res == MP_YES) {
+ return MP_OKAY;
+ }
+
+ /* now perform the miller-rabin rounds */
+ if ((err = mp_init (&b)) != MP_OKAY) {
+ return err;
+ }
+ if ((err = mp_init (&c)) != MP_OKAY) {
+ mp_clear(&b);
+ return err;
+ }
+
+ baseSz = mp_count_bits(a);
+ baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);
+
+ base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (base == NULL) {
+ err = MP_MEM;
+ goto LBL_B;
+ }
+
+ if ((err = mp_sub_d(a, 2, &c)) != MP_OKAY) {
+ goto LBL_B;
+ }
+
+ /* now do a miller rabin with up to t random numbers, this should
+ * give a (1/4)^t chance of a false prime. */
+ for (ix = 0; ix < t; ix++) {
+ /* Set a test candidate. */
+ if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
+ goto LBL_B;
+ }
+
+ if ((err = mp_read_unsigned_bin(&b, base, baseSz)) != MP_OKAY) {
+ goto LBL_B;
+ }
+
+ if (mp_cmp_d(&b, 2) != MP_GT || mp_cmp(&b, &c) != MP_LT) {
+ ix--;
+ continue;
+ }
+
+ if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+ goto LBL_B;
+ }
+
+ if (res == MP_NO) {
+ goto LBL_B;
+ }
+ }
+
+ /* passed the test */
+ *result = MP_YES;
+LBL_B:mp_clear (&b);
+ mp_clear (&c);
+ XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return err;
+}
+
+#endif /* WOLFSSL_KEY_GEN NO_DH NO_DSA NO_RSA */
+
+#ifdef WOLFSSL_KEY_GEN
+
+static const int USE_BBS = 1;
+
+int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap)
+{
+ int err, res, type;
+ byte* buf;
+
+ if (N == NULL || rng == NULL)
+ return MP_VAL;
+
+ /* get type */
+ if (len < 0) {
+ type = USE_BBS;
+ len = -len;
+ } else {
+ type = 0;
+ }
+
+ /* allow sizes between 2 and 512 bytes for a prime size */
+ if (len < 2 || len > 512) {
+ return MP_VAL;
+ }
+
+ /* allocate buffer to work with */
+ buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
+ if (buf == NULL) {
+ return MP_MEM;
+ }
+ XMEMSET(buf, 0, len);
+
+ do {
+#ifdef SHOW_GEN
+ printf(".");
+ fflush(stdout);
+#endif
+ /* generate value */
+ err = wc_RNG_GenerateBlock(rng, buf, len);
+ if (err != 0) {
+ XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+ return err;
+ }
+
+ /* munge bits */
+ buf[0] |= 0x80 | 0x40;
+ buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
+
+ /* load value */
+ if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
+ XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+ return err;
+ }
+
+ /* test */
+ /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance
+ * of a 1024-bit candidate being a false positive, when it is our
+ * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)
+ * Using 8 because we've always used 8. */
+ if ((err = mp_prime_is_prime_ex(N, 8, &res, rng)) != MP_OKAY) {
+ XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+ return err;
+ }
+ } while (res == MP_NO);
+
+ XMEMSET(buf, 0, len);
+ XFREE(buf, heap, DYNAMIC_TYPE_RSA);
+
+ return MP_OKAY;
+}
+
+
/* computes least common multiple as |a*b|/(a, b) */
int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
{
@@ -4411,7 +5052,7 @@ int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
}
}
- while (mp_iszero(&v) == 0) {
+ while (mp_iszero(&v) == MP_NO) {
/* make sure v is the largest */
if (mp_cmp_mag(&u, &v) == MP_GT) {
/* swap u and v to make sure v is >= u */
@@ -4435,21 +5076,24 @@ int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
}
c->sign = MP_ZPOS;
res = MP_OKAY;
-LBL_V:mp_clear (&u);
-LBL_U:mp_clear (&v);
+LBL_V:mp_clear (&v);
+LBL_U:mp_clear (&u);
return res;
}
-
-
#endif /* WOLFSSL_KEY_GEN */
-#ifdef HAVE_ECC
+#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \
+ defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \
+ defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)
/* chars used in radix conversions */
-const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+ abcdefghijklmnopqrstuvwxyz+/";
+#endif
+#if !defined(NO_DSA) || defined(HAVE_ECC)
/* read a string [ASCII] in a given radix */
int mp_read_radix (mp_int * a, const char *str, int radix)
{
@@ -4460,7 +5104,7 @@ int mp_read_radix (mp_int * a, const char *str, int radix)
mp_zero(a);
/* make sure the radix is ok */
- if (radix < 2 || radix > 64) {
+ if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
return MP_VAL;
}
@@ -4478,12 +5122,12 @@ int mp_read_radix (mp_int * a, const char *str, int radix)
mp_zero (a);
/* process each digit of the string */
- while (*str) {
- /* if the radix < 36 the conversion is case insensitive
+ while (*str != '\0') {
+ /* if the radix <= 36 the conversion is case insensitive
* this allows numbers like 1AB and 1ab to represent the same value
* [e.g. in hex]
*/
- ch = (char) ((radix < 36) ? XTOUPPER((unsigned char)*str) : *str);
+ ch = (radix <= 36) ? (char)XTOUPPER((unsigned char)*str) : *str;
for (y = 0; y < 64; y++) {
if (ch == mp_s_rmap[y]) {
break;
@@ -4507,16 +5151,170 @@ int mp_read_radix (mp_int * a, const char *str, int radix)
++str;
}
+ /* if digit in isn't null term, then invalid character was found */
+ if (*str != '\0') {
+ mp_zero (a);
+ return MP_VAL;
+ }
+
/* set the sign only if a != 0 */
- if (mp_iszero(a) != 1) {
+ if (mp_iszero(a) != MP_YES) {
a->sign = neg;
}
return MP_OKAY;
}
+#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */
+
+#ifdef WC_MP_TO_RADIX
+
+/* returns size of ASCII representation */
+int mp_radix_size (mp_int *a, int radix, int *size)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+
+ *size = 0;
+
+ /* special case for binary */
+ if (radix == MP_RADIX_BIN) {
+ *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+ return MP_OKAY;
+ }
+
+ /* make sure the radix is in range */
+ if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
+ return MP_VAL;
+ }
+
+ if (mp_iszero(a) == MP_YES) {
+ *size = 2;
+ return MP_OKAY;
+ }
+
+ /* digs is the digit count */
+ digs = 0;
+
+ /* if it's negative add one for the sign */
+ if (a->sign == MP_NEG) {
+ ++digs;
+ }
+
+ /* init a copy of the input */
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* force temp to positive */
+ t.sign = MP_ZPOS;
+
+ /* fetch out all of the digits */
+ while (mp_iszero (&t) == MP_NO) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ ++digs;
+ }
+ mp_clear (&t);
+
+ /* return digs + 1, the 1 is for the NULL byte that would be required. */
+ *size = digs + 1;
+ return MP_OKAY;
+}
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int *a, char *str, int radix)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the radix */
+ if (radix < MP_RADIX_BIN || radix > MP_RADIX_MAX) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == MP_YES) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ ++_s;
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == MP_NO) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+#ifndef WC_DISABLE_RADIX_ZERO_PAD
+ /* For hexadecimal output, add zero padding when number of digits is odd */
+ if ((digs & 1) && (radix == 16)) {
+ *str++ = mp_s_rmap[0];
+ ++digs;
+ }
+#endif
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [excluding the sign] of the number]
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#ifdef WOLFSSL_DEBUG_MATH
+void mp_dump(const char* desc, mp_int* a, byte verbose)
+{
+ char *buffer;
+ int size = a->alloc;
+
+ buffer = (char*)XMALLOC(size * sizeof(mp_digit) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (buffer == NULL) {
+ return;
+ }
+
+ printf("%s: ptr=%p, used=%d, sign=%d, size=%d, mpd=%d\n",
+ desc, a, a->used, a->sign, size, (int)sizeof(mp_digit));
+
+ mp_tohex(a, buffer);
+ printf(" %s\n ", buffer);
+
+ if (verbose) {
+ int i;
+ for(i=0; i<a->alloc * (int)sizeof(mp_digit); i++) {
+ printf("%02x ", *(((byte*)a->dp) + i));
+ }
+ printf("\n");
+ }
+
+ XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+}
+#endif /* WOLFSSL_DEBUG_MATH */
-#endif /* HAVE_ECC */
+#endif /* WC_MP_TO_RADIX */
+
+#endif /* WOLFSSL_SP_MATH */
#endif /* USE_FAST_MATH */
#endif /* NO_BIG_INT */
-