diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 57b7b295..648807fc 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go @@ -842,6 +842,14 @@ type ProtocolBugs struct { // SendSCTListOnResume, if not nil, causes the server to send the // supplied SCT list in resumption handshakes. SendSCTListOnResume []byte + + // CECPQ1BadX25519Part corrupts the X25519 part of a CECPQ1 key exchange, as + // a trivial proof that it is actually used. + CECPQ1BadX25519Part bool + + // CECPQ1BadNewhopePart corrupts the Newhope part of a CECPQ1 key exchange, + // as a trivial proof that it is actually used. + CECPQ1BadNewhopePart bool } func (c *Config) serverInit() { diff --git a/ssl/test/runner/key_agreement.go b/ssl/test/runner/key_agreement.go index 9a9962bf..5e5d976d 100644 --- a/ssl/test/runner/key_agreement.go +++ b/ssl/test/runner/key_agreement.go @@ -732,6 +732,16 @@ func (ka *cecpq1KeyAgreement) generateServerKeyExchange(config *Config, cert *Ce return nil, err } + if config.Bugs.CECPQ1BadX25519Part { + publicKey[0] ^= 1 + } + if config.Bugs.CECPQ1BadNewhopePart { + publicKey[32] ^= 1 + publicKey[33] ^= 1 + publicKey[34] ^= 1 + publicKey[35] ^= 1 + } + var params []byte params = append(params, byte(len(publicKey)>>8)) params = append(params, byte(len(publicKey)&0xff)) @@ -779,6 +789,16 @@ func (ka *cecpq1KeyAgreement) generateClientKeyExchange(config *Config, clientHe return nil, nil, err } + if config.Bugs.CECPQ1BadX25519Part { + publicKey[0] ^= 1 + } + if config.Bugs.CECPQ1BadNewhopePart { + publicKey[32] ^= 1 + publicKey[33] ^= 1 + publicKey[34] ^= 1 + publicKey[35] ^= 1 + } + ckx := new(clientKeyExchangeMsg) ckx.ciphertext = append(ckx.ciphertext, byte(len(publicKey)>>8)) ckx.ciphertext = append(ckx.ciphertext, byte(len(publicKey)&0xff)) diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 962ac019..8ea71725 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -5101,6 +5101,65 @@ func addCurveTests() { }) } +func addCECPQ1Tests() { + testCases = append(testCases, testCase{ + testType: clientTest, + name: "CECPQ1-Client-BadX25519Part", + config: Config{ + MinVersion: VersionTLS12, + CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, + Bugs: ProtocolBugs{ + CECPQ1BadX25519Part: true, + }, + }, + flags: []string{"-cipher", "kCECPQ1"}, + shouldFail: true, + expectedLocalError: "local error: bad record MAC", + }) + testCases = append(testCases, testCase{ + testType: clientTest, + name: "CECPQ1-Client-BadNewhopePart", + config: Config{ + MinVersion: VersionTLS12, + CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, + Bugs: ProtocolBugs{ + CECPQ1BadNewhopePart: true, + }, + }, + flags: []string{"-cipher", "kCECPQ1"}, + shouldFail: true, + expectedLocalError: "local error: bad record MAC", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "CECPQ1-Server-BadX25519Part", + config: Config{ + MinVersion: VersionTLS12, + CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, + Bugs: ProtocolBugs{ + CECPQ1BadX25519Part: true, + }, + }, + flags: []string{"-cipher", "kCECPQ1"}, + shouldFail: true, + expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "CECPQ1-Server-BadNewhopePart", + config: Config{ + MinVersion: VersionTLS12, + CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, + Bugs: ProtocolBugs{ + CECPQ1BadNewhopePart: true, + }, + }, + flags: []string{"-cipher", "kCECPQ1"}, + shouldFail: true, + expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", + }) +} + func addKeyExchangeInfoTests() { testCases = append(testCases, testCase{ name: "KeyExchangeInfo-RSA-Client", @@ -5254,6 +5313,7 @@ func main() { addCustomExtensionTests() addRSAClientKeyExchangeTests() addCurveTests() + addCECPQ1Tests() addKeyExchangeInfoTests() for _, async := range []bool{false, true} { for _, splitHandshake := range []bool{false, true} {