From 80e98445824e5acde32399e165927333fff32eff Mon Sep 17 00:00:00 2001 From: Jason Katonica Date: Thu, 30 Nov 2023 11:36:25 -0500 Subject: [PATCH] Enable ECDSA ciphers when running with FIPS cryptography In FIPS mode, certain cryptographic algorithms are typically disabled. This includes the algorithm `SHA1withECDSA` since `SHA1` is no longer recommended for general use. The `JSSE`provider, responsible for managing TLS cipher specifications, currently disables all `*ECDSA*` ciphers due to the absence of the `SHA1withECDSA` algorithm on the system when running in FIPS mode. This behavior is inaccurate, since other ECDSA-related transformations, such as `SHA512withECDSA` or `SHA384withECDSA`, are available in a FIPS environment and can be used for TLS connections. With this update, `*ECDSA*` ciphers can now be enabled in FIPS mode. We will allow for `*ECDSA*` ciphers to be enabled if any algorithm in the ECDSA family is present such as `SHA512withECDSA`, `SHA384withECDSA`, `SHA256withECDSA`, or `SHA224withECDSA`. We expect all these algorithms to be present in the various FIPS solutions available within Semeru. Signed-off-by: Jason Katonica --- .../classes/sun/security/ssl/JsseJce.java | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/sun/security/ssl/JsseJce.java b/src/java.base/share/classes/sun/security/ssl/JsseJce.java index eefaaf2b79a..552ffc137b1 100644 --- a/src/java.base/share/classes/sun/security/ssl/JsseJce.java +++ b/src/java.base/share/classes/sun/security/ssl/JsseJce.java @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved + * =========================================================================== + */ + package sun.security.ssl; import java.math.BigInteger; @@ -90,6 +96,26 @@ final class JsseJce { */ static final String SIGNATURE_ECDSA = "SHA1withECDSA"; + /** + * JCA identifier string for ECDSA, i.e. a ECDSA with SHA224. + */ + static final String SIGNATURE_ECDSA_224 = "SHA224withECDSA"; + + /** + * JCA identifier string for ECDSA, i.e. a ECDSA with SHA256. + */ + static final String SIGNATURE_ECDSA_256 = "SHA256withECDSA"; + + /** + * JCA identifier string for ECDSA, i.e. a ECDSA with SHA384. + */ + static final String SIGNATURE_ECDSA_384 = "SHA384withECDSA"; + + /** + * JCA identifier string for ECDSA, i.e. a ECDSA with SHA512. + */ + static final String SIGNATURE_ECDSA_512 = "SHA512withECDSA"; + /** * JCA identifier for EdDSA signatures. */ @@ -163,10 +189,38 @@ private static class EcAvailability { // Is EC crypto available? private static final boolean isAvailable; + /** + * Checks if a particular signature algorithm is available. + * + * @param algorithm the algorithm we will attempt to instantiate to check if it is available + * @return true if the signature algorithm is found, false otherwise + */ + private static boolean isSignatureAlgorithmAvailable(String algorithm) { + try { + // Attempt to create a Cipher instance with the specified algorithm. + Signature.getInstance(algorithm); + return true; + } catch (NoSuchAlgorithmException e) { + return false; + } + } + static { boolean mediator = true; try { - Signature.getInstance(SIGNATURE_ECDSA); + // When running in FIPS mode, the signature "SHA1withECDSA" is not + // available by default. In this scenario we should still set EC + // availability to true since other algorithms in the ECDSA signature + // family are available for use in various ECDSA TLS ciphers. All + // FIPS solutions are expected to have an algorithm such as + // "SHA512withECDSA", "SHA384withECDSA", "SHA256withECDSA", or + // "SHA224withECDSA" available so we will also check for these algorithms. + mediator = isSignatureAlgorithmAvailable(SIGNATURE_ECDSA) + || isSignatureAlgorithmAvailable(SIGNATURE_ECDSA_224) + || isSignatureAlgorithmAvailable(SIGNATURE_ECDSA_256) + || isSignatureAlgorithmAvailable(SIGNATURE_ECDSA_384) + || isSignatureAlgorithmAvailable(SIGNATURE_ECDSA_512); + Signature.getInstance(SIGNATURE_RAWECDSA); KeyAgreement.getInstance("ECDH"); KeyFactory.getInstance("EC");