diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 99287dfee..9c05fb883 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -11896,10 +11896,12 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) else if (m->used == 4) { sp_int_digit l; sp_int_digit h; + sp_int_digit o2; l = 0; h = 0; o = 0; + o2 = 0; for (i = 0; i < 4; i++) { mu = mp * a->dp[i]; if ((i == 3) && (mask != 0)) { @@ -11919,15 +11921,17 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[2]); a->dp[i + 2] = l; l = h; - h = 0; + h = o2; + o2 = 0; SP_ASM_ADDC_REG(l, h, o); SP_ASM_ADDC(l, h, a->dp[i + 3]); - SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[3]); + SP_ASM_MUL_ADD(l, h, o2, mu, m->dp[3]); a->dp[i + 3] = l; o = h; l = h; h = 0; } + h = o2; SP_ASM_ADDC(l, h, a->dp[7]); a->dp[7] = l; a->dp[8] = h; @@ -11936,10 +11940,12 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) else if (m->used == 6) { sp_int_digit l; sp_int_digit h; + sp_int_digit o2; l = 0; h = 0; o = 0; + o2 = 0; for (i = 0; i < 6; i++) { mu = mp * a->dp[i]; if ((i == 5) && (mask != 0)) { @@ -11969,15 +11975,17 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[4]); a->dp[i + 4] = l; l = h; - h = 0; + h = o2; + o2 = 0; SP_ASM_ADDC_REG(l, h, o); SP_ASM_ADDC(l, h, a->dp[i + 5]); - SP_ASM_MUL_ADD_NO(l, h, mu, m->dp[5]); + SP_ASM_MUL_ADD(l, h, o2, mu, m->dp[5]); a->dp[i + 5] = l; o = h; l = h; h = 0; } + h = o2; SP_ASM_ADDC(l, h, a->dp[11]); a->dp[11] = l; a->dp[12] = h; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7cd327650..84d6104e5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -35851,6 +35851,7 @@ static int mp_test_mont(mp_int* a, mp_int* m, mp_int* n, mp_int* r, WC_RNG* rng) 0x01, 0x9f, 0x13, 0xbd, 0x1f, 0x13d, 0x45, 0x615 }; + int bits[] = { 256, 384, 2048, 3072 }; int i; int j; @@ -35908,6 +35909,31 @@ static int mp_test_mont(mp_int* a, mp_int* m, mp_int* n, mp_int* r, WC_RNG* rng) } } + /* Force carries. */ + for (i = 0; i < (int)(sizeof(bits) / sizeof(*bits)); i++) { + /* a = 2^(bits*2) - 1 */ + mp_zero(a); + mp_set_bit(a, bits[i] * 2); + mp_sub_d(a, 1, a); + /* m = 2^(bits) - 1 */ + mp_zero(m); + mp_set_bit(m, bits[i]); + mp_sub_d(m, 1, m); + mp = 1; + /* result = r = 2^(bits) - 1 */ + mp_zero(r); + mp_set_bit(r, bits[i]); + mp_sub_d(r, 1, r); + + ret = mp_montgomery_reduce(a, m, mp); + if (ret != MP_OKAY) + return -13240; + + /* Result is m or 0 if reduced to range of modulus. */ + if (mp_cmp(a, r) != MP_EQ && mp_iszero(a) != MP_YES) + return -13241; + } + return 0; } #endif