Remove SSL_export_early_keying_material.

We did not end up needing this feature. Removing it trims 64 bytes of
per-connection memory.

Change-Id: Ifb8e66af2d583b6bf00c63f509eda8e8691d452a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/36789
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index c3735cd..3d2bc07 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -3327,13 +3327,6 @@
 // |SSL_ERROR_EARLY_DATA_REJECTED|.
 OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl);
 
-// SSL_export_early_keying_material behaves like |SSL_export_keying_material|,
-// but it uses the early exporter. The operation will fail if |ssl| did not
-// negotiate TLS 1.3 or 0-RTT.
-OPENSSL_EXPORT int SSL_export_early_keying_material(
-    SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len,
-    const uint8_t *context, size_t context_len);
-
 // SSL_get_ticket_age_skew returns the difference, in seconds, between the
 // client-sent ticket age and the server-computed value in TLS 1.3 server
 // connections which resumed a session.
diff --git a/ssl/internal.h b/ssl/internal.h
index 85b8112..81242ca 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -2296,11 +2296,9 @@
   uint8_t write_traffic_secret[EVP_MAX_MD_SIZE] = {0};
   uint8_t read_traffic_secret[EVP_MAX_MD_SIZE] = {0};
   uint8_t exporter_secret[EVP_MAX_MD_SIZE] = {0};
-  uint8_t early_exporter_secret[EVP_MAX_MD_SIZE] = {0};
   uint8_t write_traffic_secret_len = 0;
   uint8_t read_traffic_secret_len = 0;
   uint8_t exporter_secret_len = 0;
-  uint8_t early_exporter_secret_len = 0;
 
   // Connection binding to prevent renegotiation attacks
   uint8_t previous_client_finished[12] = {0};
diff --git a/ssl/t1_enc.cc b/ssl/t1_enc.cc
index c6b2844..4c2fffb 100644
--- a/ssl/t1_enc.cc
+++ b/ssl/t1_enc.cc
@@ -359,27 +359,3 @@
       MakeConstSpan(session->master_key, session->master_key_length),
       MakeConstSpan(label, label_len), seed, {});
 }
-
-int SSL_export_early_keying_material(
-    SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len,
-    const uint8_t *context, size_t context_len) {
-  if (!SSL_in_early_data(ssl) &&
-      (!ssl->s3->have_version ||
-       ssl_protocol_version(ssl) < TLS1_3_VERSION)) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
-    return 0;
-  }
-
-  // The early exporter only exists if we accepted early data or offered it as
-  // a client.
-  if (!SSL_in_early_data(ssl) && !SSL_early_data_accepted(ssl)) {
-    OPENSSL_PUT_ERROR(SSL, SSL_R_EARLY_DATA_NOT_IN_USE);
-    return 0;
-  }
-
-  return tls13_export_keying_material(
-      ssl, MakeSpan(out, out_len),
-      MakeConstSpan(ssl->s3->early_exporter_secret,
-                    ssl->s3->early_exporter_secret_len),
-      MakeConstSpan(label, label_len), MakeConstSpan(context, context_len));
-}
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index dfcb2c7..f58c151 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -872,22 +872,6 @@
     GetTestState(ssl)->got_new_session = false;
   }
 
