Skip to content

Commit 89b40e0

Browse files
committed
Return an error if SHA-1 used with RSA signing.
1 parent 6499cab commit 89b40e0

File tree

10 files changed

+222
-5
lines changed

10 files changed

+222
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ make
6363
sudo make install
6464
```
6565

66-
Add `--enable-fips=v2` to the configure command above if building from a FIPS bundle and not the git repository.
66+
Remove `-DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_PSS_SALT_LEN_DISCOVER` and add `--enable-fips=v2` to the configure command above if building from a FIPS bundle and not the git repository.
6767

6868
### wolfEngine
6969

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
2+
index f038bea31d..e81a34d4d4 100644
3+
--- a/test/recipes/80-test_cms.t
4+
+++ b/test/recipes/80-test_cms.t
5+
@@ -108,7 +108,7 @@ my @smime_pkcs7_tests = (
6+
],
7+
8+
[ "signed content S/MIME format, RSA key SHA1",
9+
- [ "-sign", "-in", $smcont, "-md", "sha1",
10+
+ [ "-sign", "-in", $smcont, "-md", "sha256",
11+
"-certfile", catfile($smdir, "smroot.pem"),
12+
"-signer", catfile($smdir, "smrsa1.pem"), "-out", "test.cms" ],
13+
[ "-verify", "-in", "test.cms",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t
2+
index 377bf090ba..ec10448c55 100644
3+
--- a/test/recipes/80-test_ssl_old.t
4+
+++ b/test/recipes/80-test_ssl_old.t
5+
@@ -32,8 +32,8 @@ my $no_anydtls = alldisabled(available_protocols("dtls"));
6+
plan skip_all => "No SSL/TLS/DTLS protocol is support by this OpenSSL build"
7+
if $no_anytls && $no_anydtls;
8+
9+
-my $digest = "-sha1";
10+
-my @reqcmd = ("openssl", "req");
11+
+my $digest = "-sha256";
12+
+my @reqcmd = ("openssl", "req", $digest);
13+
my @x509cmd = ("openssl", "x509", $digest);
14+
my @verifycmd = ("openssl", "verify");
15+
my @gendsacmd = ("openssl", "gendsa");
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
diff --git a/test/recipes/30-test_evp_data/evppkey.txt b/test/recipes/30-test_evp_data/evppkey.txt
2+
index 736e0ce4d3..4ebbc27d50 100644
3+
--- a/test/recipes/30-test_evp_data/evppkey.txt
4+
+++ b/test/recipes/30-test_evp_data/evppkey.txt
5+
@@ -134,6 +134,7 @@ Sign = RSA-2048
6+
Ctrl = digest:SHA1
7+
Input = "0123456789ABCDEF1234"
8+
Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
9+
+Result = KEYOP_LENGTH_ERROR
10+
11+
Verify = RSA-2048
12+
Ctrl = digest:SHA1
13+
@@ -162,14 +163,14 @@ Sign = RSA-2048
14+
Ctrl = digest:SHA1
15+
Input = "0123456789ABCDEF12345"
16+
Output = 00
17+
-Result = KEYOP_ERROR
18+
+Result = KEYOP_LENGTH_ERROR
19+
20+
# Digest too short
21+
Sign = RSA-2048
22+
Ctrl = digest:SHA1
23+
Input = "0123456789ABCDEF12345"
24+
Output = 00
25+
-Result = KEYOP_ERROR
26+
+Result = KEYOP_LENGTH_ERROR
27+
28+
# Mismatched digest
29+
Verify = RSA-2048
30+
@@ -17402,6 +17403,7 @@ DigestSign = SHA1
31+
Key = RSA-2048
32+
Input = "Hello World"
33+
Output = 3da3ca2bdd1b23a231b0e3c49d95d5959f9398c27a1e534c7e6baf1d2682304d3b6b229385b1edf483f5ef6f9b35bf10c519a302bb2f79c564e1a59ba71aa2fa36df96c942c43e8d9bd4702b5f61c12a078ae2b34d0de221fc8f9f936b79a67c89d11ba5da8c63a1370d0e824c6b661123e9b58b143ff533cf362cbdad70e65b419a6d45723bf22db3c76bb8f5337c5c5c93cb6f38b30d0c835b54c23405ca4217dd0b755f3712ebad285d9e0c02655f6ce5ce6fed78f3c81843de325f628055eef57f280dee0c3170050137ee599b9ab7f2b5d3c5f831777ea05a5eb097c70bad1a7214dadae12d7960bb9425390c7d25a79985e1e3c28ad422ff93c808f4b5
34+
+Result = DIGESTSIGNFINAL_LENGTH_ERROR
35+
36+
DigestSign = SHA256
37+
Key = RSA-2048
38+
@@ -17455,6 +17457,7 @@ OneShotDigestSign = SHA1
39+
Key = RSA-2048
40+
Input = "Hello World"
41+
Output = 3da3ca2bdd1b23a231b0e3c49d95d5959f9398c27a1e534c7e6baf1d2682304d3b6b229385b1edf483f5ef6f9b35bf10c519a302bb2f79c564e1a59ba71aa2fa36df96c942c43e8d9bd4702b5f61c12a078ae2b34d0de221fc8f9f936b79a67c89d11ba5da8c63a1370d0e824c6b661123e9b58b143ff533cf362cbdad70e65b419a6d45723bf22db3c76bb8f5337c5c5c93cb6f38b30d0c835b54c23405ca4217dd0b755f3712ebad285d9e0c02655f6ce5ce6fed78f3c81843de325f628055eef57f280dee0c3170050137ee599b9ab7f2b5d3c5f831777ea05a5eb097c70bad1a7214dadae12d7960bb9425390c7d25a79985e1e3c28ad422ff93c808f4b5
42+
+Result = DIGESTSIGN_LENGTH_ERROR
43+
44+
Title = ED25519 tests from RFC8032
45+

scripts/openssl-unit-tests.sh

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,7 @@ EOF
124124
export OPENSSL_CONF=$TMP_CONF
125125
}
126126

127-
patch_openssl() {
128-
printf "\tPatching unit tests to use wolfEngine.\n"
129-
PATCHES=`find $TEST_PATCH_DIR -name "*.patch"`
127+
apply_patches() {
130128
for PATCH in $PATCHES
131129
do
132130
# Try to patch. If doesn't work, check whether it has already been
@@ -140,6 +138,32 @@ patch_openssl() {
140138
done
141139
}
142140

141+
patch_openssl_fips() {
142+
if [ "$WOLFSSL_FIPS" == 1 ]; then
143+
cd $OPENSSL_SOURCE
144+
printf "Patching unit tests to support wolfCrypt FIPS.\n"
145+
if [ -d "$TEST_PATCH_DIR/fips" ]; then
146+
PATCHES=`find $TEST_PATCH_DIR/fips -name "*.patch"`
147+
apply_patches
148+
fi
149+
printf "\tRebuilding patched tests.\n"
150+
make -j$MAKE_JOBS 2>&1 | tee -a $LOGFILE
151+
if [ "${PIPESTATUS[0]}" != 0 ]; then
152+
printf "make failed\n"
153+
do_cleanup
154+
exit 1
155+
fi
156+
else
157+
printf "Skipping unit test FIPS patches.\n"
158+
fi
159+
}
160+
161+
patch_openssl() {
162+
printf "\tPatching unit tests to use wolfEngine.\n"
163+
PATCHES=`find $TEST_PATCH_DIR -maxdepth 1 -name "*.patch"`
164+
apply_patches
165+
}
166+
143167
setup_openssl_102h() {
144168
printf "Setting up OpenSSL 1.0.2h.\n"
145169
if [ -z "${OPENSSL_1_0_2_SOURCE}" ]; then
@@ -230,6 +254,28 @@ setup_openssl_111b() {
230254
fi
231255
}
232256

257+
check_fips() {
258+
printf "Checking if libwolfssl is FIPS.\n"
259+
local LIBWOLFENGINE="$WOLFENGINE_LIBS/libwolfengine.so"
260+
if [ ! -f $LIBWOLFENGINE ]; then
261+
printf "\tlibwolfengine.so not built yet, can't do FIPS check.\n"
262+
else
263+
local LIBWOLFSSL=$(ldd $LIBWOLFENGINE | grep -oP "(?<!=>)+\/.*(libwolfssl\.so(\.[0-9]+)*)")
264+
if [ -z "$LIBWOLFSSL" ]; then
265+
printf "\tUnable to find libwolfssl.\n"
266+
else
267+
nm $LIBWOLFSSL | grep -q "fipsEntry"
268+
if [ $? == 0 ]; then
269+
printf "\tlibwolfssl is FIPS.\n"
270+
WOLFSSL_FIPS=1
271+
else
272+
printf "\tlibwolfssl is not FIPS.\n"
273+
WOLFSSL_FIPS=0
274+
fi
275+
fi
276+
fi
277+
}
278+
233279
build_wolfssl() {
234280
if [ -z "${WOLFENGINE_NO_BUILD}" ]; then
235281
printf "Setting up wolfEngine to use $OPENSSL_VERS_STR.\n"
@@ -259,6 +305,9 @@ build_wolfssl() {
259305
exit 1
260306
fi
261307
fi
308+
309+
check_fips
310+
patch_openssl_fips
262311
}
263312

264313
run_patched_tests() {

src/we_hkdf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static void we_hkdf_cleanup(EVP_PKEY_CTX *ctx)
116116
* Derive the key from the key and info.
117117
*
118118
* @param ctx [in] PKEY context.
119-
* @param key [in] Calculated key data.
119+
* @param key [out] Calculated key data.
120120
* @param keySz [in,out] On in, size of key data to calculate in bytes.
121121
* On out, size of key data in bytes. When extracting
122122
* only this will be the size of the digest.

src/we_rsa.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,32 @@ static int we_check_rsa_key_size(int size, int allow1024) {
107107
return ret;
108108
}
109109

110+
/**
111+
* Check that the digest used for signing is allowed. For FIPS, SHA-1 isn't
112+
* allowed for signing, only verifying.
113+
*
114+
* @param nid [in] The OpenSSL numerical ID of the digest.
115+
* @returns 1 if the digest is allowed, 0 if it isn't.
116+
*/
117+
static int we_check_rsa_signing_md(int nid) {
118+
int ret = 1;
119+
120+
(void) nid;
121+
122+
WOLFENGINE_ENTER(WE_LOG_PK, "we_check_rsa_md");
123+
124+
#if defined(HAVE_FIPS) || defined(HAVE_FIPS_VERSION)
125+
if (fipsChecks == 1 && nid == NID_sha1) {
126+
ret = 0;
127+
WOLFENGINE_ERROR_MSG(WE_LOG_PK, "SHA-1 isn't allowed in FIPS mode.");
128+
}
129+
#endif /* HAVE_FIPS || HAVE_FIPS_VERSION */
130+
131+
WOLFENGINE_LEAVE(WE_LOG_PK, "we_check_rsa_md", ret);
132+
133+
return ret;
134+
}
135+
110136
/**
111137
* Convert an OpenSSL hash NID to a wolfSSL MGF1 algorithm.
112138
*
@@ -2023,6 +2049,11 @@ static int we_rsa_pkey_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
20232049
ret = 0;
20242050
}
20252051

2052+
if (rsa->md != NULL &&
2053+
we_check_rsa_signing_md(EVP_MD_type(rsa->md)) != 1) {
2054+
ret = 0;
2055+
}
2056+
20262057
/* Set up private key */
20272058
if ((ret == 1) && (!rsa->privKeySet)) {
20282059
/* OpenSSL RSA key in EVP PKEY associated with context. */

test/test_rsa.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,68 @@ static int test_rsa_sign_verify_pad(ENGINE *e, int padMode, const EVP_MD *md,
827827
return err;
828828
}
829829

830+
int test_rsa_sign_sha1(ENGINE *e, void *data)
831+
{
832+
int err = 0;
833+
834+
(void)data;
835+
(void)e;
836+
#if defined(HAVE_FIPS) || defined(HAVE_FIPS_VERSION)
837+
/* Signing with wolfEngine should fail, but verifying with wolfEngine should
838+
* succeed. In FIPS mode, we can only verify RSA signatures using SHA-1, not
839+
* generate them. */
840+
EVP_PKEY *pkey = NULL;
841+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
842+
const RSA *rsaKey = NULL;
843+
#else
844+
RSA *rsaKey = NULL;
845+
#endif
846+
unsigned char *rsaSig = NULL;
847+
size_t rsaSigLen = 0;
848+
unsigned char buf[20];
849+
const unsigned char *p = rsa_key_der_2048;
850+
851+
PRINT_MSG("Load RSA key");
852+
pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &p, sizeof(rsa_key_der_2048));
853+
err = pkey == NULL;
854+
if (err == 0) {
855+
rsaKey = EVP_PKEY_get0_RSA(pkey);
856+
err = rsaKey == NULL;
857+
}
858+
if (err == 0) {
859+
rsaSigLen = RSA_size(rsaKey);
860+
rsaSig = (unsigned char*)OPENSSL_malloc(rsaSigLen);
861+
err = rsaSig == NULL;
862+
}
863+
if (err == 0) {
864+
err = RAND_bytes(buf, sizeof(buf)) == 0;
865+
}
866+
867+
if (err == 0) {
868+
PRINT_MSG("Sign with OpenSSL");
869+
err = test_digest_sign(pkey, NULL, buf, sizeof(buf), EVP_sha1(),
870+
rsaSig, &rsaSigLen, 0);
871+
}
872+
if (err == 0) {
873+
PRINT_MSG("Verify with wolfengine");
874+
err = test_digest_verify(pkey, e, buf, sizeof(buf), EVP_sha1(),
875+
rsaSig, rsaSigLen, 0);
876+
}
877+
if (err == 0) {
878+
PRINT_MSG("Sign with wolfengine");
879+
rsaSigLen = RSA_size(rsaKey);
880+
err = test_digest_sign(pkey, e, buf, sizeof(buf), EVP_sha1(),
881+
rsaSig, &rsaSigLen, 0) != 1;
882+
}
883+
EVP_PKEY_free(pkey);
884+
885+
if (rsaSig)
886+
OPENSSL_free(rsaSig);
887+
#endif /* HAVE_FIPS || HAVE_FIPS_VERSION */
888+
889+
return err;
890+
}
891+
830892
int test_rsa_sign_verify_pkcs1(ENGINE *e, void *data)
831893
{
832894
(void)data;

test/unit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ TEST_CASE test_case[] = {
167167
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
168168
#ifdef WE_HAVE_EVP_PKEY
169169
#ifdef WE_HAVE_RSA
170+
TEST_DECL(test_rsa_sign_sha1, NULL),
170171
TEST_DECL(test_rsa_sign_verify_pkcs1, NULL),
171172
TEST_DECL(test_rsa_sign_verify_no_pad, NULL),
172173
TEST_DECL(test_rsa_sign_verify_pss, NULL),

test/unit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ int test_pkey_enc_rsa(EVP_PKEY *pkey, ENGINE *e, unsigned char *msg, size_t msgL
217217
int test_pkey_dec_rsa(EVP_PKEY *pkey, ENGINE *e, unsigned char *msg, size_t msgLen,
218218
unsigned char *ciphertext, size_t cipherLen, int padMode,
219219
const EVP_MD *rsaMd, const EVP_MD *rsaMgf1Md);
220+
int test_rsa_sign_sha1(ENGINE *e, void *data);
220221
int test_rsa_sign_verify_pkcs1(ENGINE *e, void *data);
221222
int test_rsa_sign_verify_no_pad(ENGINE *e, void *data);
222223
int test_rsa_sign_verify_pss(ENGINE *e, void *data);

0 commit comments

Comments
 (0)