Skip to content

Commit ff487da

Browse files
committed
Reject even moduli in sp_exptmod_nct for all RSA verify/public builds
No RSA, DH or ECC modulus is even, so the guard no longer depends on DH.
1 parent 173f2fd commit ff487da

3 files changed

Lines changed: 28 additions & 33 deletions

File tree

‎.github/configs/os-check-linux.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,11 +563,11 @@
563563
"--disable-dh", "--disable-fpecc", "--with-eccminsz=160",
564564
"--enable-ecccustcurves=all"]},
565565
{"name": "cryptonly-rsapub-no-dh-public-mp", "minutes": 1.0,
566-
"comment": "RSA public only with DH off, so sp_exptmod_ex hands every modulus to sp_exptmod_nct and the constant-time generic exponentiation is not compiled. WOLFSSL_PUBLIC_MP lets wolfcrypt test run mp_test, whose even modulus checks confirm sp_exptmod_nct returns MP_VAL in this shape instead of a wrong Montgomery result.",
566+
"comment": "RSA public only with DH off, so sp_exptmod_ex hands every modulus to sp_exptmod_nct. WOLFSSL_PUBLIC_MP lets wolfcrypt test run mp_test, whose even modulus checks confirm both return MP_VAL instead of a wrong Montgomery result.",
567567
"configure": ["--enable-cryptonly", "--enable-rsapub", "--disable-dh",
568568
"--disable-examples", "CPPFLAGS=-DWOLFSSL_PUBLIC_MP"]},
569569
{"name": "cryptonly-rsapub-public-mp", "minutes": 1.0,
570-
"comment": "RSA public only with DH at its default (on), so the generic exponentiation is compiled and sp_exptmod_nct must use it for an even modulus rather than Montgomery. WOLFSSL_PUBLIC_MP lets wolfcrypt test run mp_test's even modulus checks in this shape.",
570+
"comment": "RSA public only with DH at its default (on). sp_exptmod_ex keeps its existing route for an even modulus to the generic exponentiation, while sp_exptmod_nct returns MP_VAL. WOLFSSL_PUBLIC_MP lets wolfcrypt test run mp_test's even modulus checks in this shape.",
571571
"configure": ["--enable-cryptonly", "--enable-rsapub",
572572
"--disable-examples", "CPPFLAGS=-DWOLFSSL_PUBLIC_MP"]},
573573
{"name": "pkcs12-pbkdf-mp-api", "minutes": 1.0,

‎wolfcrypt/src/sp_int.c‎

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14200,7 +14200,7 @@ static int _sp_exptmod_base_2(const sp_int* e, int digits, const sp_int* m,
1420014200
* @return MP_OKAY on success.
1420114201
* @return MP_VAL when b, e, m or r is NULL, digits is negative, or m <= 0 or
1420214202
* e is negative; or m is even in an RSA verify/public only build
14203-
* without DH or OPENSSL_ALL.
14203+
* without DH.
1420414204
* @return MP_MEM when dynamic memory allocation fails.
1420514205
*/
1420614206
int sp_exptmod_ex(const sp_int* b, const sp_int* e, int digits, const sp_int* m,
@@ -14381,8 +14381,7 @@ int sp_exptmod_ex(const sp_int* b, const sp_int* e, int digits, const sp_int* m,
1438114381
*
1438214382
* @return MP_OKAY on success.
1438314383
* @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative; or
14384-
* m is even in an RSA verify/public only build without DH or
14385-
* OPENSSL_ALL.
14384+
* m is even in an RSA verify/public only build without DH.
1438614385
* @return MP_MEM when dynamic memory allocation fails.
1438714386
*/
1438814387
int sp_exptmod(const sp_int* b, const sp_int* e, const sp_int* m, sp_int* r)
@@ -14843,8 +14842,8 @@ static int _sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
1484314842
*
1484414843
* @return MP_OKAY on success.
1484514844
* @return MP_VAL when b, e, m or r is NULL; or m <= 0 or e is negative; or
14846-
* m is even in an RSA verify/public only build without DH or
14847-
* OPENSSL_ALL.
14845+
* m is even in an RSA verify/public only build, even where
14846+
* sp_exptmod_ex accepts it (DH builds).
1484814847
* @return MP_MEM when dynamic memory allocation fails.
1484914848
*/
1485014849
int sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m, sp_int* r)
@@ -14892,14 +14891,10 @@ int sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m, sp_int* r)
1489214891
err = MP_VAL;
1489314892
}
1489414893
else if (mp_iseven(m)) {
14895-
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \
14896-
!defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH) || \
14897-
defined(OPENSSL_ALL)
14894+
#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)
1489814895
err = _sp_exptmod_ex(b, e, (int)(e->used * SP_WORD_SIZE), m, r);
1489914896
#else
14900-
/* Montgomery form requires an odd modulus and the generic
14901-
* implementation is not compiled in (RSA verify/public only without
14902-
* DH). */
14897+
/* Montgomery form requires an odd modulus. */
1490314898
err = MP_VAL;
1490414899
#endif
1490514900
}

