Merge "Correct mistaken cherry-pick detail in tls deprecation." into udc-mainline-prod am: 3267dee745

Original change: https://googleplex-android-review.googlesource.com/c/platform/external/conscrypt/+/25370795

Change-Id: I4c172291e9f177f999af58703362cf0782dc5324
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 80212d8..891df1b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -346,6 +346,7 @@
     ],
     srcs: [
         ":conscrypt_java_files",
+        ":conscrypt_public_api_files",
     ],
     api_dir: "api/platform",
     api_only: true,
@@ -354,6 +355,8 @@
     },
     droiddoc_options: [
         "--hide-annotation libcore.api.Hide",
+        // Include the "public" API in the "platform" API.
+        "--show-unannotated",
         "--show-single-annotation libcore.api.CorePlatformApi\\(status=libcore.api.CorePlatformApi.Status.STABLE\\)",
     ],
     hostdex: true,
@@ -594,6 +597,7 @@
     visibility: [
         "//cts/tests/libcore/luni",
         "//external/conscrypt/apex/tests",
+        "//libcore",
     ],
     hostdex: true,
     srcs: [
diff --git a/BUILDING.md b/BUILDING.md
index 4eb9539..952abf4 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -69,7 +69,7 @@
 To build the x86_64 version:
 ```bash
 mkdir build.x86
-cd build.86
+cd build.x86
 cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \
       -DCMAKE_BUILD_TYPE=Release \
       -DCMAKE_ASM_FLAGS=-Wa,--noexecstack \
diff --git a/android/build.gradle b/android/build.gradle
index 2333e36..e02dcfa 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -57,7 +57,8 @@
                 cmake {
                     arguments '-DANDROID=True',
                             '-DANDROID_STL=c++_static',
-                            "-DBORINGSSL_HOME=$boringsslHome"
+                            "-DBORINGSSL_HOME=$boringsslHome",
+                            "-DCMAKE_CXX_STANDARD=17"
                     cFlags '-fvisibility=hidden',
                             '-DBORINGSSL_SHARED_LIBRARY',
                             '-DBORINGSSL_IMPLEMENTATION',
diff --git a/apex/Android.bp b/apex/Android.bp
index 970752d..2271655 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -136,6 +136,7 @@
         "target-cacert-apex-7892ad52.0",
         "target-cacert-apex-7a7c655d.0",
         "target-cacert-apex-7a819ef2.0",
+        "target-cacert-apex-7e067d03.0",
         "target-cacert-apex-81b9768f.0",
         "target-cacert-apex-82223c44.0",
         "target-cacert-apex-83e9984f.0",
@@ -154,7 +155,6 @@
         "target-cacert-apex-9576d26b.0",
         "target-cacert-apex-9591a472.0",
         "target-cacert-apex-95aff9e3.0",
-        "target-cacert-apex-9685a493.0",
         "target-cacert-apex-985c1f52.0",
         "target-cacert-apex-99e1b953.0",
         "target-cacert-apex-9aef356c.0",
@@ -218,6 +218,7 @@
         "target-cacert-apex-fb5fa911.0",
         "target-cacert-apex-fd08c599.0",
         "target-cacert-apex-fde84897.0",
+        "target-cacert-apex-ffa7f1eb.0",
     ],
 }
 
diff --git a/apex/ca-certificates/files/7e067d03.0 b/apex/ca-certificates/files/7e067d03.0
new file mode 100644
index 0000000..cdca909
--- /dev/null
+++ b/apex/ca-certificates/files/7e067d03.0
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw
+CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ
+VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy
+MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ
+TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS
+b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B
+IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+
++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK
+sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA
+94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B
+43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            2c:17:08:7d:64:2a:c0:fe:85:18:59:06:cf:b4:4a:eb
+        Signature Algorithm: ecdsa-with-SHA384
+        Issuer: C=CN, O=BEIJING CERTIFICATE AUTHORITY, CN=BJCA Global Root CA2
+        Validity
+            Not Before: Dec 19 03:18:21 2019 GMT
+            Not After : Dec 12 03:18:21 2044 GMT
+        Subject: C=CN, O=BEIJING CERTIFICATE AUTHORITY, CN=BJCA Global Root CA2
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub:
+                    04:9d:cb:80:91:8d:53:67:b5:b9:50:b1:03:f8:e5:
+                    49:1f:41:22:09:b0:51:52:58:d6:2b:34:8f:c5:12:
+                    46:14:c5:8b:2f:2c:84:ff:2c:6e:a8:d5:f1:09:e3:
+                    03:21:14:c4:43:3d:7c:c1:2c:c4:4b:6a:4a:cd:e9:
+                    87:e0:7d:f6:22:be:fa:4a:51:b8:30:8a:fd:e1:de:
+                    18:12:0a:f6:47:b7:e7:17:bf:27:8a:d4:41:4c:96:
+                    3c:60:96:c1:fd:15:1c
+                ASN1 OID: secp384r1
+                NIST CURVE: P-384
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                D2:4A:B1:51:7F:06:F0:D1:82:1F:4E:6E:5F:AB:83:FC:48:D4:B0:91
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+    Signature Algorithm: ecdsa-with-SHA384
+    Signature Value:
+        30:65:02:30:1a:bc:5b:d7:fe:a9:d2:54:0e:4a:5d:d2:6d:b1:
+        40:dc:f4:43:d5:d2:4a:99:19:12:56:80:f7:83:34:e1:35:4e:
+        48:6d:04:0f:57:31:30:30:2d:b1:aa:9d:03:38:db:06:02:31:
+        00:cb:cc:87:53:cb:7a:df:20:51:73:90:c0:a8:5b:61:d0:c5:
+        50:39:fd:85:fe:c1:e3:78:f8:a6:d6:4b:bd:9b:87:8f:0f:e5:
+        d6:53:96:ab:3c:c8:40:da:61:f7:53:a3:f7
+SHA1 Fingerprint=F4:27:86:EB:6E:B8:6D:88:31:67:02:FB:BA:66:A4:53:00:AA:7A:A6
diff --git a/apex/ca-certificates/files/9685a493.0 b/apex/ca-certificates/files/9685a493.0
deleted file mode 100644
index 8b9de91..0000000
--- a/apex/ca-certificates/files/9685a493.0
+++ /dev/null
@@ -1,76 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
-FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
-Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
-A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
-b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
-jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
-PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
-ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
-nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
-q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
-MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
-mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
-7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
-oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
-EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
-fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
-AmvZWg==
------END CERTIFICATE-----
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 1000 (0x3e8)
-        Signature Algorithm: sha1WithRSAEncryption
-        Issuer: C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
-        Validity
-            Not Before: May 15 05:13:14 2003 GMT
-            Not After : May 15 04:52:29 2023 GMT
-        Subject: C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
-        Subject Public Key Info:
-            Public Key Algorithm: rsaEncryption
-                Public-Key: (2048 bit)
-                Modulus:
-                    00:ac:ff:38:b6:e9:66:02:49:e3:a2:b4:e1:90:f9:
-                    40:8f:79:f9:e2:bd:79:fe:02:bd:ee:24:92:1d:22:
-                    f6:da:85:72:69:fe:d7:3f:09:d4:dd:91:b5:02:9c:
-                    d0:8d:5a:e1:55:c3:50:86:b9:29:26:c2:e3:d9:a0:
-                    f1:69:03:28:20:80:45:22:2d:56:a7:3b:54:95:56:
-                    22:59:1f:28:df:1f:20:3d:6d:a2:36:be:23:a0:b1:
-                    6e:b5:b1:27:3f:39:53:09:ea:ab:6a:e8:74:b2:c2:
-                    65:5c:8e:bf:7c:c3:78:84:cd:9e:16:fc:f5:2e:4f:
-                    20:2a:08:9f:77:f3:c5:1e:c4:9a:52:66:1e:48:5e:
-                    e3:10:06:8f:22:98:e1:65:8e:1b:5d:23:66:3b:b8:
-                    a5:32:51:c8:86:aa:a1:a9:9e:7f:76:94:c2:a6:6c:
-                    b7:41:f0:d5:c8:06:38:e6:d4:0c:e2:f3:3b:4c:6d:
-                    50:8c:c4:83:27:c1:13:84:59:3d:9e:75:74:b6:d8:
-                    02:5e:3a:90:7a:c0:42:36:72:ec:6a:4d:dc:ef:c4:
-                    00:df:13:18:57:5f:26:78:c8:d6:0a:79:77:bf:f7:
-                    af:b7:76:b9:a5:0b:84:17:5d:10:ea:6f:e1:ab:95:
-                    11:5f:6d:3c:a3:5c:4d:83:5b:f2:b3:19:8a:80:8b:
-                    0b:87
-                Exponent: 65537 (0x10001)
-        X509v3 extensions:
-            X509v3 Basic Constraints: critical
-                CA:TRUE, pathlen:3
-            X509v3 Key Usage: critical
-                Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
-    Signature Algorithm: sha1WithRSAEncryption
-    Signature Value:
-        0e:46:d5:3c:ae:e2:87:d9:5e:81:8b:02:98:41:08:8c:4c:bc:
-        da:db:ee:27:1b:82:e7:6a:45:ec:16:8b:4f:85:a0:f3:b2:70:
-        bd:5a:96:ba:ca:6e:6d:ee:46:8b:6e:e7:2a:2e:96:b3:19:33:
-        eb:b4:9f:a8:b2:37:ee:98:a8:97:b6:2e:b6:67:27:d4:a6:49:
-        fd:1c:93:65:76:9e:42:2f:dc:22:6c:9a:4f:f2:5a:15:39:b1:
-        71:d7:2b:51:e8:6d:1c:98:c0:d9:2a:f4:a1:82:7b:d5:c9:41:
-        a2:23:01:74:38:55:8b:0f:b9:2e:67:a2:20:04:37:da:9c:0b:
-        d3:17:21:e0:8f:97:79:34:6f:84:48:02:20:33:1b:e6:34:44:
-        9f:91:70:f4:80:5e:84:43:c2:29:d2:6c:12:14:e4:61:8d:ac:
-        10:90:9e:84:50:bb:f0:96:6f:45:9f:8a:f3:ca:6c:4f:fa:11:
-        3a:15:15:46:c3:cd:1f:83:5b:2d:41:12:ed:50:67:41:13:3d:
-        21:ab:94:8a:aa:4e:7c:c1:b1:fb:a7:d6:b5:27:2f:97:ab:6e:
-        e0:1d:e2:d1:1c:2c:1f:44:e2:fc:be:91:a1:9c:fb:d6:29:53:
-        73:86:9f:53:d8:43:0e:5d:d6:63:82:71:1d:80:74:ca:f6:e2:
-        02:6b:d9:5a
-SHA1 Fingerprint=D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58
diff --git a/apex/ca-certificates/files/ffa7f1eb.0 b/apex/ca-certificates/files/ffa7f1eb.0
new file mode 100644
index 0000000..19ce09a
--- /dev/null
+++ b/apex/ca-certificates/files/ffa7f1eb.0
@@ -0,0 +1,122 @@
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU
+MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI
+T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz
+MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF
+SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh
+bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z
+xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ
+spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5
+58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR
+at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll
+5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq
+nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK
+V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/
+pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO
+z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn
+jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+
+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF
+7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
+AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4
+YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli
+awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u
++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88
+X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN
+SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo
+P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI
++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz
+znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9
+eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2
+YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy
+r/6zcCwupvI=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            55:6f:65:e3:b4:d9:90:6a:1b:09:d1:6c:3e:c0:6c:20
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=CN, O=BEIJING CERTIFICATE AUTHORITY, CN=BJCA Global Root CA1
+        Validity
+            Not Before: Dec 19 03:16:17 2019 GMT
+            Not After : Dec 12 03:16:17 2044 GMT
+        Subject: C=CN, O=BEIJING CERTIFICATE AUTHORITY, CN=BJCA Global Root CA1
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:f1:66:08:bd:d9:c5:15:61:cb:84:04:41:a5:69:
+                    37:77:1d:c1:b0:7b:fa:c3:77:48:90:13:72:64:d1:
+                    b8:7c:90:35:9d:18:79:88:e3:97:01:3c:47:81:f2:
+                    0e:a2:98:0d:9e:3f:37:e0:19:b2:90:f2:46:1c:92:
+                    b1:3a:61:ce:fa:b7:46:9e:03:86:d7:33:6e:ed:f7:
+                    45:8c:76:37:de:6e:96:91:f7:d7:7e:2b:87:17:d5:
+                    8b:35:ee:84:91:72:57:dc:60:c3:c3:b9:e7:c7:67:
+                    24:23:4f:63:0a:63:f6:66:7d:4b:55:a7:3f:78:64:
+                    49:69:12:97:e0:4c:0d:d3:09:a0:32:30:3a:fa:9f:
+                    c0:f2:9c:c5:12:2a:2e:1c:b5:04:33:da:a4:38:11:
+                    6a:de:c6:18:f6:47:3a:22:41:87:22:fc:c4:89:28:
+                    54:d8:8c:a5:30:0a:f8:17:16:ca:ac:37:fd:79:a7:
+                    91:17:78:38:99:ad:58:ed:b2:de:cc:89:7d:03:9c:
+                    b3:89:65:e7:e3:3b:b1:22:86:8f:06:6d:78:07:fd:
+                    91:12:7f:b0:6b:1c:89:0d:f9:b8:cb:74:5b:07:c2:
+                    c8:f4:35:d1:64:63:7a:e9:6e:9a:28:d6:30:bd:e6:
+                    1b:dd:15:af:84:ea:9c:c7:ca:f5:0e:ea:f2:5d:29:
+                    87:8f:69:73:39:be:2e:24:6f:45:21:ac:c5:d4:69:
+                    25:06:83:ad:7a:48:85:13:2c:0d:06:b8:6c:79:56:
+                    fc:a3:67:32:81:f5:57:a5:ca:57:42:69:e9:5c:24:
+                    61:ef:e2:30:18:4e:44:98:55:6f:7a:c2:93:d8:19:
+                    b6:de:7c:47:8a:11:4e:49:47:db:28:94:02:0b:94:
+                    4a:2c:f9:12:d0:4f:e8:31:7e:6c:7a:bf:a6:3f:9b:
+                    39:3d:02:16:a3:18:b3:67:ac:5b:3f:2c:83:2b:67:
+                    39:81:5c:b9:7e:94:d5:64:dd:9e:8f:6e:ae:e8:7c:
+                    5b:b4:d7:6a:47:48:d7:7e:b3:d4:2d:8e:56:76:4e:
+                    cf:69:f1:6e:44:6c:d4:24:ea:8d:24:a1:18:bf:bd:
+                    57:fe:a9:99:35:b5:db:10:77:b8:3d:48:ba:d6:c1:
+                    e7:f1:23:3e:d7:df:85:9d:27:3c:d4:40:bd:0a:0c:
+                    bd:f5:e7:8d:25:d6:81:74:87:46:d4:29:75:a2:42:
+                    6c:f7:73:89:e7:7d:bf:7a:4a:1f:d3:22:c9:15:55:
+                    cf:df:6f:7c:55:d0:a4:8b:07:11:37:5f:83:a6:26:
+                    57:a6:01:5b:7e:fe:58:68:07:a9:e9:7a:d9:b9:e8:
+                    ff:50:1f:ab:c2:b4:c0:ce:e8:ea:fd:0f:bd:8d:4d:
+                    b8:bc:71
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                C5:EF:ED:CC:D8:8D:21:C6:48:E4:E3:D7:14:2E:A7:16:93:E5:98:01
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        52:82:ac:21:34:1f:23:f2:a2:d8:f9:b8:af:37:36:20:89:d1:
+        37:03:d6:69:9f:b8:61:10:ba:a2:31:98:59:47:e8:d1:0d:25:
+        1e:15:41:0c:e0:2a:55:d5:57:52:cb:f8:e4:c7:69:a3:1d:4d:
+        71:02:5e:5f:21:45:60:48:5c:09:8e:49:10:c1:04:dc:a9:62:
+        6b:02:f0:43:c8:4e:9d:38:49:74:c9:32:70:54:6d:c1:47:fc:
+        8e:b4:36:9e:d4:9c:bd:dd:20:d6:53:c9:18:a9:b5:56:b9:76:
+        8b:95:67:66:ee:bd:98:fe:ae:ef:be:6e:fb:60:f6:fd:59:c6:
+        2a:1b:3f:23:4a:94:24:30:27:c8:89:bc:eb:44:24:9a:cb:3d:
+        be:4f:d5:7a:ce:8e:17:cb:62:c1:d9:de:1e:0e:7a:ff:43:86:
+        34:52:bc:61:3f:3c:5f:bb:d9:76:b4:53:bc:97:b3:fe:8a:4c:
+        12:2e:2b:f3:d7:ce:e1:a2:ff:dd:7b:70:fb:3b:a1:4d:a4:63:
+        02:fd:38:97:95:3f:05:70:a0:6b:df:62:81:43:8b:b4:59:0d:
+        4a:8c:54:9c:c5:bb:81:9f:cd:7d:a5:ef:0b:25:1e:3a:20:db:
+        1c:fc:1f:98:67:02:0a:d4:73:44:13:db:51:84:1a:55:03:56:
+        e0:00:7e:74:06:ff:38:c4:72:1d:d3:a8:3f:68:31:5d:d3:09:
+        c7:2e:8c:5b:63:e0:e8:dc:1e:d2:ec:61:1e:f2:de:e5:ef:f6:
+        99:76:60:2d:1e:94:72:71:c6:0b:2a:32:c7:92:4e:d5:46:d7:
+        1d:f9:a9:19:0a:c8:fa:95:ce:6d:23:98:aa:0b:38:ad:9a:56:
+        0d:6f:8d:f1:31:00:88:c1:17:9c:cd:19:36:35:fe:55:53:a0:
+        e0:3c:33:5f:96:5e:e2:32:e9:df:33:bb:06:4a:a9:d8:84:73:
+        ce:77:d2:c6:ac:71:e1:5c:a3:1d:0c:bb:0a:df:5f:e2:a3:71:
+        d8:da:37:5a:a0:78:2b:f4:d4:7d:eb:76:ed:f2:61:70:a5:65:
+        9a:d3:89:34:18:ab:fb:72:3e:d7:b4:3d:79:5c:d8:1f:a1:33:
+        7b:d9:82:50:0c:93:17:aa:6c:dc:c2:82:bb:02:57:36:af:98:
+        27:2a:39:50:e1:b0:89:f5:25:97:7e:47:68:10:b4:ec:73:ca:
+        b3:97:d1:24:dc:f6:62:a0:28:d3:b5:a3:b8:64:b7:88:62:42:
+        cf:9d:53:cd:99:be:64:68:8f:4f:1e:12:48:f7:d2:29:c3:98:
+        28:ca:f2:32:0b:93:8c:29:4f:3c:60:32:cd:05:96:61:ec:f2:
+        af:fe:b3:70:2c:2e:a6:f2
+SHA1 Fingerprint=D5:EC:8D:7B:4C:BA:79:F4:E7:E8:CB:9D:6B:AE:77:83:10:03:21:6A
diff --git a/apex/tests/AndroidManifest.xml b/apex/tests/AndroidManifest.xml
index f8cb64d..7ec61f8 100644
--- a/apex/tests/AndroidManifest.xml
+++ b/apex/tests/AndroidManifest.xml
@@ -28,8 +28,6 @@
   <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                    android:targetPackage="com.android.conscrypt.mts"
                    android:label="MTS tests for the Conscrypt mainline module">
-    <meta-data android:name="listener"
-               android:value="com.android.cts.runner.CtsTestRunListener" />
   </instrumentation>
 
 </manifest>
diff --git a/api/platform/current.txt b/api/platform/current.txt
index 932b9d7..b4138e4 100644
--- a/api/platform/current.txt
+++ b/api/platform/current.txt
@@ -1,4 +1,20 @@
 // Signature format: 2.0
+package android.net.ssl {
+
+  public class SSLEngines {
+    method @Nullable public static byte[] exportKeyingMaterial(@NonNull javax.net.ssl.SSLEngine, @NonNull String, @Nullable byte[], int) throws javax.net.ssl.SSLException;
+    method public static boolean isSupportedEngine(@NonNull javax.net.ssl.SSLEngine);
+    method public static void setUseSessionTickets(@NonNull javax.net.ssl.SSLEngine, boolean);
+  }
+
+  public class SSLSockets {
+    method @Nullable public static byte[] exportKeyingMaterial(@NonNull javax.net.ssl.SSLSocket, @NonNull String, @Nullable byte[], int) throws javax.net.ssl.SSLException;
+    method public static boolean isSupportedSocket(@NonNull javax.net.ssl.SSLSocket);
+    method public static void setUseSessionTickets(@NonNull javax.net.ssl.SSLSocket, boolean);
+  }
+
+}
+
 package com.android.org.conscrypt {
 
   public interface CertPinManager {
@@ -34,6 +50,7 @@
     method public final void connect(java.net.SocketAddress) throws java.io.IOException;
     method public final void connect(java.net.SocketAddress, int) throws java.io.IOException;
     method @Deprecated public final byte[] getAlpnSelectedProtocol();
+    method public abstract javax.net.ssl.SSLSession getHandshakeSession();
     method @Deprecated public final byte[] getNpnSelectedProtocol();
     method public final int getPort();
     method public final int getSoTimeout() throws java.net.SocketException;
diff --git a/build.gradle b/build.gradle
index bd547a2..e504bbc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,6 @@
         // This must be applied in the root project otherwise each subproject will
         // have it in a different ClassLoader.
         classpath android_tools
-        classpath 'biz.aQute.bnd:biz.aQute.bnd.gradle:4.3.0'
     }
 }
 
@@ -23,6 +22,7 @@
     id 'org.ajoberstar.grgit' version '3.1.1'
     id 'net.ltgt.errorprone' version '1.3.0'
     id "com.google.osdetector" version "1.7.3"
+    id "biz.aQute.bnd.builder" version "6.4.0" apply false
 }
 
 subprojects {
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index a52df9f..6d831d0 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -33,6 +33,7 @@
 #include <nativehelper/scoped_utf_chars.h>
 #include <openssl/aead.h>
 #include <openssl/asn1.h>
+#include <openssl/bn.h>
 #include <openssl/chacha.h>
 #include <openssl/cmac.h>
 #include <openssl/crypto.h>
@@ -201,40 +202,12 @@
     return true;
 }
 
-/**
- * arrayToBignumSize sets |*out_size| to the size of the big-endian number
- * contained in |source|. It returns true on success and sets an exception and
- * returns false otherwise.
- */
-static bool arrayToBignumSize(JNIEnv* env, jbyteArray source, size_t* out_size) {
-    JNI_TRACE("arrayToBignumSize(%p, %p)", source, out_size);
-
-    ScopedByteArrayRO sourceBytes(env, source);
-    if (sourceBytes.get() == nullptr) {
-        JNI_TRACE("arrayToBignum(%p, %p) => null", source, out_size);
-        return false;
+static bssl::UniquePtr<BIGNUM> arrayToBignum(JNIEnv* env, jbyteArray source) {
+    BIGNUM *bn = nullptr;
+    if (!arrayToBignum(env, source, &bn)) {
+        return nullptr;
     }
-    const uint8_t* tmp = reinterpret_cast<const uint8_t*>(sourceBytes.get());
-    size_t tmpSize = sourceBytes.size();
-
-    if (tmpSize == 0) {
-        *out_size = 0;
-        return true;
-    }
-
-    if ((tmp[0] & 0x80) != 0) {
-        // Negative numbers are invalid.
-        conscrypt::jniutil::throwRuntimeException(env, "Negative number");
-        return false;
-    }
-
-    while (tmpSize > 0 && tmp[0] == 0) {
-        tmp++;
-        tmpSize--;
-    }
-
-    *out_size = tmpSize;
-    return true;
+    return bssl::UniquePtr<BIGNUM>(bn);
 }
 
 /**
@@ -458,32 +431,20 @@
     return bitsRef.release();
 }
 
-static int bio_stream_create(BIO* b) {
-    b->init = 1;
-    b->num = 0;
-    b->ptr = nullptr;
-    b->flags = 0;
-    return 1;
-}
-
 static int bio_stream_destroy(BIO* b) {
     if (b == nullptr) {
         return 0;
     }
 
-    if (b->ptr != nullptr) {
-        delete static_cast<BioStream*>(b->ptr);
-        b->ptr = nullptr;
-    }
-
-    b->init = 0;
-    b->flags = 0;
+    delete static_cast<BioStream*>(BIO_get_data(b));
+    BIO_set_data(b, nullptr);
+    BIO_set_init(b, 0);
     return 1;
 }
 
 static int bio_stream_read(BIO* b, char* buf, int len) {
     BIO_clear_retry_flags(b);
-    BioInputStream* stream = static_cast<BioInputStream*>(b->ptr);
+    BioInputStream* stream = static_cast<BioInputStream*>(BIO_get_data(b));
     int ret = stream->read(buf, len);
     if (ret == 0) {
         if (stream->isFinite()) {
@@ -499,27 +460,23 @@
 
 static int bio_stream_write(BIO* b, const char* buf, int len) {
     BIO_clear_retry_flags(b);
-    BioOutputStream* stream = static_cast<BioOutputStream*>(b->ptr);
+    BioOutputStream* stream = static_cast<BioOutputStream*>(BIO_get_data(b));
     return stream->write(buf, len);
 }
 
-static int bio_stream_puts(BIO* b, const char* buf) {
-    BioOutputStream* stream = static_cast<BioOutputStream*>(b->ptr);
-    return stream->write(buf, static_cast<int>(strlen(buf)));
-}
-
 static int bio_stream_gets(BIO* b, char* buf, int len) {
-    BioInputStream* stream = static_cast<BioInputStream*>(b->ptr);
+    BioInputStream* stream = static_cast<BioInputStream*>(BIO_get_data(b));
     return stream->gets(buf, len);
 }
 
 static void bio_stream_assign(BIO* b, BioStream* stream) {
-    b->ptr = static_cast<void*>(stream);
+    BIO_set_data(b, stream);
+    BIO_set_init(b, 1);
 }
 
 // NOLINTNEXTLINE(runtime/int)
 static long bio_stream_ctrl(BIO* b, int cmd, long, void*) {
-    BioStream* stream = static_cast<BioStream*>(b->ptr);
+    BioStream* stream = static_cast<BioStream*>(BIO_get_data(b));
 
     switch (cmd) {
         case BIO_CTRL_EOF:
@@ -531,18 +488,21 @@
     }
 }
 
-static BIO_METHOD stream_bio_method = {
-        (100 | 0x0400), /* source/sink BIO */
-        "InputStream/OutputStream BIO",
-        bio_stream_write,   /* bio_write */
-        bio_stream_read,    /* bio_read */
-        bio_stream_puts,    /* bio_puts */
-        bio_stream_gets,    /* bio_gets */
-        bio_stream_ctrl,    /* bio_ctrl */
-        bio_stream_create,  /* bio_create */
-        bio_stream_destroy, /* bio_free */
-        nullptr,            /* no bio_callback_ctrl */
-};
+static const BIO_METHOD *stream_bio_method() {
+    static const BIO_METHOD* stream_method = []() -> const BIO_METHOD* {
+        BIO_METHOD* method = BIO_meth_new(0, nullptr);
+        if (!method || !BIO_meth_set_write(method, bio_stream_write) ||
+            !BIO_meth_set_read(method, bio_stream_read) ||
+            !BIO_meth_set_gets(method, bio_stream_gets) ||
+            !BIO_meth_set_ctrl(method, bio_stream_ctrl) ||
+            !BIO_meth_set_destroy(method, bio_stream_destroy)) {
+            BIO_meth_free(method);
+            return nullptr;
+        }
+        return method;
+    }();
+    return stream_method;
+}
 
 static jbyteArray ecSignDigestWithPrivateKey(JNIEnv* env, jobject privateKey, const char* message,
                                              size_t message_len) {
@@ -659,10 +619,6 @@
 struct KeyExData {
     // private_key contains a reference to a Java, private-key object.
     jobject private_key;
-    // cached_size contains the "size" of the key. This is the size of the
-    // modulus (in bytes) for RSA, or the group order size for ECDSA. This
-    // avoids calling into Java to calculate the size.
-    size_t cached_size;
 };
 
 // ExDataDup is called when one of the RSA or EC_KEY objects is duplicated. We
@@ -697,11 +653,6 @@
     return reinterpret_cast<KeyExData*>(RSA_get_ex_data(rsa, g_rsa_exdata_index));
 }
 
-size_t RsaMethodSize(const RSA* rsa) {
-    const KeyExData* ex_data = RsaGetExData(rsa);
-    return ex_data->cached_size;
-}
-
 int RsaMethodSignRaw(RSA* rsa, size_t* out_len, uint8_t* out, size_t max_out, const uint8_t* in,
                      size_t in_len, int padding) {
     if (padding != RSA_PKCS1_PADDING && padding != RSA_NO_PADDING) {
@@ -849,7 +800,6 @@
                                                    nullptr /* new_func */, ExDataDup, ExDataFree);
 
     g_rsa_method.common.is_static = 1;
-    g_rsa_method.size = RsaMethodSize;
     g_rsa_method.sign_raw = RsaMethodSignRaw;
     g_rsa_method.decrypt = RsaMethodDecrypt;
     g_rsa_method.flags = RSA_FLAG_OPAQUE;
@@ -887,12 +837,6 @@
     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p, dmp1=%p, dmq1=%p, iqmp=%p)", n, e, d,
               p, q, dmp1, dmq1, iqmp);
 
-    bssl::UniquePtr<RSA> rsa(RSA_new());
-    if (rsa.get() == nullptr) {
-        conscrypt::jniutil::throwRuntimeException(env, "RSA_new failed");
-        return 0;
-    }
-
     if (e == nullptr && d == nullptr) {
         conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException",
                                            "e == null && d == null");
@@ -900,6 +844,83 @@
         return 0;
     }
 
+#if BORINGSSL_API_VERSION >= 20
+    bssl::UniquePtr<BIGNUM> nBN, eBN, dBN, pBN, qBN, dmp1BN, dmq1BN, iqmpBN;
+    nBN = arrayToBignum(env, n);
+    if (!nBN) {
+        return 0;
+    }
+    if (e != nullptr) {
+        eBN = arrayToBignum(env, e);
+        if (!eBN) {
+            return 0;
+        }
+    }
+    if (d != nullptr) {
+        dBN = arrayToBignum(env, d);
+        if (!dBN) {
+            return 0;
+        }
+    }
+    if (p != nullptr) {
+        pBN = arrayToBignum(env, p);
+        if (!pBN) {
+            return 0;
+        }
+    }
+    if (q != nullptr) {
+        qBN = arrayToBignum(env, q);
+        if (!qBN) {
+            return 0;
+        }
+    }
+    if (dmp1 != nullptr) {
+        dmp1BN = arrayToBignum(env, dmp1);
+        if (!dmp1BN) {
+            return 0;
+        }
+    }
+    if (dmq1 != nullptr) {
+        dmq1BN = arrayToBignum(env, dmq1);
+        if (!dmq1BN) {
+            return 0;
+        }
+    }
+    if (iqmp != nullptr) {
+        iqmpBN = arrayToBignum(env, iqmp);
+        if (!iqmpBN) {
+            return 0;
+        }
+    }
+
+    // Determine what kind of key this is.
+    //
+    // TODO(davidben): The caller already knows what kind of key they expect. Ideally we would have
+    // separate APIs for the caller. However, we currently tolerate, say, an RSAPrivateCrtKeySpec
+    // where most fields are null and silently make a public key out of it. This is probably a
+    // mistake, but would need to be a breaking change.
+    bssl::UniquePtr<RSA> rsa;
+    if (!dBN) {
+        rsa.reset(RSA_new_public_key(nBN.get(), eBN.get()));
+    } else if (!eBN) {
+        rsa.reset(RSA_new_private_key_no_e(nBN.get(), dBN.get()));
+    } else if (!pBN || !qBN || !dmp1BN || !dmq1BN || !iqmpBN) {
+        rsa.reset(RSA_new_private_key_no_crt(nBN.get(), eBN.get(), dBN.get()));
+    } else {
+        rsa.reset(RSA_new_private_key(nBN.get(), eBN.get(), dBN.get(), pBN.get(), qBN.get(),
+                                      dmp1BN.get(), dmq1BN.get(), iqmpBN.get()));
+    }
+    if (rsa == nullptr) {
+        conscrypt::jniutil::throwRuntimeException(env, "Creating RSA key failed");
+        return 0;
+    }
+#else
+    bssl::UniquePtr<RSA> rsa(RSA_new());
+    if (rsa.get() == nullptr) {
+        conscrypt::jniutil::throwRuntimeException(env, "RSA_new failed");
+        return 0;
+    }
+
     if (!arrayToBignum(env, n, &rsa->n)) {
         return 0;
     }
@@ -956,6 +977,7 @@
         JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get());
         rsa->flags |= RSA_FLAG_NO_BLINDING;
     }
+#endif
 
     bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
     if (pkey.get() == nullptr) {
@@ -987,11 +1009,10 @@
 
     bssl::UniquePtr<BIGNUM> key(nullptr);
     if (keyJavaBytes != nullptr) {
-        BIGNUM* keyRef = nullptr;
-        if (!arrayToBignum(env, keyJavaBytes, &keyRef)) {
+        key = arrayToBignum(env, keyJavaBytes);
+        if (!key) {
             return 0;
         }
-        key.reset(keyRef);
     }
 
     bssl::UniquePtr<EC_KEY> eckey(EC_KEY_new());
@@ -1267,16 +1288,25 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     JNI_TRACE("getRSAPrivateKeyWrapper(%p, %p)", javaKey, modulusBytes);
 
-    size_t cached_size;
-    if (!arrayToBignumSize(env, modulusBytes, &cached_size)) {
-        JNI_TRACE("getRSAPrivateKeyWrapper failed");
+    ensure_engine_globals();
+
+#if BORINGSSL_API_VERSION >= 20
+    // The PSS padding code needs access to the actual n, so set it even though we
+    // don't set any other parts of the key
+    bssl::UniquePtr<BIGNUM> n = arrayToBignum(env, modulusBytes);
+    if (n == nullptr) {
         return 0;
     }
 
-    ensure_engine_globals();
-
+    // TODO(crbug.com/boringssl/602): RSA_METHOD is not the ideal abstraction to use here.
+    bssl::UniquePtr<RSA> rsa(RSA_new_method_no_e(g_engine, n.get()));
+    if (rsa == nullptr) {
+        conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate RSA key");
+        return 0;
+    }
+#else
     bssl::UniquePtr<RSA> rsa(RSA_new_method(g_engine));
-    if (rsa.get() == nullptr) {
+    if (rsa == nullptr) {
         conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate RSA key");
         return 0;
     }
@@ -1286,10 +1316,10 @@
     if (!arrayToBignum(env, modulusBytes, &rsa->n)) {
         return 0;
     }
+#endif
 
     auto ex_data = new KeyExData;
     ex_data->private_key = env->NewGlobalRef(javaKey);
-    ex_data->cached_size = cached_size;
     RSA_set_ex_data(rsa.get(), g_rsa_exdata_index, ex_data);
 
     bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
@@ -1371,11 +1401,10 @@
     CHECK_ERROR_QUEUE_ON_RETURN;
     JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
 
-    BIGNUM* eRef = nullptr;
-    if (!arrayToBignum(env, publicExponent, &eRef)) {
+    bssl::UniquePtr<BIGNUM> e = arrayToBignum(env, publicExponent);
+    if (e == nullptr) {
         return 0;
     }
-    bssl::UniquePtr<BIGNUM> e(eRef);
 
     bssl::UniquePtr<RSA> rsa(RSA_new());
     if (rsa.get() == nullptr) {
@@ -1690,9 +1719,6 @@
                                                  jbyteArray xBytes, jbyteArray yBytes,
                                                  jbyteArray orderBytes, jint cofactorInt) {
     CHECK_ERROR_QUEUE_ON_RETURN;
-    BIGNUM *p = nullptr, *a = nullptr, *b = nullptr, *x = nullptr, *y = nullptr;
-    BIGNUM *order = nullptr, *cofactor = nullptr;
-
     JNI_TRACE("EC_GROUP_new_arbitrary");
 
     if (cofactorInt < 1) {
@@ -1701,34 +1727,37 @@
         return 0;
     }
 
-    cofactor = BN_new();
-    if (cofactor == nullptr) {
+    bssl::UniquePtr<BIGNUM> p = arrayToBignum(env, pBytes);
+    if (p == nullptr) {
         return 0;
     }
-
-    int ok = 1;
-
-    if (!arrayToBignum(env, pBytes, &p) || !arrayToBignum(env, aBytes, &a) ||
-        !arrayToBignum(env, bBytes, &b) || !arrayToBignum(env, xBytes, &x) ||
-        !arrayToBignum(env, yBytes, &y) || !arrayToBignum(env, orderBytes, &order) ||
-        !BN_set_word(cofactor, static_cast<uint32_t>(cofactorInt))) {
-        ok = 0;
+    bssl::UniquePtr<BIGNUM> a = arrayToBignum(env, aBytes);
+    if (a == nullptr) {
+        return 0;
     }
-
-    bssl::UniquePtr<BIGNUM> pStorage(p);
-    bssl::UniquePtr<BIGNUM> aStorage(a);
-    bssl::UniquePtr<BIGNUM> bStorage(b);
-    bssl::UniquePtr<BIGNUM> xStorage(x);
-    bssl::UniquePtr<BIGNUM> yStorage(y);
-    bssl::UniquePtr<BIGNUM> orderStorage(order);
-    bssl::UniquePtr<BIGNUM> cofactorStorage(cofactor);
-
-    if (!ok) {
+    bssl::UniquePtr<BIGNUM> b = arrayToBignum(env, bBytes);
+    if (b == nullptr) {
+        return 0;
+    }
+    bssl::UniquePtr<BIGNUM> x = arrayToBignum(env, xBytes);
+    if (x == nullptr) {
+        return 0;
+    }
+    bssl::UniquePtr<BIGNUM> y = arrayToBignum(env, yBytes);
+    if (y == nullptr) {
+        return 0;
+    }
+    bssl::UniquePtr<BIGNUM> order = arrayToBignum(env, orderBytes);
+    if (order == nullptr) {
+        return 0;
+    }
+    bssl::UniquePtr<BIGNUM> cofactor(BN_new());
+    if (cofactor == nullptr || !BN_set_word(cofactor.get(), static_cast<uint32_t>(cofactorInt))) {
         return 0;
     }
 
     bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
-    bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_curve_GFp(p, a, b, ctx.get()));
+    bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
     if (group.get() == nullptr) {
         JNI_TRACE("EC_GROUP_new_curve_GFp => null");
         conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EC_GROUP_new_curve_GFp");
@@ -1742,14 +1771,14 @@
         return 0;
     }
 
-    if (!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(), x, y, ctx.get())) {
+    if (!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(), x.get(), y.get(), ctx.get())) {
         JNI_TRACE("EC_POINT_set_affine_coordinates_GFp => error");
         conscrypt::jniutil::throwExceptionFromBoringSSLError(env,
                                                              "EC_POINT_set_affine_coordinates_GFp");
         return 0;
     }
 
-    if (!EC_GROUP_set_generator(group.get(), generator.get(), order, cofactor)) {
+    if (!EC_GROUP_set_generator(group.get(), generator.get(), order.get(), cofactor.get())) {
         JNI_TRACE("EC_GROUP_set_generator => error");
         conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EC_GROUP_set_generator");
         return 0;
@@ -1995,17 +2024,15 @@
     JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) <- ptr", group, point, xjavaBytes,
               yjavaBytes);
 
-    BIGNUM* xRef = nullptr;
-    if (!arrayToBignum(env, xjavaBytes, &xRef)) {
+    bssl::UniquePtr<BIGNUM> x = arrayToBignum(env, xjavaBytes);
+    if (x == nullptr) {
         return;
     }
-    bssl::UniquePtr<BIGNUM> x(xRef);
 
-    BIGNUM* yRef = nullptr;
-    if (!arrayToBignum(env, yjavaBytes, &yRef)) {
+    bssl::UniquePtr<BIGNUM> y = arrayToBignum(env, yjavaBytes);
+    if (y == nullptr) {
         return;
     }
-    bssl::UniquePtr<BIGNUM> y(yRef);
 
     int ret = EC_POINT_set_affine_coordinates_GFp(group, point, x.get(), y.get(), nullptr);
     if (ret != 1) {
@@ -4548,7 +4575,11 @@
         return 0;
     }
 
-    bssl::UniquePtr<BIO> bio(BIO_new(&stream_bio_method));
+    const BIO_METHOD *method = stream_bio_method();
+    if (!method) {
+        return 0;
+    }
+    bssl::UniquePtr<BIO> bio(BIO_new(method));
     if (bio.get() == nullptr) {
         return 0;
     }
@@ -4568,7 +4599,11 @@
         return 0;
     }
 
-    bssl::UniquePtr<BIO> bio(BIO_new(&stream_bio_method));
+    const BIO_METHOD *method = stream_bio_method();
+    if (!method) {
+        return 0;
+    }
+    bssl::UniquePtr<BIO> bio(BIO_new(method));
     if (bio.get() == nullptr) {
         return 0;
     }
@@ -5150,14 +5185,8 @@
         return 0;
     }
 
-    bssl::UniquePtr<BIGNUM> serialBn(BN_new());
-    if (serialBn.get() == nullptr) {
-        JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN allocation failed", x509crl, serialArray);
-        return 0;
-    }
-
-    BIGNUM* serialBare = serialBn.get();
-    if (!arrayToBignum(env, serialArray, &serialBare)) {
+    bssl::UniquePtr<BIGNUM> serialBn = arrayToBignum(env, serialArray);
+    if (serialBn == nullptr) {
         if (!env->ExceptionCheck()) {
             conscrypt::jniutil::throwNullPointerException(env, "serial == null");
         }
diff --git a/common/src/main/java/org/conscrypt/NativeCrypto.java b/common/src/main/java/org/conscrypt/NativeCrypto.java
index b440fc3..bd1239f 100644
--- a/common/src/main/java/org/conscrypt/NativeCrypto.java
+++ b/common/src/main/java/org/conscrypt/NativeCrypto.java
@@ -850,8 +850,11 @@
     static {
         if (loadError == null) {
             // If loadError is not null, it means the native code was not loaded, so
-            // get_cipher_names will throw UnsatisfiedLinkError.
-            String[] allCipherSuites = get_cipher_names("ALL:!DHE");
+            // get_cipher_names will throw UnsatisfiedLinkError. Populate the list of supported
+            // ciphers with BoringSSL's default, and also explicitly include 3DES.
+            // https://boringssl-review.googlesource.com/c/boringssl/+/59425 will remove 3DES
+            // from BoringSSL's default, but Conscrypt isn't quite ready to remove it yet.
+            String[] allCipherSuites = get_cipher_names("ALL:3DES");
 
             // get_cipher_names returns an array where even indices are the standard name and odd
             // indices are the OpenSSL name.
diff --git a/common/src/main/java/org/conscrypt/OpenSSLMac.java b/common/src/main/java/org/conscrypt/OpenSSLMac.java
index 8091226..1bef88f 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLMac.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLMac.java
@@ -44,6 +44,7 @@
      * Holds a dummy buffer for writing single bytes to the digest.
      */
     private final byte[] singleByte = new byte[1];
+    protected boolean initialized = false;
 
     private OpenSSLMac(int size) {
         this.size = size;
@@ -80,7 +81,12 @@
             throw new InvalidKeyException("key cannot be encoded");
         }
 
-        resetContext();
+        try {
+            resetContext();
+        } catch (RuntimeException e) {
+            throw new InvalidKeyException("invalid key", e);
+        }
+        initialized = true;
     }
 
     @Override
@@ -137,6 +143,9 @@
 
     @Override
     protected void engineReset() {
+        if (!initialized) {
+            return;
+        }
         resetContext();
     }
 
diff --git a/common/src/main/java/org/conscrypt/OpenSSLProvider.java b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
index 1e2fcef..99547dc 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLProvider.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLProvider.java
@@ -198,6 +198,7 @@
 
         put("KeyPairGenerator.XDH", PREFIX + "OpenSSLXDHKeyPairGenerator");
         put("Alg.Alias.KeyPairGenerator.1.3.101.110", "XDH");
+        put("Alg.Alias.KeyPairGenerator.X25519", "XDH");
 
         /* == KeyFactory == */
         put("KeyFactory.RSA", PREFIX + "OpenSSLRSAKeyFactory");
@@ -211,6 +212,7 @@
 
         put("KeyFactory.XDH", PREFIX + "OpenSSLXDHKeyFactory");
         put("Alg.Alias.KeyFactory.1.3.101.110", "XDH");
+        put("Alg.Alias.KeyFactory.X25519", "XDH");
 
         /* == SecretKeyFactory == */
         put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
@@ -628,6 +630,8 @@
                 PREFIX + className,
                 supportedKeyClasses,
                 supportedKeyFormats);
+
+        put("Alg.Alias.KeyAgreement.X25519", "XDH");
     }
 
     private void putImplClassWithKeyConstraints(String typeAndAlgName,
diff --git a/common/src/main/java/org/conscrypt/OpenSSLXDHKeyFactory.java b/common/src/main/java/org/conscrypt/OpenSSLXDHKeyFactory.java
index 100d24f..c6babde 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLXDHKeyFactory.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLXDHKeyFactory.java
@@ -81,8 +81,9 @@
             throw new InvalidKeySpecException("keySpec == null");
         }
 
-        if (!"XDH".equals(key.getAlgorithm())) {
-            throw new InvalidKeySpecException("Key must be an XDH key");
+        // Support XDH or X25519 algorithm names per JEP 324
+        if (!"XDH".equals(key.getAlgorithm()) && !"X25519".equals(key.getAlgorithm()) ) {
+            throw new InvalidKeySpecException("Key must be an XDH or X25519 key");
         }
 
         Class<?> publicKeySpec = getJavaPublicKeySpec();
diff --git a/common/src/test/java/org/conscrypt/ConscryptSuite.java b/common/src/test/java/org/conscrypt/ConscryptSuite.java
index eab794d..c0950f2 100644
--- a/common/src/test/java/org/conscrypt/ConscryptSuite.java
+++ b/common/src/test/java/org/conscrypt/ConscryptSuite.java
@@ -36,6 +36,8 @@
 import org.conscrypt.java.security.KeyFactoryTestEC;
 import org.conscrypt.java.security.KeyFactoryTestRSA;
 import org.conscrypt.java.security.KeyFactoryTestRSACrt;
+import org.conscrypt.java.security.KeyFactoryTestRSACustom;
+import org.conscrypt.java.security.KeyFactoryTestXDH;
 import org.conscrypt.java.security.KeyPairGeneratorTest;
 import org.conscrypt.java.security.KeyPairGeneratorTestDH;
 import org.conscrypt.java.security.KeyPairGeneratorTestDSA;
@@ -114,6 +116,8 @@
         KeyFactoryTestEC.class,
         KeyFactoryTestRSA.class,
         KeyFactoryTestRSACrt.class,
+        KeyFactoryTestRSACustom.class,
+        KeyFactoryTestXDH.class,
         KeyPairGeneratorTest.class,
         KeyPairGeneratorTestDH.class,
         KeyPairGeneratorTestDSA.class,
diff --git a/common/src/test/java/org/conscrypt/MacTest.java b/common/src/test/java/org/conscrypt/MacTest.java
index a80065a..1fadbd6 100644
--- a/common/src/test/java/org/conscrypt/MacTest.java
+++ b/common/src/test/java/org/conscrypt/MacTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
@@ -31,6 +32,7 @@
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.spec.AlgorithmParameterSpec;
 import java.util.HashSet;
@@ -145,6 +147,8 @@
                     mac = Mac.getInstance(algorithm, provider);
                     assertEquals(algorithm, mac.getAlgorithm());
                     assertEquals(provider, mac.getProvider());
+                    // It's not an error to reset an uninitialised Mac.
+                    mac.reset();
                     if (key != null) {
                         // TODO(prb) Ensure we have at least one test vector for every
                         // MAC in Conscrypt and Android.
@@ -164,7 +168,7 @@
     }
 
     @Test
-    public void invalidKeyThrows() {
+    public void invalidKeyTypeThrows() {
         newMacServiceTester()
             // BC actually accepts RSA public keys for these algorithms for some reason.
             .skipCombination("BC", "PBEWITHHMACSHA")
@@ -188,6 +192,16 @@
     }
 
     @Test
+    public void invalidCmacKeySizeThrows() throws Exception {
+        // TODO(prb): extend to other Macs, deal with inconsistencies between providers.
+        Mac mac = Mac.getInstance("AESCMAC", conscryptProvider);
+        byte[] keyBytes = new byte[1];
+        SecretKeySpec key = new SecretKeySpec(keyBytes, "RawBytes");
+
+        assertThrows(InvalidKeyException.class, () -> mac.init(key));
+    }
+
+    @Test
     public void uninitializedMacThrows() {
         newMacServiceTester()
             .run(new ServiceTester.Test() {
diff --git a/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java b/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
index 919be53..67721da 100644
--- a/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
+++ b/common/src/test/java/org/conscrypt/java/security/KeyPairGeneratorTest.java
@@ -151,8 +151,8 @@
         putKeySize("DSA", 512);
         putKeySize("DSA", 512+64);
         putKeySize("DSA", 1024);
-        putKeySize("RSA", 512);
-        putKeySize("RSASSA-PSS", 512);
+        putKeySize("RSA", 2048);
+        putKeySize("RSASSA-PSS", 2048);
         putKeySize("DH", 512);
         putKeySize("DH", 512+64);
         putKeySize("DH", 1024);
diff --git a/common/src/test/java/org/conscrypt/java/security/SignatureTest.java b/common/src/test/java/org/conscrypt/java/security/SignatureTest.java
index bba0863..bfaec85 100644
--- a/common/src/test/java/org/conscrypt/java/security/SignatureTest.java
+++ b/common/src/test/java/org/conscrypt/java/security/SignatureTest.java
@@ -115,6 +115,7 @@
             .skipAlgorithm("Ed448")
             .skipAlgorithm("Ed25519")
             .skipAlgorithm("EdDSA")
+            .skipAlgorithm("HSS/LMS")
             .run(new ServiceTester.Test() {
                 @Override
                 public void test(Provider provider, String algorithm) throws Exception {
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
index ac651a7..687e4d1 100644
--- a/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
+++ b/common/src/test/java/org/conscrypt/javax/crypto/CipherTest.java
@@ -72,6 +72,7 @@
 import javax.crypto.spec.SecretKeySpec;
 import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
 import libcore.test.annotation.NonCts;
+import libcore.test.reasons.NonCtsReasons;
 import org.bouncycastle.asn1.x509.KeyUsage;
 import org.conscrypt.Conscrypt;
 import org.conscrypt.TestUtils;
@@ -1068,15 +1069,20 @@
                 if (firstSlash == -1) {
                     seenBaseCipherNames.add(algorithm);
                 } else {
-                    final String baseCipherName = algorithm.substring(0, firstSlash);
-                    if (!seenBaseCipherNames.contains(baseCipherName)
+                    final int secondSlash = algorithm.indexOf('/', firstSlash + 1);
+                    if (secondSlash > 0) {
+                        // Only look for a base Cipher if there are two slashes, to avoid SunJCE
+                        // quirks like PBEWithHmacSHA512/224AndAES_128
+                        final String baseCipherName = algorithm.substring(0, firstSlash);
+                        if (!seenBaseCipherNames.contains(baseCipherName)
                             && !(baseCipherName.equals("AES_128")
-                                || baseCipherName.equals("AES_192")
-                                || baseCipherName.equals("AES_256"))) {
-                        seenCiphersWithModeAndPadding.add(baseCipherName);
-                    }
-                    if (!Conscrypt.isConscrypt(provider)) {
-                        continue;
+                            || baseCipherName.equals("AES_192")
+                            || baseCipherName.equals("AES_256"))) {
+                            seenCiphersWithModeAndPadding.add(baseCipherName);
+                        }
+                        if (!Conscrypt.isConscrypt(provider)) {
+                            continue;
+                        }
                     }
                 }
 
@@ -4653,72 +4659,6 @@
         assertEquals(Arrays.toString(c1.doFinal()), Arrays.toString(c2.doFinal()));
     }
 
-    /**
-     * http://b/27224566
-     * http://b/27994930
-     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
-     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
-     * mixing them is not recommended.
-     */
-    @NonCts(bug = 287231726, reason = "The test asserts buggy or non-breaking "
-            + "behaviors, but the behavior has been fixed in the future ART module version.")
-    @Test
-    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV() throws Exception {
-        Assume.assumeNotNull(Security.getProvider("BC"));
-        byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-                17, 18, 19 };
-        byte[] ciphertext = new byte[] {  92, -65, -128, 16, -102, -115, -44, 52, 16, 124, -34,
-                -45, 58, -70, -17, 127, 119, -67, 87, 91, 63, -13, -40, 9, 97, -17, -71, 97, 10,
-                -61, -19, -73 };
-        SecretKeyFactory skf =
-                SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
-        PBEKeySpec pbeks = new PBEKeySpec("password".toCharArray(),
-                "salt".getBytes(TestUtils.UTF_8),
-                100, 128);
-        SecretKey secretKey = skf.generateSecret(pbeks);
-
-        Cipher cipher =
-                Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
-        PBEParameterSpec paramSpec = new PBEParameterSpec("salt".getBytes(TestUtils.UTF_8), 100);
-        assertThrows(InvalidAlgorithmParameterException.class,
-                () -> cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec));
-    }
-
-    /**
-     * http://b/27224566
-     * http://b/27994930
-     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
-     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
-     * mixing them is not recommended. However, until 1.52 BouncyCastle was accepting this mixture,
-     * assuming the IV was a 0 vector. Some apps still use this functionality. This
-     * compatibility is likely to be removed in later versions of Android.
-     * TODO(27995180): consider whether we keep this compatibility. Consider whether we only allow
-     * if an IV is passed in the parameters.
-     */
-    @Test
-    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_withIV() throws Exception {
-        Assume.assumeNotNull(Security.getProvider("BC"));
-        byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,  12, 13, 14, 15, 16,
-                17, 18, 19 };
-        byte[] ciphertext = { 68, -87, 71, -6, 32, -77, 124, 3, 35, -26, 96, -16, 100, -17, 52, -32,
-                110, 26, -117, 112, -25, -113, -58, -30, 19, -46, -21, 59, -126, -8, -70, -89 };
-        byte[] iv = new byte[] { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-        SecretKeyFactory skf =
-                SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
-        PBEKeySpec pbeks = new PBEKeySpec("password".toCharArray(),
-                "salt".getBytes(TestUtils.UTF_8),
-                100, 128);
-        SecretKey secretKey = skf.generateSecret(pbeks);
-        Cipher cipher =
-                Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
-        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
-        assertEquals(Arrays.toString(ciphertext), Arrays.toString(cipher.doFinal(plaintext)));
-
-        secretKey = skf.generateSecret(pbeks);
-        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
-        assertEquals(Arrays.toString(plaintext), Arrays.toString(cipher.doFinal(ciphertext)));
-    }
-
     private static Cipher createAesCipher(int opmode) {
         try {
             final Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java b/common/src/test/java/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java
new file mode 100644
index 0000000..a235a2b
--- /dev/null
+++ b/common/src/test/java/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java
@@ -0,0 +1,28 @@
+package org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import javax.crypto.KeyAgreement;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+/**
+ * Tests for all registered X25519 {@link KeyAgreement} providers.
+ */
+@RunWith(JUnit4.class)
+public class X25519KeyAgreementTest extends XDHKeyAgreementTest {
+
+    @Override
+    protected String getAlgorithm() {
+        return "X25519";
+    }
+}
diff --git a/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java b/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
index 9f64315..fb679ad 100644
--- a/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
+++ b/common/src/test/java/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
@@ -59,7 +59,7 @@
     private PublicKey rfc7748X25519PublicKey;
 
     private void setupKeys(Provider p) throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("XDH", p);
+        KeyFactory kf = KeyFactory.getInstance(getAlgorithm(), p);
 
         byte[] privateKey;
         if ("SunEC".equalsIgnoreCase(p.getName())
@@ -84,17 +84,23 @@
 
     @Test
     public void test_XDHKeyAgreement() throws Exception {
-        for (Provider p : Security.getProviders("KeyAgreement.XDH")) {
+        final String keyAgreementAlgorithm = String.format("KeyAgreement.%s", getAlgorithm());
+        for (Provider p : Security.getProviders(keyAgreementAlgorithm)) {
             // Skip testing Android Keystore as it's covered by CTS tests.
             if ("AndroidKeyStore".equals(p.getName())) {
                 continue;
             }
             setupKeys(p);
 
-            KeyAgreement ka = KeyAgreement.getInstance("XDH", p);
+            KeyAgreement ka = KeyAgreement.getInstance(getAlgorithm(), p);
 
             test_x25519_keyAgreement_rfc7748_kat_success(ka);
         }
+
+    }
+
+    protected String getAlgorithm() {
+        return "XDH";
     }
 
     private void test_x25519_keyAgreement_rfc7748_kat_success(KeyAgreement ka) throws Exception {
diff --git a/openjdk/build.gradle b/openjdk/build.gradle
index 913a36e..2c0adb1 100644
--- a/openjdk/build.gradle
+++ b/openjdk/build.gradle
@@ -458,6 +458,7 @@
                                 "/GS",
                                 "/Gy",
                                 "/fp:precise",
+                                "/std:c++17",
                                 "-wd4514", // Unreferenced inline function removed
                                 "-wd4548", // Expression before comma has no effect
                                 "-wd4625", // Copy constructor was implicitly defined as deleted
diff --git a/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java b/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
index 781c93f..813eaac 100644
--- a/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
+++ b/openjdk/src/test/java/org/conscrypt/ConscryptOpenJdkSuite.java
@@ -8,91 +8,22 @@
 
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
-        // org.conscrypt tests
-        AddressUtilsTest.class,
-        ApplicationProtocolSelectorAdapterTest.class,
-        CertPinManagerTest.class,
-        ChainStrengthAnalyzerTest.class,
-        ClientSessionContextTest.class,
-        ConscryptSocketTest.class,
-        ConscryptTest.class,
-        DuckTypedHpkeSpiTest.class,
-        DuckTypedPSKKeyManagerTest.class,
-        FileClientSessionCacheTest.class,
-        HostnameVerifierTest.class,
-        NativeCryptoArgTest.class,
-        NativeCryptoTest.class,
-        NativeRefTest.class,
-        NativeSslSessionTest.class,
-        OpenSSLKeyTest.class,
-        OpenSSLX509CertificateTest.class,
-        PlatformTest.class,
-        SSLUtilsTest.class,
-        ServerSessionContextTest.class,
-        TestSessionBuilderTest.class,
-        TrustManagerImplTest.class,
-        // org.conscrypt.ct tests
-        CTVerifierTest.class,
-        SerializationTest.class,
-        // java.security tests
-        CertificateFactoryTest.class,
-        X509CertificateTest.class,
-        X509CRLTest.class,
-        AlgorithmParameterGeneratorTestDH.class,
-        AlgorithmParameterGeneratorTestDSA.class,
-        AlgorithmParametersPSSTest.class,
-        AlgorithmParametersTestAES.class,
-        AlgorithmParametersTestDES.class,
-        AlgorithmParametersTestDESede.class,
-        AlgorithmParametersTestDH.class,
-        AlgorithmParametersTestDSA.class,
-        AlgorithmParametersTestEC.class,
-        AlgorithmParametersTestGCM.class,
-        AlgorithmParametersTestOAEP.class,
-        BufferUtilsTest.class,
-        CipherSuiteTest.class,
-        KeyFactoryTestDH.class,
-        KeyFactoryTestDSA.class,
-        KeyFactoryTestEC.class,
-        KeyFactoryTestRSA.class,
-        KeyFactoryTestRSACrt.class,
-        KeyPairGeneratorTest.class,
-        KeyPairGeneratorTestDH.class,
-        KeyPairGeneratorTestDSA.class,
-        KeyPairGeneratorTestRSA.class,
-        KeyPairGeneratorTestXDH.class,
-        MessageDigestTest.class,
-        SignatureTest.class,
-        // javax.crypto tests
-        AeadCipherTest.class,
-        CipherBasicsTest.class,
-        CipherTest.class,
-        MacTest.class,
-        ECDHKeyAgreementTest.class,
-        KeyGeneratorTest.class,
-        XDHKeyAgreementTest.class,
-        // javax.net.ssl tests
-        HttpsURLConnectionTest.class,
-        KeyManagerFactoryTest.class,
-        KeyStoreBuilderParametersTest.class,
-        OptionalMethodTest.class,
-        ProtocolTest.class,
-        ScryptTest.class,
-        SNIHostNameTest.class,
-        SSLContextTest.class,
-        SSLEngineTest.class,
-        SSLEngineVersionCompatibilityTest.class,
-        SSLParametersTest.class,
-        SSLServerSocketFactoryTest.class,
-        SSLServerSocketTest.class,
-        SSLSessionContextTest.class,
-        SSLSessionTest.class,
-        SSLSocketFactoryTest.class,
-        SSLSocketTest.class,
-        SSLSocketVersionCompatibilityTest.class,
-        TrustManagerFactoryTest.class,
-        VeryBasicHttpServerTest.class,
-        X509KeyManagerTest.class,
+  AddressUtilsTest.class,
+  ApplicationProtocolSelectorAdapterTest.class,
+  ClientSessionContextTest.class,
+  ConscryptSocketTest.class,
+  ConscryptTest.class,
+  DuckTypedPSKKeyManagerTest.class,
+  FileClientSessionCacheTest.class,
+  NativeCryptoTest.class,
+  NativeRefTest.class,
+  NativeSslSessionTest.class,
+  OpenSSLKeyTest.class,
+  OpenSSLX509CertificateTest.class,
+  PlatformTest.class,
+  ServerSessionContextTest.class,
+  SSLUtilsTest.class,
+  TestSessionBuilderTest.class,
 })
 public class ConscryptOpenJdkSuite {
 
diff --git a/platform/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java b/platform/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
index 06ff2cd..8108d44 100644
--- a/platform/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
+++ b/platform/src/test/java/org/conscrypt/TrustedCertificateStoreTest.java
@@ -833,14 +833,14 @@
         assertFalse(store.isUserAddedCertificate(getCa2()));
     }
 
-
-    // TODO(b/293296163): re-enable once https://r.android.com/2675835 ships via Mainline.
-    private void dontestSystemCaCertsUseCorrectFileNames() throws Exception {
+    @Test
+    public void testSystemCaCertsUseCorrectFileNames() throws Exception {
         File dir = new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
         useCorrectFileNamesTest(dir);
     }
 
-    private void dontTestSystemCaCertsUseCorrectFileNamesUpdatable() throws Exception {
+    @Test
+    public void testSystemCaCertsUseCorrectFileNamesUpdatable() throws Exception {
         File dir = new File("/apex/com.android.conscrypt/cacerts");
         useCorrectFileNamesTest(dir);
     }
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
index 9c037b3..f53c91d 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/NativeCrypto.java
@@ -18,6 +18,7 @@
 package com.android.org.conscrypt;
 
 import com.android.org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+import com.android.org.conscrypt.Platform;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -44,7 +45,6 @@
 import javax.crypto.ShortBufferException;
 import javax.net.ssl.SSLException;
 import javax.security.auth.x500.X500Principal;
-import com.android.org.conscrypt.Platform;
 
 /**
  * Provides the Java side of our JNI glue for OpenSSL.
@@ -880,8 +880,11 @@
     static {
         if (loadError == null) {
             // If loadError is not null, it means the native code was not loaded, so
-            // get_cipher_names will throw UnsatisfiedLinkError.
-            String[] allCipherSuites = get_cipher_names("ALL:!DHE");
+            // get_cipher_names will throw UnsatisfiedLinkError. Populate the list of supported
+            // ciphers with BoringSSL's default, and also explicitly include 3DES.
+            // https://boringssl-review.googlesource.com/c/boringssl/+/59425 will remove 3DES
+            // from BoringSSL's default, but Conscrypt isn't quite ready to remove it yet.
+            String[] allCipherSuites = get_cipher_names("ALL:3DES");
 
             // get_cipher_names returns an array where even indices are the standard name and odd
             // indices are the OpenSSL name.
@@ -1068,6 +1071,7 @@
             SUPPORTED_PROTOCOL_TLSV1_2,
             SUPPORTED_PROTOCOL_TLSV1_3,
     };
+
     public static String[] getDefaultProtocols() {
         if (Platform.isTlsV1Deprecated()) {
           return DEFAULT_PROTOCOLS.clone();
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
index 62414fc..7b3ee3b 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLMac.java
@@ -46,6 +46,7 @@
      * Holds a dummy buffer for writing single bytes to the digest.
      */
     private final byte[] singleByte = new byte[1];
+    protected boolean initialized = false;
 
     private OpenSSLMac(int size) {
         this.size = size;
@@ -82,7 +83,12 @@
             throw new InvalidKeyException("key cannot be encoded");
         }
 
-        resetContext();
+        try {
+            resetContext();
+        } catch (RuntimeException e) {
+            throw new InvalidKeyException("invalid key", e);
+        }
+        initialized = true;
     }
 
     @Override
@@ -139,6 +145,9 @@
 
     @Override
     protected void engineReset() {
+        if (!initialized) {
+            return;
+        }
         resetContext();
     }
 
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
index d496965..4891295 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLProvider.java
@@ -205,6 +205,7 @@
 
         put("KeyPairGenerator.XDH", PREFIX + "OpenSSLXDHKeyPairGenerator");
         put("Alg.Alias.KeyPairGenerator.1.3.101.110", "XDH");
+        put("Alg.Alias.KeyPairGenerator.X25519", "XDH");
 
         /* == KeyFactory == */
         put("KeyFactory.RSA", PREFIX + "OpenSSLRSAKeyFactory");
@@ -218,6 +219,7 @@
 
         put("KeyFactory.XDH", PREFIX + "OpenSSLXDHKeyFactory");
         put("Alg.Alias.KeyFactory.1.3.101.110", "XDH");
+        put("Alg.Alias.KeyFactory.X25519", "XDH");
 
         /* == SecretKeyFactory == */
         put("SecretKeyFactory.DESEDE", PREFIX + "DESEDESecretKeyFactory");
@@ -626,6 +628,8 @@
         String supportedKeyFormats = "PKCS#8";
         putImplClassWithKeyConstraints(
                 "KeyAgreement.XDH", PREFIX + className, supportedKeyClasses, supportedKeyFormats);
+
+        put("Alg.Alias.KeyAgreement.X25519", "XDH");
     }
 
     private void putImplClassWithKeyConstraints(String typeAndAlgName,
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLXDHKeyFactory.java b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLXDHKeyFactory.java
index 5271316..edd50f5 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLXDHKeyFactory.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/OpenSSLXDHKeyFactory.java
@@ -83,8 +83,9 @@
             throw new InvalidKeySpecException("keySpec == null");
         }
 
-        if (!"XDH".equals(key.getAlgorithm())) {
-            throw new InvalidKeySpecException("Key must be an XDH key");
+        // Support XDH or X25519 algorithm names per JEP 324
+        if (!"XDH".equals(key.getAlgorithm()) && !"X25519".equals(key.getAlgorithm())) {
+            throw new InvalidKeySpecException("Key must be an XDH or X25519 key");
         }
 
         Class<?> publicKeySpec = getJavaPublicKeySpec();
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING b/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING
index 317e347..70cd8ee 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/TEST_MAPPING
@@ -8,8 +8,14 @@
         },
         {
           "include-filter": "libcore.java.security"
+        },
+        {
+          "include-filter": "libcore.javax.net"
+        },
+        {
+          "include-filter": "libcore.java.net"
         }
       ]
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ReflexiveStatsEvent.java b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ReflexiveStatsEvent.java
index 9f8f36a..f223363 100644
--- a/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ReflexiveStatsEvent.java
+++ b/repackaged/common/src/main/java/com/android/org/conscrypt/metrics/ReflexiveStatsEvent.java
@@ -163,4 +163,4 @@
             return new ReflexiveStatsEvent(statsEvent);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
index 577162b..d0a1c64 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/MacTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
@@ -32,6 +33,7 @@
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.spec.AlgorithmParameterSpec;
 import java.util.HashSet;
@@ -151,6 +153,8 @@
                         mac = Mac.getInstance(algorithm, provider);
                         assertEquals(algorithm, mac.getAlgorithm());
                         assertEquals(provider, mac.getProvider());
+                        // It's not an error to reset an uninitialised Mac.
+                        mac.reset();
                         if (key != null) {
                             // TODO(prb) Ensure we have at least one test vector for every
                             // MAC in Conscrypt and Android.
@@ -170,7 +174,7 @@
     }
 
     @Test
-    public void invalidKeyThrows() {
+    public void invalidKeyTypeThrows() {
         newMacServiceTester()
                 // BC actually accepts RSA public keys for these algorithms for some reason.
                 .skipCombination("BC", "PBEWITHHMACSHA")
@@ -195,6 +199,16 @@
     }
 
     @Test
+    public void invalidCmacKeySizeThrows() throws Exception {
+        // TODO(prb): extend to other Macs, deal with inconsistencies between providers.
+        Mac mac = Mac.getInstance("AESCMAC", conscryptProvider);
+        byte[] keyBytes = new byte[1];
+        SecretKeySpec key = new SecretKeySpec(keyBytes, "RawBytes");
+
+        assertThrows(InvalidKeyException.class, () -> mac.init(key));
+    }
+
+    @Test
     public void uninitializedMacThrows() {
         newMacServiceTester().run(new ServiceTester.Test() {
             @Override
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java
index eabd058..3c83bad 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/KeyPairGeneratorTest.java
@@ -155,8 +155,8 @@
         putKeySize("DSA", 512);
         putKeySize("DSA", 512+64);
         putKeySize("DSA", 1024);
-        putKeySize("RSA", 512);
-        putKeySize("RSASSA-PSS", 512);
+        putKeySize("RSA", 2048);
+        putKeySize("RSASSA-PSS", 2048);
         putKeySize("DH", 512);
         putKeySize("DH", 512+64);
         putKeySize("DH", 1024);
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java
index 1599bfc..06b4f62 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/java/security/SignatureTest.java
@@ -120,6 +120,7 @@
                 .skipAlgorithm("Ed448")
                 .skipAlgorithm("Ed25519")
                 .skipAlgorithm("EdDSA")
+                .skipAlgorithm("HSS/LMS")
                 .run(new ServiceTester.Test() {
                     @Override
                     public void test(Provider provider, String algorithm) throws Exception {
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
index 5d7192d..bc42890 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/CipherTest.java
@@ -77,6 +77,7 @@
 import javax.crypto.spec.SecretKeySpec;
 import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
 import libcore.test.annotation.NonCts;
+import libcore.test.reasons.NonCtsReasons;
 import org.bouncycastle.asn1.x509.KeyUsage;
 import org.junit.Assume;
 import org.junit.BeforeClass;
@@ -1068,15 +1069,20 @@
                 if (firstSlash == -1) {
                     seenBaseCipherNames.add(algorithm);
                 } else {
-                    final String baseCipherName = algorithm.substring(0, firstSlash);
-                    if (!seenBaseCipherNames.contains(baseCipherName)
-                            && !(baseCipherName.equals("AES_128")
-                                || baseCipherName.equals("AES_192")
-                                || baseCipherName.equals("AES_256"))) {
-                        seenCiphersWithModeAndPadding.add(baseCipherName);
-                    }
-                    if (!Conscrypt.isConscrypt(provider)) {
-                        continue;
+                    final int secondSlash = algorithm.indexOf('/', firstSlash + 1);
+                    if (secondSlash > 0) {
+                        // Only look for a base Cipher if there are two slashes, to avoid SunJCE
+                        // quirks like PBEWithHmacSHA512/224AndAES_128
+                        final String baseCipherName = algorithm.substring(0, firstSlash);
+                        if (!seenBaseCipherNames.contains(baseCipherName)
+                                && !(baseCipherName.equals("AES_128")
+                                        || baseCipherName.equals("AES_192")
+                                        || baseCipherName.equals("AES_256"))) {
+                            seenCiphersWithModeAndPadding.add(baseCipherName);
+                        }
+                        if (!Conscrypt.isConscrypt(provider)) {
+                            continue;
+                        }
                     }
                 }
 
@@ -4645,69 +4651,6 @@
         assertEquals(Arrays.toString(c1.doFinal()), Arrays.toString(c2.doFinal()));
     }
 
-    /**
-     * http://b/27224566
-     * http://b/27994930
-     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
-     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
-     * mixing them is not recommended.
-     */
-    @NonCts(bug = 287231726, reason = "The test asserts buggy or non-breaking "
-            + "behaviors, but the behavior has been fixed in the future ART module version.")
-    @Test
-    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_noIV() throws Exception {
-        Assume.assumeNotNull(Security.getProvider("BC"));
-        byte[] plaintext =
-                new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
-        byte[] ciphertext = new byte[] {92, -65, -128, 16, -102, -115, -44, 52, 16, 124, -34, -45,
-                58, -70, -17, 127, 119, -67, 87, 91, 63, -13, -40, 9, 97, -17, -71, 97, 10, -61,
-                -19, -73};
-        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
-        PBEKeySpec pbeks = new PBEKeySpec(
-                "password".toCharArray(), "salt".getBytes(TestUtils.UTF_8), 100, 128);
-        SecretKey secretKey = skf.generateSecret(pbeks);
-
-        Cipher cipher = Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
-        PBEParameterSpec paramSpec = new PBEParameterSpec("salt".getBytes(TestUtils.UTF_8), 100);
-        assertThrows(InvalidAlgorithmParameterException.class,
-                () -> cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec));
-    }
-
-    /**
-     * http://b/27224566
-     * http://b/27994930
-     * Check that a PBKDF2WITHHMACSHA1 secret key factory works well with a
-     * PBEWITHSHAAND128BITAES-CBC-BC cipher. The former is PKCS5 and the latter is PKCS12, and so
-     * mixing them is not recommended. However, until 1.52 BouncyCastle was accepting this mixture,
-     * assuming the IV was a 0 vector. Some apps still use this functionality. This
-     * compatibility is likely to be removed in later versions of Android.
-     * TODO(27995180): consider whether we keep this compatibility. Consider whether we only allow
-     * if an IV is passed in the parameters.
-     */
-    @Test
-    public void test_PBKDF2WITHHMACSHA1_SKFactory_and_PBEAESCBC_Cipher_withIV() throws Exception {
-        Assume.assumeNotNull(Security.getProvider("BC"));
-        byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,  12, 13, 14, 15, 16,
-                17, 18, 19 };
-        byte[] ciphertext = { 68, -87, 71, -6, 32, -77, 124, 3, 35, -26, 96, -16, 100, -17, 52, -32,
-                110, 26, -117, 112, -25, -113, -58, -30, 19, -46, -21, 59, -126, -8, -70, -89 };
-        byte[] iv = new byte[] { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-        SecretKeyFactory skf =
-                SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA1");
-        PBEKeySpec pbeks = new PBEKeySpec("password".toCharArray(),
-                "salt".getBytes(TestUtils.UTF_8),
-                100, 128);
-        SecretKey secretKey = skf.generateSecret(pbeks);
-        Cipher cipher =
-                Cipher.getInstance("PBEWITHSHAAND128BITAES-CBC-BC");
-        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
-        assertEquals(Arrays.toString(ciphertext), Arrays.toString(cipher.doFinal(plaintext)));
-
-        secretKey = skf.generateSecret(pbeks);
-        cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
-        assertEquals(Arrays.toString(plaintext), Arrays.toString(cipher.doFinal(ciphertext)));
-    }
-
     private static Cipher createAesCipher(int opmode) {
         try {
             final Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java
new file mode 100644
index 0000000..cecc1d0
--- /dev/null
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/X25519KeyAgreementTest.java
@@ -0,0 +1,30 @@
+/* GENERATED SOURCE. DO NOT MODIFY. */
+package com.android.org.conscrypt.javax.crypto;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import javax.crypto.KeyAgreement;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+/**
+ * Tests for all registered X25519 {@link KeyAgreement} providers.
+ * @hide This class is not part of the Android public SDK API
+ */
+@RunWith(JUnit4.class)
+public class X25519KeyAgreementTest extends XDHKeyAgreementTest {
+
+    @Override
+    protected String getAlgorithm() {
+        return "X25519";
+    }
+}
diff --git a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
index 7f44a34..80c10eb 100644
--- a/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
+++ b/repackaged/common/src/test/java/com/android/org/conscrypt/javax/crypto/XDHKeyAgreementTest.java
@@ -61,7 +61,7 @@
     private PublicKey rfc7748X25519PublicKey;
 
     private void setupKeys(Provider p) throws Exception {
-        KeyFactory kf = KeyFactory.getInstance("XDH", p);
+        KeyFactory kf = KeyFactory.getInstance(getAlgorithm(), p);
 
         byte[] privateKey;
         if ("SunEC".equalsIgnoreCase(p.getName())
@@ -86,19 +86,24 @@
 
     @Test
     public void test_XDHKeyAgreement() throws Exception {
-        for (Provider p : Security.getProviders("KeyAgreement.XDH")) {
+        final String keyAgreementAlgorithm = String.format("KeyAgreement.%s", getAlgorithm());
+        for (Provider p : Security.getProviders(keyAgreementAlgorithm)) {
             // Skip testing Android Keystore as it's covered by CTS tests.
             if ("AndroidKeyStore".equals(p.getName())) {
                 continue;
             }
             setupKeys(p);
 
-            KeyAgreement ka = KeyAgreement.getInstance("XDH", p);
+            KeyAgreement ka = KeyAgreement.getInstance(getAlgorithm(), p);
 
             test_x25519_keyAgreement_rfc7748_kat_success(ka);
         }
     }
 
+    protected String getAlgorithm() {
+        return "XDH";
+    }
+
     private void test_x25519_keyAgreement_rfc7748_kat_success(KeyAgreement ka) throws Exception {
         ka.init(rfc7748X25519PrivateKey);
         ka.doPhase(rfc7748X25519PublicKey, true);
diff --git a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
index 54fec4c..42d9663 100644
--- a/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
+++ b/repackaged/openjdk/src/test/java/com/android/org/conscrypt/ConscryptOpenJdkSuite.java
@@ -12,91 +12,22 @@
  */
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
-        // org.conscrypt tests
-        AddressUtilsTest.class,
-        ApplicationProtocolSelectorAdapterTest.class,
-        CertPinManagerTest.class,
-        ChainStrengthAnalyzerTest.class,
-        ClientSessionContextTest.class,
-        ConscryptSocketTest.class,
-        ConscryptTest.class,
-        DuckTypedHpkeSpiTest.class,
-        DuckTypedPSKKeyManagerTest.class,
-        FileClientSessionCacheTest.class,
-        HostnameVerifierTest.class,
-        NativeCryptoArgTest.class,
-        NativeCryptoTest.class,
-        NativeRefTest.class,
-        NativeSslSessionTest.class,
-        OpenSSLKeyTest.class,
-        OpenSSLX509CertificateTest.class,
-        PlatformTest.class,
-        SSLUtilsTest.class,
-        ServerSessionContextTest.class,
-        TestSessionBuilderTest.class,
-        TrustManagerImplTest.class,
-        // org.conscrypt.ct tests
-        CTVerifierTest.class,
-        SerializationTest.class,
-        // java.security tests
-        CertificateFactoryTest.class,
-        X509CertificateTest.class,
-        X509CRLTest.class,
-        AlgorithmParameterGeneratorTestDH.class,
-        AlgorithmParameterGeneratorTestDSA.class,
-        AlgorithmParametersPSSTest.class,
-        AlgorithmParametersTestAES.class,
-        AlgorithmParametersTestDES.class,
-        AlgorithmParametersTestDESede.class,
-        AlgorithmParametersTestDH.class,
-        AlgorithmParametersTestDSA.class,
-        AlgorithmParametersTestEC.class,
-        AlgorithmParametersTestGCM.class,
-        AlgorithmParametersTestOAEP.class,
-        BufferUtilsTest.class,
-        CipherSuiteTest.class,
-        KeyFactoryTestDH.class,
-        KeyFactoryTestDSA.class,
-        KeyFactoryTestEC.class,
-        KeyFactoryTestRSA.class,
-        KeyFactoryTestRSACrt.class,
-        KeyPairGeneratorTest.class,
-        KeyPairGeneratorTestDH.class,
-        KeyPairGeneratorTestDSA.class,
-        KeyPairGeneratorTestRSA.class,
-        KeyPairGeneratorTestXDH.class,
-        MessageDigestTest.class,
-        SignatureTest.class,
-        // javax.crypto tests
-        AeadCipherTest.class,
-        CipherBasicsTest.class,
-        CipherTest.class,
-        MacTest.class,
-        ECDHKeyAgreementTest.class,
-        KeyGeneratorTest.class,
-        XDHKeyAgreementTest.class,
-        // javax.net.ssl tests
-        HttpsURLConnectionTest.class,
-        KeyManagerFactoryTest.class,
-        KeyStoreBuilderParametersTest.class,
-        OptionalMethodTest.class,
-        ProtocolTest.class,
-        ScryptTest.class,
-        SNIHostNameTest.class,
-        SSLContextTest.class,
-        SSLEngineTest.class,
-        SSLEngineVersionCompatibilityTest.class,
-        SSLParametersTest.class,
-        SSLServerSocketFactoryTest.class,
-        SSLServerSocketTest.class,
-        SSLSessionContextTest.class,
-        SSLSessionTest.class,
-        SSLSocketFactoryTest.class,
-        SSLSocketTest.class,
-        SSLSocketVersionCompatibilityTest.class,
-        TrustManagerFactoryTest.class,
-        VeryBasicHttpServerTest.class,
-        X509KeyManagerTest.class,
+  AddressUtilsTest.class,
+  ApplicationProtocolSelectorAdapterTest.class,
+  ClientSessionContextTest.class,
+  ConscryptSocketTest.class,
+  ConscryptTest.class,
+  DuckTypedPSKKeyManagerTest.class,
+  FileClientSessionCacheTest.class,
+  NativeCryptoTest.class,
+  NativeRefTest.class,
+  NativeSslSessionTest.class,
+  OpenSSLKeyTest.class,
+  OpenSSLX509CertificateTest.class,
+  PlatformTest.class,
+  ServerSessionContextTest.class,
+  SSLUtilsTest.class,
+  TestSessionBuilderTest.class,
 })
 public class ConscryptOpenJdkSuite {
 
diff --git a/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java b/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java
index cb2041b..f0fd50f 100644
--- a/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java
+++ b/repackaged/platform/src/test/java/com/android/org/conscrypt/TrustedCertificateStoreTest.java
@@ -17,6 +17,14 @@
 
 package com.android.org.conscrypt;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import com.android.org.conscrypt.java.security.TestKeyStore;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -56,14 +64,6 @@
 import org.junit.runners.Parameterized.Parameter;
 import org.junit.runners.Parameterized.Parameters;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
 /**
  * @hide This class is not part of the Android public SDK API
  */
@@ -837,13 +837,14 @@
         assertFalse(store.isUserAddedCertificate(getCa2()));
     }
 
-    // TODO(b/293296163): re-enable once https://r.android.com/2675835 ships via Mainline.
-    private void dontestSystemCaCertsUseCorrectFileNames() throws Exception {
+    @Test
+    public void testSystemCaCertsUseCorrectFileNames() throws Exception {
         File dir = new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
         useCorrectFileNamesTest(dir);
     }
 
-    private void dontTestSystemCaCertsUseCorrectFileNamesUpdatable() throws Exception {
+    @Test
+    public void testSystemCaCertsUseCorrectFileNamesUpdatable() throws Exception {
         File dir = new File("/apex/com.android.conscrypt/cacerts");
         useCorrectFileNamesTest(dir);
     }