fips: update DSA security check to fix legacy verify strengths

Refer SP 800-131Ar2 table 2:
    https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final

Fixes #21185

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21186)
This commit is contained in:
Pauli 2023-06-13 09:37:57 +10:00
parent f3f3f86a14
commit 71cf587ea2
3 changed files with 106 additions and 63 deletions

View File

@ -167,17 +167,25 @@ int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign)
/* /*
* For Digital signature verification DSA keys with < 112 bits of * For Digital signature verification DSA keys with < 112 bits of
* security strength (i.e L < 2048 bits), are still allowed for legacy * security strength, are still allowed for legacy
* use. The bounds given in SP800 131Ar2 - Table 2 are * use. The bounds given in SP 800-131Ar2 - Table 2 are
* (512 <= L < 2048 and 160 <= N < 224) * (512 <= L < 2048 or 160 <= N < 224).
*
* We are a little stricter and insist that both minimums are met.
* For example a L = 256, N = 160 key *would* be allowed by SP 800-131Ar2
* but we don't.
*/ */
if (!sign && L < 2048) if (!sign) {
return (L >= 512 && N >= 160 && N < 224); if (L < 512 || N < 160)
return 0;
if (L < 2048 || N < 224)
return 1;
}
/* Valid sizes for both sign and verify */ /* Valid sizes for both sign and verify */
if (L == 2048 && (N == 224 || N == 256)) if (L == 2048 && (N == 224 || N == 256)) /* 112 bits */
return 1; return 1;
return (L == 3072 && N == 256); return (L == 3072 && N == 256); /* 128 bits */
} }
# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
return 1; return 1;

View File

@ -109,65 +109,70 @@ sub tsignverify {
$ENV{OPENSSL_CONF} = $defaultconf; $ENV{OPENSSL_CONF} = $defaultconf;
$sigfile = $nonfips_sigfile; SKIP : {
$testtext = $prefix.': '. skip "FIPS failure testing", 6
'Sign something with a non-FIPS key'. if ($nonfips_key eq '');
' with the default provider';
ok(run(app(['openssl', 'dgst', '-sha256',
'-sign', $nonfips_key,
'-out', $sigfile,
$tbs_data])),
$testtext);
$testtext = $prefix.': '. $sigfile = $nonfips_sigfile;
'Verify something with a non-FIPS key'. $testtext = $prefix.': '.
' with the default provider'; 'Sign something with a non-FIPS key'.
ok(run(app(['openssl', 'dgst', '-sha256', ' with the default provider';
'-verify', $nonfips_pub_key, ok(run(app(['openssl', 'dgst', '-sha256',
'-signature', $sigfile, '-sign', $nonfips_key,
$tbs_data])), '-out', $sigfile,
$testtext); $tbs_data])),
$testtext);
$ENV{OPENSSL_CONF} = $fipsconf; $testtext = $prefix.': '.
'Verify something with a non-FIPS key'.
' with the default provider';
ok(run(app(['openssl', 'dgst', '-sha256',
'-verify', $nonfips_pub_key,
'-signature', $sigfile,
$tbs_data])),
$testtext);
$testtext = $prefix.': '. $ENV{OPENSSL_CONF} = $fipsconf;
'Sign something with a non-FIPS key'.
' (should fail)';
ok(!run(app(['openssl', 'dgst', '-sha256',
'-sign', $nonfips_key,
'-out', $prefix.'.nonfips.fail.sig',
$tbs_data])),
$testtext);
$testtext = $prefix.': '. $testtext = $prefix.': '.
'Verify something with a non-FIPS key'. 'Sign something with a non-FIPS key'.
' (should fail)'; ' (should fail)';
ok(!run(app(['openssl', 'dgst', '-sha256', ok(!run(app(['openssl', 'dgst', '-sha256',
'-verify', $nonfips_pub_key, '-sign', $nonfips_key,
'-signature', $sigfile, '-out', $prefix.'.nonfips.fail.sig',
$tbs_data])), $tbs_data])),
$testtext); $testtext);
$testtext = $prefix.': '. $testtext = $prefix.': '.
'Verify something with a non-FIPS key'. 'Verify something with a non-FIPS key'.
' in FIPS mode but with a non-FIPS property query'; ' (should fail)';
ok(run(app(['openssl', 'dgst', ok(!run(app(['openssl', 'dgst', '-sha256',
'-provider', 'default', '-verify', $nonfips_pub_key,
'-propquery', '?fips!=yes', '-signature', $sigfile,
'-sha256', $tbs_data])),
'-verify', $nonfips_pub_key, $testtext);
'-signature', $sigfile,
$tbs_data])),
$testtext);
$testtext = $prefix.': '. $testtext = $prefix.': '.
'Verify a valid signature against the wrong data with a non-FIPS key'. 'Verify something with a non-FIPS key'.
' (should fail)'; ' in FIPS mode but with a non-FIPS property query';
ok(!run(app(['openssl', 'dgst', '-sha256', ok(run(app(['openssl', 'dgst',
'-verify', $nonfips_pub_key, '-provider', 'default',
'-signature', $sigfile, '-propquery', '?fips!=yes',
$bogus_data])), '-sha256',
$testtext); '-verify', $nonfips_pub_key,
'-signature', $sigfile,
$tbs_data])),
$testtext);
$testtext = $prefix.': '.
'Verify a valid signature against the wrong data with a non-FIPS key'.
' (should fail)';
ok(!run(app(['openssl', 'dgst', '-sha256',
'-verify', $nonfips_pub_key,
'-signature', $sigfile,
$bogus_data])),
$testtext);
}
} }
SKIP : { SKIP : {
@ -395,7 +400,6 @@ SKIP : {
'-out', $testtext_prefix.'.fail.priv.pem'])), '-out', $testtext_prefix.'.fail.priv.pem'])),
$testtext); $testtext);
tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, tsignverify($testtext_prefix, $fips_key, $fips_pub_key, '', '');
$nonfips_pub_key);
}; };
} }