‎wolfcrypt/test/test.c‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96192,43 +96192,43 @@ static wc_test_ret_t mp_test_exptmod(mp_int* b, mp_int* e, mp_int* m, mp_int* r,
9619296192
return WC_TEST_RET_ENC_NC;
9619396193
}
9619496194

96195-
/* Even, multi-word modulus uses the generic exponentiation path for
96196-
* both mp_exptmod_ex and mp_exptmod_nct. Verify b^6 mod m against
96197-
* repeated modular multiplication. RSA public only builds without DH
96198-
* do not compile the generic path, and mp_exptmod_ex hands every modulus
96199-
* to mp_exptmod_nct, so both must reject the even modulus instead of
96200-
* returning a wrong Montgomery result. */
96195+
/* Even, multi-word modulus. Verify b^6 mod m against repeated modular
96196+
* multiplication. RSA verify/public only builds reject an even modulus
96197+
* in mp_exptmod_nct rather than return a wrong Montgomery result.
96198+
* Without DH, mp_exptmod_ex hands every modulus to mp_exptmod_nct, so it
96199+
* rejects it too; with DH it uses the generic exponentiation. */
9620196200
if ((ret = mp_set(m, 1)) != MP_OKAY ||
9620296201
(ret = mp_mul_2d(m, 521, m)) != MP_OKAY || /* m = 2^521 (even) */
9620396202
(ret = mp_set(b, 7)) != MP_OKAY ||
96204-
(ret = mp_set(e, 6)) != MP_OKAY) {
96203+
(ret = mp_set(e, 6)) != MP_OKAY ||
96204+
(ret = mp_set(t, 1)) != MP_OKAY) {
9620596205
return WC_TEST_RET_ENC_EC(ret);
9620696206
}
96207+
for (k = 0; k < 6; k++) {
96208+
if ((ret = mp_mulmod(t, b, m, t)) != MP_OKAY) {
96209+
return WC_TEST_RET_ENC_EC(ret);
96210+
}
96211+
}
9620796212
#if (defined(WOLFSSL_RSA_VERIFY_ONLY) || defined(WOLFSSL_RSA_PUBLIC_ONLY)) && \
96208-
defined(NO_DH) && !defined(OPENSSL_ALL)
96213+
defined(NO_DH)
9620996214
ret = mp_exptmod_ex(b, e, (int)e->used, m, r);
9621096215
if (ret != WC_NO_ERR_TRACE(MP_VAL)) {
9621196216
return WC_TEST_RET_ENC_EC(ret);
9621296217
}
96213-
ret = mp_exptmod_nct(b, e, m, r);
96214-
if (ret != WC_NO_ERR_TRACE(MP_VAL)) {
96215-
return WC_TEST_RET_ENC_EC(ret);
96216-
}
9621796218
#else
96218-
if ((ret = mp_set(t, 1)) != MP_OKAY) {
96219-
return WC_TEST_RET_ENC_EC(ret);
96220-
}
96221-
for (k = 0; k < 6; k++) {
96222-
if ((ret = mp_mulmod(t, b, m, t)) != MP_OKAY) {
96223-
return WC_TEST_RET_ENC_EC(ret);
96224-
}
96225-
}
9622696219
if ((ret = mp_exptmod_ex(b, e, (int)e->used, m, r)) != MP_OKAY) {
9622796220
return WC_TEST_RET_ENC_EC(ret);
9622896221
}
9622996222
if (mp_cmp(r, t) != MP_EQ) {
9623096223
return WC_TEST_RET_ENC_NC;
9623196224
}
96225+
#endif
96226+
#if defined(WOLFSSL_RSA_VERIFY_ONLY) || defined(WOLFSSL_RSA_PUBLIC_ONLY)
96227+
ret = mp_exptmod_nct(b, e, m, r);
96228+
if (ret != WC_NO_ERR_TRACE(MP_VAL)) {
96229+
return WC_TEST_RET_ENC_EC(ret);
96230+
}
96231+
#else
9623296232
if ((ret = mp_exptmod_nct(b, e, m, r)) != MP_OKAY) {
9623396233
return WC_TEST_RET_ENC_EC(ret);
9623496234
}

0 commit comments

Comments
 (0)