diff --git a/demo/test.c b/demo/test.c index 2fa6e08d..1eef2004 100644 --- a/demo/test.c +++ b/demo/test.c @@ -158,6 +158,121 @@ static int test_trivial_stuff(void) return EXIT_FAILURE; } +static int test_null_guards(void) +{ + mp_int a, b, c; + char str[64]; + uint8_t ubuf[64]; + size_t sz; + int val; + bool bval; + + DOR(mp_init_multi(&a, &b, &c, NULL)); + + /* mp_init / mp_init_size */ + EXPECT(mp_init(NULL) == MP_VAL); + EXPECT(mp_init_size(NULL, 10) == MP_VAL); + EXPECT(mp_init_copy(NULL, &a) == MP_VAL); + EXPECT(mp_init_copy(&b, NULL) == MP_VAL); + + /* mp_clear / mp_zero / mp_clamp */ + mp_clear(NULL); + mp_zero(NULL); + mp_clamp(NULL); + mp_set(NULL, 1); + mp_exch(NULL, &a); + mp_exch(&a, NULL); + + /* mp_grow / mp_shrink / mp_copy */ + EXPECT(mp_grow(NULL, 10) == MP_VAL); + EXPECT(mp_shrink(NULL) == MP_VAL); + EXPECT(mp_copy(NULL, &a) == MP_VAL); + EXPECT(mp_copy(&a, NULL) == MP_VAL); + + /* comparisons */ + EXPECT(mp_cmp(NULL, &a) == MP_LT); + EXPECT(mp_cmp(&a, NULL) == MP_GT); + EXPECT(mp_cmp(NULL, NULL) == MP_EQ); + EXPECT(mp_cmp_mag(NULL, &a) == MP_LT); + EXPECT(mp_cmp_mag(&a, NULL) == MP_GT); + EXPECT(mp_cmp_d(NULL, 10) == MP_LT); + + /* count bits, sizes, get/set double */ + EXPECT(mp_count_bits(NULL) == 0); + EXPECT(mp_ubin_size(NULL) == 0u); + EXPECT(mp_sbin_size(NULL) == 0u); + EXPECT(mp_get_double(NULL) == 0.0); + EXPECT(mp_set_double(NULL, 1.0) == MP_VAL); + + /* arithmetic */ + EXPECT(mp_add(NULL, &a, &b) == MP_VAL); + EXPECT(mp_add(&a, NULL, &b) == MP_VAL); + EXPECT(mp_add(&a, &a, NULL) == MP_VAL); + EXPECT(mp_sub(NULL, &a, &b) == MP_VAL); + EXPECT(mp_mul(NULL, &a, &b) == MP_VAL); + EXPECT(mp_div(NULL, &a, &b, &c) == MP_VAL); + EXPECT(mp_div(&a, NULL, &b, &c) == MP_VAL); + EXPECT(mp_mod(NULL, &a, &b) == MP_VAL); + + /* radix / string */ + EXPECT(mp_read_radix(NULL, "123", 10) == MP_VAL); + EXPECT(mp_read_radix(&a, NULL, 10) == MP_VAL); + EXPECT(mp_to_radix(NULL, str, sizeof(str), &sz, 10) == MP_VAL); + EXPECT(mp_to_radix(&a, NULL, sizeof(str), &sz, 10) == MP_VAL); + EXPECT(mp_radix_size(NULL, 10, &sz) == MP_VAL); + EXPECT(mp_radix_size(&a, 10, NULL) == MP_VAL); + + /* bin / binary import/export */ + EXPECT(mp_to_ubin(NULL, ubuf, sizeof(ubuf), &sz) == MP_VAL); + EXPECT(mp_to_ubin(&a, NULL, sizeof(ubuf), &sz) == MP_VAL); + EXPECT(mp_from_ubin(NULL, ubuf, sizeof(ubuf)) == MP_VAL); + EXPECT(mp_from_ubin(&a, NULL, sizeof(ubuf)) == MP_VAL); + EXPECT(mp_to_sbin(NULL, ubuf, sizeof(ubuf), &sz) == MP_VAL); + EXPECT(mp_to_sbin(&a, NULL, sizeof(ubuf), &sz) == MP_VAL); + EXPECT(mp_from_sbin(NULL, ubuf, sizeof(ubuf)) == MP_VAL); + EXPECT(mp_from_sbin(&a, NULL, sizeof(ubuf)) == MP_VAL); + + /* bitwise */ + EXPECT(mp_and(NULL, &a, &b) == MP_VAL); + EXPECT(mp_or(NULL, &a, &b) == MP_VAL); + EXPECT(mp_xor(NULL, &a, &b) == MP_VAL); + EXPECT(mp_2expt(NULL, 5) == MP_VAL); + EXPECT(mp_lshd(NULL, 1) == MP_VAL); + mp_rshd(NULL, 1); + EXPECT(mp_div_2d(NULL, 1, &b, &c) == MP_VAL); + EXPECT(mp_div_2d(&a, 1, NULL, &c) == MP_VAL); + EXPECT(mp_mod_2d(NULL, 1, &b) == MP_VAL); + EXPECT(mp_mod_2d(&a, 1, NULL) == MP_VAL); + EXPECT(mp_mul_2d(NULL, 1, &b) == MP_VAL); + EXPECT(mp_mul_2d(&a, 1, NULL) == MP_VAL); + + /* math functions */ + EXPECT(mp_gcd(NULL, &a, &b) == MP_VAL); + EXPECT(mp_lcm(NULL, &a, &b) == MP_VAL); + EXPECT(mp_exptmod(NULL, &a, &a, &b) == MP_VAL); + EXPECT(mp_invmod(NULL, &a, &b) == MP_VAL); + EXPECT(mp_sqrt(NULL, &b) == MP_VAL); + EXPECT(mp_sqrt(&a, NULL) == MP_VAL); + EXPECT(mp_is_square(NULL, &bval) == MP_VAL); + EXPECT(mp_is_square(&a, NULL) == MP_VAL); + EXPECT(mp_root_n(NULL, 2, &b) == MP_VAL); + EXPECT(mp_root_n(&a, 2, NULL) == MP_VAL); + EXPECT(mp_log(NULL, &a, &val) == MP_VAL); + EXPECT(mp_kronecker(NULL, &a, &val) == MP_VAL); + EXPECT(mp_prime_is_prime(NULL, 5, &bval) == MP_VAL); + EXPECT(mp_prime_is_prime(&a, 5, NULL) == MP_VAL); + EXPECT(mp_prime_next_prime(NULL, 5, false) == MP_VAL); + EXPECT(mp_rand(NULL, 5) == MP_VAL); + EXPECT(mp_signed_rsh(NULL, 1, &b) == MP_VAL); + EXPECT(mp_pack_count(NULL, 0, 1) == 0u); + + mp_clear_multi(&a, &b, &c, NULL); + return EXIT_SUCCESS; +LBL_ERR: + mp_clear_multi(&a, &b, &c, NULL); + return EXIT_FAILURE; +} + static int test_mp_hash(void) { mp_int a; @@ -2556,6 +2671,7 @@ static int unit_tests(int argc, char **argv) #define T3(n, o1, o2, o3) { #n, (MP_HAS(o1) && MP_HAS(o2) && MP_HAS(o3)) ? test_##n : NULL } T0(feature_detection), T0(trivial_stuff), + T0(null_guards), T1(mp_hash, MP_HASH), T2(mp_get_set_i32, MP_GET_I32, MP_GET_MAG_U32), T2(mp_get_set_i64, MP_GET_I64, MP_GET_MAG_U64), diff --git a/mp_2expt.c b/mp_2expt.c index c11fe4cb..6d6d924e 100644 --- a/mp_2expt.c +++ b/mp_2expt.c @@ -12,7 +12,7 @@ mp_err mp_2expt(mp_int *a, int b) { mp_err err; - if (b < 0) { + if (a == NULL || b < 0) { return MP_VAL; } diff --git a/mp_add.c b/mp_add.c index bf7a61e2..fabb526a 100644 --- a/mp_add.c +++ b/mp_add.c @@ -6,6 +6,10 @@ /* high level addition (handles signs) */ mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) { + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + /* handle two cases, not four */ if (a->sign == b->sign) { /* both positive or both negative */ diff --git a/mp_and.c b/mp_and.c index b5230c4d..5f4c353d 100644 --- a/mp_and.c +++ b/mp_and.c @@ -6,10 +6,17 @@ /* two complement and */ mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; + int used, i; mp_err err; mp_digit ac = 1, bc = 1, cc = 1; - bool neg = (mp_isneg(a) && mp_isneg(b)); + bool neg; + + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + + used = MP_MAX(a->used, b->used) + 1; + neg = (mp_isneg(a) && mp_isneg(b)); if ((err = mp_grow(c, used)) != MP_OKAY) { return err; diff --git a/mp_clamp.c b/mp_clamp.c index 463f22dc..891eedfd 100644 --- a/mp_clamp.c +++ b/mp_clamp.c @@ -12,6 +12,9 @@ */ void mp_clamp(mp_int *a) { + if (a == NULL) { + return; + } /* decrease used while the most significant digit is * zero. */ diff --git a/mp_clear.c b/mp_clear.c index 11094b26..62b2ba7e 100644 --- a/mp_clear.c +++ b/mp_clear.c @@ -7,7 +7,7 @@ void mp_clear(mp_int *a) { /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { + if (a != NULL && a->dp != NULL) { /* free ram */ MP_FREE_DIGS(a->dp, a->alloc); diff --git a/mp_cmp.c b/mp_cmp.c index 9f3847b8..efd9e721 100644 --- a/mp_cmp.c +++ b/mp_cmp.c @@ -6,6 +6,16 @@ /* compare two ints (signed)*/ mp_ord mp_cmp(const mp_int *a, const mp_int *b) { + if (a == b) { + return MP_EQ; + } + if (a == NULL) { + return MP_LT; + } + if (b == NULL) { + return MP_GT; + } + /* compare based on sign */ if (a->sign != b->sign) { return mp_isneg(a) ? MP_LT : MP_GT; diff --git a/mp_cmp_d.c b/mp_cmp_d.c index 42f7b160..1df74dad 100644 --- a/mp_cmp_d.c +++ b/mp_cmp_d.c @@ -6,6 +6,10 @@ /* compare a digit */ mp_ord mp_cmp_d(const mp_int *a, mp_digit b) { + if (a == NULL) { + return MP_LT; + } + /* compare based on sign */ if (mp_isneg(a)) { return MP_LT; diff --git a/mp_cmp_mag.c b/mp_cmp_mag.c index 06f22e7c..7008e30c 100644 --- a/mp_cmp_mag.c +++ b/mp_cmp_mag.c @@ -8,6 +8,16 @@ mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) { int n; + if (a == b) { + return MP_EQ; + } + if (a == NULL) { + return MP_LT; + } + if (b == NULL) { + return MP_GT; + } + /* compare based on # of non-zero digits */ if (a->used != b->used) { return a->used > b->used ? MP_GT : MP_LT; diff --git a/mp_copy.c b/mp_copy.c index d79e2b8b..ea5336b9 100644 --- a/mp_copy.c +++ b/mp_copy.c @@ -8,6 +8,10 @@ mp_err mp_copy(const mp_int *a, mp_int *b) { mp_err err; + if (a == NULL || b == NULL) { + return MP_VAL; + } + /* if dst == src do nothing */ if (a == b) { return MP_OKAY; diff --git a/mp_count_bits.c b/mp_count_bits.c index 52b463d4..16850c70 100644 --- a/mp_count_bits.c +++ b/mp_count_bits.c @@ -10,7 +10,7 @@ int mp_count_bits(const mp_int *a) mp_digit q; /* shortcut */ - if (mp_iszero(a)) { + if (a == NULL || mp_iszero(a)) { return 0; } diff --git a/mp_div.c b/mp_div.c index b092d7bb..969f6ad3 100644 --- a/mp_div.c +++ b/mp_div.c @@ -7,6 +7,10 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_err err; + if (a == NULL || b == NULL) { + return MP_VAL; + } + /* is divisor zero ? */ if (mp_iszero(b)) { return MP_VAL; diff --git a/mp_div_2d.c b/mp_div_2d.c index e523465a..068d134b 100644 --- a/mp_div_2d.c +++ b/mp_div_2d.c @@ -8,7 +8,7 @@ mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) { mp_err err; - if (b < 0) { + if (a == NULL || c == NULL || b < 0) { return MP_VAL; } diff --git a/mp_exch.c b/mp_exch.c index 50b97d96..29b82a8d 100644 --- a/mp_exch.c +++ b/mp_exch.c @@ -8,6 +8,9 @@ */ void mp_exch(mp_int *a, mp_int *b) { + if (a == NULL || b == NULL || a == b) { + return; + } MP_EXCH(mp_int, *a, *b); } #endif diff --git a/mp_exptmod.c b/mp_exptmod.c index eaab861e..3730463a 100644 --- a/mp_exptmod.c +++ b/mp_exptmod.c @@ -12,6 +12,10 @@ mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) { int dr; + if (G == NULL || X == NULL || P == NULL || Y == NULL) { + return MP_VAL; + } + /* modulus P must be positive */ if (mp_isneg(P)) { return MP_VAL; diff --git a/mp_fread.c b/mp_fread.c index 53c35e82..54411b06 100644 --- a/mp_fread.c +++ b/mp_fread.c @@ -11,6 +11,10 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream) mp_sign sign = MP_ZPOS; int ch; + if (a == NULL || stream == NULL) { + return MP_VAL; + } + /* make sure the radix is ok */ if ((radix < 2) || (radix > 64)) { return MP_VAL; diff --git a/mp_from_sbin.c b/mp_from_sbin.c index 2d32a1d8..617c191a 100644 --- a/mp_from_sbin.c +++ b/mp_from_sbin.c @@ -8,6 +8,10 @@ mp_err mp_from_sbin(mp_int *a, const uint8_t *buf, size_t size) { mp_err err; + if (a == NULL || (size > 0u && buf == NULL)) { + return MP_VAL; + } + if (size == 0) { return MP_VAL; } diff --git a/mp_from_ubin.c b/mp_from_ubin.c index 8272185b..4d0e005e 100644 --- a/mp_from_ubin.c +++ b/mp_from_ubin.c @@ -8,6 +8,10 @@ mp_err mp_from_ubin(mp_int *a, const uint8_t *buf, size_t size) { mp_err err; + if (a == NULL || (size > 0u && buf == NULL)) { + return MP_VAL; + } + /* make sure there are at least two digits */ if ((err = mp_grow(a, 2)) != MP_OKAY) { return err; diff --git a/mp_fwrite.c b/mp_fwrite.c index 8ea9d327..5031ba3b 100644 --- a/mp_fwrite.c +++ b/mp_fwrite.c @@ -10,6 +10,10 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) mp_err err; size_t size, written; + if (a == NULL || stream == NULL) { + return MP_VAL; + } + if ((err = mp_radix_size_overestimate(a, radix, &size)) != MP_OKAY) { return err; } diff --git a/mp_gcd.c b/mp_gcd.c index be77b34a..9d330acb 100644 --- a/mp_gcd.c +++ b/mp_gcd.c @@ -10,6 +10,10 @@ mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) int k, u_lsb, v_lsb; mp_err err; + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + /* either zero than gcd is the largest */ if (mp_iszero(a)) { return mp_abs(b, c); diff --git a/mp_get_double.c b/mp_get_double.c index f462eb8e..2793d2c3 100644 --- a/mp_get_double.c +++ b/mp_get_double.c @@ -7,6 +7,11 @@ double mp_get_double(const mp_int *a) { int i; double d = 0.0, fac = 1.0; + + if (a == NULL) { + return 0.0; + } + for (i = 0; i < MP_DIGIT_BIT; ++i) { fac *= 2.0; } diff --git a/mp_grow.c b/mp_grow.c index 551d1a3b..5d721ee0 100644 --- a/mp_grow.c +++ b/mp_grow.c @@ -6,7 +6,7 @@ /* grow as required */ mp_err mp_grow(mp_int *a, int size) { - if (size < 0) { + if (a == NULL || size < 0) { return MP_VAL; } diff --git a/mp_init.c b/mp_init.c index af167448..afccc493 100644 --- a/mp_init.c +++ b/mp_init.c @@ -6,6 +6,10 @@ /* init a new mp_int */ mp_err mp_init(mp_int *a) { + if (a == NULL) { + return MP_VAL; + } + /* allocate memory required and clear it */ a->dp = (mp_digit *) MP_CALLOC((size_t)MP_DEFAULT_DIGIT_COUNT, sizeof(mp_digit)); if (a->dp == NULL) { diff --git a/mp_init_copy.c b/mp_init_copy.c index 4d0773ba..97b9cc01 100644 --- a/mp_init_copy.c +++ b/mp_init_copy.c @@ -8,6 +8,10 @@ mp_err mp_init_copy(mp_int *a, const mp_int *b) { mp_err err; + if (a == NULL || b == NULL) { + return MP_VAL; + } + if ((err = mp_init_size(a, b->used)) != MP_OKAY) { return err; } diff --git a/mp_init_size.c b/mp_init_size.c index 87a4256e..b1f9c41d 100644 --- a/mp_init_size.c +++ b/mp_init_size.c @@ -6,7 +6,7 @@ /* init an mp_init for a given size */ mp_err mp_init_size(mp_int *a, int size) { - if (size < 0) { + if (a == NULL || size < 0) { return MP_VAL; } diff --git a/mp_invmod.c b/mp_invmod.c index 2494acbf..0b07d800 100644 --- a/mp_invmod.c +++ b/mp_invmod.c @@ -6,6 +6,10 @@ /* hac 14.61, pp608 */ mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) { + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + /* for all n in N and n > 0, n = 0 mod 1 */ if (!mp_isneg(a) && mp_cmp_d(b, 1uL) == MP_EQ) { mp_zero(c); diff --git a/mp_is_square.c b/mp_is_square.c index d2856e25..56c57a64 100644 --- a/mp_is_square.c +++ b/mp_is_square.c @@ -33,6 +33,10 @@ mp_err mp_is_square(const mp_int *arg, bool *ret) mp_int t; uint32_t r; + if (arg == NULL || ret == NULL) { + return MP_VAL; + } + /* Default to Non-square :) */ *ret = false; diff --git a/mp_kronecker.c b/mp_kronecker.c index 282c0d86..b69a11e2 100644 --- a/mp_kronecker.c +++ b/mp_kronecker.c @@ -25,6 +25,10 @@ mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) static const int8_t table[] = {0, 1, 0, -1, 0, -1, 0, 1}; + if (a == NULL || p == NULL || c == NULL) { + return MP_VAL; + } + if (mp_iszero(p)) { if ((a->used == 1) && (a->dp[0] == 1u)) { *c = 1; diff --git a/mp_lcm.c b/mp_lcm.c index f2044f0e..8fc6b8e3 100644 --- a/mp_lcm.c +++ b/mp_lcm.c @@ -10,6 +10,10 @@ mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) mp_int t1, t2; + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) { return err; } diff --git a/mp_log.c b/mp_log.c index 0d5d893a..2289981b 100644 --- a/mp_log.c +++ b/mp_log.c @@ -55,6 +55,10 @@ mp_err mp_log(const mp_int *a, const mp_int *b, int *lb) mp_err err; mp_ord cmp; + if (a == NULL || b == NULL || lb == NULL) { + return MP_VAL; + } + if (mp_isneg(a) || mp_iszero(a) || (mp_cmp_d(b, 2u) == MP_LT)) { return MP_VAL; } diff --git a/mp_lshd.c b/mp_lshd.c index 90014e48..de3ce7f8 100644 --- a/mp_lshd.c +++ b/mp_lshd.c @@ -9,6 +9,10 @@ mp_err mp_lshd(mp_int *a, int b) mp_err err; int x; + if (a == NULL) { + return MP_VAL; + } + /* if its less than zero return */ if (b <= 0) { return MP_OKAY; diff --git a/mp_mod.c b/mp_mod.c index beae13e7..46146715 100644 --- a/mp_mod.c +++ b/mp_mod.c @@ -7,6 +7,11 @@ mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) { mp_err err; + + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + if ((err = mp_div(a, b, NULL, c)) != MP_OKAY) { return err; } diff --git a/mp_mod_2d.c b/mp_mod_2d.c index 82c64f05..d73e192f 100644 --- a/mp_mod_2d.c +++ b/mp_mod_2d.c @@ -9,7 +9,7 @@ mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) int x; mp_err err; - if (b < 0) { + if (a == NULL || c == NULL || b < 0) { return MP_VAL; } diff --git a/mp_mul.c b/mp_mul.c index 81807406..e2e8f826 100644 --- a/mp_mul.c +++ b/mp_mul.c @@ -7,10 +7,17 @@ mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) { mp_err err; - int min = MP_MIN(a->used, b->used), - max = MP_MAX(a->used, b->used), - digs = a->used + b->used + 1; - bool neg = (a->sign != b->sign); + int min, max, digs; + bool neg; + + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + + min = MP_MIN(a->used, b->used); + max = MP_MAX(a->used, b->used); + digs = a->used + b->used + 1; + neg = (a->sign != b->sign); if ((a == b) && MP_HAS(S_MP_SQR_TOOM) && /* use Toom-Cook? */ diff --git a/mp_mul_2d.c b/mp_mul_2d.c index e4581375..940eb2e0 100644 --- a/mp_mul_2d.c +++ b/mp_mul_2d.c @@ -8,7 +8,7 @@ mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) { mp_err err; - if (b < 0) { + if (a == NULL || c == NULL || b < 0) { return MP_VAL; } diff --git a/mp_or.c b/mp_or.c index 15958524..57f50380 100644 --- a/mp_or.c +++ b/mp_or.c @@ -6,10 +6,17 @@ /* two complement or */ mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; + int used, i; mp_err err; mp_digit ac = 1, bc = 1, cc = 1; - bool neg = (mp_isneg(a) || mp_isneg(b)); + bool neg; + + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + + used = MP_MAX(a->used, b->used) + 1; + neg = (mp_isneg(a) || mp_isneg(b)); if ((err = mp_grow(c, used)) != MP_OKAY) { return err; diff --git a/mp_pack.c b/mp_pack.c index 447f1fdf..0f0b40d3 100644 --- a/mp_pack.c +++ b/mp_pack.c @@ -15,6 +15,10 @@ mp_err mp_pack(void *rop, size_t maxcount, size_t *written, mp_order order, size mp_int t; + if (op == NULL || (maxcount > 0u && rop == NULL)) { + return MP_VAL; + } + count = mp_pack_count(op, nails, size); if (count > maxcount) { diff --git a/mp_pack_count.c b/mp_pack_count.c index aa682ba6..90de9abb 100644 --- a/mp_pack_count.c +++ b/mp_pack_count.c @@ -5,7 +5,11 @@ size_t mp_pack_count(const mp_int *a, size_t nails, size_t size) { - size_t bits = (size_t)mp_count_bits(a); + size_t bits; + if (a == NULL || ((size * 8u) <= nails)) { + return 0u; + } + bits = (size_t)mp_count_bits(a); return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u)); } diff --git a/mp_prime_is_prime.c b/mp_prime_is_prime.c index bb24f594..5256e803 100644 --- a/mp_prime_is_prime.c +++ b/mp_prime_is_prime.c @@ -20,6 +20,10 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, bool *result) bool res; mp_err err; + if (a == NULL || result == NULL) { + return MP_VAL; + } + /* default to no */ *result = false; diff --git a/mp_prime_next_prime.c b/mp_prime_next_prime.c index 6faa08de..9ee41c9f 100644 --- a/mp_prime_next_prime.c +++ b/mp_prime_next_prime.c @@ -16,6 +16,10 @@ mp_err mp_prime_next_prime(mp_int *a, int t, bool bbs_style) mp_digit res_tab[MP_PRIME_TAB_SIZE], kstep; mp_int b; + if (a == NULL) { + return MP_VAL; + } + /* force positive */ a->sign = MP_ZPOS; diff --git a/mp_radix_size.c b/mp_radix_size.c index ca08438b..19575a42 100644 --- a/mp_radix_size.c +++ b/mp_radix_size.c @@ -10,6 +10,10 @@ mp_err mp_radix_size(const mp_int *a, int radix, size_t *size) mp_int a_; int b; + if (a == NULL || size == NULL) { + return MP_VAL; + } + /* make sure the radix is in range */ if ((radix < 2) || (radix > 64)) { return MP_VAL; diff --git a/mp_rand.c b/mp_rand.c index 19364755..99c40db1 100644 --- a/mp_rand.c +++ b/mp_rand.c @@ -8,6 +8,10 @@ mp_err mp_rand(mp_int *a, int digits) int i; mp_err err; + if (a == NULL) { + return MP_VAL; + } + mp_zero(a); if (digits <= 0) { diff --git a/mp_read_radix.c b/mp_read_radix.c index 28e6eb60..b196bd92 100644 --- a/mp_read_radix.c +++ b/mp_read_radix.c @@ -9,6 +9,10 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix) mp_err err; mp_sign sign = MP_ZPOS; + if (a == NULL || str == NULL) { + return MP_VAL; + } + /* make sure the radix is ok */ if ((radix < 2) || (radix > 64)) { return MP_VAL; diff --git a/mp_root_n.c b/mp_root_n.c index d904df88..13c67a37 100644 --- a/mp_root_n.c +++ b/mp_root_n.c @@ -18,7 +18,7 @@ mp_err mp_root_n(const mp_int *a, int b, mp_int *c) int ilog2; mp_err err; - if (b < 0 || (unsigned)b > (unsigned)MP_DIGIT_MAX) { + if (a == NULL || c == NULL || b < 0 || (unsigned)b > (unsigned)MP_DIGIT_MAX) { return MP_VAL; } diff --git a/mp_rshd.c b/mp_rshd.c index 3f0a9416..af554ba3 100644 --- a/mp_rshd.c +++ b/mp_rshd.c @@ -8,6 +8,10 @@ void mp_rshd(mp_int *a, int b) { int x; + if (a == NULL) { + return; + } + /* if b <= 0 then ignore it */ if (b <= 0) { return; diff --git a/mp_sbin_size.c b/mp_sbin_size.c index 2f40df3e..23527f14 100644 --- a/mp_sbin_size.c +++ b/mp_sbin_size.c @@ -6,6 +6,9 @@ /* get the size for an signed equivalent */ size_t mp_sbin_size(const mp_int *a) { + if (a == NULL) { + return 0u; + } return 1u + mp_ubin_size(a); } #endif diff --git a/mp_set.c b/mp_set.c index bc0c4da7..a1da2d1e 100644 --- a/mp_set.c +++ b/mp_set.c @@ -6,6 +6,9 @@ /* set to a digit */ void mp_set(mp_int *a, mp_digit b) { + if (a == NULL) { + return; + } int oldused = a->used; a->dp[0] = b & MP_MASK; a->sign = MP_ZPOS; diff --git a/mp_set_double.c b/mp_set_double.c index 0ede359c..5b6c2275 100644 --- a/mp_set_double.c +++ b/mp_set_double.c @@ -13,6 +13,11 @@ mp_err mp_set_double(mp_int *a, double b) double dbl; uint64_t bits; } cast; + + if (a == NULL) { + return MP_VAL; + } + cast.dbl = b; exp = (int)((unsigned)(cast.bits >> 52) & 0x7FFu); diff --git a/mp_shrink.c b/mp_shrink.c index 3d9b1626..d3af45f1 100644 --- a/mp_shrink.c +++ b/mp_shrink.c @@ -6,6 +6,9 @@ /* shrink a bignum */ mp_err mp_shrink(mp_int *a) { + if (a == NULL) { + return MP_VAL; + } int alloc = MP_MAX(MP_MIN_DIGIT_COUNT, a->used); if (a->alloc != alloc) { mp_digit *dp = (mp_digit *) MP_REALLOC(a->dp, diff --git a/mp_signed_rsh.c b/mp_signed_rsh.c index 3b7e232e..aa7f5ff7 100644 --- a/mp_signed_rsh.c +++ b/mp_signed_rsh.c @@ -7,6 +7,10 @@ mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) { mp_err err; + if (a == NULL || c == NULL) { + return MP_VAL; + } + if (!mp_isneg(a)) { return mp_div_2d(a, b, c, NULL); } diff --git a/mp_sqrt.c b/mp_sqrt.c index 1a9dca7d..f08f99a6 100644 --- a/mp_sqrt.c +++ b/mp_sqrt.c @@ -9,6 +9,10 @@ mp_err mp_sqrt(const mp_int *arg, mp_int *ret) mp_err err; mp_int t1, t2; + if (arg == NULL || ret == NULL) { + return MP_VAL; + } + /* must be positive */ if (mp_isneg(arg)) { return MP_VAL; diff --git a/mp_sub.c b/mp_sub.c index 1c95ad54..cb690257 100644 --- a/mp_sub.c +++ b/mp_sub.c @@ -6,6 +6,10 @@ /* high level subtraction (handles signs) */ mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + if (a->sign != b->sign) { /* subtract a negative from a positive, OR */ /* subtract a positive from a negative. */ diff --git a/mp_to_radix.c b/mp_to_radix.c index 1e5e6711..917d8c06 100644 --- a/mp_to_radix.c +++ b/mp_to_radix.c @@ -27,6 +27,10 @@ mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, i mp_digit d; char *_s = str; + if (a == NULL || str == NULL) { + return MP_VAL; + } + /* check range of radix and size*/ if (maxlen < 2u) { return MP_BUF; diff --git a/mp_to_sbin.c b/mp_to_sbin.c index 00884c3b..e2e28296 100644 --- a/mp_to_sbin.c +++ b/mp_to_sbin.c @@ -7,6 +7,9 @@ mp_err mp_to_sbin(const mp_int *a, uint8_t *buf, size_t maxlen, size_t *written) { mp_err err; + if (a == NULL || buf == NULL) { + return MP_VAL; + } if (maxlen == 0u) { return MP_BUF; } diff --git a/mp_to_ubin.c b/mp_to_ubin.c index e8643cc0..f0ee78d5 100644 --- a/mp_to_ubin.c +++ b/mp_to_ubin.c @@ -10,6 +10,10 @@ mp_err mp_to_ubin(const mp_int *a, uint8_t *buf, size_t maxlen, size_t *written) mp_err err; mp_int t; + if (a == NULL || (maxlen > 0u && buf == NULL)) { + return MP_VAL; + } + count = mp_ubin_size(a); if (count > maxlen) { return MP_BUF; diff --git a/mp_ubin_size.c b/mp_ubin_size.c index 4f16404f..1fc12900 100644 --- a/mp_ubin_size.c +++ b/mp_ubin_size.c @@ -6,6 +6,9 @@ /* get the size for an unsigned equivalent */ size_t mp_ubin_size(const mp_int *a) { + if (a == NULL) { + return 0u; + } size_t size = (size_t)mp_count_bits(a); return (size / 8u) + (((size & 7u) != 0u) ? 1u : 0u); } diff --git a/mp_unpack.c b/mp_unpack.c index f0127fa4..49fcc49d 100644 --- a/mp_unpack.c +++ b/mp_unpack.c @@ -13,6 +13,10 @@ mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, size_t odd_nails, nail_bytes, i, j; uint8_t odd_nail_mask; + if (rop == NULL || (count > 0u && op == NULL)) { + return MP_VAL; + } + mp_zero(rop); if (endian == MP_NATIVE_ENDIAN) { diff --git a/mp_xor.c b/mp_xor.c index ff264192..7bddbab9 100644 --- a/mp_xor.c +++ b/mp_xor.c @@ -6,10 +6,17 @@ /* two complement xor */ mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; + int used, i; mp_err err; mp_digit ac = 1, bc = 1, cc = 1; - bool neg = (a->sign != b->sign); + bool neg; + + if (a == NULL || b == NULL || c == NULL) { + return MP_VAL; + } + + used = MP_MAX(a->used, b->used) + 1; + neg = (a->sign != b->sign); if ((err = mp_grow(c, used)) != MP_OKAY) { return err; diff --git a/mp_zero.c b/mp_zero.c index 48b60e45..bee9776f 100644 --- a/mp_zero.c +++ b/mp_zero.c @@ -6,6 +6,9 @@ /* set to zero */ void mp_zero(mp_int *a) { + if (a == NULL) { + return; + } a->sign = MP_ZPOS; s_mp_zero_digs(a->dp, a->used); a->used = 0; diff --git a/tommath_private.h b/tommath_private.h index be620dbc..c6806fa9 100644 --- a/tommath_private.h +++ b/tommath_private.h @@ -295,6 +295,7 @@ extern MP_PRIVATE const mp_digit s_mp_prime_tab[]; void name(mp_int * a, type b) \ { \ int i = 0; \ + if (a == NULL) { return; } \ while (b != 0u) { \ a->dp[i++] = ((mp_digit)b & MP_MASK); \ if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \ @@ -308,6 +309,7 @@ extern MP_PRIVATE const mp_digit s_mp_prime_tab[]; #define MP_SET_SIGNED(name, uname, type, utype) \ void name(mp_int * a, type b) \ { \ + if (a == NULL) { return; } \ uname(a, (b < 0) ? -(utype)b : (utype)b); \ if (b < 0) { a->sign = MP_NEG; } \ } @@ -326,6 +328,7 @@ extern MP_PRIVATE const mp_digit s_mp_prime_tab[]; #define MP_GET_MAG(name, type) \ type name(const mp_int* a) \ { \ + if (a == NULL) { return (type)0u; } \ int i = MP_MIN(a->used, (int)((MP_SIZEOF_BITS(type) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT)); \ type res = 0u; \ while (i --> 0) { \ @@ -339,6 +342,7 @@ extern MP_PRIVATE const mp_digit s_mp_prime_tab[]; #define MP_GET_SIGNED(name, mag, type, utype) \ type name(const mp_int* a) \ { \ + if (a == NULL) { return (type)0; } \ utype res = mag(a); \ return mp_isneg(a) ? (type)-res : (type)res; \ }