Skip to content

Commit d3ad9d3

Browse files
authored
RSA key pair-wise consistency test with approved APIs (#1518)
This commit reverts a change done in: c8bdf89, where the RSA PWCT was implemented using RSA_sign/verify API. According to our FIPS lab we ought to use the approved EVP_DigestSign/Verify API, which is what we do in this commmit.
1 parent 9cc4f2b commit d3ad9d3

File tree

1 file changed

+55
-17
lines changed
  • crypto/fipsmodule/rsa

1 file changed

+55
-17
lines changed

crypto/fipsmodule/rsa/rsa.c

+55-17
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,59 @@ int RSA_check_key(const RSA *key) {
11421142
return ret;
11431143
}
11441144

1145+
// Performs Pair-Wise Consistency Test (PWCT) with the given RSA key
1146+
// by signing and verifying a message. This is required for RSA_check_fips
1147+
// function further below. According to our FIPS lab we have to do the test
1148+
// with EVP_DigestSign/Verify API.
1149+
static int rsa_key_fips_pairwise_consistency_test_signing(RSA *key) {
1150+
int ret = 0;
1151+
1152+
uint8_t msg[1] = {0};
1153+
size_t msg_len = 1;
1154+
uint8_t *sig_der = NULL;
1155+
size_t sig_len = 0;
1156+
1157+
EVP_PKEY *evp_pkey = NULL;
1158+
EVP_MD_CTX md_ctx;
1159+
const EVP_MD *md = EVP_sha256();
1160+
1161+
evp_pkey = EVP_PKEY_new();
1162+
if (!evp_pkey || !EVP_PKEY_set1_RSA(evp_pkey, key)) {
1163+
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1164+
goto end;
1165+
}
1166+
1167+
// Initialize the context and grab the expected signature length.
1168+
EVP_MD_CTX_init(&md_ctx);
1169+
if (!EVP_DigestSignInit(&md_ctx, NULL, md, NULL, evp_pkey) ||
1170+
!EVP_DigestSign(&md_ctx, NULL, &sig_len, msg, msg_len)) {
1171+
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1172+
goto end;
1173+
}
1174+
1175+
sig_der = OPENSSL_malloc(sig_len);
1176+
if (!sig_der ||
1177+
!EVP_DigestSign(&md_ctx, sig_der, &sig_len, msg, msg_len)) {
1178+
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1179+
goto end;
1180+
}
1181+
if (boringssl_fips_break_test("RSA_PWCT")) {
1182+
msg[0] = ~msg[0];
1183+
}
1184+
if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, evp_pkey) ||
1185+
!EVP_DigestVerify(&md_ctx, sig_der, sig_len, msg, msg_len)) {
1186+
goto end;
1187+
}
1188+
1189+
ret = 1;
1190+
1191+
end:
1192+
EVP_PKEY_free(evp_pkey);
1193+
EVP_MD_CTX_cleanse(&md_ctx);
1194+
OPENSSL_free(sig_der);
1195+
return ret;
1196+
}
1197+
11451198
// This is the product of the 132 smallest odd primes, from 3 to 751,
11461199
// as defined in SP 800-89 5.3.3.
11471200
static const BN_ULONG kSmallFactorsLimbs[] = {
@@ -1242,23 +1295,8 @@ int RSA_check_fips(RSA *key) {
12421295
// encryption, so either pair-wise consistency self-test is acceptable. We
12431296
// perform a signing test. The same guidance can be found in FIPS 140-3 IG
12441297
// in Section 7.10.3.3, sub-section Additional comments.
1245-
uint8_t data[32] = {0};
1246-
unsigned sig_len = RSA_size(key);
1247-
sig = OPENSSL_malloc(sig_len);
1248-
if (sig == NULL) {
1249-
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1250-
goto end;
1251-
}
1252-
1253-
if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) {
1254-
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1255-
goto end;
1256-
}
1257-
if (boringssl_fips_break_test("RSA_PWCT")) {
1258-
data[0] = ~data[0];
1259-
}
1260-
if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
1261-
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
1298+
if (!rsa_key_fips_pairwise_consistency_test_signing(key)) {
1299+
OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
12621300
goto end;
12631301
}
12641302

0 commit comments

Comments
 (0)