@@ -1346,7 +1346,9 @@ static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng);
13461346 !defined(WOLFSSL_CRYPTOCELL)
13471347
13481348#ifndef WOLFSSL_SP_MATH
1349+ #if !defined(SQRTMOD_USE_MOD_EXP)
13491350static int mp_jacobi(mp_int* a, mp_int* n, int* c);
1351+ #endif
13501352static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
13511353#endif
13521354#endif
@@ -14480,6 +14482,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
1448014482 !defined(WOLFSSL_CRYPTOCELL)
1448114483
1448214484#ifndef WOLFSSL_SP_MATH
14485+ #if !defined(SQRTMOD_USE_MOD_EXP)
1448314486/* computes the jacobi c = (a | n) (or Legendre if n is prime)
1448414487 */
1448514488static int mp_jacobi(mp_int* a, mp_int* n, int* c)
@@ -14599,6 +14602,7 @@ static int mp_jacobi(mp_int* a, mp_int* n, int* c)
1459914602
1460014603 return res;
1460114604}
14605+ #endif /* !SQRTMOD_USE_MOD_EXP */
1460214606
1460314607
1460414608/* Solves the modular equation x^2 = n (mod p)
@@ -14608,18 +14612,44 @@ static int mp_jacobi(mp_int* a, mp_int* n, int* c)
1460814612 */
1460914613static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
1461014614{
14611- #ifdef SQRTMOD_USE_MOD_EXP
14615+ #if defined( SQRTMOD_USE_MOD_EXP)
1461214616 int res;
14613-
14617+ mp_digit i;
1461414618 mp_int e;
1461514619
14620+ /* first handle the simple cases n = 0 or n = 1 */
14621+ if (mp_cmp_d(n, 0) == MP_EQ) {
14622+ mp_zero(ret);
14623+ return MP_OKAY;
14624+ }
14625+ if (mp_cmp_d(n, 1) == MP_EQ) {
14626+ return mp_set(ret, 1);
14627+ }
14628+
14629+ if (mp_iseven(prime)) {
14630+ return MP_VAL;
14631+ }
14632+
1461614633 SAVE_VECTOR_REGISTERS(return _svr_ret;);
1461714634
1461814635 res = mp_init(&e);
1461914636 if (res == MP_OKAY)
14637+ res = mp_mod_d(prime, 8, &i);
14638+ if (res == MP_OKAY && i == 1) {
14639+ return MP_VAL;
14640+ }
14641+ /* prime mod 8 = 5 */
14642+ else if (res == MP_OKAY && i == 5) {
14643+ res = mp_sub_d(prime, 1, &e);
14644+ if (res == MP_OKAY)
14645+ res = mp_div_2d(&e, 2, &e, NULL);
14646+ }
14647+ /* prime mod 4 = 3 */
14648+ else if (res == MP_OKAY && ((i == 3) || (i == 7))) {
1462014649 res = mp_add_d(prime, 1, &e);
14621- if (res == MP_OKAY)
14622- res = mp_div_2d(&e, 2, &e, NULL);
14650+ if (res == MP_OKAY)
14651+ res = mp_div_2d(&e, 2, &e, NULL);
14652+ }
1462314653 if (res == MP_OKAY)
1462414654 res = mp_exptmod(n, &e, prime, ret);
1462514655
@@ -14758,6 +14788,15 @@ static int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
1475814788 if (res == MP_OKAY && legendre == -1)
1475914789 break;
1476014790
14791+ #if defined(WOLFSSL_CUSTOM_CURVES)
14792+ /* P224R1 succeeds with a value of 11. */
14793+ if (mp_cmp_d(Z, 22) == MP_EQ) {
14794+ /* This is to clamp the loop in case 'prime' is not really prime */
14795+ res = MP_VAL;
14796+ break;
14797+ }
14798+ #endif
14799+
1476114800 /* Z = Z + 1 */
1476214801 if (res == MP_OKAY)
1476314802 res = mp_add_d(Z, 1, Z);
0 commit comments