@@ -6124,14 +6124,17 @@ int sp_leading_bit(const sp_int* a)
61246124int sp_set_bit(sp_int* a, int i)
61256125{
61266126 int err = MP_OKAY;
6127- /* Get index of word to set. */
6128- sp_size_t w = (sp_size_t)(i >> SP_WORD_SHIFT);
6127+ /* Compute word index in full int width so that bit indices large enough
6128+ * to make the word index overflow sp_size_t are caught by the bounds
6129+ * check below rather than wrapping. */
6130+ int wi = (i < 0) ? 0 : (i >> SP_WORD_SHIFT);
61296131
61306132 /* Check for valid number and space for bit. */
6131- if ((a == NULL) || (i < 0) || (w >= a->size)) {
6133+ if ((a == NULL) || (i < 0) || (wi >= (int) a->size)) {
61326134 err = MP_VAL;
61336135 }
61346136 if (err == MP_OKAY) {
6137+ sp_size_t w = (sp_size_t)wi;
61356138 /* Amount to shift up to set bit in word. */
61366139 unsigned int s = (unsigned int)(i & (SP_WORD_SIZE - 1));
61376140 unsigned int j;
@@ -8605,15 +8608,16 @@ void sp_rshd(sp_int* a, int c)
86058608{
86068609 /* Do shift if we have an SP int. */
86078610 if ((a != NULL) && (c > 0)) {
8608- /* Make zero if shift removes all digits. */
8609- if ((sp_size_t)c >= a->used) {
8611+ /* Compare c in int width to avoid narrowing to sp_size_t (which can
8612+ * be word16) before the bounds check. */
8613+ if (c >= (int)a->used) {
86108614 _sp_zero(a);
86118615 }
86128616 else {
86138617 sp_size_t i;
86148618
86158619 /* Update used digits count. */
8616- a->used = (sp_size_t)(a->used - c);
8620+ a->used = (sp_size_t)((int) a->used - c);
86178621 /* Move digits down. */
86188622 for (i = 0; i < a->used; i++, c++) {
86198623 a->dp[i] = a->dp[c];
@@ -8635,21 +8639,23 @@ void sp_rshd(sp_int* a, int c)
86358639int sp_rshb(const sp_int* a, int n, sp_int* r)
86368640{
86378641 int err = MP_OKAY;
8638- /* Number of digits to shift down. */
8639- sp_size_t i;
8642+ /* Compute the digit-shift count in full int width to avoid wrapping
8643+ * when n is large enough that the count would exceed sp_size_t range. */
8644+ int ni = (n < 0) ? 0 : (n >> SP_WORD_SHIFT);
86408645
86418646 if ((a == NULL) || (n < 0)) {
86428647 err = MP_VAL;
86438648 }
86448649 /* Handle case where shifting out all digits. */
8645- else if ((i = (sp_size_t)(n >> SP_WORD_SHIFT)) >= a->used) {
8650+ else if (ni > = (int) a->used) {
86468651 _sp_zero(r);
86478652 }
86488653 /* Change callers when more error cases returned. */
8649- else if ((err == MP_OKAY) && (a->used - i > r->size)) {
8654+ else if ((err == MP_OKAY) && ((int) a->used - ni > (int) r->size)) {
86508655 err = MP_VAL;
86518656 }
86528657 else if (err == MP_OKAY) {
8658+ sp_size_t i = (sp_size_t)ni;
86538659 sp_size_t j;
86548660
86558661 /* Number of bits to shift in digits. */
@@ -14848,16 +14854,25 @@ int sp_div_2d(const sp_int* a, int e, sp_int* r, sp_int* rem)
1484814854int sp_mod_2d(const sp_int* a, int e, sp_int* r)
1484914855{
1485014856 int err = MP_OKAY;
14851- sp_size_t digits = (sp_size_t)((e + SP_WORD_SIZE - 1) >> SP_WORD_SHIFT);
14857+ /* Compute digit count in full int width. Decompose to avoid signed
14858+ * overflow if e is near INT_MAX: (e + SP_WORD_SIZE - 1) >> SHIFT is
14859+ * equivalent to (e >> SHIFT) + (e has remainder ? 1 : 0). */
14860+ int digits_full = 0;
14861+ sp_size_t digits = 0;
1485214862
1485314863 if ((a == NULL) || (r == NULL) || (e < 0)) {
1485414864 err = MP_VAL;
1485514865 }
14856- if ((err == MP_OKAY) && (digits > r->size)) {
14857- err = MP_VAL;
14866+ if (err == MP_OKAY) {
14867+ digits_full = (e >> SP_WORD_SHIFT) +
14868+ (((e & (SP_WORD_SIZE - 1)) != 0) ? 1 : 0);
14869+ if (digits_full > (int)r->size) {
14870+ err = MP_VAL;
14871+ }
1485814872 }
1485914873
1486014874 if (err == MP_OKAY) {
14875+ digits = (sp_size_t)digits_full;
1486114876 /* Copy a into r if not same pointer. */
1486214877 if (a != r) {
1486314878 sp_size_t cnt = (a->used < digits) ? a->used : digits;
0 commit comments