ClientHello Padding for Fast Radio Opening in 3G.

The ClientHello record is padded to 1024 bytes when
fastradio_padding is enabled. As a result, the 3G cellular radio
is fast forwarded to DCH (high data rate) state. This mechanism
leads to a substantial redunction in terms of TLS handshake
latency, and benefits mobile apps that are running on top of TLS.

Change-Id: I3d55197b6d601761c94c0f22871774b5a3dad614
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index 30cdab7..e04e44b 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -429,6 +429,7 @@
     BIO_print_errors_fp(stdout);
     return 1;
   }
+  SSL_enable_fastradio_padding(ssl, config->fastradio_padding);
 
   BIO *bio = BIO_new_fd(fd, 1 /* take ownership */);
   if (bio == NULL) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 628c208..90c5294 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -582,6 +582,10 @@
 	// to require that all ClientHellos match in offered version
 	// across a renego.
 	RequireSameRenegoClientVersion bool
+
+	// RequireFastradioPadding, if true, requires that ClientHello messages
+	// be at least 1000 bytes long.
+	RequireFastradioPadding bool
 }
 
 func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 4bdede1..284f314 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -120,6 +120,9 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return false, unexpectedMessageError(hs.clientHello, msg)
 	}
+	if config.Bugs.RequireFastradioPadding && len(hs.clientHello.raw) < 1000 {
+		return false, errors.New("tls: ClientHello record size should be larger than 1000 bytes when padding enabled.")
+	}
 
 	if c.isDTLS && !config.Bugs.SkipHelloVerifyRequest {
 		// Per RFC 6347, the version field in HelloVerifyRequest SHOULD
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 421940d..ecf80db 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2156,6 +2156,29 @@
 	})
 }
 
+func addFastRadioPaddingTests() {
+	testCases = append(testCases, testCase {
+		protocol:	tls,
+		name:		"FastRadio-Padding",
+		config: Config{
+			Bugs: ProtocolBugs{
+				RequireFastradioPadding: true,
+			},
+		},
+		flags:		[]string{"-fastradio-padding"},
+	})
+	testCases = append(testCases, testCase {
+		protocol:	dtls,
+		name:		"FastRadio-Padding",
+		config: Config{
+			Bugs: ProtocolBugs{
+				RequireFastradioPadding: true,
+			},
+		},
+		flags:		[]string{"-fastradio-padding"},
+	})
+}
+
 var testHashes = []struct {
 	name string
 	id   uint8
@@ -2337,6 +2360,7 @@
 	addRenegotiationTests()
 	addDTLSReplayTests()
 	addSigningHashTests()
+	addFastRadioPaddingTests()
 	for _, async := range []bool{false, true} {
 		for _, splitHandshake := range []bool{false, true} {
 			for _, protocol := range []protocol{tls, dtls} {
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index e8034ce..59874ef 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -65,6 +65,7 @@
   { "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
   { "-enable-signed-cert-timestamps",
     &TestConfig::enable_signed_cert_timestamps },
+  { "-fastradio-padding", &TestConfig::fastradio_padding },
 };
 
 const size_t kNumBoolFlags = sizeof(kBoolFlags) / sizeof(kBoolFlags[0]);
@@ -124,7 +125,8 @@
       renegotiate(false),
       allow_unsafe_legacy_renegotiation(false),
       enable_ocsp_stapling(false),
-      enable_signed_cert_timestamps(false) {
+      enable_signed_cert_timestamps(false),
+      fastradio_padding(false) {
 }
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_config) {
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 5f050a8..f778c28 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -63,6 +63,7 @@
   std::string expected_ocsp_response;
   bool enable_signed_cert_timestamps;
   std::string expected_signed_cert_timestamps;
+  bool fastradio_padding;
 };
 
 bool ParseConfig(int argc, char **argv, TestConfig *out_config);