Skip to content

Commit

Permalink
FEAT(SM): Support RFC 8998
Browse files Browse the repository at this point in the history
--story=115436236
  • Loading branch information
johnshajiang authored and shiyuexw committed Jan 23, 2024
1 parent 553c079 commit d8b2ad9
Show file tree
Hide file tree
Showing 13 changed files with 1,893 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ static final class T13CertificateVerifyMessage extends HandshakeMessage {

try {
Signature signer =
signatureScheme.getVerifier(x509Credentials.popPublicKey);
signatureScheme.getVerifier(x509Credentials.popPublicKey, true);
signer.update(contentCovered);
if (!signer.verify(signature)) {
throw context.conContext.fatal(Alert.HANDSHAKE_FAILURE,
Expand Down
11 changes: 9 additions & 2 deletions jdk/src/share/classes/sun/security/ssl/CipherSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ enum CipherSuite {
0x1301, true, "TLS_AES_128_GCM_SHA256",
ProtocolVersion.PROTOCOLS_OF_13, B_AES_128_GCM_IV, H_SHA256),

// ShangMi algorithm defined by RFC 8998
TLS_SM4_GCM_SM3(
0x00C6, true, "TLS_SM4_GCM_SM3",
ProtocolVersion.PROTOCOLS_OF_13, B_SM4_GCM_IV, H_SM3),

// Suite B compliant cipher suites, see RFC 6460.
//
// Note that, at present this provider is not Suite B compliant. The
Expand Down Expand Up @@ -1172,7 +1177,8 @@ static enum MacAlg {
M_MD5 ("MD5", 16, 64, 9),
M_SHA ("SHA", 20, 64, 9),
M_SHA256 ("SHA256", 32, 64, 9),
M_SHA384 ("SHA384", 48, 128, 17);
M_SHA384 ("SHA384", 48, 128, 17),
M_SM3 ("SM3", 32, 64, 9);

// descriptive name, e.g. MD5
final String name;
Expand Down Expand Up @@ -1209,7 +1215,8 @@ public String toString() {
static enum HashAlg {
H_NONE ("NONE", 0, 0),
H_SHA256 ("SHA-256", 32, 64),
H_SHA384 ("SHA-384", 48, 128);
H_SHA384 ("SHA-384", 48, 128),
H_SM3 ("SM3", 32, 64);

final String name;
final int hashLength;
Expand Down
6 changes: 6 additions & 0 deletions jdk/src/share/classes/sun/security/ssl/JsseJce.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ public Object run() {
*/
static final String CIPHER_AES_GCM = "AES/GCM/NoPadding";

/**
* JCE transformation string for SM4 in GCM mode
* without padding.
*/
static final String CIPHER_SM4_GCM = "SM4/GCM/NoPadding";

/**
* JCA identifier string for DSA, i.e. a DSA with SHA-1.
*/
Expand Down
18 changes: 17 additions & 1 deletion jdk/src/share/classes/sun/security/ssl/SSLCipher.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,23 @@ enum SSLCipher {

@SuppressWarnings({"unchecked", "rawtypes"})
B_AES_256_GCM_IV(CIPHER_AES_GCM, AEAD_CIPHER, 32, 32, 12, 0, true, false,
(Map.Entry<ReadCipherGenerator,
ProtocolVersion[]>[])(new Map.Entry[] {
new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>(
new T13GcmReadCipherGenerator(),
ProtocolVersion.PROTOCOLS_OF_13
)
}),
(Map.Entry<WriteCipherGenerator,
ProtocolVersion[]>[])(new Map.Entry[] {
new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>(
new T13GcmWriteCipherGenerator(),
ProtocolVersion.PROTOCOLS_OF_13
)
})),

@SuppressWarnings({"unchecked", "rawtypes"})
B_SM4_GCM_IV(CIPHER_SM4_GCM, AEAD_CIPHER, 16, 16, 12, 0, true, false,
(Map.Entry<ReadCipherGenerator,
ProtocolVersion[]>[])(new Map.Entry[] {
new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>(
Expand Down Expand Up @@ -2360,4 +2377,3 @@ private static int[] checkPadding(ByteBuffer bb, byte pad) {
return results;
}
}

14 changes: 14 additions & 0 deletions jdk/src/share/classes/sun/security/ssl/SSLSecretDerivation.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ final class SSLSecretDerivation implements SSLKeyDerivation {
(byte)0x48, (byte)0x98, (byte)0xB9, (byte)0x5B
};

// See above
private static final byte[] sm3EmptyDigest = new byte[] {
(byte)0x1A, (byte)0xB2, (byte)0x1D, (byte)0x83,
(byte)0x55, (byte)0xCF, (byte)0xA1, (byte)0x7F,
(byte)0x8E, (byte)0x61, (byte)0x19, (byte)0x48,
(byte)0x31, (byte)0xE8, (byte)0x1A, (byte)0x8F,
(byte)0x22, (byte)0xBE, (byte)0xC8, (byte)0xC7,
(byte)0x28, (byte)0xFE, (byte)0xFB, (byte)0x74,
(byte)0x7E, (byte)0xD0, (byte)0x35, (byte)0xEB,
(byte)0x50, (byte)0x82, (byte)0xAA, (byte)0x2B
};

private final HandshakeContext context;
private final String hkdfAlg;
private final HashAlg hashAlg;
Expand Down Expand Up @@ -92,6 +104,8 @@ public SecretKey deriveKey(String algorithm,
expandContext = sha256EmptyDigest;
} else if (hashAlg == HashAlg.H_SHA384) {
expandContext = sha384EmptyDigest;
} else if (hashAlg == HashAlg.H_SM3) {
expandContext = sm3EmptyDigest;
} else {
// unlikely, but please update if more hash algorithm
// get supported in the future.
Expand Down
53 changes: 49 additions & 4 deletions jdk/src/share/classes/sun/security/ssl/SignatureScheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@
package sun.security.ssl;

import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.security.spec.SM2SignatureParameterSpec;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -122,6 +123,13 @@ enum SignatureScheme {
ProtocolVersion.PROTOCOLS_TO_13,
ProtocolVersion.PROTOCOLS_TO_12),

// ShangMi algorithm defined by RFC 8998
SM2SIG_SM3 (0x0708, "sm2sig_sm3",
"SM3withSM2",
"EC",
NamedGroup.CURVESM2,
ProtocolVersion.PROTOCOLS_TO_13),

// Legacy algorithms
DSA_SHA256 (0x0402, "dsa_sha256", "SHA256withDSA",
"DSA",
Expand Down Expand Up @@ -224,6 +232,12 @@ AlgorithmParameterSpec getParameterSpec() {
private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));

// This ID, exactly TLSv1.3+GM+Cipher+Suite, is defined by RFC 8998.
// It is only used by signature scheme sm2sig_sm3 for TLS 1.3 handshaking.
private static final byte[] TLS13_SM2_ID = new byte[] {
0x54, 0x4c, 0x53, 0x76, 0x31, 0x2e, 0x33, 0x2b,
0x47, 0x4d, 0x2b, 0x43, 0x69, 0x70, 0x68, 0x65,
0x72, 0x2b, 0x53, 0x75, 0x69, 0x74, 0x65};

private SignatureScheme(int id, String name,
String algorithm, String keyAlgorithm,
Expand Down Expand Up @@ -476,7 +490,9 @@ static Map.Entry<SignatureScheme, Signature> getSignerOfPreferableAlgorithm(
x509Possession.getECParameterSpec();
if (params != null &&
ss.namedGroup == NamedGroup.valueOf(params)) {
Signature signer = ss.getSigner(signingKey);
Signature signer = ss.getSigner(signingKey,
x509Possession.popCerts[0].getPublicKey(),
version.useTLS13PlusSpec());
if (signer != null) {
return new SimpleImmutableEntry<>(ss, signer);
}
Expand Down Expand Up @@ -547,29 +563,54 @@ static String[] getAlgorithmNames(Collection<SignatureScheme> schemes) {
// is bubbled up. If the public key does not support this signature
// scheme, it normally means the TLS handshaking cannot continue and
// the connection should be terminated.
Signature getVerifier(PublicKey publicKey) throws NoSuchAlgorithmException,
Signature getVerifier(PublicKey publicKey, boolean isTLS13)
throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException {
if (!isAvailable) {
return null;
}

Signature verifier = Signature.getInstance(algorithm);

// sm2sig_sm3 uses "TLSv1.3+GM+Cipher+Suite" as ID for TLS 1.3.
if (this == SM2SIG_SM3 && isTLS13) {
verifier.setParameter(new SM2SignatureParameterSpec(
TLS13_SM2_ID, (ECPublicKey) publicKey));
}

SignatureUtil.initVerifyWithParam(verifier, publicKey, signAlgParameter);

return verifier;
}

Signature getVerifier(PublicKey publicKey) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException {
return getVerifier(publicKey, false);
}

// This method is also used to choose preferable signature scheme for the
// specific private key. If the private key does not support the signature
// scheme, {@code null} is returned, and the caller may fail back to next
// available signature scheme.
private Signature getSigner(PrivateKey privateKey) {
private Signature getSigner(PrivateKey privateKey, PublicKey publicKey,
boolean isTLS13) {
if (!isAvailable) {
return null;
}

try {
Signature signer = Signature.getInstance(algorithm);

// sm2sig_sm3 always needs public key for signing.
// And it uses "TLSv1.3+GM+Cipher+Suite" as ID for TLS 1.3.
if (this == SM2SIG_SM3) {
SM2SignatureParameterSpec paramSpec = isTLS13
? new SM2SignatureParameterSpec(TLS13_SM2_ID,
(ECPublicKey) publicKey)
: new SM2SignatureParameterSpec((ECPublicKey) publicKey);
signer.setParameter(paramSpec);
}

SignatureUtil.initSignWithParam(signer, privateKey,
signAlgParameter,
null);
Expand All @@ -586,4 +627,8 @@ private Signature getSigner(PrivateKey privateKey) {

return null;
}

private Signature getSigner(PrivateKey privateKey) {
return getSigner(privateKey, null, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ static enum NamedGroup {
FFDHE_8192 (0x0104, "ffdhe8192", true,
ProtocolVersion.PROTOCOLS_TO_13),

// ShangMi curve defined by RFC 8998
CURVESM2 (0x0029, "curvesm2", "1.2.156.10197.1.301", false,
ProtocolVersion.PROTOCOLS_TO_13),

// Elliptic Curves (RFC 4492)
//
// arbitrary prime and characteristic-2 curves
Expand Down Expand Up @@ -551,6 +555,9 @@ static class SupportedGroups {
NamedGroup.FFDHE_4096,
NamedGroup.FFDHE_6144,
NamedGroup.FFDHE_8192,

// ShangMi curve last
NamedGroup.CURVESM2
};
}

Expand Down
2 changes: 2 additions & 0 deletions jdk/test/javax/net/ssl/TLSCommon/CipherSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ public enum CipherSuite {
0x1302, null, Protocol.TLSV1_3, Protocol.TLSV1_3),
TLS_AES_128_GCM_SHA256(
0x1301, null, Protocol.TLSV1_3, Protocol.TLSV1_3),
TLS_SM4_GCM_SM3(
0x00C6, null, Protocol.TLSV1_3, Protocol.TLSV1_3),
TLS_DH_anon_WITH_AES_256_GCM_SHA384(
0x00A7, KeyExAlgorithm.DH_ANON, Protocol.TLSV1_2, Protocol.TLSV1_2),
TLS_DH_anon_WITH_AES_128_GCM_SHA256(
Expand Down
3 changes: 2 additions & 1 deletion jdk/test/javax/net/ssl/TLSCommon/SSLEngineTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ public enum HandshakeMode {

private static final String[] TLS13_CIPHERS = {
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256"
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3"
};

private static final String[] SUPPORTED_NON_KRB_CIPHERS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class CheckCipherSuites {
// TLS 1.3 cipher suites
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3",

// Suite B compliant cipher suites
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
Expand Down Expand Up @@ -130,6 +131,7 @@ public class CheckCipherSuites {
// property is set to "limited".
private final static String[] ENABLED_LIMITED = {
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
Expand Down Expand Up @@ -160,6 +162,7 @@ public class CheckCipherSuites {
// TLS 1.3 cipher suites
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3",

// Suite B compliant cipher suites
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
Expand Down Expand Up @@ -249,6 +252,7 @@ public class CheckCipherSuites {
// property is set to "limited".
private final static String[] SUPPORTED_LIMITED = {
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class CipherSuitesInOrder {
// TLS 1.3 cipher suites.
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_SM4_GCM_SM3",
// Suite B compliant cipher suites, see RFC 6460.
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
Expand Down
Loading

0 comments on commit d8b2ad9

Please sign in to comment.