-  if (config->export_early_keying_material > 0) {
-    std::vector<uint8_t> result(
-        static_cast<size_t>(config->export_early_keying_material));
-    if (!SSL_export_early_keying_material(
-            ssl, result.data(), result.size(), config->export_label.data(),
-            config->export_label.size(),
-            reinterpret_cast<const uint8_t *>(config->export_context.data()),
-            config->export_context.size())) {
-      fprintf(stderr, "failed to export keying material\n");
-      return false;
-    }
-    if (WriteAll(ssl, result.data(), result.size()) < 0) {
-      return false;
-    }
-  }
-
   if (config->export_keying_material > 0) {
     std::vector<uint8_t> result(
         static_cast<size_t>(config->export_keying_material));
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 9930bd3..b56b9b3 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -1326,21 +1326,6 @@
 	// it was accepted.
 	SendEarlyDataExtension bool
 
-	// ExpectEarlyKeyingMaterial, if non-zero, causes a TLS 1.3 server to
-	// read an application data record after the ClientHello before it sends
-	// a ServerHello. The record's contents have the specified length and
-	// match the corresponding early exporter value. This is used to test
-	// the client using the early exporter in the 0-RTT state.
-	ExpectEarlyKeyingMaterial int
-
-	// ExpectEarlyKeyingLabel is the label to use with
-	// ExpectEarlyKeyingMaterial.
-	ExpectEarlyKeyingLabel string
-
-	// ExpectEarlyKeyingContext is the context string to use with
-	// ExpectEarlyKeyingMaterial
-	ExpectEarlyKeyingContext string
-
 	// ExpectEarlyData causes a TLS 1.3 server to read application
 	// data after the ClientHello (assuming the server is able to
 	// derive the key under which the data is encrypted) before it
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go
index 1eb92bf..3a6c810 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -726,16 +726,7 @@
 			}
 
 			c.earlyCipherSuite = hs.suite
-			expectEarlyData := config.Bugs.ExpectEarlyData
-			if n := config.Bugs.ExpectEarlyKeyingMaterial; n > 0 {
-				exporter, err := c.ExportEarlyKeyingMaterial(n, []byte(config.Bugs.ExpectEarlyKeyingLabel), []byte(config.Bugs.ExpectEarlyKeyingContext))
-				if err != nil {
-					return err
-				}
-				expectEarlyData = append([][]byte{exporter}, expectEarlyData...)
-			}
-
-			for _, expectedMsg := range expectEarlyData {
+			for _, expectedMsg := range config.Bugs.ExpectEarlyData {
 				if err := c.readRecord(recordTypeApplicationData); err != nil {
 					return err
 				}
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index ff4a55a..877a239 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -589,9 +589,6 @@
 	exportLabel          string
 	exportContext        string
 	useExportContext     bool
-	// exportEarlyKeyingMaterial, if non-zero, behaves like
-	// exportKeyingMaterial, but for the early exporter.
-	exportEarlyKeyingMaterial int
 	// flags, if not empty, contains a list of command-line flags that will
 	// be passed to the shim program.
 	flags []string
@@ -881,20 +878,6 @@
 		}
 	}
 
-	if isResume && test.exportEarlyKeyingMaterial > 0 {
-		actual := make([]byte, test.exportEarlyKeyingMaterial)
-		if _, err := io.ReadFull(tlsConn, actual); err != nil {
-			return err
-		}
-		expected, err := tlsConn.ExportEarlyKeyingMaterial(test.exportEarlyKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext))
-		if err != nil {
-			return err
-		}
-		if !bytes.Equal(actual, expected) {
-			return fmt.Errorf("early keying material mismatch; got %x, wanted %x", actual, expected)
-		}
-	}
-
 	if test.exportKeyingMaterial > 0 {
 		actual := make([]byte, test.exportKeyingMaterial)
 		if _, err := io.ReadFull(tlsConn, actual); err != nil {
@@ -1272,10 +1255,7 @@
 			flags = append(flags, "-use-export-context")
 		}
 	}
-	if test.exportEarlyKeyingMaterial > 0 {
-		flags = append(flags, "-on-resume-export-early-keying-material", strconv.Itoa(test.exportEarlyKeyingMaterial))
-	}
-	if test.exportKeyingMaterial > 0 || test.exportEarlyKeyingMaterial > 0 {
+	if test.exportKeyingMaterial > 0 {
 		flags = append(flags, "-export-label", test.exportLabel)
 		flags = append(flags, "-export-context", test.exportContext)
 	}
@@ -10146,106 +10126,6 @@
 				expectedError: ":HANDSHAKE_NOT_COMPLETE:",
 			})
 
