Fix test of first of 255 CBC padding bytes.

Thanks to Peter Gijsels for pointing out that if a CBC record has 255
bytes of padding, the first was not being checked.
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 9812bde..0905e9f 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -332,6 +332,15 @@
 	// can be invalid.
 	BadECDSAR BadValue
 	BadECDSAS BadValue
+
+	// MaxPadding causes CBC records to have the maximum possible padding.
+	MaxPadding bool
+	// PaddingFirstByteBad causes the first byte of the padding to be
+	// incorrect.
+	PaddingFirstByteBad bool
+	// PaddingFirstByteBadIf255 causes the first byte of padding to be
+	// incorrect if there's a maximum amount of padding (i.e. 255 bytes).
+	PaddingFirstByteBadIf255 bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go
index d130895..49224a2 100644
--- a/ssl/test/runner/conn.go
+++ b/ssl/test/runner/conn.go
@@ -106,6 +106,8 @@
 
 	// used to save allocating a new buffer for each MAC.
 	inDigestBuf, outDigestBuf []byte
+
+	config *Config
 }
 
 func (hc *halfConn) setErrorLocked(err error) error {
@@ -130,7 +132,7 @@
 
 // changeCipherSpec changes the encryption and MAC states
 // to the ones previously passed to prepareCipherSpec.
-func (hc *halfConn) changeCipherSpec() error {
+func (hc *halfConn) changeCipherSpec(config *Config) error {
 	if hc.nextCipher == nil {
 		return alertInternalError
 	}
@@ -138,6 +140,7 @@
 	hc.mac = hc.nextMac
 	hc.nextCipher = nil
 	hc.nextMac = nil
+	hc.config = config
 	for i := range hc.seq {
 		hc.seq[i] = 0
 	}
@@ -336,15 +339,26 @@
 // block of payload. finalBlock is a fresh slice which contains the contents of
 // any suffix of payload as well as the needed padding to make finalBlock a
 // full block.
-func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
+func padToBlockSize(payload []byte, blockSize int, config *Config) (prefix, finalBlock []byte) {
 	overrun := len(payload) % blockSize
-	paddingLen := blockSize - overrun
 	prefix = payload[:len(payload)-overrun]
-	finalBlock = make([]byte, blockSize)
-	copy(finalBlock, payload[len(payload)-overrun:])
-	for i := overrun; i < blockSize; i++ {
+
+	paddingLen := blockSize - overrun
+	finalSize := blockSize
+	if config.Bugs.MaxPadding {
+		for paddingLen+blockSize <= 256 {
+			paddingLen += blockSize
+		}
+		finalSize = 256
+	}
+	finalBlock = make([]byte, finalSize)
+	for i := range finalBlock {
 		finalBlock[i] = byte(paddingLen - 1)
 	}
+	if config.Bugs.PaddingFirstByteBad || config.Bugs.PaddingFirstByteBadIf255 && paddingLen == 256 {
+		finalBlock[overrun] ^= 0xff
+	}
+	copy(finalBlock, payload[len(payload)-overrun:])
 	return
 }
 
@@ -387,7 +401,7 @@
 				c.SetIV(payload[:explicitIVLen])
 				payload = payload[explicitIVLen:]
 			}
-			prefix, finalBlock := padToBlockSize(payload, blockSize)
+			prefix, finalBlock := padToBlockSize(payload, blockSize, hc.config)
 			b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
 			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
 			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
@@ -633,7 +647,7 @@
 			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
 			break
 		}
-		err := c.in.changeCipherSpec()
+		err := c.in.changeCipherSpec(c.config)
 		if err != nil {
 			c.in.setErrorLocked(c.sendAlert(err.(alert)))
 		}
@@ -752,7 +766,7 @@
 	c.out.freeBlock(b)
 
 	if typ == recordTypeChangeCipherSpec {
-		err = c.out.changeCipherSpec()
+		err = c.out.changeCipherSpec(c.config)
 		if err != nil {
 			// Cannot call sendAlert directly,
 			// because we already hold c.out.Mutex.
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 1edd00b..b5743c5 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -47,6 +47,9 @@
 	config        Config
 	shouldFail    bool
 	expectedError string
+	// messageLen is the length, in bytes, of the test message that will be
+	// sent.
+	messageLen int
 }
 
 var clientTests = []testCase{
@@ -87,12 +90,17 @@
 	},
 }
 
-var testMessage = []byte("testing")
-
-func doExchange(tlsConn *Conn) error {
+func doExchange(tlsConn *Conn, messageLen int) error {
 	if err := tlsConn.Handshake(); err != nil {
 		return err
 	}
+	if messageLen == 0 {
+		messageLen = 32
+	}
+	testMessage := make([]byte, messageLen)
+	for i := range testMessage {
+		testMessage[i] = 0x42
+	}
 	tlsConn.Write(testMessage)
 
 	buf := make([]byte, len(testMessage))
@@ -168,7 +176,7 @@
 	}
 
 	tlsConn := Server(conn, &config)
-	err = doExchange(tlsConn)
+	err = doExchange(tlsConn, test.messageLen)
 
 	conn.Close()
 	childErr := client.Wait()
@@ -288,6 +296,45 @@
 	}
 }
 
+func addCBCPaddingTests() {
+	clientTests = append(clientTests, testCase{
+		name: "MaxCBCPadding",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+			Bugs: ProtocolBugs{
+				MaxPadding: true,
+			},
+		},
+		messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
+	})
+	clientTests = append(clientTests, testCase{
+		name: "BadCBCPadding",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+			Bugs: ProtocolBugs{
+				PaddingFirstByteBad: true,
+			},
+		},
+		shouldFail:    true,
+		expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+	})
+	// OpenSSL previously had an issue where the first byte of padding in
+	// 255 bytes of padding wasn't checked.
+	clientTests = append(clientTests, testCase{
+		name: "BadCBCPadding255",
+		config: Config{
+			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+			Bugs: ProtocolBugs{
+				MaxPadding:               true,
+				PaddingFirstByteBadIf255: true,
+			},
+		},
+		messageLen:    12, // 20 bytes of SHA-1 + 12 == 0 % block size
+		shouldFail:    true,
+		expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
+	})
+}
+
 func worker(statusChan chan statusMsg, c chan *testCase, wg *sync.WaitGroup) {
 	defer wg.Done()
 
@@ -334,6 +381,7 @@
 
 	addCipherSuiteTests()
 	addBadECDSASignatureTests()
+	addCBCPaddingTests()
 
 	var wg sync.WaitGroup