@@ -6140,14 +6140,17 @@ int sp_leading_bit(const sp_int* a)
61406140int sp_set_bit(sp_int* a, int i)
61416141{
61426142 int err = MP_OKAY;
6143- /* Get index of word to set. */
6144- sp_size_t w = (sp_size_t)(i >> SP_WORD_SHIFT);
6143+ /* Compute word index in full int width so that bit indices large enough
6144+ * to make the word index overflow sp_size_t are caught by the bounds
6145+ * check below rather than wrapping. */
6146+ int wi = (i < 0) ? 0 : (i >> SP_WORD_SHIFT);
61456147
61466148 /* Check for valid number and space for bit. */
6147- if ((a == NULL) || (i < 0) || (w >= a->size)) {
6149+ if ((a == NULL) || (i < 0) || (wi >= (int) a->size)) {
61486150 err = MP_VAL;
61496151 }
61506152 if (err == MP_OKAY) {
6153+ sp_size_t w = (sp_size_t)wi;
61516154 /* Amount to shift up to set bit in word. */
61526155 unsigned int s = (unsigned int)(i & (SP_WORD_SIZE - 1));
61536156 unsigned int j;
@@ -8621,15 +8624,16 @@ void sp_rshd(sp_int* a, int c)
86218624{
86228625 /* Do shift if we have an SP int. */
86238626 if ((a != NULL) && (c > 0)) {
8624- /* Make zero if shift removes all digits. */
8625- if ((sp_size_t)c >= a->used) {
8627+ /* Compare c in int width to avoid narrowing to sp_size_t (which can
8628+ * be word16) before the bounds check. */
8629+ if (c >= (int)a->used) {
86268630 _sp_zero(a);
86278631 }
86288632 else {
86298633 sp_size_t i;
86308634
86318635 /* Update used digits count. */
8632- a->used = (sp_size_t)(a->used - c);
8636+ a->used = (sp_size_t)((int) a->used - c);
86338637 /* Move digits down. */
86348638 for (i = 0; i < a->used; i++, c++) {
86358639 a->dp[i] = a->dp[c];
@@ -8651,21 +8655,23 @@ void sp_rshd(sp_int* a, int c)
86518655int sp_rshb(const sp_int* a, int n, sp_int* r)
86528656{
86538657 int err = MP_OKAY;
8654- /* Number of digits to shift down. */
8655- sp_size_t i;
8658+ /* Compute the digit-shift count in full int width to avoid wrapping
8659+ * when n is large enough that the count would exceed sp_size_t range. */
8660+ int ni = (n < 0) ? 0 : (n >> SP_WORD_SHIFT);
86568661
86578662 if ((a == NULL) || (n < 0)) {
86588663 err = MP_VAL;
86598664 }
86608665 /* Handle case where shifting out all digits. */
8661- else if ((i = (sp_size_t)(n >> SP_WORD_SHIFT)) >= a->used) {
8666+ else if (ni > = (int) a->used) {
86628667 _sp_zero(r);
86638668 }
86648669 /* Change callers when more error cases returned. */
8665- else if ((err == MP_OKAY) && (a->used - i > r->size)) {
8670+ else if ((err == MP_OKAY) && ((int) a->used - ni > (int) r->size)) {
86668671 err = MP_VAL;
86678672 }
86688673 else if (err == MP_OKAY) {
8674+ sp_size_t i = (sp_size_t)ni;
86698675 sp_size_t j;
86708676
86718677 /* Number of bits to shift in digits. */
@@ -14914,16 +14920,25 @@ int sp_div_2d(const sp_int* a, int e, sp_int* r, sp_int* rem)
1491414920int sp_mod_2d(const sp_int* a, int e, sp_int* r)
1491514921{
1491614922 int err = MP_OKAY;
14917- sp_size_t digits = (sp_size_t)((e + SP_WORD_SIZE - 1) >> SP_WORD_SHIFT);
14923+ /* Compute digit count in full int width. Decompose to avoid signed
14924+ * overflow if e is near INT_MAX: (e + SP_WORD_SIZE - 1) >> SHIFT is
14925+ * equivalent to (e >> SHIFT) + (e has remainder ? 1 : 0). */
14926+ int digits_full = 0;
14927+ sp_size_t digits = 0;
1491814928
1491914929 if ((a == NULL) || (r == NULL) || (e < 0)) {
1492014930 err = MP_VAL;
1492114931 }
14922- if ((err == MP_OKAY) && (digits > r->size)) {
14923- err = MP_VAL;
14932+ if (err == MP_OKAY) {
14933+ digits_full = (e >> SP_WORD_SHIFT) +
14934+ (((e & (SP_WORD_SIZE - 1)) != 0) ? 1 : 0);
14935+ if (digits_full > (int)r->size) {
14936+ err = MP_VAL;
14937+ }
1492414938 }
1492514939
1492614940 if (err == MP_OKAY) {
14941+ digits = (sp_size_t)digits_full;
1492714942 /* Copy a into r if not same pointer. */
1492814943 if (a != r) {
1492914944 sp_size_t cnt = (a->used < digits) ? a->used : digits;
0 commit comments