diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 669d54d43..ddaad3f59 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -3903,25 +3903,32 @@ int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) } -/* 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, 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(long) * 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 >> (32 - 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; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index fd9840dcd..274bcc4be 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1484,7 +1484,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY) return err; - err = mp_set_int(&tmp3, (mp_digit)e); + err = mp_set_int(&tmp3, e); /* make p */ if (err == MP_OKAY) { diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 6b63b6aa1..68738b36b 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1963,6 +1963,40 @@ void fp_set(fp_int *a, fp_digit b) a->used = a->dp[0] ? 1 : 0; } + +#ifndef MP_SET_CHUNK_BITS + #define MP_SET_CHUNK_BITS 4 +#endif +void fp_set_int(fp_int *a, unsigned long b) +{ + int x; + + /* use direct fp_set if b is less than fp_digit max */ + if (b < FP_DIGIT_MAX) { + fp_set (a, b); + return; + } + + fp_zero (a); + + /* set chunk bits at a time */ + for (x = 0; x < (int)(sizeof(long) * 8) / MP_SET_CHUNK_BITS; x++) { + fp_mul_2d (a, MP_SET_CHUNK_BITS, a); + + /* OR in the top bits of the source */ + a->dp[0] |= (b >> (32 - MP_SET_CHUNK_BITS)) & ((1 << MP_SET_CHUNK_BITS) - 1); + + /* shift the source up to the next chunk bits */ + b <<= MP_SET_CHUNK_BITS; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + + /* clamp digits */ + fp_clamp(a); +} + /* check if a bit is set */ int fp_is_bit_set (fp_int *a, fp_digit b) { @@ -2440,9 +2474,9 @@ void mp_rshd (mp_int* a, int x) fp_rshd(a, x); } -int mp_set_int(mp_int *a, mp_digit b) +int mp_set_int(mp_int *a, unsigned long b) { - fp_set(a, b); + fp_set_int(a, b); return MP_OKAY; } diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 8d3d7077d..8427412d0 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -260,6 +260,7 @@ #endif #define FP_MASK (fp_digit)(-1) +#define FP_DIGIT_MAX FP_MASK #define FP_SIZE (FP_MAX_SIZE/DIGIT_BIT) /* signs */ @@ -382,6 +383,7 @@ void fp_clear(fp_int *a); /* uses ForceZero to clear sensitive memory */ /* set to a small digit */ void fp_set(fp_int *a, fp_digit b); +void fp_set_int(fp_int *a, unsigned long b); /* check if a bit is set */ int fp_is_bit_set(fp_int *a, fp_digit b); @@ -650,7 +652,7 @@ int mp_isodd(mp_int* a); int mp_iszero(mp_int* a); int mp_count_bits(mp_int *a); int mp_leading_bit(mp_int *a); -int mp_set_int(mp_int *a, mp_digit b); +int mp_set_int(mp_int *a, unsigned long b); int mp_is_bit_set (mp_int * a, mp_digit b); int mp_set_bit (mp_int * a, mp_digit b); void mp_rshb(mp_int *a, int x);