View File

@ -142,6 +142,23 @@ Kr2KShQB0FlSgvcCDTX7g8eJ/UuIWo6wX4hSdHDhBB4CHAdVVg1m5ikOICUBo37Y
/TqkTaCFsMDwcDc20Jg= /TqkTaCFsMDwcDc20Jg=
-----END PRIVATE KEY----- -----END PRIVATE KEY-----
PrivateKey = DSA-2048-160
-----BEGIN PRIVATE KEY-----
MIICTAIBADCCAi0GByqGSM44BAEwggIgAoIBAQCOypCJyAO7uNZSPSNGalSkyjQC
xdFVIGfMJKjEXzJnH4g3ts0UqUyO8126REDJEXDeMi22841xsSvzz0ZJeT5YvMLW
t1BtSTiYg2QOar1qEGJunHgjsWKJbVzIqWNw60ZP7pNKmlR7PKa3WDaPhdeVP8zJ
PEMeUHOSprO5Jk/Hjr8jxV0znIIixb9L9PgJAwxiM7rkRHS2Oz1FCYDmNmuFhQDh
Cb3wY9t1AcAHZ05uZ4PtNjdRPwFLPeVdckPj0ntApvOrH18xPWBmwcVeHAH1SV2k
7LPK7wILHVzcKm74ubX/s1wKysyyXyKM+oCgG9jvfh09VQJcHTHaVS643ohZAhUA
uQMLDZqMQbh9TYlm9xYCEBaeVs0CggEAcum3PgEQIRfukytMQ7gKMyfxHqhMmJ6t
RolRhgMrSfl99dmMoqJV+sdSjYvZSkwl71N1Y4Al8GcJB1SzTSb8qGRzM+43pa4k
SyQZ62WA8w5gaIQJ85JUrWiT8C6SgwAbruS5BVHRbQD6FxZwro9+s8uPnLesMTQX
p4maNSQaqYX7tqGl6Z7Wo0PsEwuDRvBlI6sl97gl4q3FQPByCq/64UW/eF6Illo1
dpfbiWCszsp8oczXCEuP+2Y67WUIj3LjFA7WM/R8K4SfdMQ/VXY/cyRhlUqQl8Qe
ndBVKe0IeSdqvMcLNoUip7DGcOXW2ogZl+wgeP4xL3pdo8uS025kjwQWAhRfutAE
r/MlbdGMvcA7l0XmzzY85w==
-----END PRIVATE KEY-----
PrivateKey = DSA-2048-224 PrivateKey = DSA-2048-224
-----BEGIN PRIVATE KEY----- -----BEGIN PRIVATE KEY-----
MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQDVjuiHR3XA9yAjToNQOmdg2rN9 MIICXAIBADCCAjUGByqGSM44BAEwggIoAoIBAQDVjuiHR3XA9yAjToNQOmdg2rN9
@ -249,9 +266,16 @@ bDfJavyQoCWW6EF260m2+rWtl6ILGhhWIbDN5KfXBhrOPvxvHQQiAiBZM1KxUjGw
h2C/91Z0b0Xg4QYNOtVUbfqQTJQAqEpaRg== h2C/91Z0b0Xg4QYNOtVUbfqQTJQAqEpaRg==
-----END PRIVATE KEY----- -----END PRIVATE KEY-----
Title = FIPS Tests (using different key sizes and digests) Title = FIPS Tests (using different key sizes and digests)
# Test sign with a 2048 bit key with N == 160 is not allowed in fips mode
Availablein = fips
DigestSign = SHA256
Key = DSA-2048-160
Input = "Hello"
Output = 00
Result = DIGESTSIGNINIT_ERROR
# Test sign with a 2048 bit key with N == 224 is allowed in fips mode # Test sign with a 2048 bit key with N == 224 is allowed in fips mode
DigestSign = SHA256 DigestSign = SHA256
Key = DSA-2048-224 Key = DSA-2048-224
@ -289,6 +313,13 @@ Key = DSA-1024
Input = "Hello " Input = "Hello "
Output = 302c0214602d21ed37e46051bb3d06cc002adddeb4cdb3bd02144f39f75587b286588862d06366b2f29bddaf8cf6 Output = 302c0214602d21ed37e46051bb3d06cc002adddeb4cdb3bd02144f39f75587b286588862d06366b2f29bddaf8cf6
# Test verify with a 2048/160 bit key is allowed in fips mode
FIPSversion = >3.1.1
DigestVerify = SHA256
Key = DSA-2048-160
Input = "Hello"
Output = 302e021500a51ca7f70ae206f221dc9b805bb04bfc07d6e448021500b16e45f9dac8aff04e115f96c00f4237d0fced41
Title = Fips Negative Tests (using different key sizes and digests) Title = Fips Negative Tests (using different key sizes and digests)
# Test sign with a 1024 bit key is not allowed in fips mode # Test sign with a 1024 bit key is not allowed in fips mode