diff options
Diffstat (limited to 'security/nss/lib/freebl/mpi')
-rw-r--r-- | security/nss/lib/freebl/mpi/README | 1 | ||||
-rw-r--r-- | security/nss/lib/freebl/mpi/mpcpucache.c | 2 | ||||
-rw-r--r-- | security/nss/lib/freebl/mpi/mpi.c | 69 | ||||
-rw-r--r-- | security/nss/lib/freebl/mpi/mpi.h | 11 |
4 files changed, 50 insertions, 33 deletions
diff --git a/security/nss/lib/freebl/mpi/README b/security/nss/lib/freebl/mpi/README index cf4302758..a49aa9d8d 100644 --- a/security/nss/lib/freebl/mpi/README +++ b/security/nss/lib/freebl/mpi/README @@ -167,6 +167,7 @@ To set an mp_int to a given value, the following functions are given: mp_set(mp_int *mp, mp_digit d); mp_set_int(mp_int *mp, long z); + mp_set_ulong(mp_int *mp, unsigned long z); The mp_set() function sets the mp_int to a single digit value, while mp_set_int() sets the mp_int to a signed long integer value. diff --git a/security/nss/lib/freebl/mpi/mpcpucache.c b/security/nss/lib/freebl/mpi/mpcpucache.c index 336b4cc55..2ad291fab 100644 --- a/security/nss/lib/freebl/mpi/mpcpucache.c +++ b/security/nss/lib/freebl/mpi/mpcpucache.c @@ -727,7 +727,7 @@ static inline void dcbzl(char *array) { register char *a asm("r2") = array; - __asm__ __volatile__("dcbzl %0,r0" + __asm__ __volatile__("dcbzl %0,0" : "=r"(a) : "0"(a)); } diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index 401eac51d..7e96e51ff 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -341,33 +341,21 @@ mp_set(mp_int *mp, mp_digit d) mp_err mp_set_int(mp_int *mp, long z) { - int ix; unsigned long v = labs(z); mp_err res; ARGCHK(mp != NULL, MP_BADARG); - mp_zero(mp); - if (z == 0) - return MP_OKAY; /* shortcut for zero */ - - if (sizeof v <= sizeof(mp_digit)) { - DIGIT(mp, 0) = v; - } else { - for (ix = sizeof(long) - 1; ix >= 0; ix--) { - if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY) - return res; - - res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); - if (res != MP_OKAY) - return res; - } + /* https://bugzilla.mozilla.org/show_bug.cgi?id=1509432 */ + if ((res = mp_set_ulong(mp, v)) != MP_OKAY) { /* avoids duplicated code */ + return res; } - if (z < 0) + + if (z < 0) { SIGN(mp) = NEG; + } return MP_OKAY; - } /* end mp_set_int() */ /* }}} */ @@ -1441,7 +1429,7 @@ s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c) mp_digit d; unsigned int dig, bit; - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && b != NULL && c != NULL && m != NULL, MP_BADARG); if (mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) return MP_RANGE; @@ -1528,7 +1516,7 @@ mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c) mp_int s, x; mp_err res; - ARGCHK(a != NULL && c != NULL, MP_BADARG); + ARGCHK(a != NULL && c != NULL && m != NULL, MP_BADARG); if ((res = mp_init(&s)) != MP_OKAY) return res; @@ -1581,6 +1569,8 @@ X: int mp_cmp_z(const mp_int *a) { + ARGMPCHK(a != NULL); + if (SIGN(a) == NEG) return MP_LT; else if (USED(a) == 1 && DIGIT(a, 0) == 0) @@ -1671,7 +1661,7 @@ mp_cmp_mag(const mp_int *a, const mp_int *b) int mp_isodd(const mp_int *a) { - ARGCHK(a != NULL, 0); + ARGMPCHK(a != NULL); return (int)(DIGIT(a, 0) & 1); @@ -2015,7 +2005,7 @@ s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c) mp_err k = 0; mp_int d, f, g; - ARGCHK(a && p && c, MP_BADARG); + ARGCHK(a != NULL && p != NULL && c != NULL, MP_BADARG); MP_DIGITS(&d) = 0; MP_DIGITS(&f) = 0; @@ -2063,7 +2053,10 @@ s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c) } } if (res >= 0) { - while (MP_SIGN(c) != MP_ZPOS) { + if (mp_cmp_mag(c, p) >= 0) { + MP_CHECKOK(mp_div(c, p, NULL, c)); + } + if (MP_SIGN(c) != MP_ZPOS) { MP_CHECKOK(mp_add(c, p, c)); } res = k; @@ -2146,7 +2139,7 @@ s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c) mp_err res; mp_int x; - ARGCHK(a && m && c, MP_BADARG); + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) return MP_RANGE; @@ -2184,7 +2177,7 @@ mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c) mp_int g, x; mp_err res; - ARGCHK(a && m && c, MP_BADARG); + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) return MP_RANGE; @@ -2280,6 +2273,8 @@ s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c) mp_int oddPart, evenPart; /* parts to combine via CRT. */ mp_int C2, tmp1, tmp2; + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + /*static const mp_digit d1 = 1; */ /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */ @@ -2358,8 +2353,7 @@ CLEANUP: mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) { - - ARGCHK(a && m && c, MP_BADARG); + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); if (mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) return MP_RANGE; @@ -2726,6 +2720,8 @@ mp_strerror(mp_err ec) mp_err s_mp_grow(mp_int *mp, mp_size min) { + ARGCHK(mp != NULL, MP_BADARG); + if (min > ALLOC(mp)) { mp_digit *tmp; @@ -2755,6 +2751,8 @@ s_mp_grow(mp_int *mp, mp_size min) mp_err s_mp_pad(mp_int *mp, mp_size min) { + ARGCHK(mp != NULL, MP_BADARG); + if (min > USED(mp)) { mp_err res; @@ -2874,6 +2872,8 @@ s_mp_lshd(mp_int *mp, mp_size p) mp_err res; unsigned int ix; + ARGCHK(mp != NULL, MP_BADARG); + if (p == 0) return MP_OKAY; @@ -3006,6 +3006,8 @@ s_mp_mul_2(mp_int *mp) unsigned int ix, used; mp_digit kin = 0; + ARGCHK(mp != NULL, MP_BADARG); + /* Shift digits leftward by 1 bit */ used = MP_USED(mp); pd = MP_DIGITS(mp); @@ -3115,6 +3117,8 @@ s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd) mp_digit b_msd; mp_err res = MP_OKAY; + ARGCHK(a != NULL && b != NULL && pd != NULL, MP_BADARG); + d = 0; mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */ b_msd = DIGIT(b, USED(b) - 1); @@ -4379,6 +4383,8 @@ CLEANUP: int s_mp_cmp(const mp_int *a, const mp_int *b) { + ARGMPCHK(a != NULL && b != NULL); + mp_size used_a = MP_USED(a); { mp_size used_b = MP_USED(b); @@ -4430,6 +4436,8 @@ IS_GT: int s_mp_cmp_d(const mp_int *a, mp_digit d) { + ARGMPCHK(a != NULL); + if (USED(a) > 1) return MP_GT; @@ -4456,6 +4464,8 @@ s_mp_ispow2(const mp_int *v) mp_digit d; int extra = 0, ix; + ARGMPCHK(v != NULL); + ix = MP_USED(v) - 1; d = MP_DIGIT(v, ix); /* most significant digit of v */ @@ -4783,10 +4793,7 @@ mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) int ix, jx; unsigned int bytes; - ARGCHK(mp != NULL, MP_BADARG); - ARGCHK(str != NULL, MP_BADARG); - ARGCHK(!SIGN(mp), MP_BADARG); - ARGCHK(length > 0, MP_BADARG); + ARGCHK(mp != NULL && str != NULL && !SIGN(mp) && length > 0, MP_BADARG); /* Constant time on the value of mp. Don't use mp_unsigned_octet_size. */ bytes = USED(mp) * MP_DIGIT_SIZE; diff --git a/security/nss/lib/freebl/mpi/mpi.h b/security/nss/lib/freebl/mpi/mpi.h index d5aef46d7..af608b43d 100644 --- a/security/nss/lib/freebl/mpi/mpi.h +++ b/security/nss/lib/freebl/mpi/mpi.h @@ -288,7 +288,14 @@ void freebl_cpuid(unsigned long op, unsigned long *eax, #define DIGITS(MP) MP_DIGITS(MP) #define DIGIT(MP, N) MP_DIGIT(MP, N) +/* Functions which return an mp_err value will NULL-check their arguments via + * ARGCHK(condition, return), where the caller is responsible for checking the + * mp_err return code. For functions that return an integer type, the caller + * has no way to tell if the value is an error code or a legitimate value. + * Therefore, ARGMPCHK(condition) will trigger an assertion failure on debug + * builds, but no-op in optimized builds. */ #if MP_ARGCHK == 1 +#define ARGMPCHK(X) /* */ #define ARGCHK(X, Y) \ { \ if (!(X)) { \ @@ -297,9 +304,11 @@ void freebl_cpuid(unsigned long op, unsigned long *eax, } #elif MP_ARGCHK == 2 #include <assert.h> +#define ARGMPCHK(X) assert(X) #define ARGCHK(X, Y) assert(X) #else -#define ARGCHK(X, Y) /* */ +#define ARGMPCHK(X) /* */ +#define ARGCHK(X, Y) /* */ #endif #ifdef CT_VERIF |