-			// Test the early exporter works while the client is
-			// sending 0-RTT data. This data arrives during the
-			// server handshake, so we test it with ProtocolBugs.
-			testCases = append(testCases, testCase{
-				name: "ExportEarlyKeyingMaterial-Client-InEarlyData-" + vers.name,
-				config: Config{
-					MaxVersion:       vers.version,
-					MaxEarlyDataSize: 16384,
-				},
-				resumeConfig: &Config{
-					MaxVersion:       vers.version,
-					MaxEarlyDataSize: 16384,
-					Bugs: ProtocolBugs{
-						ExpectEarlyKeyingMaterial: 1024,
-						ExpectEarlyKeyingLabel:    "label",
-						ExpectEarlyKeyingContext:  "context",
-					},
-				},
-				resumeSession: true,
-				flags: []string{
-					"-enable-early-data",
-					"-expect-ticket-supports-early-data",
-					"-on-resume-expect-accept-early-data",
-					"-on-resume-export-early-keying-material", "1024",
-					"-on-resume-export-label", "label",
-					"-on-resume-export-context", "context",
-				},
-			})
-
-			// Test the early exporter still works on the client
-			// after the handshake is confirmed. This arrives after
-			// the server handshake, so the normal hooks work.
-			testCases = append(testCases, testCase{
-				name: "ExportEarlyKeyingMaterial-Client-EarlyDataAccept-" + vers.name,
-				config: Config{
-					MaxVersion:       vers.version,
-					MaxEarlyDataSize: 16384,
-				},
-				resumeConfig: &Config{
-					MaxVersion:       vers.version,
-					MaxEarlyDataSize: 16384,
-				},
-				resumeSession:             true,
-				exportEarlyKeyingMaterial: 1024,
-				exportLabel:               "label",
-				exportContext:             "context",
-				flags: []string{
-					"-enable-early-data",
-					"-expect-ticket-supports-early-data",
-					"-on-resume-expect-accept-early-data",
-					// Handshake twice on the client to force
-					// handshake confirmation.
-					"-handshake-twice",
-				},
-			})
-
-			// Test the early exporter does not work on the client
-			// if 0-RTT was not offered.
-			testCases = append(testCases, testCase{
-				name: "NoExportEarlyKeyingMaterial-Client-Initial-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				flags:         []string{"-export-early-keying-material", "1024"},
-				shouldFail:    true,
-				expectedError: ":EARLY_DATA_NOT_IN_USE:",
-			})
-			testCases = append(testCases, testCase{
-				name: "NoExportEarlyKeyingMaterial-Client-Resume-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				resumeSession: true,
-				flags:         []string{"-on-resume-export-early-keying-material", "1024"},
-				shouldFail:    true,
-				expectedError: ":EARLY_DATA_NOT_IN_USE:",
-			})
-
-			// Test the early exporter does not work on the client
-			// after a 0-RTT reject.
-			testCases = append(testCases, testCase{
-				name: "NoExportEarlyKeyingMaterial-Client-EarlyDataReject-" + vers.name,
-				config: Config{
-					MaxVersion:       vers.version,
-					MaxEarlyDataSize: 16384,
-					Bugs: ProtocolBugs{
-						AlwaysRejectEarlyData: true,
-					},
-				},
-				resumeSession: true,
-				flags: []string{
-					"-enable-early-data",
-					"-expect-ticket-supports-early-data",
-					"-expect-reject-early-data",
-					"-on-retry-export-early-keying-material", "1024",
-				},
-				shouldFail:    true,
-				expectedError: ":EARLY_DATA_NOT_IN_USE:",
-			})
-
 			// Test the normal exporter on the server in half-RTT.
 			testCases = append(testCases, testCase{
 				testType: serverTest,
@@ -10264,75 +10144,6 @@
 				useExportContext:     true,
 				flags:                []string{"-enable-early-data"},
 			})
