Skip to content

Commit

Permalink
Merge pull request #1020 from tls-attacker/sm-ciphers
Browse files Browse the repository at this point in the history
SM ciphersuites support for TLS 1.3
  • Loading branch information
NErinola authored Jun 29, 2023
2 parents a913d6b + e2b8dbd commit 5fe90d0
Show file tree
Hide file tree
Showing 41 changed files with 502 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ private List<String> getResourceFiles() throws IOException {
filenames.add("ec_sect193r1_ecdsa_cert.pem");
filenames.add("ec_secp256r1_ecdsa_cert.pem");
filenames.add("ec_secp256r1_rsa_cert.pem");
filenames.add("ec_sm2p256v1_sm2_cert.pem");
filenames.add("dh3072_ecdsa_cert.pem");
filenames.add("dh2048_ecdsa_cert.pem");
filenames.add("dh1024_ecdsa_cert.pem");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import jakarta.xml.bind.annotation.XmlElements;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.*;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
Expand Down Expand Up @@ -195,7 +196,7 @@ public CertificateKeyPair(
CertificateKeyType certSignatureType,
File certFile,
File privateKeyFile)
throws CertificateException, IOException {
throws CertificateException, IOException, NoSuchProviderException {
this.certPublicKeyType = certPublicKeyType;
this.certSignatureType = certSignatureType;
Certificate certificate = PemUtil.readCertificate(certFile);
Expand Down Expand Up @@ -224,6 +225,7 @@ private CertificateKeyType getPublicKeyType(Certificate cert) {
case "1.2.840.113549.1.1.1":
return CertificateKeyType.RSA;
case "1.2.840.10045.2.1":
case "1.2.156.10197.1.301":
return CertificateKeyType.ECDH;
case "1.2.840.10045.4.1":
case "1.2.840.10045.4.2":
Expand Down Expand Up @@ -335,6 +337,8 @@ private SignatureAndHashAlgorithm getSignatureAndHashAlgorithmFromCert(Certifica
return SignatureAndHashAlgorithm.GOSTR34102012_256_GOSTR34112012_256;
case "1.2.643.7.1.1.3.3":
return SignatureAndHashAlgorithm.GOSTR34102012_512_GOSTR34112012_512;
case "1.2.156.10197.1.501":
return SignatureAndHashAlgorithm.SM2_SM3;
default:
LOGGER.warn("Unknown algorithm ID: " + algorithmOid + " using \"ANONYMOUS_NONE\"");
return SignatureAndHashAlgorithm.ANONYMOUS_NONE;
Expand Down Expand Up @@ -376,6 +380,8 @@ private CertificateKeyType getSignatureType(Certificate cert) {
case "1.2.643.7.1.1.3.2":
case "1.2.643.7.1.1.3.3":
return CertificateKeyType.GOST12;
case "1.2.156.10197.1.501":
return CertificateKeyType.ECDH;
default:
LOGGER.warn(
"Unknown algorithm ID: "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package de.rub.nds.tlsattacker.core.certificate;

import java.io.*;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateException;
Expand Down Expand Up @@ -90,8 +91,8 @@ public static void writeCertificate(Certificate cert, File file) {
}

public static Certificate readCertificate(InputStream stream)
throws CertificateException, IOException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
throws CertificateException, IOException, NoSuchProviderException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");
Collection<? extends java.security.cert.Certificate> certs =
certFactory.generateCertificates(stream);
java.security.cert.Certificate sunCert =
Expand All @@ -108,7 +109,8 @@ public static Certificate readCertificate(InputStream stream)
return tlsCerts;
}

public static Certificate readCertificate(File f) throws CertificateException, IOException {
public static Certificate readCertificate(File f)
throws CertificateException, IOException, NoSuchProviderException {
try (FileInputStream fis = new FileInputStream(f)) {
return readCertificate(fis);
}
Expand All @@ -123,8 +125,10 @@ public static PrivateKey readPrivateKey(InputStream stream) throws IOException {
obj = pair.getPrivateKeyInfo();
} else if (obj instanceof ASN1ObjectIdentifier) {
obj = parser.readObject();
PEMKeyPair pair = (PEMKeyPair) obj;
obj = pair.getPrivateKeyInfo();
if (obj instanceof PEMKeyPair) {
PEMKeyPair pair = (PEMKeyPair) obj;
obj = pair.getPrivateKeyInfo();
}
}
PrivateKeyInfo privKeyInfo = (PrivateKeyInfo) obj;
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public static DigestAlgorithm getDigestAlgorithm(
|| protocolVersion == ProtocolVersion.TLS11
|| protocolVersion == ProtocolVersion.DTLS10) {
result = DigestAlgorithm.LEGACY;
} else if (cipherSuite.isSM()) {
result = DigestAlgorithm.SM3;
} else if (cipherSuite.usesSHA384()) {
result = DigestAlgorithm.SHA384;
} else {
Expand Down Expand Up @@ -298,6 +300,10 @@ public static CipherAlgorithm getCipher(CipherSuite cipherSuite) {
return CipherAlgorithm.ARIA_256_GCM;
} else if (cipher.contains("28147_CNT")) {
return CipherAlgorithm.GOST_28147_CNT;
} else if (cipher.contains("SM4_GCM")) {
return CipherAlgorithm.SM4_GCM;
} else if (cipher.contains("SM4_CCM")) {
return CipherAlgorithm.SM4_CCM;
} else if (cipher.contains("CHACHA20_POLY1305")) {
if (cipher.contains("UNOFFICIAL")) {
return CipherAlgorithm.UNOFFICIAL_CHACHA20_POLY1305;
Expand Down Expand Up @@ -385,6 +391,8 @@ public static MacAlgorithm getMacAlgorithm(
result = MacAlgorithm.HMAC_SHA384;
} else if (cipher.contains("SHA512")) {
result = MacAlgorithm.HMAC_SHA512;
} else if (cipher.contains("SM3")) {
result = MacAlgorithm.HMAC_SM3;
} else if (cipher.endsWith("NULL")) {
result = MacAlgorithm.NULL;
} else if (cipher.endsWith("IMIT")) {
Expand Down Expand Up @@ -416,6 +424,8 @@ public static HKDFAlgorithm getHKDFAlgorithm(CipherSuite cipherSuite) {
result = HKDFAlgorithm.TLS_HKDF_SHA256;
} else if (cipher.endsWith("SHA384")) {
result = HKDFAlgorithm.TLS_HKDF_SHA384;
} else if (cipher.endsWith("SM3")) {
result = HKDFAlgorithm.TLS_HKDF_SM3;
}
if (result != null) {
LOGGER.debug("Using the following HKDF Algorithm: {}", result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public enum BulkCipherAlgorithm {
ARIA,
CHACHA20_POLY1305,
GOST28147,
AES;
AES,
SM4;

private static final Logger LOGGER = LogManager.getLogger();

Expand Down Expand Up @@ -65,6 +66,8 @@ public static BulkCipherAlgorithm getBulkCipherAlgorithm(CipherSuite cipherSuite
return GOST28147;
} else if (cipher.contains("CHACHA20_POLY1305")) {
return CHACHA20_POLY1305;
} else if (cipher.contains("SM4")) {
return SM4;
}

LOGGER.warn(
Expand Down Expand Up @@ -102,6 +105,8 @@ public static BulkCipherAlgorithm getBulkCipherAlgorithm(CipherAlgorithm cipherA
return ARIA;
} else if (cipher.contains("CHACHA20_POLY1305")) {
return CHACHA20_POLY1305;
} else if (cipher.contains("SM4")) {
return SM4;
}
throw new UnsupportedOperationException(
"The cipher algorithm from " + cipherAlgorithm.name() + " is not supported yet.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public enum CipherAlgorithm {
GOST_28147_CNT(32, 8, 0, 8, "GOST28147/ECB/NoPadding"),
FORTEZZA_CBC(0, 0, 0, 0), // TODO
AES_128_CTR(16, 16, 0, 0, "AES/CTR/NoPadding"),
AES_256_CTR(32, 16, 0, 0, "AES/CTR/NoPadding");
AES_256_CTR(32, 16, 0, 0, "AES/CTR/NoPadding"),
SM4_GCM(16, 4, 8, 16, "SM4/GCM/NoPadding"),
SM4_CCM(16, 4, 8, 16, "SM4/CCM/NoPadding");

CipherAlgorithm(
int keySize,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ public enum CipherSuite {
TLS_ECCPWD_WITH_AES_256_GCM_SHA384(0xC0B1),
TLS_ECCPWD_WITH_AES_128_CCM_SHA256(0xC0B2),
TLS_ECCPWD_WITH_AES_256_CCM_SHA384(0xC0B3),
TLS_SM4_GCM_SM3(0xC6),
TLS_SM4_CCM_SM3(0xC7),
// *************************************************************************
// Unofficial cipher suites draft-mavrogiannopoulos-chacha-tls-01
// These cipher suite are from a Draft and also don't have a mac algorithm
Expand Down Expand Up @@ -1048,6 +1050,8 @@ public static List<CipherSuite> getImplemented() {
list.add(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5);
list.add(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
list.add(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
list.add(TLS_SM4_GCM_SM3);
list.add(TLS_SM4_CCM_SM3);
list.add(TLS_NULL_WITH_NULL_NULL);
return list;
}
Expand All @@ -1069,6 +1073,8 @@ public static List<CipherSuite> getTls13CipherSuites() {
list.add(CipherSuite.TLS_CHACHA20_POLY1305_SHA256);
list.add(CipherSuite.TLS_AES_128_CCM_SHA256);
list.add(CipherSuite.TLS_AES_128_CCM_8_SHA256);
list.add(TLS_SM4_GCM_SM3);
list.add(TLS_SM4_CCM_SM3);
return list;
}

Expand All @@ -1079,6 +1085,8 @@ public static List<CipherSuite> getImplementedTls13CipherSuites() {
list.add(CipherSuite.TLS_CHACHA20_POLY1305_SHA256);
list.add(CipherSuite.TLS_AES_128_CCM_SHA256);
list.add(CipherSuite.TLS_AES_128_CCM_8_SHA256);
list.add(TLS_SM4_GCM_SM3);
list.add(TLS_SM4_CCM_SM3);
return list;
}

Expand All @@ -1098,7 +1106,8 @@ public static List<CipherSuite> getNotImplemented() {
* @return True if the Ciphersuite is supported in TLS 1.3
*/
public boolean isTLS13() {
return this.getByteValue()[0] == (byte) 0x13 && this.getByteValue()[1] != (byte) 0x00;
return (this.getByteValue()[0] == (byte) 0x13 && this.getByteValue()[1] != (byte) 0x00)
|| this.isSM();
}

public boolean isImplemented() {
Expand Down Expand Up @@ -1149,6 +1158,10 @@ public boolean isGOST() {
return this.name().contains("GOST");
}

public boolean isSM() {
return this.name().contains("SM");
}

// Note: We don't consider DES as weak for these purposes.
public boolean isWeak() {
return this.isExport() || this.isExportSymmetricCipher() || this.isAnon() || this.isNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public enum DigestAlgorithm {
SHA256("SHA-256"),
SHA384("SHA-384"),
GOSTR3411("GOST3411"),
GOSTR34112012_256("GOST3411-2012-256");
GOSTR34112012_256("GOST3411-2012-256"),
SM3("SM3");

private DigestAlgorithm(String digestAlgorithm) {
this.javaName = digestAlgorithm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
public enum HKDFAlgorithm {
TLS_HKDF_SHA256(MacAlgorithm.HMAC_SHA256),
TLS_HKDF_SHA384(MacAlgorithm.HMAC_SHA384),
TLS_HKDF_SHA512(MacAlgorithm.HMAC_SHA512);
TLS_HKDF_SHA512(MacAlgorithm.HMAC_SHA512),
TLS_HKDF_SM3(MacAlgorithm.HMAC_SM3);

private HKDFAlgorithm(MacAlgorithm macAlgorithm) {
this.macAlgorithm = macAlgorithm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public enum HashAlgorithm {
SHA512("SHA-512", 256),
GOSTR3411("GOST3411", 128),
GOSTR34112012_256("GOST3411-2012-256", 128),
GOSTR34112012_512("GOST3411-2012-512", 256);
GOSTR34112012_512("GOST3411-2012-512", 256),
SM3("SM3", 128);

private final String javaName;
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public enum MacAlgorithm {
HMAC_SHA512("HmacSHA512", 64, 64),
IMIT_GOST28147("GOST28147MAC", 4, 32),
HMAC_GOSTR3411("HmacGOST3411", 32, 32),
HMAC_GOSTR3411_2012_256("HmacGOST3411-2012-256", 32, 32);
HMAC_GOSTR3411_2012_256("HmacGOST3411-2012-256", 32, 32),
HMAC_SM3("HmacSM3", 32, 32);

private final int size;
private final int keySize;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public enum NamedGroup {
BRAINPOOLP512R1(new byte[] {(byte) 0, (byte) 28}, "brainpoolp512r1", 512),
ECDH_X25519(new byte[] {(byte) 0, (byte) 29}, "ecdh_X25519", 256),
ECDH_X448(new byte[] {(byte) 0, (byte) 30}, "ecdh_X448", 448),
CURVE_SM2(new byte[] {(byte) 0, (byte) 41}, "sm2p256v1", 256),
FFDHE2048(new byte[] {(byte) 1, (byte) 0}, "FFDHE2048", 2048),
FFDHE3072(new byte[] {(byte) 1, (byte) 1}, "FFDHE3072", 3072),
FFDHE4096(new byte[] {(byte) 1, (byte) 2}, "FFDHE4096", 4096),
Expand Down Expand Up @@ -99,7 +100,8 @@ public enum NamedGroup {
FFDHE8192,
SECP256R1,
SECP384R1,
SECP521R1));
SECP521R1,
CURVE_SM2));

private NamedGroup(byte[] value, String javaName, Integer coordinateSizeInBit) {
this.value = value;
Expand Down Expand Up @@ -273,7 +275,8 @@ public boolean isStandardCurve() {

public boolean isCurve() {
return this.name().toLowerCase().contains("ec")
|| this.name().toLowerCase().contains("brainpool");
|| this.name().toLowerCase().contains("brainpool")
|| this.name().toLowerCase().contains("sm2");
}

public boolean isDhGroup() {
Expand Down Expand Up @@ -313,6 +316,7 @@ public static List<NamedGroup> getImplemented() {
list.add(SECT571R1);
list.add(ECDH_X25519);
list.add(ECDH_X448);
list.add(CURVE_SM2);
list.add(BRAINPOOLP256R1);
list.add(BRAINPOOLP384R1);
list.add(BRAINPOOLP512R1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public enum SignatureAlgorithm {
ED448,
GOSTR34102001("ECGOST3410"),
GOSTR34102012_256("ECGOST3410-2012-256"),
GOSTR34102012_512("ECGOST3410-2012-512");
GOSTR34102012_512("ECGOST3410-2012-512"),
SM2;

private final String javaName;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bouncycastle.jcajce.spec.SM2ParameterSpec;

/**
* Construction of a hash and signature algorithm. Very confusing, consists of two bytes, the first
Expand Down Expand Up @@ -56,6 +57,7 @@ public enum SignatureAndHashAlgorithm {
ECDSA_SHA256(0x0403),
ECDSA_SHA384(0x0503),
ECDSA_SHA512(0x0603),
SM2_SM3(0x0708),
ED25519(0x0807),
ED448(0x0808),
/* RSASSA-PSS algorithms with public key OID rsaEncryption */
Expand Down Expand Up @@ -114,6 +116,7 @@ public static List<? extends SignatureAndHashAlgorithm> getImplemented() {
algoList.add(GOSTR34102001_GOSTR3411);
algoList.add(GOSTR34102012_256_GOSTR34112012_256);
algoList.add(GOSTR34102012_512_GOSTR34112012_512);
algoList.add(SM2_SM3);
return algoList;
}

Expand All @@ -133,6 +136,7 @@ public static List<SignatureAndHashAlgorithm> getTls13SignatureAndHashAlgorithms
algos.add(SignatureAndHashAlgorithm.RSA_PSS_RSAE_SHA512);
algos.add(SignatureAndHashAlgorithm.ED448);
algos.add(SignatureAndHashAlgorithm.ED25519);
algos.add(SM2_SM3);
return algos;
}

Expand Down Expand Up @@ -300,6 +304,9 @@ public void setupSignature(Signature signature) throws InvalidAlgorithmParameter
new PSSParameterSpec(
hashName, "MGF1", new MGF1ParameterSpec(hashName), saltLength, 1));
}
if (this.getSignatureAlgorithm().toString().contains("SM2")) {
signature.setParameter(new SM2ParameterSpec("TLSv1.3+GM+Cipher+Suite".getBytes()));
}
}

public boolean suitedForSigningTls13Messages() {
Expand All @@ -315,6 +322,7 @@ public boolean suitedForSigningTls13Messages() {
case RSA_PSS_RSAE_SHA512:
case ED25519:
case ED448:
case SM2_SM3:
return true;

default:
Expand All @@ -329,6 +337,7 @@ public boolean suitedForSigningTls13Certs() {
case RSA_SHA512:
case RSA_SHA1:
case ECDSA_SHA1:
case SM2_SM3:
return true;

default:
Expand Down Expand Up @@ -366,6 +375,10 @@ public static SignatureAndHashAlgorithm forCertificateKeyPair(

switch (certPublicKeyType) {
case ECDH:
if (sig == SignatureAlgorithm.SM2) {
found = true;
sigHashAlgo = i;
}
case ECDSA:
if (sig == SignatureAlgorithm.ECDSA) {
found = true;
Expand Down
Loading

0 comments on commit 5fe90d0

Please sign in to comment.