-
-			// Test the early exporter works on the server in half-RTT.
-			testCases = append(testCases, testCase{
-				testType: serverTest,
-				name:     "ExportEarlyKeyingMaterial-Server-HalfRTT-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-					Bugs: ProtocolBugs{
-						SendEarlyData:           [][]byte{},
-						ExpectEarlyDataAccepted: true,
-					},
-				},
-				resumeSession:             true,
-				exportEarlyKeyingMaterial: 1024,
-				exportLabel:               "label",
-				exportContext:             "context",
-				flags:                     []string{"-enable-early-data"},
-			})
-
-			// Test the early exporter does not work on the server
-			// if 0-RTT was not offered.
-			testCases = append(testCases, testCase{
-				testType: serverTest,
-				name:     "NoExportEarlyKeyingMaterial-Server-Initial-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				flags:         []string{"-export-early-keying-material", "1024"},
-				shouldFail:    true,
-				expectedError: ":EARLY_DATA_NOT_IN_USE:",
-			})
-			testCases = append(testCases, testCase{
-				testType: serverTest,
-				name:     "NoExportEarlyKeyingMaterial-Server-Resume-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				resumeSession: true,
-				flags:         []string{"-on-resume-export-early-keying-material", "1024"},
-				shouldFail:    true,
-				expectedError: ":EARLY_DATA_NOT_IN_USE:",
-			})
-		} else {
-			// Test the early exporter fails before TLS 1.3.
-			testCases = append(testCases, testCase{
-				name: "NoExportEarlyKeyingMaterial-Client-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				resumeSession:             true,
-				exportEarlyKeyingMaterial: 1024,
-				exportLabel:               "label",
-				exportContext:             "context",
-				shouldFail:                true,
-				expectedError:             ":WRONG_SSL_VERSION:",
-			})
-			testCases = append(testCases, testCase{
-				testType: serverTest,
-				name:     "NoExportEarlyKeyingMaterial-Server-" + vers.name,
-				config: Config{
-					MaxVersion: vers.version,
-				},
-				resumeSession:             true,
-				exportEarlyKeyingMaterial: 1024,
-				exportLabel:               "label",
-				exportContext:             "context",
-				shouldFail:                true,
-				expectedError:             ":WRONG_SSL_VERSION:",
-			})
 		}
 	}
 
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index a53aed2..bd32ce9 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -207,8 +207,6 @@
     {"-max-version", &TestConfig::max_version},
     {"-expect-version", &TestConfig::expect_version},
     {"-mtu", &TestConfig::mtu},
-    {"-export-early-keying-material",
-     &TestConfig::export_early_keying_material},
     {"-export-keying-material", &TestConfig::export_keying_material},
     {"-expect-total-renegotiations", &TestConfig::expect_total_renegotiations},
     {"-expect-peer-signature-algorithm",
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index 57bf66a..ce4b416 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -89,7 +89,6 @@
   bool fail_cert_callback = false;
   std::string cipher;
   bool handshake_never_done = false;
-  int export_early_keying_material = 0;
   int export_keying_material = 0;
   std::string export_label;
   std::string export_context;
diff --git a/ssl/tls13_enc.cc b/ssl/tls13_enc.cc
index 7353561..f457c2f 100644
--- a/ssl/tls13_enc.cc
+++ b/ssl/tls13_enc.cc
@@ -215,7 +215,6 @@
 
 
 static const char kTLS13LabelExporter[] = "exp master";
-static const char kTLS13LabelEarlyExporter[] = "e exp master";
 
 static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic";
 static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic";
@@ -229,13 +228,9 @@
                      kTLS13LabelClientEarlyTraffic,
                      strlen(kTLS13LabelClientEarlyTraffic)) ||
       !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
-                      hs->early_traffic_secret, hs->hash_len) ||
-      !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len,
-                     kTLS13LabelEarlyExporter,
-                     strlen(kTLS13LabelEarlyExporter))) {
+                      hs->early_traffic_secret, hs->hash_len)) {
     return false;
   }
-  ssl->s3->early_exporter_secret_len = hs->hash_len;
 
   if (ssl->quic_method != nullptr) {
     if (ssl->server) {